@playpilot/tpi 8.4.3 → 8.5.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 +7 -7
- package/dist/link-injections.js +1 -1
- package/dist/mount.js +6 -6
- package/package.json +1 -1
- package/src/lib/scss/_functions.scss +5 -0
- package/src/routes/components/Debugger.svelte +2 -2
- package/src/routes/components/Explore/ExploreLayout.svelte +2 -1
- package/src/routes/components/Explore/Routes/ExploreHome.svelte +4 -8
- package/src/routes/components/Rails/TitlesRail.svelte +33 -16
- package/src/tests/routes/components/Explore/ExploreLayout.test.js +1 -1
- package/src/tests/routes/components/Rails/TitlesRail.test.js +2 -10
package/package.json
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
let data = $state(dataToReadable())
|
|
21
21
|
let shown = $state(false)
|
|
22
22
|
let interval: ReturnType<typeof setInterval> | null = null
|
|
23
|
-
let railSize = $state(
|
|
23
|
+
let railSize = $state(184)
|
|
24
24
|
|
|
25
25
|
onDestroy(() => {
|
|
26
26
|
if (interval) clearInterval(interval)
|
|
@@ -220,7 +220,7 @@
|
|
|
220
220
|
max={240}
|
|
221
221
|
step={8}
|
|
222
222
|
bind:value={railSize}
|
|
223
|
-
oninput={() => document.body.style.setProperty('--playpilot-rail-size-
|
|
223
|
+
oninput={() => document.body.style.setProperty('--playpilot-rail-size-flexible', `${railSize}px`)} />
|
|
224
224
|
<small>{railSize}</small>
|
|
225
225
|
</div>
|
|
226
226
|
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
let element: HTMLElement | null = null
|
|
24
24
|
let height: string | null = $state(null)
|
|
25
|
+
let clientWidth: number = $state(0)
|
|
25
26
|
|
|
26
27
|
$effect(() => {
|
|
27
28
|
// Set the height of this element to match that of it's container. That way we can
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
})
|
|
37
38
|
</script>
|
|
38
39
|
|
|
39
|
-
<div class="explore playpilot-styled-scrollbar" bind:this={element} style:height>
|
|
40
|
+
<div class="explore playpilot-styled-scrollbar" bind:this={element} bind:clientWidth style:height style:--playpilot-explore-width="{clientWidth}px">
|
|
40
41
|
<div class="header" role="banner">
|
|
41
42
|
<div>
|
|
42
43
|
<div class="divider"></div>
|
|
@@ -4,14 +4,10 @@
|
|
|
4
4
|
import TitlesRail from '../../Rails/TitlesRail.svelte'
|
|
5
5
|
import { t } from '$lib/localization'
|
|
6
6
|
import { Sorting } from '$lib/enums/Sorting'
|
|
7
|
-
import { mobileBreakpoint } from '$lib/constants'
|
|
8
7
|
|
|
9
|
-
let windowWidth = $state(0)
|
|
10
8
|
let expandedTitle: TitleData | null = $state(null)
|
|
11
9
|
let expandedRailKey: string | null = $state(null)
|
|
12
10
|
|
|
13
|
-
const size = $derived(windowWidth >= mobileBreakpoint ? 'huge' : null)
|
|
14
|
-
|
|
15
11
|
const rails: { heading: string, params: Record<string, any>, properties: Record<string, any> }[] = [{
|
|
16
12
|
heading: t('List: Trending'),
|
|
17
13
|
params: { ordering: Sorting.Popular },
|
|
@@ -19,7 +15,7 @@
|
|
|
19
15
|
}, {
|
|
20
16
|
heading: t('List: Upcoming'),
|
|
21
17
|
params: { from_playlist_sid: 'li42wf', region: null, no_region_filter: true },
|
|
22
|
-
properties: { aside: true
|
|
18
|
+
properties: { aside: true },
|
|
23
19
|
}, {
|
|
24
20
|
heading: t('List: New'),
|
|
25
21
|
params: { from_playlist_sid: 'li42WR', include_playable_types: 'SVOD,FREE' },
|
|
@@ -31,7 +27,7 @@
|
|
|
31
27
|
}, {
|
|
32
28
|
heading: t('List: Cinema'),
|
|
33
29
|
params: { from_playlist_sid: 'li42WS', region: null, no_region_filter: true },
|
|
34
|
-
properties: { aside: true
|
|
30
|
+
properties: { aside: true },
|
|
35
31
|
}]
|
|
36
32
|
|
|
37
33
|
async function getListTitles(params: Record<string, any> = {}): Promise<TitleData[]> {
|
|
@@ -39,13 +35,13 @@
|
|
|
39
35
|
}
|
|
40
36
|
</script>
|
|
41
37
|
|
|
42
|
-
<svelte:window {onscroll}
|
|
38
|
+
<svelte:window {onscroll} />
|
|
43
39
|
|
|
44
40
|
<div data-testid="explore-home"></div>
|
|
45
41
|
|
|
46
42
|
{#each rails as { heading, params, properties }}
|
|
47
43
|
<div class="rail">
|
|
48
|
-
<TitlesRail {heading} titles={getListTitles(params)} size=
|
|
44
|
+
<TitlesRail {heading} titles={getListTitles(params)} size="flexible" {...properties} bind:expandedTitle bind:expandedRailKey />
|
|
49
45
|
</div>
|
|
50
46
|
{/each}
|
|
51
47
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
interface Props {
|
|
16
16
|
titles: Promise<TitleData[]> | TitleData[]
|
|
17
17
|
heading?: string,
|
|
18
|
-
size?: 'small' | 'large' | '
|
|
18
|
+
size?: 'small' | 'large' | 'flexible'
|
|
19
19
|
aside?: boolean,
|
|
20
20
|
expandable?: boolean,
|
|
21
21
|
expandedTitle?: TitleData | null,
|
|
@@ -40,9 +40,10 @@
|
|
|
40
40
|
|
|
41
41
|
let element: HTMLElement | null = $state(null)
|
|
42
42
|
let slider: ReturnType<typeof TinySlider> | null = $state(null)
|
|
43
|
+
let recentlyExpanded = false
|
|
43
44
|
|
|
44
45
|
onMount(() => {
|
|
45
|
-
if (expandable)
|
|
46
|
+
if (expandable) expandWhenFirstInView()
|
|
46
47
|
})
|
|
47
48
|
|
|
48
49
|
function openTitle(event: MouseEvent | null, titles: TitleData[], index: number): void {
|
|
@@ -51,7 +52,17 @@
|
|
|
51
52
|
const title = titles[index]
|
|
52
53
|
|
|
53
54
|
if (expandable && !isExpanded(title)) {
|
|
55
|
+
const activeElement = element!.querySelectorAll('.title')[index]!
|
|
56
|
+
const parentOffset = element!.getBoundingClientRect().right
|
|
57
|
+
const elementOffsetInParent = parentOffset - activeElement.getBoundingClientRect().right
|
|
58
|
+
|
|
59
|
+
recentlyExpanded = true
|
|
60
|
+
setTimeout(() => recentlyExpanded = false, 500)
|
|
61
|
+
|
|
62
|
+
if (elementOffsetInParent < activeElement.clientWidth * 2) slider?.setIndex(index - 2)
|
|
63
|
+
|
|
54
64
|
expandTitleIntoTrailer(title)
|
|
65
|
+
|
|
55
66
|
return
|
|
56
67
|
}
|
|
57
68
|
|
|
@@ -64,18 +75,15 @@
|
|
|
64
75
|
onclick(title)
|
|
65
76
|
}
|
|
66
77
|
|
|
67
|
-
async function expandFirstAvailableTrailer(
|
|
78
|
+
async function expandFirstAvailableTrailer(): Promise<void> {
|
|
68
79
|
const response = await titles
|
|
69
|
-
|
|
70
80
|
const title = await getFirstTitleWithAvailableTrailer(response)
|
|
71
|
-
if (!title) return
|
|
72
81
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
82
|
+
if (!title) return
|
|
83
|
+
if (expandedTitle) return
|
|
84
|
+
if (expandedRailKey && expandedRailKey !== key) return
|
|
76
85
|
|
|
77
|
-
|
|
78
|
-
}, delay)
|
|
86
|
+
expandTitleIntoTrailer(title)
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
function expandTitleIntoTrailer(title: TitleData): void {
|
|
@@ -87,19 +95,26 @@
|
|
|
87
95
|
if (expandedRailKey === key) return
|
|
88
96
|
|
|
89
97
|
const elements = Array.from(document.querySelectorAll('[data-role="expandable-rail"]')) as HTMLElement[]
|
|
90
|
-
const elementsInView = elements.filter(element => element.getBoundingClientRect().top
|
|
98
|
+
const elementsInView = elements.filter(element => element.getBoundingClientRect().top >= 0)
|
|
91
99
|
const elementsSortedByDistance = elementsInView.sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top)
|
|
92
100
|
|
|
93
101
|
if (elementsSortedByDistance[0] !== element) return
|
|
94
102
|
|
|
95
103
|
expandedTitle = null
|
|
96
104
|
expandedRailKey = null
|
|
97
|
-
expandFirstAvailableTrailer(
|
|
105
|
+
expandFirstAvailableTrailer()
|
|
98
106
|
}
|
|
99
107
|
|
|
100
108
|
function isExpanded(title: TitleData): boolean {
|
|
101
109
|
return expandedRailKey === key && title.sid === expandedTitle?.sid
|
|
102
110
|
}
|
|
111
|
+
|
|
112
|
+
function onchange(titles: TitleData[], index: number): void {
|
|
113
|
+
if (!expandable) return
|
|
114
|
+
if (recentlyExpanded) return
|
|
115
|
+
|
|
116
|
+
setTimeout(() => openTitle(null, titles, index), 250)
|
|
117
|
+
}
|
|
103
118
|
</script>
|
|
104
119
|
|
|
105
120
|
<svelte:window onscroll={expandWhenFirstInView} />
|
|
@@ -133,7 +148,7 @@
|
|
|
133
148
|
<Rail
|
|
134
149
|
bind:slider
|
|
135
150
|
{heading}
|
|
136
|
-
onchange={(index) =>
|
|
151
|
+
onchange={(index) => onchange(titles, index)}
|
|
137
152
|
onresize={() => slider?.reposition()}>
|
|
138
153
|
{#each titles as title, index}
|
|
139
154
|
{@const expanded = isExpanded(title)}
|
|
@@ -192,8 +207,8 @@
|
|
|
192
207
|
--width: #{theme(rail-size-large, margin(7.5))};
|
|
193
208
|
}
|
|
194
209
|
|
|
195
|
-
&.
|
|
196
|
-
--width: #{theme(rail-size-
|
|
210
|
+
&.flexible {
|
|
211
|
+
--width: #{theme(rail-size-flexible, clamp(margin(6), explore-width(18), margin(11.5)))};
|
|
197
212
|
}
|
|
198
213
|
}
|
|
199
214
|
|
|
@@ -219,6 +234,7 @@
|
|
|
219
234
|
width: calc(var(--width) * 2);
|
|
220
235
|
height: var(--image-height);
|
|
221
236
|
overflow: hidden;
|
|
237
|
+
font-size: clamp(theme(font-size-small), explore-width(1.5), theme(font-size-base));
|
|
222
238
|
|
|
223
239
|
&.expanded {
|
|
224
240
|
width: calc(var(--expanded-width) + var(--width));
|
|
@@ -311,6 +327,7 @@
|
|
|
311
327
|
.with-aside & {
|
|
312
328
|
width: 100%;
|
|
313
329
|
padding-top: 0;
|
|
330
|
+
color: theme(text-color) !important;
|
|
314
331
|
font-weight: theme(rail-aside-heading-font-weight, font-bold);
|
|
315
332
|
line-clamp: 1;
|
|
316
333
|
-webkit-line-clamp: 1;
|
|
@@ -324,7 +341,7 @@
|
|
|
324
341
|
mask-image: linear-gradient(to top, transparent 0.5lh, white 1.5lh);
|
|
325
342
|
overflow: hidden;
|
|
326
343
|
color: theme(rail-text-color, text-color-alt) !important;
|
|
327
|
-
font-size:
|
|
344
|
+
font-size: 0.9em;
|
|
328
345
|
line-height: 1.2;
|
|
329
346
|
}
|
|
330
347
|
|
|
@@ -64,7 +64,7 @@ describe('ExploreLayout.svelte', () => {
|
|
|
64
64
|
})
|
|
65
65
|
|
|
66
66
|
await waitFor(() => {
|
|
67
|
-
expect(container.querySelector('.explore')?.getAttribute('style')).
|
|
67
|
+
expect(container.querySelector('.explore')?.getAttribute('style')).toContain('height: 500px;')
|
|
68
68
|
})
|
|
69
69
|
})
|
|
70
70
|
|
|
@@ -69,7 +69,7 @@ describe('TitlesRail.svelte', () => {
|
|
|
69
69
|
|
|
70
70
|
expect(getByTestId('title').classList).not.toContain('expanded')
|
|
71
71
|
|
|
72
|
-
await new Promise(res => setTimeout(res,
|
|
72
|
+
await new Promise(res => setTimeout(res, 200))
|
|
73
73
|
|
|
74
74
|
expect(getByTestId('title').classList).toContain('expanded')
|
|
75
75
|
})
|
|
@@ -79,7 +79,7 @@ describe('TitlesRail.svelte', () => {
|
|
|
79
79
|
|
|
80
80
|
expect(getByTestId('title').classList).not.toContain('expanded')
|
|
81
81
|
|
|
82
|
-
await new Promise(res => setTimeout(res,
|
|
82
|
+
await new Promise(res => setTimeout(res, 200))
|
|
83
83
|
|
|
84
84
|
expect(getByTestId('title').classList).not.toContain('expanded')
|
|
85
85
|
})
|
|
@@ -89,32 +89,24 @@ describe('TitlesRail.svelte', () => {
|
|
|
89
89
|
|
|
90
90
|
expect(getByTestId('title').classList).not.toContain('expanded')
|
|
91
91
|
|
|
92
|
-
await new Promise(res => setTimeout(res, 1000))
|
|
93
|
-
|
|
94
92
|
expect(getByTestId('title').classList).not.toContain('expanded')
|
|
95
93
|
})
|
|
96
94
|
|
|
97
95
|
it('Should not expand if a different rail key is given', async () => {
|
|
98
96
|
const { getAllByTestId } = render(TitlesRail, { titles: [title], expandable: true, expandedRailKey: 'Not this rail' })
|
|
99
97
|
|
|
100
|
-
await new Promise(res => setTimeout(res, 1000))
|
|
101
|
-
|
|
102
98
|
expect(getAllByTestId('title')[0].classList).not.toContain('expanded')
|
|
103
99
|
})
|
|
104
100
|
|
|
105
101
|
it('Should not expand if a title is given that is not present in this rail', async () => {
|
|
106
102
|
const { getAllByTestId } = render(TitlesRail, { titles: [title], expandable: true, expandedTitle: { ...title, sid: 'not' } })
|
|
107
103
|
|
|
108
|
-
await new Promise(res => setTimeout(res, 1000))
|
|
109
|
-
|
|
110
104
|
expect(getAllByTestId('title')[0].classList).not.toContain('expanded')
|
|
111
105
|
})
|
|
112
106
|
|
|
113
107
|
it('Should not expand if a title is given that is in this rail but expandedRailKey is not this rail', async () => {
|
|
114
108
|
const { getAllByTestId } = render(TitlesRail, { titles: [title], expandable: true, expandedTitle: title, expandedRailKey: 'Not this rail' })
|
|
115
109
|
|
|
116
|
-
await new Promise(res => setTimeout(res, 1000))
|
|
117
|
-
|
|
118
110
|
expect(getAllByTestId('title')[0].classList).not.toContain('expanded')
|
|
119
111
|
})
|
|
120
112
|
|