@playpilot/tpi 8.5.2 → 8.5.4

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/events.md CHANGED
@@ -109,3 +109,6 @@ Event | Action | Info | Payload
109
109
  `explore_show_more` | _Fires when "show more" is clicked on explore_ | | `page` (The current page number) |
110
110
  `explore_set_filter` | _Fires when any filter is set on the explore page._ | This includes any filter type, including sorting. | `key` (the name of the current filter being set), `value`, `total_filter` (all currently active filter items)
111
111
  `explore_search` | _Fires any time the user searches for something_ | | `query`
112
+ `venus_title_rail_modal_view` | _Fires any time a title is clicked in a rail, opening the rail modal_ | | `rail` (heading key of the rail)
113
+ `venus_title_rail_expand_click` | _Fires any time a title is expanded in a rail directly via a click_ | Does not fire when a title opens automatically on load or navigate | `Title`, `rail` (heading key of the rail)
114
+ `venus_navigate` | _Fires when navigating on the explore page_ | Does not fire on initial load | `route` (the key of the given route)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playpilot/tpi",
3
- "version": "8.5.2",
3
+ "version": "8.5.4",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -70,6 +70,9 @@ export const TrackingEvent = {
70
70
  ExploreSetFilter: 'venus_set_filter',
71
71
  ExploreSearch: 'venus_search',
72
72
  ExploreFetchProvidersFailed: 'venus_fetch_providers_failed',
73
+ ExploreTitleRailModalView: 'venus_title_rail_modal_view',
74
+ ExploreTitleRailExpandClick: 'venus_title_rail_expand_click',
75
+ ExploreNavigate: 'venus_navigate',
73
76
  } as const
74
77
 
