@playpilot/tpi 8.6.1 → 8.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editorial.mount.js +8 -8
- package/dist/link-injections.js +1 -1
- package/dist/mount.js +7 -7
- package/package.json +1 -1
- package/src/lib/data/genres.json +234 -275
- package/src/routes/components/Explore/Filter/Filter.svelte +1 -1
- package/src/routes/components/Genres.svelte +1 -0
- package/src/routes/components/Icons/IconMute.svelte +15 -0
- package/src/routes/components/Rails/TitlesRail.svelte +3 -1
- package/src/routes/components/YouTubeEmbed.svelte +47 -2
- package/src/tests/routes/components/YouTubeEmbed.test.js +6 -1
- package/src/tests/routes/components/YouTubeEmbedBackground.test.js +1 -1
- package/src/tests/routes/components/YouTubeEmbedOverlay.test.js +1 -1
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
|
|
45
45
|
let element: HTMLElement | null = $state(null)
|
|
46
46
|
let slider: ReturnType<typeof TinySlider> | null = $state(null)
|
|
47
|
+
let embed: ReturnType<typeof YouTubeEmbed> | null = $state(null)
|
|
47
48
|
let recentlyExpanded = false
|
|
48
49
|
|
|
49
50
|
onMount(() => {
|
|
@@ -80,6 +81,7 @@
|
|
|
80
81
|
openModal({ event, data: title, returnToTitle })
|
|
81
82
|
}
|
|
82
83
|
|
|
84
|
+
embed?.toggleMute(true)
|
|
83
85
|
onclick(title)
|
|
84
86
|
}
|
|
85
87
|
|
|
@@ -170,7 +172,7 @@
|
|
|
170
172
|
<a class="video-overlay" title="" {href} {onclick}></a>
|
|
171
173
|
|
|
172
174
|
{#if !!title.embeddable_url}
|
|
173
|
-
<YouTubeEmbed embeddable_url={title.embeddable_url!} muted loop />
|
|
175
|
+
<YouTubeEmbed bind:this={embed} embeddable_url={title.embeddable_url!} muted loop captions showMuteControls />
|
|
174
176
|
{:else}
|
|
175
177
|
<img class="video-fallback" src={title.medium_poster} alt="" />
|
|
176
178
|
{/if}
|
|
@@ -1,29 +1,47 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getVideoId } from '$lib/trailer'
|
|
3
|
+
import IconMute from './Icons/IconMute.svelte'
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
6
|
embeddable_url: string
|
|
6
7
|
controls?: ('play' | 'mute' | 'fullscreen' | 'progress' | 'current-time')[]
|
|
7
8
|
muted?: boolean
|
|
8
9
|
loop?: boolean
|
|
10
|
+
captions?: boolean
|
|
11
|
+
showMuteControls?: boolean
|
|
9
12
|
}
|
|
10
13
|
|
|
11
|
-
const { embeddable_url = '', controls = [], muted = false, loop = false }: Props = $props()
|
|
14
|
+
const { embeddable_url = '', controls = [], muted = false, loop = false, captions = false, showMuteControls = false }: Props = $props()
|
|
12
15
|
|
|
13
16
|
const videoId = $derived(getVideoId(embeddable_url))
|
|
14
17
|
const color = window?.getComputedStyle(document.body).getPropertyValue('--playpilot-primary')?.replace('#', '') || 'fa548a'
|
|
18
|
+
|
|
19
|
+
let iframe: HTMLIFrameElement | null = $state(null)
|
|
20
|
+
let isMuted = $state(muted)
|
|
21
|
+
|
|
22
|
+
export function toggleMute(state = !isMuted): void {
|
|
23
|
+
if (isMuted != state) iframe?.contentWindow?.postMessage('mute', '*')
|
|
24
|
+
isMuted = state
|
|
25
|
+
}
|
|
15
26
|
</script>
|
|
16
27
|
|
|
17
28
|
{#if videoId}
|
|
18
29
|
<iframe
|
|
30
|
+
bind:this={iframe}
|
|
19
31
|
width="600"
|
|
20
32
|
height="338"
|
|
21
|
-
src="https://video.playpilot.net/?video_id={videoId}&color={color}&muted={muted}&loop={loop}&controls={controls.join(',')}&autoplay=true&playsinline=true"
|
|
33
|
+
src="https://video.playpilot.net/?video_id={videoId}&color={color}&muted={muted}&loop={loop}&captions={captions}&controls={controls.join(',')}&autoplay=true&playsinline=true"
|
|
22
34
|
title="YouTube video player"
|
|
23
35
|
frameborder="0"
|
|
24
36
|
referrerpolicy="strict-origin-when-cross-origin"
|
|
25
37
|
allowfullscreen>
|
|
26
38
|
</iframe>
|
|
39
|
+
|
|
40
|
+
{#if showMuteControls}
|
|
41
|
+
<button class="mute" onclick={() => toggleMute()}>
|
|
42
|
+
<IconMute muted={isMuted} />
|
|
43
|
+
</button>
|
|
44
|
+
{/if}
|
|
27
45
|
{:else}
|
|
28
46
|
Something went wrong
|
|
29
47
|
{/if}
|
|
@@ -33,4 +51,31 @@
|
|
|
33
51
|
width: 100%;
|
|
34
52
|
height: 100%;
|
|
35
53
|
}
|
|
54
|
+
|
|
55
|
+
.mute {
|
|
56
|
+
z-index: 10;
|
|
57
|
+
display: flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
position: absolute;
|
|
61
|
+
top: margin(0.5);
|
|
62
|
+
right: margin(0.5);
|
|
63
|
+
padding: margin(0.25);
|
|
64
|
+
border: 0;
|
|
65
|
+
border-radius: 50%;
|
|
66
|
+
background: transparent;
|
|
67
|
+
filter: drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.5));
|
|
68
|
+
transition: transform 50ms;
|
|
69
|
+
cursor: pointer;
|
|
70
|
+
color: white;
|
|
71
|
+
|
|
72
|
+
&:hover {
|
|
73
|
+
outline: 1px solid white;
|
|
74
|
+
transform: scale(1.1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
&:active {
|
|
78
|
+
transform: scale(0.95);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
36
81
|
</style>
|
|
@@ -7,7 +7,7 @@ describe('YouTubeEmbed.svelte', () => {
|
|
|
7
7
|
it('Should render embed iframe with given video url and default options', () => {
|
|
8
8
|
const { container } = render(YouTubeEmbed, { embeddable_url: 'youtube.com/watch?v=abc' })
|
|
9
9
|
|
|
10
|
-
expect(/** @type {HTMLIFrameElement} */ (container.querySelector('iframe')).src).toBe('https://video.playpilot.net/?video_id=abc&color=fa548a&muted=false&loop=false&controls=&autoplay=true&playsinline=true')
|
|
10
|
+
expect(/** @type {HTMLIFrameElement} */ (container.querySelector('iframe')).src).toBe('https://video.playpilot.net/?video_id=abc&color=fa548a&muted=false&loop=false&captions=false&controls=&autoplay=true&playsinline=true')
|
|
11
11
|
})
|
|
12
12
|
|
|
13
13
|
it('Should render embed iframe with given controls', () => {
|
|
@@ -28,6 +28,11 @@ describe('YouTubeEmbed.svelte', () => {
|
|
|
28
28
|
expect(/** @type {HTMLIFrameElement} */ (container.querySelector('iframe')).src).toContain('&loop=true')
|
|
29
29
|
})
|
|
30
30
|
|
|
31
|
+
it('Should render embed iframe with captions if given', () => {
|
|
32
|
+
const { container } = render(YouTubeEmbed, { embeddable_url: 'youtube.com/watch?v=abc', captions: true })
|
|
33
|
+
|
|
34
|
+
expect(/** @type {HTMLIFrameElement} */ (container.querySelector('iframe')).src).toContain('&captions=true')
|
|
35
|
+
})
|
|
31
36
|
|
|
32
37
|
it('Should render error message if embeddable_url is invalid', () => {
|
|
33
38
|
const { container, getByText } = render(YouTubeEmbed, { embeddable_url: '-' })
|
|
@@ -8,6 +8,6 @@ describe('YouTubeEmbedBackground.svelte', () => {
|
|
|
8
8
|
const { container } = render(YouTubeEmbedBackground, { embeddable_url: 'youtube.com/watch?v=abc' })
|
|
9
9
|
|
|
10
10
|
// @ts-ignore
|
|
11
|
-
expect(container.querySelector('iframe').src).toBe('https://video.playpilot.net/?video_id=abc&color=fa548a&muted=true&loop=true&controls=&autoplay=true&playsinline=true')
|
|
11
|
+
expect(container.querySelector('iframe').src).toBe('https://video.playpilot.net/?video_id=abc&color=fa548a&muted=true&loop=true&captions=false&controls=&autoplay=true&playsinline=true')
|
|
12
12
|
})
|
|
13
13
|
})
|
|
@@ -8,7 +8,7 @@ describe('YouTubeEmbedOverlay.svelte', () => {
|
|
|
8
8
|
const { container } = render(YouTubeEmbedOverlay, { embeddable_url: 'youtube.com/watch?v=abc', onclose: () => null })
|
|
9
9
|
|
|
10
10
|
// @ts-ignore
|
|
11
|
-
expect(container.querySelector('iframe').src).toBe('https://video.playpilot.net/?video_id=abc&color=fa548a&muted=false&loop=false&controls=current-time,fullscreen,mute,play,progress&autoplay=true&playsinline=true')
|
|
11
|
+
expect(container.querySelector('iframe').src).toBe('https://video.playpilot.net/?video_id=abc&color=fa548a&muted=false&loop=false&captions=false&controls=current-time,fullscreen,mute,play,progress&autoplay=true&playsinline=true')
|
|
12
12
|
})
|
|
13
13
|
|
|
14
14
|
it('Should fire given onclose function on click of close button and backdrop', async () => {
|