@playpilot/tpi 8.32.0 → 8.33.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 +11 -11
- package/dist/link-injections.js +1 -1
- package/dist/mount.js +7 -7
- package/package.json +1 -1
- package/src/lib/scss/_mixins.scss +13 -0
- package/src/routes/components/Icons/IconFullscreen.svelte +3 -0
- package/src/routes/components/Rails/TitlesRail.svelte +1 -1
- package/src/routes/components/YouTubeEmbed.svelte +62 -15
- package/src/routes/components/YouTubeEmbedBackground.svelte +1 -1
- package/src/routes/elements/+page.svelte +1 -1
- package/src/tests/routes/components/YouTubeEmbed.test.js +9 -2
package/package.json
CHANGED
|
@@ -66,3 +66,16 @@
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
+
|
|
70
|
+
@mixin safari() {
|
|
71
|
+
@media not all and (min-resolution: 0.001dpcm) {
|
|
72
|
+
@supports (-webkit-appearance: none) {
|
|
73
|
+
@content;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@supports (hanging-punctuation: first) and (font: -apple-system-body) and
|
|
78
|
+
(-webkit-appearance: none) {
|
|
79
|
+
@content;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
<div class="video-overlay" title="" {onclick}></div>
|
|
189
189
|
|
|
190
190
|
{#if !!title.embeddable_url}
|
|
191
|
-
<YouTubeEmbed bind:this={embed} embeddable_url={title.embeddable_url!} muted loop captions
|
|
191
|
+
<YouTubeEmbed bind:this={embed} embeddable_url={title.embeddable_url!} muted loop captions showActions />
|
|
192
192
|
{:else}
|
|
193
193
|
<img class="video-fallback" src={title.medium_poster} alt="" />
|
|
194
194
|
{/if}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { getVideoId } from '$lib/trailer'
|
|
2
|
+
import { getVideoId, openTrailerOverlay } from '$lib/trailer'
|
|
3
3
|
import { onMount } from 'svelte'
|
|
4
4
|
import IconMute from './Icons/IconMute.svelte'
|
|
5
|
+
import IconFullscreen from './Icons/IconFullscreen.svelte'
|
|
6
|
+
import type { TitleData } from '$lib/types/title'
|
|
5
7
|
|
|
6
8
|
interface Props {
|
|
7
9
|
embeddable_url: string
|
|
@@ -10,17 +12,19 @@
|
|
|
10
12
|
loop?: boolean
|
|
11
13
|
captions?: boolean
|
|
12
14
|
autoplay?: boolean
|
|
13
|
-
|
|
15
|
+
showActions?: boolean
|
|
14
16
|
fallbackStartTime?: number
|
|
17
|
+
clickToPlay?: boolean
|
|
15
18
|
}
|
|
16
19
|
|
|
17
|
-
let { embeddable_url = '', controls = [], muted = false, loop = false, captions = false, autoplay = true,
|
|
20
|
+
let { embeddable_url = '', controls = [], muted = false, loop = false, captions = false, autoplay = true, showActions = false, fallbackStartTime = 0, clickToPlay = true }: Props = $props()
|
|
18
21
|
|
|
19
22
|
const videoId = $derived(getVideoId(embeddable_url))
|
|
20
23
|
const startTime = $derived((window?.PlayPilotLinkInjections?.video_playtimes?.[videoId || ''] || (fallbackStartTime + 1)) - 1)
|
|
21
24
|
const color = window?.getComputedStyle(document.body).getPropertyValue('--playpilot-primary')?.replace('#', '') || 'fa548a'
|
|
22
25
|
|
|
23
26
|
let element: HTMLElement | null = $state(null)
|
|
27
|
+
let fullscreen: boolean = $state(false)
|
|
24
28
|
let player: any
|
|
25
29
|
|
|
26
30
|
onMount(() => {
|
|
@@ -45,11 +49,12 @@
|
|
|
45
49
|
element.style.setProperty('--plyr-color-main', '#' + color)
|
|
46
50
|
|
|
47
51
|
player = new window.Plyr(element, {
|
|
48
|
-
controls,
|
|
52
|
+
controls: controls.length === 0 ? ['play', 'mute', 'fullscreen', 'progress', 'current-time'] : controls,
|
|
49
53
|
playsinline: true,
|
|
50
54
|
autoplay,
|
|
51
55
|
muted,
|
|
52
|
-
clickToPlay
|
|
56
|
+
clickToPlay,
|
|
57
|
+
storage: { enabled: false },
|
|
53
58
|
youtube: {
|
|
54
59
|
noCookie: true,
|
|
55
60
|
cc_load_policy: captions ? 1 : 0,
|
|
@@ -62,6 +67,16 @@
|
|
|
62
67
|
toggleMute(muted)
|
|
63
68
|
})
|
|
64
69
|
|
|
70
|
+
player.on('enterfullscreen', () => {
|
|
71
|
+
fullscreen = true
|
|
72
|
+
toggleMute(false)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
player.on('exitfullscreen', () => {
|
|
76
|
+
fullscreen = false
|
|
77
|
+
toggleMute(true)
|
|
78
|
+
})
|
|
79
|
+
|
|
65
80
|
if (!loop) return
|
|
66
81
|
|
|
67
82
|
player.on('statechange', (event: { detail: { code: number } }) => {
|
|
@@ -75,10 +90,19 @@
|
|
|
75
90
|
}
|
|
76
91
|
|
|
77
92
|
export function toggleMute(state = !muted): void {
|
|
93
|
+
muted = state
|
|
78
94
|
player.muted = state
|
|
79
|
-
player.volume =
|
|
95
|
+
player.volume = state ? 0 : 1
|
|
96
|
+
}
|
|
80
97
|
|
|
81
|
-
|
|
98
|
+
export function enterFullscreen(): void {
|
|
99
|
+
if (/iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) {
|
|
100
|
+
openTrailerOverlay({ embeddable_url } as TitleData)
|
|
101
|
+
toggleMute(true)
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
player.fullscreen.enter()
|
|
82
106
|
}
|
|
83
107
|
|
|
84
108
|
export function play(event: CustomEvent): void {
|
|
@@ -100,13 +124,19 @@
|
|
|
100
124
|
</svelte:head>
|
|
101
125
|
|
|
102
126
|
{#if videoId}
|
|
103
|
-
<div
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
127
|
+
<div class:fullscreen class:hide-controls={controls.length === 0 && !fullscreen}>
|
|
128
|
+
<div bind:this={element} class="player" data-plyr-provider="youtube" data-plyr-embed-id data-testid={embeddable_url}></div>
|
|
129
|
+
|
|
130
|
+
{#if showActions}
|
|
131
|
+
<button class="action" onclick={() => toggleMute()} aria-label="Mute">
|
|
132
|
+
<IconMute {muted} />
|
|
133
|
+
</button>
|
|
134
|
+
|
|
135
|
+
<button class="action secondary" onclick={enterFullscreen} aria-label="Fullscreen">
|
|
136
|
+
<IconFullscreen />
|
|
137
|
+
</button>
|
|
138
|
+
{/if}
|
|
139
|
+
</div>
|
|
110
140
|
{:else}
|
|
111
141
|
Something went wrong
|
|
112
142
|
{/if}
|
|
@@ -123,7 +153,20 @@
|
|
|
123
153
|
height: 100%;
|
|
124
154
|
}
|
|
125
155
|
|
|
126
|
-
.
|
|
156
|
+
.fullscreen :global(iframe) {
|
|
157
|
+
height: 100%;
|
|
158
|
+
width: 100%;
|
|
159
|
+
top: 0;
|
|
160
|
+
left: 0;
|
|
161
|
+
transform: none;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.hide-controls :global(.plyr__controls) {
|
|
165
|
+
display: none;
|
|
166
|
+
opacity: 0;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.action {
|
|
127
170
|
z-index: 10;
|
|
128
171
|
display: flex;
|
|
129
172
|
align-items: center;
|
|
@@ -148,5 +191,9 @@
|
|
|
148
191
|
&:active {
|
|
149
192
|
transform: scale(0.95);
|
|
150
193
|
}
|
|
194
|
+
|
|
195
|
+
&.secondary {
|
|
196
|
+
top: calc(margin(3) + var(--mute-top, 0px));
|
|
197
|
+
}
|
|
151
198
|
}
|
|
152
199
|
</style>
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
17
|
<div class="video-background" style="--height: {height}px; --width: {clientWidth}px;" bind:clientWidth bind:clientHeight data-testid="video-background">
|
|
18
|
-
<YouTubeEmbed {embeddable_url} {autoplay} fallbackStartTime={5} muted loop
|
|
18
|
+
<YouTubeEmbed {embeddable_url} {autoplay} fallbackStartTime={5} muted loop showActions clickToPlay={false} />
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
<style lang="scss">
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
<h2>Youtube Embed</h2>
|
|
49
49
|
|
|
50
50
|
<div class="video">
|
|
51
|
-
<YouTubeEmbed embeddable_url="https://www.youtube.com/watch?v=bBMajXwi6Cs" controls={['progress', 'play']} loop
|
|
51
|
+
<YouTubeEmbed embeddable_url="https://www.youtube.com/watch?v=bBMajXwi6Cs" controls={['progress', 'play']} loop showActions muted />
|
|
52
52
|
</div>
|
|
53
53
|
|
|
54
54
|
<h2>Title</h2>
|
|
@@ -54,10 +54,10 @@ describe('YouTubeEmbed.svelte', () => {
|
|
|
54
54
|
expect(Plyr).toHaveBeenCalledWith(
|
|
55
55
|
playerElement,
|
|
56
56
|
expect.objectContaining({
|
|
57
|
-
controls: [],
|
|
57
|
+
controls: ['play', 'mute', 'fullscreen', 'progress', 'current-time'],
|
|
58
58
|
autoplay: true,
|
|
59
59
|
muted: false,
|
|
60
|
-
clickToPlay:
|
|
60
|
+
clickToPlay: true,
|
|
61
61
|
playsinline: true,
|
|
62
62
|
youtube: expect.objectContaining({ noCookie: true, cc_load_policy: 0, cc_lang_pref: 'auto' }),
|
|
63
63
|
}),
|
|
@@ -145,4 +145,11 @@ describe('YouTubeEmbed.svelte', () => {
|
|
|
145
145
|
expect(container.querySelector('.player')).not.toBeTruthy()
|
|
146
146
|
expect(getByText('Something went wrong')).toBeTruthy()
|
|
147
147
|
})
|
|
148
|
+
|
|
149
|
+
it('Should render actions when showActions is true', () => {
|
|
150
|
+
const { getByLabelText } = render(YouTubeEmbed, { embeddable_url: 'youtube.com/watch?v=abc', showActions: true })
|
|
151
|
+
|
|
152
|
+
expect(getByLabelText('Mute')).toBeTruthy()
|
|
153
|
+
expect(getByLabelText('Fullscreen')).toBeTruthy()
|
|
154
|
+
})
|
|
148
155
|
})
|