@playpilot/tpi 5.34.1 → 6.0.0-beta.explore.15
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/link-injections.js +25 -10
- package/package.json +1 -1
- package/src/lib/api/titles.ts +13 -1
- package/src/lib/data/countries.json +216 -0
- package/src/lib/data/translations.ts +5 -0
- package/src/lib/enums/SplitTest.ts +1 -6
- package/src/lib/explore.ts +59 -0
- package/src/lib/fakeData.ts +1 -0
- package/src/lib/images/titles-list.webp +0 -0
- package/src/lib/modal.ts +7 -6
- package/src/lib/scss/global.scss +0 -2
- package/src/lib/trailer.ts +22 -0
- package/src/lib/types/api.d.ts +6 -0
- package/src/lib/types/config.d.ts +12 -0
- package/src/lib/types/filter.d.ts +2 -0
- package/src/lib/types/title.d.ts +4 -1
- package/src/routes/+page.svelte +6 -1
- package/src/routes/components/Ads/TopScroll.svelte +4 -18
- package/src/routes/components/Button.svelte +101 -0
- package/src/routes/components/Debugger.svelte +25 -0
- package/src/routes/components/Explore/Explore.svelte +240 -0
- package/src/routes/components/Explore/ExploreCallToAction.svelte +58 -0
- package/src/routes/components/Explore/ExploreModal.svelte +15 -0
- package/src/routes/components/Explore/Filter/Dropdown.svelte +72 -0
- package/src/routes/components/Explore/Filter/Filter.svelte +99 -0
- package/src/routes/components/Explore/Filter/FilterItem.svelte +57 -0
- package/src/routes/components/Explore/Filter/FilterSorting.svelte +70 -0
- package/src/routes/components/Explore/Filter/Search.svelte +57 -0
- package/src/routes/components/Explore/Filter/TogglesWithSearch.svelte +142 -0
- package/src/routes/components/GridTitle.svelte +122 -0
- package/src/routes/components/GridTitleSkeleton.svelte +36 -0
- package/src/routes/components/Icons/IconArrow.svelte +10 -2
- package/src/routes/components/Icons/IconClose.svelte +9 -1
- package/src/routes/components/Icons/IconFilter.svelte +5 -0
- package/src/routes/components/Icons/IconPlay.svelte +3 -0
- package/src/routes/components/Icons/IconSearch.svelte +3 -0
- package/src/routes/components/ListTitle.svelte +10 -68
- package/src/routes/components/ListTitleSkeleton.svelte +42 -0
- package/src/routes/components/Modal.svelte +5 -23
- package/src/routes/components/Participant.svelte +0 -4
- package/src/routes/components/Playlinks/PlaylinkIcon.svelte +1 -1
- package/src/routes/components/Playlinks/PlaylinksCompact.svelte +62 -0
- package/src/routes/components/Share.svelte +5 -23
- package/src/routes/components/Title.svelte +22 -22
- package/src/routes/components/TitleModal.svelte +4 -1
- package/src/routes/components/Trailer.svelte +18 -0
- package/src/routes/components/YouTubeEmbedOverlay.svelte +96 -0
- package/src/routes/elements/+page.svelte +39 -2
- package/src/routes/explore/+page.svelte +60 -0
- package/src/tests/lib/api/ads.test.js +0 -1
- package/src/tests/lib/api/titles.test.js +55 -0
- package/src/tests/lib/explore.test.js +139 -0
- package/src/tests/lib/trailer.test.js +56 -0
- package/src/tests/routes/components/Button.test.js +28 -0
- package/src/tests/routes/components/Explore/Explore.test.js +94 -0
- package/src/tests/routes/components/Explore/Filter/Dropdown.test.js +16 -0
- package/src/tests/routes/components/Explore/Filter/Filter.test.js +28 -0
- package/src/tests/routes/components/Explore/Filter/FilterItem.test.js +50 -0
- package/src/tests/routes/components/Explore/Filter/FilterSorting.test.js +34 -0
- package/src/tests/routes/components/Explore/Filter/Search.test.js +26 -0
- package/src/tests/routes/components/Explore/Filter/TogglesWithSearch.test.js +53 -0
- package/src/tests/routes/components/GridTitle.test.js +42 -0
- package/src/tests/routes/components/ListTitle.test.js +1 -1
- package/src/tests/routes/components/Playlinks/PlaylinksCompact.test.js +42 -0
- package/src/tests/routes/components/Share.test.js +12 -12
- package/src/tests/routes/components/Title.test.js +13 -0
- package/src/tests/routes/components/Trailer.test.js +20 -0
- package/src/tests/routes/components/YouTubeEmbedOverlay.test.js +31 -0
- package/src/tests/setup.js +2 -0
package/package.json
CHANGED
package/src/lib/api/titles.ts
CHANGED
|
@@ -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
|
|
18
|
+
const response = await fetchTitles({ related_to_sid: title.sid })
|
|
7
19
|
|
|
8
20
|
return response.results
|
|
9
21
|
}
|
|
@@ -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': {
|
|
@@ -4,11 +4,6 @@ export const SplitTest = {
|
|
|
4
4
|
numberOfVariants: 2,
|
|
5
5
|
variantNames: ['Separated', 'Inline'] as string[],
|
|
6
6
|
},
|
|
7
|
-
ParticipantPlaylinkFormat: {
|
|
8
|
-
key: 'participant_playlink_format',
|
|
9
|
-
numberOfVariants: 2,
|
|
10
|
-
variantNames: ['Image', 'Label'] as string[],
|
|
11
|
-
},
|
|
12
7
|
InTextEngagement: {
|
|
13
8
|
key: 'in-text-engagement',
|
|
14
9
|
numberOfVariants: 4,
|
|
@@ -18,5 +13,5 @@ export const SplitTest = {
|
|
|
18
13
|
key: 'user_time_spent',
|
|
19
14
|
numberOfVariants: 10,
|
|
20
15
|
variantNames: ['No Links', 'Default', 'Default', 'Default', 'Default', 'Default', 'Default', 'Default', 'Default', 'Default'] as string[],
|
|
21
|
-
}
|
|
16
|
+
},
|
|
22
17
|
} as const
|
|
@@ -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
|
+
}
|
package/src/lib/fakeData.ts
CHANGED
|
@@ -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
|
package/src/lib/modal.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { mount, unmount } from "svelte"
|
|
2
2
|
import { isHoldingSpecialKey } from "./event"
|
|
3
|
-
import TitleModal from "../routes/components/TitleModal.svelte"
|
|
4
3
|
import type { LinkInjection } from "./types/injection"
|
|
5
|
-
import ParticipantModal from "../routes/components/ParticipantModal.svelte"
|
|
6
4
|
import type { TitleData } from "./types/title"
|
|
7
5
|
import type { ParticipantData } from "./types/participant"
|
|
8
6
|
import { mobileBreakpoint } from "./constants"
|
|
7
|
+
import TitleModal from "../routes/components/TitleModal.svelte"
|
|
8
|
+
import ParticipantModal from "../routes/components/ParticipantModal.svelte"
|
|
9
|
+
import ExploreModal from "../routes/components/Explore/ExploreModal.svelte"
|
|
9
10
|
import { getPlayPilotWrapperElement, keyDataAttribute, keySelector } from "./injection"
|
|
10
11
|
import { playFallbackViewTransition } from "./viewTransition"
|
|
11
12
|
import { destroyLinkPopover } from "./popover"
|
|
@@ -13,7 +14,7 @@ import { prefersReducedMotion } from "svelte/motion"
|
|
|
13
14
|
import { trackSplitTestAction } from "./splitTest"
|
|
14
15
|
import { SplitTest } from "./enums/SplitTest"
|
|
15
16
|
|
|
16
|
-
type ModalType = 'title' | 'participant'
|
|
17
|
+
type ModalType = 'title' | 'participant' | 'explore'
|
|
17
18
|
|
|
18
19
|
type Modal = {
|
|
19
20
|
injection?: LinkInjection | null
|
|
@@ -51,9 +52,9 @@ export function openModal(
|
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
function getModalComponentByType({ type = 'title', target, data, props = {} }: { type: ModalType, target: Element, data: TitleData | ParticipantData | null, props?: Record<string, any> }) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
if (type === 'participant') return mount(ParticipantModal, { target, props: { participant: data as ParticipantData, ...props } })
|
|
56
|
+
if (type === 'explore') return mount(ExploreModal, { target, props: { ...props } })
|
|
57
|
+
return mount(TitleModal, { target, props: { title: data as TitleData, ...props } })
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
function addModalToList({ type = 'title', injection = null, data, scrollPosition = 0, component }: Modal) {
|
package/src/lib/scss/global.scss
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { mount, unmount } from "svelte"
|
|
2
|
+
import { getPlayPilotWrapperElement } from "./injection"
|
|
3
|
+
import type { TitleData } from "./types/title"
|
|
4
|
+
import YouTubeEmbedOverlay from "../routes/components/YouTubeEmbedOverlay.svelte"
|
|
5
|
+
|
|
6
|
+
let currentTrailerComponent: object | null = {}
|
|
7
|
+
|
|
8
|
+
export function openTrailerOverlay(title: TitleData) {
|
|
9
|
+
const target = getPlayPilotWrapperElement()
|
|
10
|
+
// !! Temporarily falls back to a placeholder is while embeddable_url is not yet present
|
|
11
|
+
const props = { onclose: closeTrailerOverlay, embeddable_url: title.embeddable_url || 'https://www.youtube.com/watch?v=xGTq0blCPVQ' }
|
|
12
|
+
|
|
13
|
+
currentTrailerComponent = mount(YouTubeEmbedOverlay, { target, props })
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function closeTrailerOverlay(): void {
|
|
17
|
+
if (!currentTrailerComponent) return
|
|
18
|
+
|
|
19
|
+
unmount(currentTrailerComponent, { outro: true })
|
|
20
|
+
|
|
21
|
+
currentTrailerComponent = null
|
|
22
|
+
}
|
|
@@ -39,4 +39,16 @@ export type ConfigResponse = {
|
|
|
39
39
|
in_text_disclaimer_text?: string
|
|
40
40
|
in_text_disclaimer_selector?: string
|
|
41
41
|
in_text_disclaimer_insert_position?: InsertPosition
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* These options are all relevant for the Explore component, which can be inserted as a widget on any page or as a modal.
|
|
45
|
+
* `explore_navigation_selector` is used to select the navigation element that should be copied and inserted _after_.
|
|
46
|
+
* `explore_navigation_label` will end up being the label of the navigation item, defaults to `Streaming Guide`.
|
|
47
|
+
* `explore_navigation_path` is the path that the navigation item will lead to, this will be set up by the third party.
|
|
48
|
+
* `explore_navigation_insert_position` is used to determine if the navigation item should be inserted before or after the given selector.
|
|
49
|
+
*/
|
|
50
|
+
explore_navigation_selector?: string
|
|
51
|
+
explore_navigation_label?: string
|
|
52
|
+
explore_navigation_path?: string
|
|
53
|
+
explore_navigation_insert_position?: InsertPosition
|
|
42
54
|
}
|
package/src/lib/types/title.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ParticipantData } from './participant'
|
|
2
2
|
import type { PlaylinkData } from './playlink'
|
|
3
3
|
|
|
4
|
+
export type ContentType = 'movie' | 'series'
|
|
5
|
+
|
|
4
6
|
export type TitleData = {
|
|
5
7
|
sid: string
|
|
6
8
|
slug: string
|
|
@@ -9,7 +11,7 @@ export type TitleData = {
|
|
|
9
11
|
genres: string[]
|
|
10
12
|
year: number
|
|
11
13
|
imdb_score: number
|
|
12
|
-
type:
|
|
14
|
+
type: ContentType
|
|
13
15
|
providers: PlaylinkData[]
|
|
14
16
|
description: string | null
|
|
15
17
|
small_poster: string
|
|
@@ -17,6 +19,7 @@ export type TitleData = {
|
|
|
17
19
|
standing_poster: string
|
|
18
20
|
title: string
|
|
19
21
|
original_title: string
|
|
22
|
+
embeddable_url: string | null
|
|
20
23
|
length?: number
|
|
21
24
|
blurb?: string
|
|
22
25
|
participants?: ParticipantData[]
|
package/src/routes/+page.svelte
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
9
9
|
import { fetchAds } from '$lib/api/ads'
|
|
10
10
|
import { fetchConfig } from '$lib/api/config'
|
|
11
|
+
import { insertExplore, insertExploreIntoNavigation } from '$lib/explore'
|
|
11
12
|
import { authorize, getAuthToken, isEditorialModeEnabled, removeAuthCookie, setEditorialParamInUrl } from '$lib/api/auth'
|
|
12
13
|
import { trackSplitTestView, getSplitTestVariantName } from '$lib/splitTest'
|
|
13
14
|
import { SplitTest } from '$lib/enums/SplitTest'
|
|
@@ -44,6 +45,8 @@
|
|
|
44
45
|
if (isEditorialMode && !loading) rerender()
|
|
45
46
|
})
|
|
46
47
|
|
|
48
|
+
insertExplore()
|
|
49
|
+
|
|
47
50
|
onDestroy(clearLinkInjections)
|
|
48
51
|
|
|
49
52
|
// This function is called when a user has properly consented via tcfapi or if no consent is required.
|
|
@@ -80,6 +83,7 @@
|
|
|
80
83
|
if (isUrlExcluded) return
|
|
81
84
|
|
|
82
85
|
if (config?.custom_style) insertCustomStyle(config.custom_style || '')
|
|
86
|
+
if (config?.explore_navigation_selector) insertExploreIntoNavigation()
|
|
83
87
|
|
|
84
88
|
setElements(config?.html_selector || '', config?.exclude_elements_selector || '')
|
|
85
89
|
} catch(error) {
|
|
@@ -254,7 +258,8 @@
|
|
|
254
258
|
<style lang="scss">
|
|
255
259
|
@import url('$lib/scss/global.scss');
|
|
256
260
|
|
|
257
|
-
.playpilot-link-injections
|
|
261
|
+
.playpilot-link-injections,
|
|
262
|
+
:global([data-playpilot-explore]) {
|
|
258
263
|
:global(*) {
|
|
259
264
|
box-sizing: border-box;
|
|
260
265
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { SplitTest } from '$lib/enums/SplitTest'
|
|
5
5
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
6
6
|
import { imageFromUUID } from '$lib/image'
|
|
7
|
-
import {
|
|
7
|
+
import { trackSplitTestView } from '$lib/splitTest'
|
|
8
8
|
import { track } from '$lib/tracking'
|
|
9
9
|
import type { Campaign } from '$lib/types/campaign'
|
|
10
10
|
import Disclaimer from './Disclaimer.svelte'
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
const { format, header, header_logo: logo, image_uuid: backgroundImageUUID } = $derived(content)
|
|
23
23
|
const { header: buttonLabel, url: href } = $derived(cta)
|
|
24
24
|
|
|
25
|
-
const inline = isInSplitTestVariant(SplitTest.TopScrollFormat, 1)
|
|
26
25
|
const simple = $derived(format === 'large')
|
|
27
26
|
|
|
28
27
|
const backgroundImage = $derived(imageFromUUID(backgroundImageUUID, ImageDimensions.TopScrollBackground))
|
|
@@ -43,7 +42,6 @@
|
|
|
43
42
|
target="_blank"
|
|
44
43
|
class="top-scroll"
|
|
45
44
|
class:simple
|
|
46
|
-
class:inline
|
|
47
45
|
tabindex="-1"
|
|
48
46
|
rel="sponsored"
|
|
49
47
|
style:--width="{clientWidth}px">
|
|
@@ -81,17 +79,13 @@
|
|
|
81
79
|
position: relative;
|
|
82
80
|
display: block;
|
|
83
81
|
width: 100%;
|
|
84
|
-
border-radius: $border-radius-size;
|
|
82
|
+
border-radius: $border-radius-size $border-radius-size 0 0;
|
|
85
83
|
background: black;
|
|
86
84
|
color: theme(top-scroll-text-color, white);
|
|
87
85
|
font-family: theme(top-scroll-font-family, font-family);
|
|
88
86
|
font-size: theme(top-scroll-font-size, font-size-base);
|
|
89
87
|
text-decoration: none;
|
|
90
88
|
line-height: 1.35;
|
|
91
|
-
|
|
92
|
-
&.inline {
|
|
93
|
-
border-radius: $border-radius-size $border-radius-size 0 0;
|
|
94
|
-
}
|
|
95
89
|
}
|
|
96
90
|
|
|
97
91
|
.content {
|
|
@@ -152,7 +146,7 @@
|
|
|
152
146
|
right: 0;
|
|
153
147
|
bottom: 0;
|
|
154
148
|
left: 0;
|
|
155
|
-
border-radius: $border-radius-size;
|
|
149
|
+
border-radius: $border-radius-size $border-radius-size 0 0;
|
|
156
150
|
background-image: var(--background);
|
|
157
151
|
background-position: center;
|
|
158
152
|
background-size: cover;
|
|
@@ -161,10 +155,6 @@
|
|
|
161
155
|
.top-scroll:hover & {
|
|
162
156
|
filter: brightness(1.15);
|
|
163
157
|
}
|
|
164
|
-
|
|
165
|
-
.inline & {
|
|
166
|
-
border-radius: $border-radius-size $border-radius-size 0 0;
|
|
167
|
-
}
|
|
168
158
|
}
|
|
169
159
|
|
|
170
160
|
.content-image {
|
|
@@ -172,14 +162,10 @@
|
|
|
172
162
|
max-width: 100%;
|
|
173
163
|
height: auto;
|
|
174
164
|
background: black;
|
|
175
|
-
border-radius: $border-radius-size;
|
|
165
|
+
border-radius: $border-radius-size $border-radius-size 0 0;
|
|
176
166
|
|
|
177
167
|
.top-scroll:hover & {
|
|
178
168
|
filter: brightness(1.15);
|
|
179
169
|
}
|
|
180
|
-
|
|
181
|
-
.inline & {
|
|
182
|
-
border-radius: $border-radius-size $border-radius-size 0 0;
|
|
183
|
-
}
|
|
184
170
|
}
|
|
185
171
|
</style>
|