@playpilot/tpi 5.32.3 → 5.33.0-beta.explore.10

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.
Files changed (81) hide show
  1. package/dist/link-injections.js +25 -10
  2. package/package.json +1 -1
  3. package/src/lib/afterArticle.ts +40 -0
  4. package/src/lib/api/api.ts +1 -1
  5. package/src/lib/api/titles.ts +13 -1
  6. package/src/lib/color.ts +19 -0
  7. package/src/lib/data/countries.json +216 -0
  8. package/src/lib/data/translations.ts +5 -0
  9. package/src/lib/disclaimer.ts +27 -0
  10. package/src/lib/enums/SplitTest.ts +5 -0
  11. package/src/lib/explore.ts +59 -0
  12. package/src/lib/fakeData.ts +1 -0
  13. package/src/lib/images/titles-list.webp +0 -0
  14. package/src/lib/injection.ts +41 -147
  15. package/src/lib/modal.ts +38 -7
  16. package/src/lib/popover.ts +71 -0
  17. package/src/lib/scss/global.scss +39 -2
  18. package/src/lib/trailer.ts +22 -0
  19. package/src/lib/types/api.d.ts +6 -0
  20. package/src/lib/types/config.d.ts +12 -0
  21. package/src/lib/types/filter.d.ts +2 -0
  22. package/src/lib/types/title.d.ts +4 -1
  23. package/src/routes/+page.svelte +13 -4
  24. package/src/routes/components/Ads/TopScroll.svelte +4 -18
  25. package/src/routes/components/Button.svelte +101 -0
  26. package/src/routes/components/Debugger.svelte +36 -0
  27. package/src/routes/components/Explore/Explore.svelte +226 -0
  28. package/src/routes/components/Explore/ExploreCallToAction.svelte +58 -0
  29. package/src/routes/components/Explore/ExploreModal.svelte +15 -0
  30. package/src/routes/components/Explore/Filter/Dropdown.svelte +72 -0
  31. package/src/routes/components/Explore/Filter/Filter.svelte +79 -0
  32. package/src/routes/components/Explore/Filter/FilterItem.svelte +57 -0
  33. package/src/routes/components/Explore/Filter/FilterSorting.svelte +70 -0
  34. package/src/routes/components/Explore/Filter/Search.svelte +56 -0
  35. package/src/routes/components/Explore/Filter/TogglesWithSearch.svelte +142 -0
  36. package/src/routes/components/GridTitle.svelte +122 -0
  37. package/src/routes/components/GridTitleSkeleton.svelte +36 -0
  38. package/src/routes/components/Icons/IconArrow.svelte +10 -2
  39. package/src/routes/components/Icons/IconClose.svelte +9 -1
  40. package/src/routes/components/Icons/IconFilter.svelte +5 -0
  41. package/src/routes/components/Icons/IconPlay.svelte +3 -0
  42. package/src/routes/components/Icons/IconSearch.svelte +3 -0
  43. package/src/routes/components/ListTitle.svelte +10 -68
  44. package/src/routes/components/ListTitleSkeleton.svelte +42 -0
  45. package/src/routes/components/Modal.svelte +27 -29
  46. package/src/routes/components/Participant.svelte +0 -2
  47. package/src/routes/components/ParticipantModal.svelte +1 -1
  48. package/src/routes/components/Playlinks/PlaylinkIcon.svelte +1 -1
  49. package/src/routes/components/Playlinks/PlaylinksCompact.svelte +71 -0
  50. package/src/routes/components/Share.svelte +5 -23
  51. package/src/routes/components/Title.svelte +22 -22
  52. package/src/routes/components/TitleModal.svelte +4 -1
  53. package/src/routes/components/Trailer.svelte +18 -0
  54. package/src/routes/components/YouTubeEmbedOverlay.svelte +96 -0
  55. package/src/routes/elements/+page.svelte +39 -2
  56. package/src/routes/explore/+page.svelte +60 -0
  57. package/src/tests/lib/afterArticle.test.js +108 -0
  58. package/src/tests/lib/api/ads.test.js +0 -1
  59. package/src/tests/lib/api/titles.test.js +55 -0
  60. package/src/tests/lib/disclaimer.test.js +90 -0
  61. package/src/tests/lib/explore.test.js +139 -0
  62. package/src/tests/lib/injections.test.js +5 -157
  63. package/src/tests/lib/modal.test.js +64 -1
  64. package/src/tests/lib/popover.test.js +70 -0
  65. package/src/tests/lib/trailer.test.js +56 -0
  66. package/src/tests/routes/components/Button.test.js +28 -0
  67. package/src/tests/routes/components/Explore/Explore.test.js +133 -0
  68. package/src/tests/routes/components/Explore/Filter/Dropdown.test.js +16 -0
  69. package/src/tests/routes/components/Explore/Filter/Filter.test.js +20 -0
  70. package/src/tests/routes/components/Explore/Filter/FilterItem.test.js +50 -0
  71. package/src/tests/routes/components/Explore/Filter/FilterSorting.test.js +34 -0
  72. package/src/tests/routes/components/Explore/Filter/Search.test.js +26 -0
  73. package/src/tests/routes/components/Explore/Filter/TogglesWithSearch.test.js +53 -0
  74. package/src/tests/routes/components/GridTitle.test.js +42 -0
  75. package/src/tests/routes/components/ListTitle.test.js +1 -1
  76. package/src/tests/routes/components/Playlinks/PlaylinksCompact.test.js +42 -0
  77. package/src/tests/routes/components/Share.test.js +12 -12
  78. package/src/tests/routes/components/Title.test.js +13 -0
  79. package/src/tests/routes/components/Trailer.test.js +20 -0
  80. package/src/tests/routes/components/YouTubeEmbedOverlay.test.js +31 -0
  81. package/src/tests/setup.js +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playpilot/tpi",