75
78
  export const MetaEvent = {
@@ -1,6 +1,8 @@
1
1
  <script lang="ts">
2
2
  import type { ExploreRoute } from '$lib/types/explore'
3
3
  import { useExploreRouter } from '$lib/explore'
4
+ import { track } from '$lib/tracking'
5
+ import { TrackingEvent } from '$lib/enums/TrackingEvent'
4
6
  import ExploreHome from './Routes/ExploreHome.svelte'
5
7
  import ExploreResults from './Routes/ExploreResults.svelte'
6
8
  import ExploreLayout from './ExploreLayout.svelte'
@@ -32,6 +34,8 @@
32
34
 
33
35
  function navigate(route: ExploreRoute): void {
34
36
  currentRoute = route
37
+
38
+ track(TrackingEvent.ExploreNavigate, null, { route: route.key })
35
39
  }
36
40
  </script>
37
41
 
@@ -2,6 +2,8 @@
2
2
  import { flip } from 'svelte/animate'
3
3
  import { scale } from 'svelte/transition'
4
4
  import { t } from '$lib/localization'
5
+ import IconMinus from '../../Icons/IconMinus.svelte'
6
+ import IconPlus from '../../Icons/IconPlus.svelte'
5
7
 
6
8
  interface Option {
7
9
  label: string
@@ -58,7 +60,11 @@
58
60
  <div class="action">
59
61
  {#key active}
60
62
  <div class="icon" transition:scale={{ start: 0.25, duration: 100 }}>
61
- {active ? '-' : '+'}
63
+ {#if active}
64
+ <IconMinus />
65
+ {:else}
66
+ <IconPlus />
67
+ {/if}
62
68
  </div>
63
69
  {/key}
64
70
  </div>
@@ -1,31 +1,33 @@
1
1
  <script lang="ts">
2
2
  import type { TitleData } from '$lib/types/title'
3
3
  import { fetchTitles } from '$lib/api/titles'
4
- import TitlesRail from '../../Rails/TitlesRail.svelte'
5
4
  import { t } from '$lib/localization'
6
5
  import { Sorting } from '$lib/enums/Sorting'
6
+ import { track } from '$lib/tracking'
7
+ import { TrackingEvent } from '$lib/enums/TrackingEvent'
8
+ import TitlesRail from '../../Rails/TitlesRail.svelte'
7
9
 
8
10
  let expandedTitle: TitleData | null = $state(null)
9
11
  let expandedRailKey: string | null = $state(null)
10
12
 
11
13
  const rails: { heading: string, params: Record<string, any>, properties: Record<string, any> }[] = [{
12
- heading: t('List: Trending'),
14
+ heading: 'List: Trending',
13
15
  params: { ordering: Sorting.Popular },
14
16
  properties: { expandable: true },
15
17
  }, {
16
- heading: t('List: Upcoming'),
18
+ heading: 'List: Upcoming',
17
19
  params: { from_playlist_sid: 'li42wf', region: null, no_region_filter: true },
18
20
  properties: { aside: true },
19
21
  }, {
20
- heading: t('List: New'),
22
+ heading: 'List: New',
21
23
  params: { from_playlist_sid: 'li42WR', include_playable_types: 'SVOD,FREE' },
22
24
  properties: { expandable: true },
23
25
  }, {
24
- heading: t('List: Demand'),
26
+ heading: 'List: Demand',
25
27
  params: { from_playlist_sid: 'licBS' },
26
28
  properties: {},
27
29
  }, {
28
- heading: t('List: Cinema'),
30
+ heading: 'List: Cinema',
29
31
  params: { from_playlist_sid: 'li42WS', region: null, no_region_filter: true },
30
32
  properties: { aside: true },
31
33
  }]
@@ -41,7 +43,16 @@
41
43
 
42
44
  {#each rails as { heading, params, properties }}
43
45
  <div class="rail">
44
- <TitlesRail {heading} titles={getListTitles(params)} size="flexible" {...properties} bind:expandedTitle bind:expandedRailKey />
46
+ <TitlesRail
47
+ heading={t(heading)}
48
+ titles={getListTitles(params)}
49
+ size="flexible"
50
+ minimumLength={7}
51
+ {...properties}
52
+ bind:expandedTitle
53
+ bind:expandedRailKey
54
+ onclick={() => track(TrackingEvent.ExploreTitleRailModalView, null, { rail: heading })}
55
+ onexpand={(title) => track(TrackingEvent.ExploreTitleRailExpandClick, title, { rail: heading })} />
45
56
  </div>
46
57
  {/each}
47
58
 
@@ -43,7 +43,7 @@
43
43
  const SkeletonComponent = $derived(grid ? GridTitleSkeleton : ListTitleSkeleton)
44
44
 
45
45
  $effect(() => {
46
- if (searchQuery) search(searchQuery)
46
+ if (searchQuery || latestRequestId != 0) search(searchQuery)
47
47
  })
48
48
 
49
49
  async function getTitlesForFilter(): Promise<APIPaginatedResult<TitleData>> {
@@ -0,0 +1,3 @@
1
+ <svg width="18px" height="18px" viewBox="0 -960 960 960" fill="currentColor">
2
+ <path d="M200-440v-80h560v80H200Z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="18px" height="18px" viewBox="0 -960 960 960" fill="currentColor">
2
+ <path d="M440-440H200v-80h240v-240h80v240h240v80H520v240h-80v-240Z"/>
3
+ </svg>
@@ -14,17 +14,20 @@
14
14
 
15
15
  interface Props {
16
16
  titles: Promise<TitleData[]> | TitleData[]
17
+ minimumLength?: number,
17
18
  heading?: string,
18
19
  size?: 'small' | 'large' | 'flexible'
19
20
  aside?: boolean,
20
21
  expandable?: boolean,
21
22
  expandedTitle?: TitleData | null,
22
23
  expandedRailKey?: string | null,
23
- onclick?: (title: TitleData) => void
24
+ onclick?: (title: TitleData) => void,
25
+ onexpand?: (title: TitleData) => void
24
26
  }
25
27
 
26
28
  let {
27
29
  titles,
30
+ minimumLength = 1,
28
31
  heading = '',
29
32
  size = 'small',
30
33
  aside = false,
@@ -32,6 +35,7 @@
32
35
  expandedTitle = $bindable(null),
33
36
  expandedRailKey = $bindable(null),
34
37
  onclick = () => null,
38
+ onexpand = () => null,
35
39
  }: Props = $props()
36
40
 
37
41
  const key = generateRandomHash()
@@ -52,8 +56,8 @@
52
56
  const title = titles[index]
53
57
 
54
58
  if (expandable && !isExpanded(title)) {
55
- const activeElement = element!.querySelectorAll('.title')[index]!
56
- const parentOffset = element!.getBoundingClientRect().right
59
+ const activeElement = element?.querySelectorAll('.title')[index]!
60
+ const parentOffset = element?.getBoundingClientRect().right || 0
57
61
  const elementOffsetInParent = parentOffset - activeElement.getBoundingClientRect().right
58
62
 
59
63
  recentlyExpanded = true
@@ -63,9 +67,13 @@
63
67
 
64
68
  expandTitleIntoTrailer(title)
65
69
 
70
+ if (event) onexpand(title)
71
+
66
72
  return
67
73
  }
68
74
 
75
+ if (!event) return
76
+
69
77
  if (useExploreRouter()) {
70
78
  openModal({ event, type: 'titles-rail', data: titles as TitleData[], returnToTitle, props: { initialIndex: index } })
71
79
  } else {
@@ -144,7 +152,7 @@
144
152
  {/each}
145
153
  </Rail>
146
154
  {:then titles}
147
- {#if titles?.length}
155
+ {#if titles?.length >= minimumLength}
148
156
  <Rail
149
157
  bind:slider
150
158
  {heading}
@@ -182,7 +190,7 @@
182
190
  <!-- svelte-ignore a11y_click_events_have_key_events -->
183
191
  <!-- svelte-ignore a11y_no_static_element_interactions -->
184
192
  <div class="aside" {onclick} data-testid="aside">
185
- {title.blurb || title.description}
193
+ {title.description}
186
194
  </div>
187
195
  {/if}
188
196
  </div>
@@ -20,6 +20,7 @@
20
20
  explore_custom_style: 'main { border: 2px solid white }',
21
21
  explore_use_router: true,
22
22
  },
23
+ require_consent: false,
23
24
  }
24
25
  }
25
26
 
@@ -149,6 +149,21 @@ describe('TitlesRail.svelte', () => {
149
149
  })
150
150
  })
151
151
 
152
+ it('Should fire onexpand even on expand on click of title but not on subsequent click', async () => {
153
+ const titles = [{ ...title }, { ...title, sid: 'some-other-sid' }]
154
+ const onexpand = vi.fn()
155
+
156
+ const { getAllByTestId } = render(TitlesRail, { titles, onexpand, expandable: true })
157
+
158
+ expect(onexpand).toHaveBeenCalledTimes(0)
159
+
160
+ await fireEvent.click(getAllByTestId('heading')[1])
161
+ expect(onexpand).toHaveBeenCalledTimes(1)
162
+
163
+ await fireEvent.click(getAllByTestId('heading')[1])
164
+ expect(onexpand).toHaveBeenCalledTimes(1)
165
+ })
166
+
152
167
  it('Should not call openModal after changing if expandable is false', async () => {
153
168
  const titles = [{ ...title }, { ...title, sid: 'some-other-sid' }]
154
169
 
@@ -186,4 +201,16 @@ describe('TitlesRail.svelte', () => {
186
201
  expect(/** @type {HTMLElement} */ (container.querySelector('.titles.small'))).not.toBeTruthy()
187
202
  expect(/** @type {HTMLElement} */ (container.querySelector('.titles.large'))).toBeTruthy()
188
203
  })
204
+
205
+ it('Should not render rails if fewer than given mimimumLength of titles were returned', () => {
206
+ const { container } = render(TitlesRail, { titles: [title, title], minimumLength: 3 })
207
+
208
+ expect(container.querySelector('.titles .slider')).not.toBeTruthy()
209
+ })
210
+
211
+ it('Should render rails if equal or more than given mimimumLength of titles were returned', () => {
212
+ const { container } = render(TitlesRail, { titles: [title, title, title], minimumLength: 3 })
213
+
214
+ expect(container.querySelector('.titles .slider')).toBeTruthy()
215
+ })
189
216
  })