@playpilot/tpi 8.10.1 → 8.11.0-beta.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 +6 -6
- package/package.json +1 -1
- package/src/lib/api/youtubeAvailability.ts +3 -4
- package/src/lib/data/translations.ts +5 -0
- package/src/lib/injection.ts +0 -8
- package/src/routes/components/Explore/ExploreLayout.svelte +9 -3
- package/src/routes/components/Explore/Routes/ExploreHome.svelte +6 -4
- package/src/routes/components/Modals/RailModal.svelte +1 -1
- package/src/routes/components/Rails/TitlesRail.svelte +19 -4
- package/src/routes/components/Title.svelte +1 -1
- package/src/tests/lib/api/youtubeAvailability.test.js +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { PUBLIC_YOUTUBE_AVAILABILITY_URL } from '$env/static/public'
|
|
2
|
-
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
3
|
-
import { track } from '$lib/tracking'
|
|
4
2
|
|
|
5
3
|
export async function isYouTubeVideoAvailableInRegion(videoId: string): Promise<boolean> {
|
|
6
4
|
const region = window.PlayPilotLinkInjections?.region?.toUpperCase()
|
|
@@ -18,8 +16,9 @@ export async function isYouTubeVideoAvailableInRegion(videoId: string): Promise<
|
|
|
18
16
|
if (!data.blocked && !!data.allowed && !data.allowed?.includes(region)) return false
|
|
19
17
|
|
|
20
18
|
return true
|
|
21
|
-
} catch
|
|
22
|
-
|
|
19
|
+
} catch {
|
|
20
|
+
// Silently fail for now
|
|
21
|
+
// track(TrackingEvent.YouTubeAvailabilityRequestFailed, null, { message: error.message })
|
|
23
22
|
|
|
24
23
|
return false
|
|
25
24
|
}
|
|
@@ -166,6 +166,11 @@ export const translations = {
|
|
|
166
166
|
[Language.Swedish]: 'Streaming Guide',
|
|
167
167
|
[Language.Danish]: 'Streaming Guide',
|
|
168
168
|
},
|
|
169
|
+
'Streaming Guide Heading': {
|
|
170
|
+
[Language.English]: 'Discover and search all movies and tv-shows',
|
|
171
|
+
[Language.Swedish]: 'Upptäck och sök bland alla filmer och tv-serier',
|
|
172
|
+
[Language.Danish]: 'Opdag og søg i alle film og tv-serier',
|
|
173
|
+
},
|
|
169
174
|
'Streaming Guide Description': {
|
|
170
175
|
[Language.English]: 'Find where to watch movies online - the ultimate guide that helps you find the best movies and shows across streaming services.',
|
|
171
176
|
[Language.Swedish]: 'Sök bland alla filmer och serier för att ta reda på var du kan streama dem',
|
package/src/lib/injection.ts
CHANGED
|
@@ -169,7 +169,6 @@ export function injectLinksInDocument(elements: HTMLElement[], injections: LinkI
|
|
|
169
169
|
if (document.querySelector(keySelector)) insertInTextDisclaimer(elements)
|
|
170
170
|
|
|
171
171
|
return mergedInjections.filter(i => i.title_details).map((injection, index) => {
|
|
172
|
-
// Favour manual injections over AI injections
|
|
173
172
|
const hasManualEquivalent = !injection.manual && isAvailableAsManualInjection(injection, index, mergedInjections)
|
|
174
173
|
const duplicate = injection.duplicate ?? hasManualEquivalent
|
|
175
174
|
|
|
@@ -307,9 +306,6 @@ function addCSSVariablesToLinks(): void {
|
|
|
307
306
|
}
|
|
308
307
|
}
|
|
309
308
|
|
|
310
|
-
/**
|
|
311
|
-
* Add event listeners to all injected links. These events are for both the popover and the modal.
|
|
312
|
-
*/
|
|
313
309
|
function addLinkInjectionEventListeners(injections: LinkInjection[]): void {
|
|
314
310
|
window.addEventListener('mousemove', destroyLinkPopoverOnMouseleave)
|
|
315
311
|
window.addEventListener('click', (event) => openModalForInjectedLink(event, injections))
|
|
@@ -341,10 +337,6 @@ export function clearLinkInjections(): void {
|
|
|
341
337
|
destroyLinkPopover(false)
|
|
342
338
|
}
|
|
343
339
|
|
|
344
|
-
/**
|
|
345
|
-
* Clear specific link injection from the page
|
|
346
|
-
* @param key Given of the injection to be removed from the page
|
|
347
|
-
*/
|
|
348
340
|
export function clearLinkInjection(key: string): void {
|
|
349
341
|
const element: HTMLAnchorElement | null = document.querySelector(`[${keyDataAttribute}="${key}"]`)
|
|
350
342
|
if (!element) return
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
let { navigate = () => null, searchQuery = $bindable(''), filter = $bindable({}), children }: Props = $props()
|
|
23
23
|
|
|
24
|
+
// svelte-ignore non_reactive_update
|
|
24
25
|
let element: HTMLElement | null = null
|
|
25
26
|
let height: string | null = $state(null)
|
|
26
27
|
let clientWidth: number = $state(window.innerWidth)
|
|
@@ -44,7 +45,7 @@
|
|
|
44
45
|
<div class="divider"></div>
|
|
45
46
|
|
|
46
47
|
<div class="heading" use:heading>
|
|
47
|
-
{t('Streaming Guide')}
|
|
48
|
+
{t('Streaming Guide Heading')}
|
|
48
49
|
</div>
|
|
49
50
|
|
|
50
51
|
{#if !useExploreRouter()}
|
|
@@ -98,8 +99,13 @@
|
|
|
98
99
|
display: flex;
|
|
99
100
|
flex-direction: column;
|
|
100
101
|
gap: margin(0.5);
|
|
101
|
-
margin: theme(explore-header-margin, 0 0 margin(
|
|
102
|
+
margin: theme(explore-header-margin, 0 0 margin(1));
|
|
102
103
|
width: 100%;
|
|
104
|
+
max-width: margin(12);
|
|
105
|
+
|
|
106
|
+
@include desktop {
|
|
107
|
+
max-width: margin(20);
|
|
108
|
+
}
|
|
103
109
|
}
|
|
104
110
|
|
|
105
111
|
.divider {
|
|
@@ -112,7 +118,7 @@
|
|
|
112
118
|
.heading {
|
|
113
119
|
margin: theme(explore-heading-margin, margin(0.25) 0);
|
|
114
120
|
color: theme(text-color);
|
|
115
|
-
font-size: theme(explore-heading-size, clamp(margin(1
|
|
121
|
+
font-size: theme(explore-heading-size, clamp(margin(1), 2.5vw, margin(1.5)));
|
|
116
122
|
font-weight: theme(explore-heading-font-weight, font-bold);
|
|
117
123
|
text-transform: theme(explore-heading-text-transform, normal);
|
|
118
124
|
line-height: theme(explore-heading-line-height, 1.5);
|
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
import { track } from '$lib/tracking'
|
|
7
7
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
8
8
|
import TitlesRail from '../../Rails/TitlesRail.svelte'
|
|
9
|
+
import { mobileBreakpoint } from '$lib/constants'
|
|
9
10
|
|
|
10
11
|
let expandedTitle: TitleData | null = $state(null)
|
|
11
12
|
let expandedRailKey: string | null = $state(null)
|
|
13
|
+
let windowWidth: number = $state(window.innerWidth)
|
|
12
14
|
|
|
13
15
|
const rails: { heading: string, params: Record<string, any>, properties: Record<string, any> }[] = [{
|
|
14
16
|
heading: 'List: Trending',
|
|
@@ -17,7 +19,7 @@
|
|
|
17
19
|
}, {
|
|
18
20
|
heading: 'List: New',
|
|
19
21
|
params: { from_playlist_sid: 'li42WR', include_playable_types: 'SVOD,FREE' },
|
|
20
|
-
properties: { aside: true },
|
|
22
|
+
properties: { aside: true, size: 'flexible' },
|
|
21
23
|
}, {
|
|
22
24
|
heading: 'List: Upcoming',
|
|
23
25
|
params: { from_playlist_sid: 'li42wf', region: null, no_region_filter: true },
|
|
@@ -29,7 +31,7 @@
|
|
|
29
31
|
}, {
|
|
30
32
|
heading: 'List: Demand',
|
|
31
33
|
params: { from_playlist_sid: 'licBS' },
|
|
32
|
-
properties: { aside: true },
|
|
34
|
+
properties: { aside: true, size: 'flexible' },
|
|
33
35
|
}]
|
|
34
36
|
|
|
35
37
|
async function getListTitles(params: Record<string, any> = {}): Promise<TitleData[]> {
|
|
@@ -43,7 +45,7 @@
|
|
|
43
45
|
}
|
|
44
46
|
</script>
|
|
45
47
|
|
|
46
|
-
<svelte:window {onscroll} />
|
|
48
|
+
<svelte:window {onscroll} bind:innerWidth={windowWidth} />
|
|
47
49
|
|
|
48
50
|
<div data-testid="explore-home"></div>
|
|
49
51
|
|
|
@@ -52,7 +54,7 @@
|
|
|
52
54
|
<TitlesRail
|
|
53
55
|
heading={t(heading)}
|
|
54
56
|
titles={getListTitles(params)}
|
|
55
|
-
size=
|
|
57
|
+
size={windowWidth >= mobileBreakpoint ? 'flexible' : 'huge'}
|
|
56
58
|
minimumLength={7}
|
|
57
59
|
{...properties}
|
|
58
60
|
bind:expandedTitle
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
border-radius: theme(rail-modal-item-border-radius, border-radius-huge) theme(rail-modal-item-border-radius, border-radius-huge) 0 0;
|
|
132
132
|
background: theme(rail-modal-item-background, light);
|
|
133
133
|
box-shadow: none;
|
|
134
|
-
height:
|
|
134
|
+
height: 90vh;
|
|
135
135
|
overflow: auto;
|
|
136
136
|
overscroll-behavior: contain;
|
|
137
137
|
transition: box-shadow var(--transition-duration);
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
titles: Promise<TitleData[]> | TitleData[]
|
|
17
17
|
minimumLength?: number,
|
|
18
18
|
heading?: string,
|
|
19
|
-
size?: 'small' | 'large' | 'flexible'
|
|
19
|
+
size?: 'small' | 'large' | 'huge' | 'flexible'
|
|
20
20
|
aside?: boolean,
|
|
21
21
|
expandable?: boolean,
|
|
22
22
|
expandedTitle?: TitleData | null,
|
|
@@ -64,7 +64,9 @@
|
|
|
64
64
|
recentlyExpanded = true
|
|
65
65
|
setTimeout(() => recentlyExpanded = false, 500)
|
|
66
66
|
|
|
67
|
-
if (elementOffsetInParent < activeElement.clientWidth * 2)
|
|
67
|
+
if (size === 'flexible' && elementOffsetInParent < activeElement.clientWidth * 2) {
|
|
68
|
+
slider?.setIndex(index - 2)
|
|
69
|
+
}
|
|
68
70
|
|
|
69
71
|
expandTitleIntoTrailer(title)
|
|
70
72
|
|
|
@@ -206,7 +208,7 @@
|
|
|
206
208
|
.titles {
|
|
207
209
|
--width: #{theme(rail-size-default, margin(6))};
|
|
208
210
|
--image-height: #{calc(var(--width) * 3 / 2)};
|
|
209
|
-
--expanded-width:
|
|
211
|
+
--expanded-width: var(--width);
|
|
210
212
|
--border-radius: #{theme(rail-border-radius, border-radius)};
|
|
211
213
|
|
|
212
214
|
&.with-aside {
|
|
@@ -217,8 +219,13 @@
|
|
|
217
219
|
--width: #{theme(rail-size-large, margin(7.5))};
|
|
218
220
|
}
|
|
219
221
|
|
|
222
|
+
&.huge {
|
|
223
|
+
--width: #{theme(rail-size-large, min(explore-width(65), margin(15)))};
|
|
224
|
+
}
|
|
225
|
+
|
|
220
226
|
&.flexible {
|
|
221
|
-
--width: #{theme(rail-size-flexible, clamp(margin(
|
|
227
|
+
--width: #{theme(rail-size-flexible, clamp(margin(8), explore-width(20), margin(11.5)))};
|
|
228
|
+
--expanded-width: #{calc(var(--image-height) / 9 * 16)};
|
|
222
229
|
}
|
|
223
230
|
}
|
|
224
231
|
|
|
@@ -286,6 +293,14 @@
|
|
|
286
293
|
:global(iframe) {
|
|
287
294
|
opacity: 0;
|
|
288
295
|
animation: fade-iframe 500ms 500ms forwards;
|
|
296
|
+
|
|
297
|
+
@include mobile {
|
|
298
|
+
position: absolute;
|
|
299
|
+
width: 225%;
|
|
300
|
+
top: 50%;
|
|
301
|
+
left: 50%;
|
|
302
|
+
transform: translateX(-50%) translateY(-50%);
|
|
303
|
+
}
|
|
289
304
|
}
|
|
290
305
|
|
|
291
306
|
:global(+ .poster) {
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
2
|
import { isYouTubeVideoAvailableInRegion } from '$lib/api/youtubeAvailability'
|
|
3
3
|
import { fakeFetch } from '../../helpers'
|
|
4
|
-
import { track } from '$lib/tracking'
|
|
5
|
-
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
6
4
|
|
|
7
5
|
vi.mock('$lib/tracking', () => ({
|
|
8
6
|
track: vi.fn(),
|
|
@@ -64,7 +62,9 @@ describe('youtubeAvailability', () => {
|
|
|
64
62
|
fakeFetch({ ok: false, status: 500 })
|
|
65
63
|
|
|
66
64
|
expect(await isYouTubeVideoAvailableInRegion('video-id')).toBe(false)
|
|
67
|
-
|
|
65
|
+
|
|
66
|
+
// For now it's silently failing on purpose
|
|
67
|
+
// expect(track).toHaveBeenCalledWith(TrackingEvent.YouTubeAvailabilityRequestFailed, null, { message: expect.any(String) })
|
|
68
68
|
})
|
|
69
69
|
})
|
|
70
70
|
})
|