3
- "version": "5.32.3",
3
+ "version": "5.33.0-beta.explore.10",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -0,0 +1,40 @@
1
+ import { mount, unmount } from 'svelte'
2
+ import AfterArticlePlaylinks from '../routes/components/Playlinks/AfterArticlePlaylinks.svelte'
3
+ import type { LinkInjection } from './types/injection'
4
+ import { openModal } from './modal'
5
+
6
+ export let afterArticlePlaylinkInsertedComponent: object | null = null
7
+
8
+ /**
9
+ * Insert AfterArticlePlaylinks after the last valid element or at the position given in the window config object.
10
+ * The config object contains a selector option as well as a position. This way a selector can be given and you can
11
+ * choose to insert the after article before or after the given element.
12
+ */
13
+ export function insertAfterArticlePlaylinks(elements: HTMLElement[], injections: LinkInjection[]): void {
14
+ if (afterArticlePlaylinkInsertedComponent) return
15
+ if (!injections.length) return
16
+
17
+ const target = document.createElement('div')
18
+ const afterArticleSelector = window.PlayPilotLinkInjections?.after_article_selector
19
+ const insertElement = (afterArticleSelector ? document.querySelector(afterArticleSelector) : null) || elements[elements.length - 1]
20
+ const insertPosition = window.PlayPilotLinkInjections?.after_article_insert_position || 'afterend'
21
+
22
+ target.dataset.playpilotAfterArticlePlaylinks = 'true'
23
+ insertElement.insertAdjacentElement(insertPosition, target)
24
+
25
+ afterArticlePlaylinkInsertedComponent = mount(AfterArticlePlaylinks, {
26
+ target,
27
+ props: {
28
+ linkInjections: injections,
29
+ onclickmodal: (event, injection) => openModal({ event, injection, data: injection.title_details }),
30
+ },
31
+ })
32
+ }
33
+
34
+ export function clearAfterArticlePlaylinks(): void {
35
+ if (!afterArticlePlaylinkInsertedComponent) return
36
+
37
+ unmount(afterArticlePlaylinkInsertedComponent)
38
+ document.querySelector('[data-playpilot-after-article-playlinks]')?.remove()
39
+ afterArticlePlaylinkInsertedComponent = null
40
+ }
@@ -16,7 +16,7 @@ export async function api<T>(path: string, { headers = {}, method = 'GET', body
16
16
  const useCache = !isEditorialModeEnabled() && method === 'GET'
17
17
  if (useCache && (path in cache)) return cache[path]
18
18
 
19
- const baseHeaders = { 'Content-Type': 'application/json' }
19
+ const baseHeaders: Record<string, string> = method === 'GET' ? {} : { 'Content-Type': 'application/json' }
20
20
 
21
21
  const response = await fetch(apiBaseUrl + path, {
22
22
  method,
@@ -1,9 +1,21 @@
1
1
  import { getApiToken } from '$lib/token'
2
+ import type { APIPaginatedResult } from '$lib/types/api'
2
3
  import type { TitleData } from '../types/title'
3
4
  import { api } from './api'
4
5
 
6
+ export async function fetchTitles(params: Record<string, string | number> = {}): Promise<APIPaginatedResult<TitleData>> {
7
+ const apiToken = getApiToken()
8
+
9
+ if (!apiToken) throw new Error('No token was provided')
10
+
11
+ const paramsAsString = Object.entries(params).map(([key, value]) => `${key}=${value}`).join('&')
12
+ const response = await api<APIPaginatedResult<TitleData>>(`/titles/browse?api-token=${apiToken}&` + paramsAsString)
13
+
14
+ return response
15
+ }
16
+
5
17
  export async function fetchSimilarTitles(title: TitleData): Promise<TitleData[]> {
6
- const response = await api<{ results: TitleData[] }>(`/titles/browse?api-token=${getApiToken()}&related_to_sid=${title.sid}`)
18
+ const response = await fetchTitles({ related_to_sid: title.sid })
7
19
 
8
20
  return response.results
9
21
  }
@@ -0,0 +1,19 @@
1
+ /** Adjust the lightness of an RGB color. */
2
+ export function colorLuminance(input: string, luminosity: number): string {
3
+ const match = input
4
+ .replace(/\s+/g, '')
5
+ .match(/^rgb\((\d+),(\d+),(\d+)\)$/i)
6
+
7
+ if (!match) return ''
8
+
9
+ const [, r, g, b] = match
10
+
11
+ const adjust = (v: string) => {
12
+ const color = parseInt(v, 10)
13
+ return Math.round(Math.min(Math.max(0, color + color * luminosity), 255))
14
+ }
15
+
16
+ return `rgb(${adjust(r)}, ${adjust(g)}, ${adjust(b)})`
17
+ }
18
+
19
+
@@ -0,0 +1,216 @@
1
+ [
2
+ { "label": "Aruba", "value": "AW" },
3
+ { "label": "Afghanistan", "value": "AF" },
4
+ { "label": "Angola", "value": "AO" },
5
+ { "label": "Anguilla", "value": "AI" },
6
+ { "label": "Albania", "value": "AL" },
7
+ { "label": "Andorra", "value": "AD" },
8
+ { "label": "United Arab Emirates", "value": "AE" },
9
+ { "label": "Argentina", "value": "AR" },
10
+ { "label": "Armenia", "value": "AM" },
11
+ { "label": "American Samoa", "value": "AS" },
12
+ { "label": "Antigua and Barbuda", "value": "AG" },
13
+ { "label": "Australia", "value": "AU" },
14
+ { "label": "Austria", "value": "AT" },
15
+ { "label": "Azerbaijan", "value": "AZ" },
16
+ { "label": "Burundi", "value": "BI" },
17
+ { "label": "Belgium", "value": "BE" },
18
+ { "label": "Benin", "value": "BJ" },
19
+ { "label": "Burkina Faso", "value": "BF" },
20
+ { "label": "Bangladesh", "value": "BD" },
21
+ { "label": "Bulgaria", "value": "BG" },
22
+ { "label": "Bahrain", "value": "BH" },
23
+ { "label": "Bahamas", "value": "BS" },
24
+ { "label": "Bosnia and Herzegovina", "value": "BA" },
25
+ { "label": "Belarus", "value": "BY" },
26
+ { "label": "Belize", "value": "BZ" },
27
+ { "label": "Bermuda", "value": "BM" },
28
+ { "label": "Bolivia", "value": "BO" },
29
+ { "label": "Brazil", "value": "BR" },
30
+ { "label": "Barbados", "value": "BB" },
31
+ { "label": "Brunei", "value": "BN" },
32
+ { "label": "Bhutan", "value": "BT" },
33
+ { "label": "Botswana", "value": "BW" },
34
+ { "label": "Central African Republic", "value": "CF" },
35
+ { "label": "Canada", "value": "CA" },
36
+ { "label": "Switzerland", "value": "CH" },
37
+ { "label": "Chile", "value": "CL" },
38
+ { "label": "China", "value": "CN" },
39
+ { "label": "Côte d'Ivoire", "value": "CI" },
40
+ { "label": "Cameroon", "value": "CM" },
41
+ { "label": "DR Congo", "value": "CD" },
42
+ { "label": "Congo", "value": "CG" },
43
+ { "label": "Cook Islands", "value": "CK" },
44
+ { "label": "Colombia", "value": "CO" },
45
+ { "label": "Comoros", "value": "KM" },
46
+ { "label": "Cabo Verde", "value": "CV" },
47
+ { "label": "Costa Rica", "value": "CR" },
48
+ { "label": "Cuba", "value": "CU" },
49
+ { "label": "Curaçao", "value": "CW" },
50
+ { "label": "Cayman Islands", "value": "KY" },
51
+ { "label": "Cyprus", "value": "CY" },
52
+ { "label": "Czechia", "value": "CZ" },
53
+ { "label": "Germany", "value": "DE" },
54
+ { "label": "Djibouti", "value": "DJ" },
55
+ { "label": "Dominica", "value": "DM" },
56
+ { "label": "Denmark", "value": "DK" },
57
+ { "label": "Dominican Republic", "value": "DO" },
58
+ { "label": "Algeria", "value": "DZ" },
59
+ { "label": "Ecuador", "value": "EC" },
60
+ { "label": "Egypt", "value": "EG" },
61
+ { "label": "Eritrea", "value": "ER" },
62
+ { "label": "Spain", "value": "ES" },
63
+ { "label": "Estonia", "value": "EE" },
64
+ { "label": "Ethiopia", "value": "ET" },
65
+ { "label": "Finland", "value": "FI" },
66
+ { "label": "Fiji", "value": "FJ" },
67
+ { "label": "Falkland Islands", "value": "FK" },
68
+ { "label": "France", "value": "FR" },
69
+ { "label": "Faroe Islands", "value": "FO" },
70
+ { "label": "Micronesia", "value": "FM" },
71
+ { "label": "Gabon", "value": "GA" },
72
+ { "label": "United Kingdom", "value": "GB" },
73
+ { "label": "Georgia", "value": "GE" },
74
+ { "label": "Ghana", "value": "GH" },
75
+ { "label": "Gibraltar", "value": "GI" },
76
+ { "label": "Guinea", "value": "GN" },
77
+ { "label": "Guadeloupe", "value": "GP" },
78
+ { "label": "Gambia", "value": "GM" },
79
+ { "label": "Guinea-Bissau", "value": "GW" },
80
+ { "label": "Equatorial Guinea", "value": "GQ" },
81
+ { "label": "Greece", "value": "GR" },
82
+ { "label": "Grenada", "value": "GD" },
83
+ { "label": "Greenland", "value": "GL" },
84
+ { "label": "Guatemala", "value": "GT" },
85
+ { "label": "Guyana", "value": "GY" },
86
+ { "label": "Hong Kong", "value": "HK" },
87
+ { "label": "Honduras", "value": "HN" },
88
+ { "label": "Croatia", "value": "HR" },
89
+ { "label": "Haiti", "value": "HT" },
90
+ { "label": "Hungary", "value": "HU" },
91
+ { "label": "Indonesia", "value": "ID" },
92
+ { "label": "India", "value": "IN" },
93
+ { "label": "Ireland", "value": "IE" },
94
+ { "label": "Iran", "value": "IR" },
95
+ { "label": "Iraq", "value": "IQ" },
96
+ { "label": "Iceland", "value": "IS" },
97
+ { "label": "Israel", "value": "IL" },
98
+ { "label": "Italy", "value": "IT" },
99
+ { "label": "Jamaica", "value": "JM" },
100
+ { "label": "Jordan", "value": "JO" },
101
+ { "label": "Japan", "value": "JP" },
102
+ { "label": "Kazakhstan", "value": "KZ" },
103
+ { "label": "Kenya", "value": "KE" },
104
+ { "label": "Kyrgyzstan", "value": "KG" },
105
+ { "label": "Cambodia", "value": "KH" },
106
+ { "label": "Kiribati", "value": "KI" },
107
+ { "label": "Saint Kitts and Nevis", "value": "KN" },
108
+ { "label": "South Korea", "value": "KR" },
109
+ { "label": "Kuwait", "value": "KW" },
110
+ { "label": "Laos", "value": "LA" },
111
+ { "label": "Lebanon", "value": "LB" },
112
+ { "label": "Liberia", "value": "LR" },
113
+ { "label": "Libya", "value": "LY" },
114
+ { "label": "Saint Lucia", "value": "LC" },
115
+ { "label": "Liechtenstein", "value": "LI" },
116
+ { "label": "Sri Lanka", "value": "LK" },
117
+ { "label": "Lesotho", "value": "LS" },
118
+ { "label": "Lithuania", "value": "LT" },
119
+ { "label": "Luxembourg", "value": "LU" },
120
+ { "label": "Latvia", "value": "LV" },
121
+ { "label": "Macao", "value": "MO" },
122
+ { "label": "Morocco", "value": "MA" },
123
+ { "label": "Monaco", "value": "MC" },
124
+ { "label": "Moldova", "value": "MD" },
125
+ { "label": "Madagascar", "value": "MG" },
126
+ { "label": "Maldives", "value": "MV" },
127
+ { "label": "Mexico", "value": "MX" },
128
+ { "label": "Marshall Islands", "value": "MH" },
129
+ { "label": "North Macedonia", "value": "MK" },
130
+ { "label": "Mali", "value": "ML" },
131
+ { "label": "Malta", "value": "MT" },
132
+ { "label": "Myanmar", "value": "MM" },
133
+ { "label": "Montenegro", "value": "ME" },
134
+ { "label": "Mongolia", "value": "MN" },
135
+ { "label": "Mozambique", "value": "MZ" },
136
+ { "label": "Mauritania", "value": "MR" },
137
+ { "label": "Martinique", "value": "MQ" },
138
+ { "label": "Mauritius", "value": "MU" },
139
+ { "label": "Malawi", "value": "MW" },
140
+ { "label": "Malaysia", "value": "MY" },
141
+ { "label": "Namibia", "value": "NA" },
142
+ { "label": "New Caledonia", "value": "NC" },
143
+ { "label": "Niger", "value": "NE" },
144
+ { "label": "Nigeria", "value": "NG" },
145
+ { "label": "Nicaragua", "value": "NI" },
146
+ { "label": "Niue", "value": "NU" },
147
+ { "label": "Netherlands", "value": "NL" },
148
+ { "label": "Norway", "value": "NO" },
149
+ { "label": "Nepal", "value": "NP" },
150
+ { "label": "Nauru", "value": "NR" },
151
+ { "label": "New Zealand", "value": "NZ" },
152
+ { "label": "Oman", "value": "OM" },
153
+ { "label": "Pakistan", "value": "PK" },
154
+ { "label": "Panama", "value": "PA" },
155
+ { "label": "Peru", "value": "PE" },
156
+ { "label": "Philippines", "value": "PH" },
157
+ { "label": "Palau", "value": "PW" },
158
+ { "label": "Papua New Guinea", "value": "PG" },
159
+ { "label": "Poland", "value": "PL" },
160
+ { "label": "Puerto Rico", "value": "PR" },
161
+ { "label": "North Korea", "value": "KP" },
162
+ { "label": "Portugal", "value": "PT" },
163
+ { "label": "Paraguay", "value": "PY" },
164
+ { "label": "Palestine", "value": "PS" },
165
+ { "label": "French Polynesia", "value": "PF" },
166
+ { "label": "Qatar", "value": "QA" },
167
+ { "label": "Romania", "value": "RO" },
168
+ { "label": "Russian Federation", "value": "RU" },
169
+ { "label": "Rwanda", "value": "RW" },
170
+ { "label": "Saudi Arabia", "value": "SA" },
171
+ { "label": "Sudan", "value": "SD" },
172
+ { "label": "Senegal", "value": "SN" },
173
+ { "label": "Singapore", "value": "SG" },
174
+ { "label": "Solomon Islands", "value": "SB" },
175
+ { "label": "Sierra Leone", "value": "SL" },
176
+ { "label": "El Salvador", "value": "SV" },
177
+ { "label": "San Marino", "value": "SM" },
178
+ { "label": "Somalia", "value": "SO" },
179
+ { "label": "Serbia", "value": "RS" },
180
+ { "label": "South Sudan", "value": "SS" },
181
+ { "label": "São Tomé and Príncipe", "value": "ST" },
182
+ { "label": "Suriname", "value": "SR" },
183
+ { "label": "Slovakia", "value": "SK" },
184
+ { "label": "Slovenia", "value": "SI" },
185
+ { "label": "Sweden", "value": "SE" },
186
+ { "label": "Eswatini", "value": "SZ" },
187
+ { "label": "Seychelles", "value": "SC" },
188
+ { "label": "Syria", "value": "SY" },
189
+ { "label": "Chad", "value": "TD" },
190
+ { "label": "Togo", "value": "TG" },
191
+ { "label": "Thailand", "value": "TH" },
192
+ { "label": "Tajikistan", "value": "TJ" },
193
+ { "label": "Turkmenistan", "value": "TM" },
194
+ { "label": "Timor-Leste", "value": "TL" },
195
+ { "label": "Tonga", "value": "TO" },
196
+ { "label": "Trinidad and Tobago", "value": "TT" },
197
+ { "label": "Tunisia", "value": "TN" },
198
+ { "label": "Turkey", "value": "TR" },
199
+ { "label": "Tuvalu", "value": "TV" },
200
+ { "label": "Taiwan", "value": "TW" },
201
+ { "label": "Tanzania", "value": "TZ" },
202
+ { "label": "Uganda", "value": "UG" },
203
+ { "label": "Ukraine", "value": "UA" },
204
+ { "label": "Uruguay", "value": "UY" },
205
+ { "label": "United States", "value": "US" },
206
+ { "label": "Uzbekistan", "value": "UZ" },
207
+ { "label": "Saint Vincent and the Grenadines", "value": "VC" },
208
+ { "label": "Venezuela", "value": "VE" },
209
+ { "label": "Vietnam", "value": "VN" },
210
+ { "label": "Vanuatu", "value": "VU" },
211
+ { "label": "Samoa", "value": "WS" },
212
+ { "label": "Yemen", "value": "YE" },
213
+ { "label": "South Africa", "value": "ZA" },
214
+ { "label": "Zambia", "value": "ZM" },
215
+ { "label": "Zimbabwe", "value": "ZW" }
216
+ ]
@@ -126,6 +126,11 @@ export const translations = {
126
126
  [Language.Swedish]: 'Liknande filmer och serier',
127
127
  [Language.Danish]: 'Lignende film og serier',
128
128
  },
129
+ 'Watch Trailer': {
130
+ [Language.English]: 'Watch trailer',
131
+ [Language.Swedish]: 'Se trailer',
132
+ [Language.Danish]: 'Se trailer',
133
+ },
129
134
 
130
135
  // Genres
131
136
  'All': {
@@ -0,0 +1,27 @@
1
+ import { mount, unmount } from 'svelte'
2
+ import InTextDisclaimer from '../routes/components/InTextDisclaimer.svelte'
3
+
4
+ export let inTextDisclaimerInsertComponent: object | null = null
5
+
6
+ export function insertInTextDisclaimer(elements: HTMLElement[]): void {
7
+ if (!window.PlayPilotLinkInjections?.config?.in_text_disclaimer_enabled) return
8
+ if (inTextDisclaimerInsertComponent) return
9
+
10
+ const target = document.createElement('div')
11
+ const selector = window.PlayPilotLinkInjections?.config?.in_text_disclaimer_selector
12
+ const insertElement = (selector ? document.querySelector(selector) : null) || elements[0]
13
+ const insertPosition = window.PlayPilotLinkInjections?.config?.in_text_disclaimer_insert_position || 'beforebegin'
14
+
15
+ target.dataset.playpilotInTextDisclaimer = 'true'
16
+ insertElement.insertAdjacentElement(insertPosition, target)
17
+
18
+ inTextDisclaimerInsertComponent = mount(InTextDisclaimer, { target })
19
+ }
20
+
21
+ export function clearInTextDisclaimer(): void {
22
+ if (!inTextDisclaimerInsertComponent) return
23
+
24
+ unmount(inTextDisclaimerInsertComponent)
25
+ document.querySelector('[data-playpilot-in-text-disclaimer]')?.remove()
26
+ inTextDisclaimerInsertComponent = null
27
+ }
@@ -9,6 +9,11 @@ export const SplitTest = {
9
9
  numberOfVariants: 2,
10
10
  variantNames: ['Image', 'Label'] as string[],
11
11
  },
12
+ InTextEngagement: {
13
+ key: 'in-text-engagement',
14
+ numberOfVariants: 4,
15
+ variantNames: ['Default', 'Clapper Icon', 'Play Icon', 'Animated Link'] as string[]
16
+ },
12
17
  UserTimeSpent: {
13
18
  key: 'user_time_spent',
14
19
  numberOfVariants: 10,
@@ -0,0 +1,59 @@
1
+ import { mount, unmount } from 'svelte'
2
+ import Explore from '../routes/components/Explore/Explore.svelte'
3
+
4
+ export const exploreParentSelector = `[data-playpilot-explore]`
5
+
6
+ let exploreInsertedComponent: object | null = null
7
+
8
+ /**
9
+ * Insert the Explore component inside of the needed selector. If no element is found, do nothing.
10
+ * Only one Explore component can exist per page.
11
+ */
12
+ export function insertExplore(): void {
13
+ const target = document.querySelector<HTMLElement>(exploreParentSelector)
14
+ if (!target) return
15
+
16
+ destroyExplore()
17
+
18
+ target.innerHTML = ''
19
+ exploreInsertedComponent = mount(Explore, { target })
20
+ }
21
+
22
+ export function destroyExplore(): void {
23
+ if (!exploreInsertedComponent) return
24
+
25
+ unmount(exploreInsertedComponent)
26
+ exploreInsertedComponent = null
27
+ }
28
+
29
+ /**
30
+ * Copy over an existing element on the page given by the selector. This will link to a page that is
31
+ * set up by the third party to hold the explore component.
32
+ * @returns Whether or not the component was succesfully inserted
33
+ */
34
+ export function insertExploreIntoNavigation(): boolean {
35
+ const config = window.PlayPilotLinkInjections.config
36
+ if (!config) return false
37
+
38
+ const { explore_navigation_selector: selector, explore_navigation_label: label, explore_navigation_path: path, explore_navigation_insert_position: insertPosition } = window.PlayPilotLinkInjections.config
39
+ if (!selector) return false
40
+
41
+ // Make sure to remove an element we created if it already exists. Should not be possible under normal circumstances.
42
+ document.querySelector('[data-playpilot-explore-navigation-element]')?.remove()
43
+
44
+ const navigationElement = document.querySelector<HTMLElement>(selector)
45
+ if (!navigationElement) return false
46
+
47
+ const copiedElement = navigationElement.cloneNode(true) as HTMLElement
48
+ const linkElement = (copiedElement.nodeName === 'A' ? copiedElement : copiedElement.querySelector('a')) as HTMLLinkElement
49
+
50
+ linkElement.classList.remove('active')
51
+ linkElement.innerText = label || 'Streaming Guide'
52
+ linkElement.href = path
53
+
54
+ copiedElement.dataset.playpilotExploreNavigationElement = 'true'
55
+
56
+ navigationElement.insertAdjacentElement(insertPosition || 'afterend', copiedElement)
57
+
58
+ return true
59
+ }
@@ -38,6 +38,7 @@ export const title: TitleData = {
38
38
  standing_poster: 'https://img.playpilot.tech/6239ee86a58f11efb0b50a58a9feac02/src/img?optimizer=image&class=2by3x18',
39
39
  title: 'Dune: Prophecy',
40
40
  original_title: 'Dune: Prophecy',
41
+ embeddable_url: null,
41
42
  }
42
43
 
43
44
  export const linkInjections: LinkInjection[] = [{
Binary file