@playpilot/tpi 8.23.0-beta.6 → 8.23.0
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 +2 -2
- package/dist/mount.js +7 -7
- package/package.json +1 -1
- package/src/lib/enums/SplitTest.ts +5 -0
- package/src/lib/splitTest.ts +14 -3
- package/src/routes/components/Explore/Routes/ExploreModal.svelte +8 -1
- package/src/routes/components/Modals/TitlesReelModal.svelte +21 -6
- package/src/routes/components/YouTubeEmbed.svelte +3 -2
- package/src/routes/components/YouTubeEmbedBackground.svelte +1 -1
- package/src/tests/lib/splitTest.test.js +13 -2
- package/src/tests/routes/components/YouTubeEmbed.test.js +6 -0
- package/src/tests/routes/components/YouTubeEmbedBackground.test.js +1 -1
package/package.json
CHANGED
package/src/lib/splitTest.ts
CHANGED
|
@@ -8,6 +8,8 @@ type SplitTest = {
|
|
|
8
8
|
variantNames?: string[]
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
export const sessionStoragePrefix = 'playpilot_split_test_'
|
|
12
|
+
|
|
11
13
|
/**
|
|
12
14
|
* Each split test uses a different split test identifier so a user can be part of one, multiple, or none, tests.
|
|
13
15
|
* The identifier is saved on the window object so that it is consistent across this session.
|
|
@@ -20,10 +22,19 @@ export function getSplitTestIdentifier({ key }: SplitTest): number {
|
|
|
20
22
|
|
|
21
23
|
if (!window.PlayPilotLinkInjections?.split_test_identifiers) window.PlayPilotLinkInjections.split_test_identifiers = {}
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
let storedIdentifier = sessionStorage.getItem(sessionStoragePrefix + key)
|
|
26
|
+
|
|
27
|
+
if (!storedIdentifier) {
|
|
28
|
+
const randomIdentifier = Math.random().toString()
|
|
29
|
+
sessionStorage.setItem(sessionStoragePrefix + key, randomIdentifier)
|
|
30
|
+
storedIdentifier = randomIdentifier
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const parsed = parseFloat(storedIdentifier!)
|
|
34
|
+
|
|
35
|
+
window.PlayPilotLinkInjections.split_test_identifiers[key] = parsed
|
|
25
36
|
|
|
26
|
-
return
|
|
37
|
+
return parsed
|
|
27
38
|
}
|
|
28
39
|
|
|
29
40
|
export function getSplitTestVariantIndex(test: SplitTest): number {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { fetchSimilarTitles, fetchTitleBySid } from '$lib/api/titles'
|
|
3
3
|
import { mobileBreakpoint } from '$lib/constants'
|
|
4
|
+
import { SplitTest } from '$lib/enums/SplitTest'
|
|
4
5
|
import { openModal } from '$lib/modal'
|
|
6
|
+
import { getSplitTestVariantName, trackSplitTestView } from '$lib/splitTest'
|
|
5
7
|
import type { TitleData } from '$lib/types/title'
|
|
6
8
|
|
|
7
9
|
interface Props {
|
|
@@ -15,10 +17,15 @@
|
|
|
15
17
|
async function openModalViaRoute(): Promise<void> {
|
|
16
18
|
const currentUrl = new URL(document.location.toString())
|
|
17
19
|
const sid = currentUrl.searchParams.get('sid')
|
|
18
|
-
const type = window.innerWidth > mobileBreakpoint ? 'titles-rail' : 'titles-reel'
|
|
19
20
|
|
|
20
21
|
if (!sid) return
|
|
21
22
|
|
|
23
|
+
const isMobile = window.innerWidth < mobileBreakpoint
|
|
24
|
+
const isInReelSplitTest = isMobile && getSplitTestVariantName(SplitTest.Reels) === 'Reel'
|
|
25
|
+
const type = isMobile && isInReelSplitTest ? 'titles-reel' : 'titles-rail'
|
|
26
|
+
|
|
27
|
+
if (isMobile) trackSplitTestView(SplitTest.Reels)
|
|
28
|
+
|
|
22
29
|
try {
|
|
23
30
|
const [title, railTitles] = (await Promise.allSettled([
|
|
24
31
|
fetchTitleBySid(sid),
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
<Modal>
|
|
50
50
|
{#snippet dialog()}
|
|
51
51
|
<div class="slider">
|
|
52
|
-
<TinySlider vertical threshold={
|
|
52
|
+
<TinySlider vertical threshold={50} moveThreshold={10} onchange={pauseAndPlay}>
|
|
53
53
|
{#snippet children({ currentIndex, setIndex })}
|
|
54
54
|
{#each titles as title, index}
|
|
55
55
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
@@ -64,7 +64,9 @@
|
|
|
64
64
|
</div>
|
|
65
65
|
|
|
66
66
|
<div class="details">
|
|
67
|
-
|
|
67
|
+
{#if title.description}
|
|
68
|
+
<Description text={title.description} blurb={title.blurb} limit={80} />
|
|
69
|
+
{/if}
|
|
68
70
|
|
|
69
71
|
<div class="playlinks-heading" use:heading={3}>{t('Where To Stream Online')}</div>
|
|
70
72
|
|
|
@@ -97,7 +99,7 @@
|
|
|
97
99
|
|
|
98
100
|
<style lang="scss">
|
|
99
101
|
$modal-height: calc(100vh - margin(4.5));
|
|
100
|
-
$item-height: calc($modal-height - margin(
|
|
102
|
+
$item-height: calc($modal-height - margin(5));
|
|
101
103
|
|
|
102
104
|
.reel {
|
|
103
105
|
--playpilot-detail-background-height: #{$item-height};
|
|
@@ -153,13 +155,14 @@
|
|
|
153
155
|
}
|
|
154
156
|
|
|
155
157
|
.header {
|
|
156
|
-
position: relative;
|
|
157
158
|
z-index: 2;
|
|
158
|
-
|
|
159
|
+
position: relative;
|
|
160
|
+
padding: theme(reel-item-padding, margin(1) margin(2) margin(2));
|
|
159
161
|
font-size: theme(reel-header-font-size, font-size-small);
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
.heading {
|
|
165
|
+
padding-right: margin(1.5);
|
|
163
166
|
margin-bottom: margin(0.5);
|
|
164
167
|
color: theme(detail-title-text-color, text-color);
|
|
165
168
|
font-family: theme(detail-title-font-family, inherit);
|
|
@@ -173,8 +176,20 @@
|
|
|
173
176
|
z-index: 1;
|
|
174
177
|
position: relative;
|
|
175
178
|
padding: theme(reel-item-padding, margin(2));
|
|
176
|
-
background: linear-gradient(to bottom, transparent, theme(detail-background, light) 4rem);
|
|
177
179
|
font-size: theme(detail-font-size, font-size-base);
|
|
180
|
+
|
|
181
|
+
&::before {
|
|
182
|
+
z-index: -1;
|
|
183
|
+
content: "";
|
|
184
|
+
display: block;
|
|
185
|
+
position: absolute;
|
|
186
|
+
top: 0;
|
|
187
|
+
right: 0;
|
|
188
|
+
bottom: 0;
|
|
189
|
+
left: 0;
|
|
190
|
+
background: linear-gradient(to bottom, transparent, theme(detail-background, light) 4rem);
|
|
191
|
+
opacity: 0.85;
|
|
192
|
+
}
|
|
178
193
|
}
|
|
179
194
|
|
|
180
195
|
.playlinks-heading {
|
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
captions?: boolean
|
|
12
12
|
autoplay?: boolean
|
|
13
13
|
showMuteControls?: boolean
|
|
14
|
+
fallbackStartTime?: number
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
const { embeddable_url = '', controls = [], muted = false, loop = false, captions = false, autoplay = true, showMuteControls = false }: Props = $props()
|
|
17
|
+
const { embeddable_url = '', controls = [], muted = false, loop = false, captions = false, autoplay = true, showMuteControls = false, fallbackStartTime = 0 }: Props = $props()
|
|
17
18
|
|
|
18
19
|
const videoId = $derived(getVideoId(embeddable_url))
|
|
19
|
-
const startTime = $derived((window?.PlayPilotLinkInjections?.video_playtimes?.[videoId || ''] || 1) - 1)
|
|
20
|
+
const startTime = $derived((window?.PlayPilotLinkInjections?.video_playtimes?.[videoId || ''] || (fallbackStartTime + 1)) - 1)
|
|
20
21
|
const color = window?.getComputedStyle(document.body).getPropertyValue('--playpilot-primary')?.replace('#', '') || 'fa548a'
|
|
21
22
|
|
|
22
23
|
let iframe: HTMLIFrameElement | null = $state(null)
|
|
@@ -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} muted loop showMuteControls />
|
|
18
|
+
<YouTubeEmbed {embeddable_url} {autoplay} fallbackStartTime={5} muted loop showMuteControls />
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
<style lang="scss">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, vi, afterEach } from 'vitest'
|
|
2
|
-
import { getSplitTestIdentifier, getSplitTestVariantIndex, getSplitTestVariantName, isInSplitTestVariant, trackSplitTestAction, trackSplitTestView } from '$lib/splitTest'
|
|
2
|
+
import { getSplitTestIdentifier, getSplitTestVariantIndex, getSplitTestVariantName, isInSplitTestVariant, sessionStoragePrefix, trackSplitTestAction, trackSplitTestView } from '$lib/splitTest'
|
|
3
3
|
import { track } from '$lib/tracking'
|
|
4
4
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
5
5
|
import { hasConsentedTo } from '$lib/consent'
|
|
@@ -28,7 +28,6 @@ describe('$lib/splitTest', () => {
|
|
|
28
28
|
})
|
|
29
29
|
|
|
30
30
|
describe('getSplitTestIdentifier', () => {
|
|
31
|
-
|
|
32
31
|
it('Should set window object with given key if window object was not set to begin with', () => {
|
|
33
32
|
// @ts-ignore
|
|
34
33
|
window.PlayPilotLinkInjections = {}
|
|
@@ -66,6 +65,18 @@ describe('$lib/splitTest', () => {
|
|
|
66
65
|
|
|
67
66
|
expect(getSplitTestIdentifier(splitTest)).toBe(0)
|
|
68
67
|
})
|
|
68
|
+
|
|
69
|
+
it('Should store value in sessionStorage', () => {
|
|
70
|
+
getSplitTestIdentifier(splitTest)
|
|
71
|
+
|
|
72
|
+
expect(sessionStorage.getItem(sessionStoragePrefix + splitTest.key)).toBeTruthy()
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('Should use value stored in sessionStorage', () => {
|
|
76
|
+
sessionStorage.setItem(sessionStoragePrefix + splitTest.key, '0.2')
|
|
77
|
+
|
|
78
|
+
expect(getSplitTestIdentifier(splitTest)).toBe(0.2)
|
|
79
|
+
})
|
|
69
80
|
})
|
|
70
81
|
|
|
71
82
|
describe('isInSplitTestVariant', () => {
|
|
@@ -46,6 +46,12 @@ describe('YouTubeEmbed.svelte', () => {
|
|
|
46
46
|
expect(/** @type {HTMLIFrameElement} */ (container.querySelector('iframe')).src).toContain('&autoplay=false')
|
|
47
47
|
})
|
|
48
48
|
|
|
49
|
+
it('Should start at given fallbackStartTime', () => {
|
|
50
|
+
const { container } = render(YouTubeEmbed, { embeddable_url: 'youtube.com/watch?v=abc', fallbackStartTime: 8 })
|
|
51
|
+
|
|
52
|
+
expect(/** @type {HTMLIFrameElement} */ (container.querySelector('iframe')).src).toContain('&start_time=8')
|
|
53
|
+
})
|
|
54
|
+
|
|
49
55
|
it('Should render error message if embeddable_url is invalid', () => {
|
|
50
56
|
const { container, getByText } = render(YouTubeEmbed, { embeddable_url: '-' })
|
|
51
57
|
|
|
@@ -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&captions=false&controls=&start_time=
|
|
11
|
+
expect(container.querySelector('iframe').src).toBe('https://video.playpilot.net/?video_id=abc&color=fa548a&muted=true&loop=true&captions=false&controls=&start_time=5&autoplay=true&playsinline=true')
|
|
12
12
|
})
|
|
13
13
|
})
|