Skip to content

Commit

Permalink
feat: add useScriptVimeo + Vimeo component (#8)
Browse files Browse the repository at this point in the history
Co-authored-by: Harlan Wilton <[email protected]>
  • Loading branch information
darioferderber and harlan-zw committed Apr 11, 2024
1 parent c03df8d commit 7626cea
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 0 deletions.
8 changes: 8 additions & 0 deletions playground/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ const thirdParties = [
name: 'Segment',
path: '/third-parties/segment',
},
{
name: 'Vimeo',
path: '/third-parties/vimeo',
},
{
name: 'Vimeo component',
path: '/third-parties/vimeo-component',
},
]
const features = [
Expand Down
16 changes: 16 additions & 0 deletions playground/pages/third-parties/vimeo-component.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script lang="ts" setup>
import { useHead } from '#imports'
import { VimeoEmbed } from '#components'
useHead({
title: 'Vimeo component',
})
function handlePlay() {
console.log('Playing')

Check failure on line 10 in playground/pages/third-parties/vimeo-component.vue

View workflow job for this annotation

GitHub Actions / ci

Unexpected console statement
}
</script>

<template>
<VimeoEmbed video-id="76979871" width="640" height="400" :loop="true" @play="handlePlay" />
</template>

Check failure on line 16 in playground/pages/third-parties/vimeo-component.vue

View workflow job for this annotation

GitHub Actions / ci

Newline required at end of file but not found
20 changes: 20 additions & 0 deletions playground/pages/third-parties/vimeo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<script lang="ts" setup>
import { onMounted, useHead, useScriptVimeo } from '#imports'
useHead({
title: 'Vimeo',
})
onMounted(() => {
const { Player } = useScriptVimeo()
Player('player', {
id: 76979871,
width: 400,
height: 400

Check failure on line 13 in playground/pages/third-parties/vimeo.vue

View workflow job for this annotation

GitHub Actions / ci

Missing trailing comma
})
})
</script>

<template>
<div id="player"></div>

Check warning on line 19 in playground/pages/third-parties/vimeo.vue

View workflow job for this annotation

GitHub Actions / ci

Require self-closing on HTML elements (<div>)
</template>

Check failure on line 20 in playground/pages/third-parties/vimeo.vue

View workflow job for this annotation

GitHub Actions / ci

Newline required at end of file but not found
10 changes: 10 additions & 0 deletions src/module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
addBuildPlugin,
addComponentsDir,
addImports,
addImportsDir,
addPlugin,
Expand Down Expand Up @@ -106,6 +107,10 @@ export default defineNuxtModule<ModuleOptions>({
resolve('./runtime/composables'),
])

addComponentsDir({
path: resolve('./runtime/components')

Check failure on line 111 in src/module.ts

View workflow job for this annotation

GitHub Actions / ci

Missing trailing comma
})

nuxt.hooks.hook('modules:done', async () => {
let registry: RegistryScripts = [
{
Expand Down Expand Up @@ -148,6 +153,11 @@ export default defineNuxtModule<ModuleOptions>({
})
},
},
{
name: 'useScriptVimeo',
from: resolve('./runtime/registry/vimeo'),
key: 'vimeo',
},
{
name: 'useScriptIntercom',
from: resolve('./runtime/registry/intercom'),
Expand Down
162 changes: 162 additions & 0 deletions src/runtime/components/VimeoEmbed.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<template>
<div ref="root" :id="id">

Check warning on line 2 in src/runtime/components/VimeoEmbed.vue

View workflow job for this annotation

GitHub Actions / ci

Attribute ":id" should go before "ref"
<slot />
</div>
</template>

<script lang="ts" setup>

Check failure on line 7 in src/runtime/components/VimeoEmbed.vue

View workflow job for this annotation

GitHub Actions / ci

'<script lang=ts setup>' should be above '<template>' on line 1
import { useIntersectionObserver } from "@vueuse/core";

Check failure on line 8 in src/runtime/components/VimeoEmbed.vue

View workflow job for this annotation

GitHub Actions / ci

Strings must use singlequote

Check failure on line 8 in src/runtime/components/VimeoEmbed.vue

View workflow job for this annotation

GitHub Actions / ci

Extra semicolon
import { ref, onBeforeUnmount, useId, useScriptVimeo } from "#imports";

Check failure on line 9 in src/runtime/components/VimeoEmbed.vue

View workflow job for this annotation

GitHub Actions / ci

Member 'onBeforeUnmount' of the import declaration should be sorted alphabetically

Check failure on line 9 in src/runtime/components/VimeoEmbed.vue

View workflow job for this annotation

GitHub Actions / ci

Strings must use singlequote
const props = withDefaults(
defineProps<{
videoId: string;
lazy?: boolean;
rootMargin?: string;
width?: string | number;
height?: string | number;
options?: Object;
loop?: boolean;
autoplay?: boolean;
controls?: boolean;
}>(),
{
lazy: true,
rootMargin: "50px 50px 50px 50px",
width: "640",
height: "360",
options: () => ({}),
loop: false,
autoplay: false,
controls: true,
}
);
// TODO: put events in <script> - after build it doesn't work for some reason
// error: "both scripts must have same language type" even if they're both written in ts
const events: string[] = [
"play",
"playing",
"pause",
"ended",
"timeupdate",
"progress",
"seeking",
"seeked",
"texttrackchange",
"chapterchange",
"cuechange",
"cuepoint",
"volumechange",
"playbackratechange",
"bufferstart",
"bufferend",
"error",
"loaded",
"durationchange",
"fullscreenchange",
"qualitychange",
"camerachange",
"resize",
];
const emit = defineEmits([
"play",
"playing",
"pause",
"ended",
"timeupdate",
"progress",
"seeking",
"seeked",
"texttrackchange",
"chapterchange",
"cuechange",
"cuepoint",
"volumechange",
"playbackratechange",
"bufferstart",
"bufferend",
"error",
"loaded",
"durationchange",
"fullscreenchange",
"qualitychange",
"camerachange",
"resize",
]);
const _id = useId();
const id = _id.replace("-", "").replace("_", "");
const status: Ref<string | null> = ref(null);
const root = ref(null);
const { Player, $script } = useScriptVimeo({
trigger: props.lazy ? "manual" : undefined,
});
let player: any;
if (!props.lazy) $script.then(init);
else {
const { stop: stopIntersectionObserver } = useIntersectionObserver(
root,
([{ isIntersecting }]) => {
if (isIntersecting && !$script.loaded) {
$script.load().then(() => {
init();
stopIntersectionObserver();
});
}
},
{ rootMargin: props.rootMargin }
);
}
onBeforeUnmount(() => player?.unload());
function init() {
player = Player(id, {
id: props.videoId,
width: props.width,
height: props.height,
loop: props.loop,
autoplay: props.autoplay,
controls: props.controls,
...props.options,
});
for (const event of events) {
player?.on(event, (e: any) => {
emit(event as keyof typeof emit, e, player);
status.value = event;
});
}
}
function play() {
player?.play();
}
function pause() {
player?.pause();
}
function mute() {
player?.setVolume(0);
}
function unmute(volume: number = 1) {
player?.setVolume(volume);
}
defineExpose({
play,
pause,
mute,
unmute,
status,
});
</script>
40 changes: 40 additions & 0 deletions src/runtime/registry/vimeo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { type Input, object, string } from 'valibot'
import { useScript } from '#imports'
import type { NuxtUseScriptOptions } from '#nuxt-scripts'

export interface VimeoScriptApi {
Player: any
}

export const VimeoScriptOptions = object({})

export type VimeoPlayer = ((...params: any[]) => void) | undefined

export type VimeoScriptInput = Input<typeof VimeoScriptOptions>

declare global {
interface Window {
Vimeo: VimeoScriptApi
}
}

export function useScriptVimeo<T>(options?: VimeoScriptInput, _scriptOptions?: Omit<NuxtUseScriptOptions<T>, 'beforeInit' | 'use'>) {
const scriptOptions: NuxtUseScriptOptions<T> = _scriptOptions || {}

return useScript<VimeoScriptApi>({
key: 'vimeo',
src: 'https://player.vimeo.com/api/player.js',
...options,
}, {
...scriptOptions,
use: () => {
let Player: VimeoPlayer
if (import.meta.client) {
Player = function (...params: any[]) {
return new window.Vimeo.Player(...params)
}
}
return { Player }
},
})
}

0 comments on commit 7626cea

Please sign in to comment.