@playpilot/tpi 8.4.2 → 8.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playpilot/tpi",
3
- "version": "8.4.2",
3
+ "version": "8.5.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -18,3 +18,8 @@
18
18
  @return var(--playpilot-#{$scope}, $fallback);
19
19
  }
20
20
  }
21
+
22
+ // Alternative to `vw` but scaled by the explore width instead.
23
+ @function explore-width($percentage) {
24
+ @return calc(theme(explore-width, 1000px) * ($percentage / 100))
25
+ }
@@ -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(136)
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-huge', `${railSize}px`)} />
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,11 +15,11 @@
19
15
  }, {
20
16
  heading: t('List: Upcoming'),
21
17
  params: { from_playlist_sid: 'li42wf', region: null, no_region_filter: true },
22
- properties: { expandable: 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' },
26
- properties: { aside: true, size: 'large' },
22
+ properties: { expandable: true },
27
23
  }, {
28
24
  heading: t('List: Demand'),
29
25
  params: { from_playlist_sid: 'licBS' },
@@ -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: {},
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} bind:innerWidth={windowWidth} />
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={size || 'small'} {...properties} bind:expandedTitle bind:expandedRailKey />
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' | 'huge'
18
+ size?: 'small' | 'large' | 'flexible'
19
19
  aside?: boolean,
20
20
  expandable?: boolean,
21
21
  expandedTitle?: TitleData | null,
@@ -40,6 +40,7 @@
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
46
  if (expandable) expandFirstAvailableTrailer()
@@ -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
 
@@ -100,6 +111,13 @@
100
111
  function isExpanded(title: TitleData): boolean {
101
112
  return expandedRailKey === key && title.sid === expandedTitle?.sid
102
113
  }
114
+
115
+ function onchange(titles: TitleData[], index: number): void {
116
+ if (!expandable) return
117
+ if (recentlyExpanded) return
118
+
119
+ setTimeout(() => openTitle(null, titles, index), 250)
120
+ }
103
121
  </script>
104
122
 
105
123
  <svelte:window onscroll={expandWhenFirstInView} />
@@ -133,7 +151,7 @@
133
151
  <Rail
134
152
  bind:slider
135
153
  {heading}
136
- onchange={(index) => { if (expandable) setTimeout(() => openTitle(null, titles, index), 250) }}
154
+ onchange={(index) => onchange(titles, index)}
137
155
  onresize={() => slider?.reposition()}>
138
156
  {#each titles as title, index}
139
157
  {@const expanded = isExpanded(title)}
@@ -192,8 +210,8 @@
192
210
  --width: #{theme(rail-size-large, margin(7.5))};
193
211
  }
194
212
 
195
- &.huge {
196
- --width: #{theme(rail-size-huge, margin(8.5))};
213
+ &.flexible {
214
+ --width: #{theme(rail-size-flexible, clamp(margin(6), explore-width(18), margin(11.5)))};
197
215
  }
198
216
  }
199
217
 
@@ -219,6 +237,11 @@
219
237
  width: calc(var(--width) * 2);
220
238
  height: var(--image-height);
221
239
  overflow: hidden;
240
+ font-size: clamp(theme(font-size-small), explore-width(1.5), theme(font-size-base));
241
+
242
+ &.expanded {
243
+ width: calc(var(--expanded-width) + var(--width));
244
+ }
222
245
  }
223
246
  }
224
247
 
@@ -307,6 +330,7 @@
307
330
  .with-aside & {
308
331
  width: 100%;
309
332
  padding-top: 0;
333
+ color: theme(text-color) !important;
310
334
  font-weight: theme(rail-aside-heading-font-weight, font-bold);
311
335
  line-clamp: 1;
312
336
  -webkit-line-clamp: 1;
@@ -320,7 +344,7 @@
320
344
  mask-image: linear-gradient(to top, transparent 0.5lh, white 1.5lh);
321
345
  overflow: hidden;
322
346
  color: theme(rail-text-color, text-color-alt) !important;
323
- font-size: theme(rail-aside-font-size, 11px);
347
+ font-size: 0.9em;
324
348
  line-height: 1.2;
325
349
  }
326
350
 
@@ -64,7 +64,7 @@ describe('ExploreLayout.svelte', () => {
64
64
  })
65
65
 
66
66
  await waitFor(() => {
67
- expect(container.querySelector('.explore')?.getAttribute('style')).toBe('height: 500px;')
67
+ expect(container.querySelector('.explore')?.getAttribute('style')).toContain('height: 500px;')
68
68
  })
69
69
  })
70
70