@playpilot/tpi 8.40.0-beta.5 → 8.40.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/dist/editorial.mount.js +9 -9
- package/dist/link-injections.js +2 -2
- package/dist/mount.js +5 -5
- package/package.json +1 -1
- package/src/lib/api/config.ts +4 -0
- package/src/lib/api/region.ts +2 -1
- package/src/lib/disclaimer.ts +4 -3
- package/src/lib/explore.ts +3 -2
- package/src/lib/injection.ts +9 -11
- package/src/lib/retargeting.ts +2 -1
- package/src/lib/routes.ts +2 -1
- package/src/lib/user.ts +2 -1
- package/src/routes/+page.svelte +3 -3
- package/src/routes/components/Debugger.svelte +2 -1
- package/src/routes/components/Explore/ExploreCallToAction.svelte +2 -1
- package/src/routes/components/Modals/TitleModal.svelte +2 -1
- package/src/routes/components/Playlinks/Playlink.svelte +2 -1
- package/src/routes/components/Playlinks/Playlinks.svelte +2 -1
- package/src/routes/components/PostersScrollReveal.svelte +2 -1
- package/src/routes/components/Rails/ParticipantsRail.svelte +2 -1
- package/src/routes/components/Widgets/InjectionsWidgetRail.svelte +2 -1
- package/src/tests/routes/+page.test.js +8 -3
package/package.json
CHANGED
package/src/lib/api/config.ts
CHANGED
|
@@ -14,3 +14,7 @@ export async function fetchConfig(): Promise<ConfigResponse | null> {
|
|
|
14
14
|
return null
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
|
|
18
|
+
export function getConfigValue<K extends keyof ConfigResponse>(key: K): ConfigResponse[K] | undefined {
|
|
19
|
+
return window.PlayPilotLinkInjections?.config?.[key]
|
|
20
|
+
}
|
package/src/lib/api/region.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { SupportedRegion } from '$lib/enums/Region'
|
|
|
2
2
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
3
3
|
import { track } from '$lib/tracking'
|
|
4
4
|
import { RETARGETING_REGION_KEY } from '@playpilot/retargeting-tracking'
|
|
5
|
+
import { getConfigValue } from './config'
|
|
5
6
|
|
|
6
7
|
export async function getRegionBasedOnIp(timeout = 5000): Promise<string> {
|
|
7
8
|
const savedRegion = window.PlayPilotLinkInjections?.region
|
|
@@ -23,7 +24,7 @@ export async function getRegionBasedOnIp(timeout = 5000): Promise<string> {
|
|
|
23
24
|
} catch (error: any) {
|
|
24
25
|
track(TrackingEvent.RegionRequestFailed, null, { message: error.message })
|
|
25
26
|
|
|
26
|
-
const fallbackRegion =
|
|
27
|
+
const fallbackRegion = getConfigValue('fallback_region')
|
|
27
28
|
return fallbackRegion || ''
|
|
28
29
|
}
|
|
29
30
|
}
|
package/src/lib/disclaimer.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { mount, unmount } from 'svelte'
|
|
2
2
|
import InTextDisclaimer from '../routes/components/InTextDisclaimer.svelte'
|
|
3
|
+
import { getConfigValue } from './api/config'
|
|
3
4
|
|
|
4
5
|
export let inTextDisclaimerInsertComponent: object | null = null
|
|
5
6
|
|
|
6
7
|
export function insertInTextDisclaimer(elements: HTMLElement[]): void {
|
|
7
|
-
if (!
|
|
8
|
+
if (!getConfigValue('in_text_disclaimer_enabled')) return
|
|
8
9
|
if (inTextDisclaimerInsertComponent) return
|
|
9
10
|
|
|
10
11
|
const target = document.createElement('div')
|
|
11
|
-
const selector =
|
|
12
|
+
const selector = getConfigValue('in_text_disclaimer_selector')
|
|
12
13
|
const insertElement = (selector ? document.querySelector(selector) : null) || elements[0]
|
|
13
|
-
const insertPosition =
|
|
14
|
+
const insertPosition = getConfigValue('in_text_disclaimer_insert_position') || 'beforebegin'
|
|
14
15
|
|
|
15
16
|
target.dataset.playpilotInTextDisclaimer = 'true'
|
|
16
17
|
insertElement.insertAdjacentElement(insertPosition, target)
|
package/src/lib/explore.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mount, unmount } from 'svelte'
|
|
2
2
|
import ExploreRouter from '../routes/components/Explore/ExploreRouter.svelte'
|
|
3
|
+
import { getConfigValue } from './api/config'
|
|
3
4
|
|
|
4
5
|
export const exploreParentSelector = '[data-playpilot-explore]'
|
|
5
6
|
export const explorePreConsentSelector = '[data-playpilot-pre-consent-explore]'
|
|
@@ -68,7 +69,7 @@ export function insertExploreIntoNavigation(): boolean {
|
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
function insertExploreCustomStyle(): void {
|
|
71
|
-
const customStyleString =
|
|
72
|
+
const customStyleString = getConfigValue('explore_custom_style')
|
|
72
73
|
|
|
73
74
|
if (!customStyleString) return
|
|
74
75
|
|
|
@@ -81,5 +82,5 @@ function insertExploreCustomStyle(): void {
|
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
export function useExploreRouter(): boolean {
|
|
84
|
-
return !!
|
|
85
|
+
return !!getConfigValue('explore_use_router')
|
|
85
86
|
}
|
package/src/lib/injection.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { exploreModalUrl, participantUrl, titleUrl } from './routes'
|
|
|
9
9
|
import { clearInTextWidgets, insertInTextWidgets } from './inTextWidgets'
|
|
10
10
|
import { encodeHtmlEntities } from './html'
|
|
11
11
|
import type { ParticipantData } from './types/participant'
|
|
12
|
+
import { getConfigValue } from './api/config'
|
|
12
13
|
|
|
13
14
|
export const keyDataAttribute = 'data-playpilot-injection-key'
|
|
14
15
|
export const keySelector = `[${keyDataAttribute}]`
|
|
@@ -219,7 +220,7 @@ function createLinkInjectionElement(injection: LinkInjection): { injectionElemen
|
|
|
219
220
|
injectionElement.dataset.playpilotInjectionKey = injection.key
|
|
220
221
|
injectionElement.dataset.playpilotInjectionType = injection.type
|
|
221
222
|
|
|
222
|
-
const openInExplore = !!
|
|
223
|
+
const openInExplore = !!getConfigValue('open_tpi_links_in_explore')
|
|
223
224
|
|
|
224
225
|
const sid = injection.title_details?.sid || injection.participant_details?.sid
|
|
225
226
|
const href = openInExplore ? exploreModalUrl(sid!) : (injection.type === 'title' ? titleUrl(injection.title_details!) : participantUrl(injection.participant_details!))
|
|
@@ -336,7 +337,7 @@ function addLinkInjectionEventListeners(injections: LinkInjection[]): void {
|
|
|
336
337
|
window.addEventListener('mousemove', destroyLinkPopoverOnMouseleave)
|
|
337
338
|
|
|
338
339
|
window.addEventListener('click', (event) => {
|
|
339
|
-
if (
|
|
340
|
+
if (getConfigValue('open_tpi_links_in_explore')) return
|
|
340
341
|
|
|
341
342
|
openModalForInjectedLink(event, injections)
|
|
342
343
|
})
|
|
@@ -454,15 +455,12 @@ export function limitInjectionsByCount(injections: LinkInjection[]): { injection
|
|
|
454
455
|
for (const injection of injections) {
|
|
455
456
|
if (!injection.manual) {
|
|
456
457
|
const previousCount = aiInjectionSidsCount[injection.sid] || 0
|
|
458
|
+
const uniqueLimit = getConfigValue('unique_injection_count_limit')
|
|
459
|
+
const totalLimit = getConfigValue('total_participant_injection_count_limit')
|
|
457
460
|
|
|
458
|
-
const exceedsUniqueCount =
|
|
459
|
-
window.PlayPilotLinkInjections?.config?.unique_injection_count_limit &&
|
|
460
|
-
previousCount >= window.PlayPilotLinkInjections?.config?.unique_injection_count_limit
|
|
461
|
+
const exceedsUniqueCount = uniqueLimit && previousCount >= uniqueLimit
|
|
461
462
|
|
|
462
|
-
const exceedsTotalParticipantsCount =
|
|
463
|
-
injection.type === 'participant' &&
|
|
464
|
-
window.PlayPilotLinkInjections?.config?.total_participant_injection_count_limit &&
|
|
465
|
-
aiParticipantInjectionsCount >= window.PlayPilotLinkInjections?.config?.total_participant_injection_count_limit
|
|
463
|
+
const exceedsTotalParticipantsCount = injection.type === 'participant' && totalLimit && aiParticipantInjectionsCount >= totalLimit
|
|
466
464
|
|
|
467
465
|
if (exceedsUniqueCount || exceedsTotalParticipantsCount) {
|
|
468
466
|
failedMessages[injection.key] = `Injection was withheld because it exceeded the maximum ${exceedsUniqueCount ? 'unique' : 'total'} count.`
|
|
@@ -521,9 +519,9 @@ export function getPlayPilotWrapperElement(): Element {
|
|
|
521
519
|
export function doesParticipantMeetThreshold(injections: LinkInjection[], participant: ParticipantData): boolean {
|
|
522
520
|
if (participant.popularity === null || participant.popularity === undefined) return true
|
|
523
521
|
|
|
524
|
-
const useArticleAverage =
|
|
522
|
+
const useArticleAverage = getConfigValue('participant_injection_popularity_threshold_use_article_average') ?? true
|
|
525
523
|
const defaultThreshold = 0
|
|
526
|
-
const configThreshold =
|
|
524
|
+
const configThreshold = getConfigValue('participant_injection_popularity_threshold')
|
|
527
525
|
const threshold = configThreshold ?? defaultThreshold
|
|
528
526
|
|
|
529
527
|
if (threshold === 0) return true
|
package/src/lib/retargeting.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { RETARGETING_USER_ID_KEY } from '@playpilot/retargeting-tracking'
|
|
2
2
|
import { hasConsentedTo } from './consent'
|
|
3
3
|
import { getUserId } from './user'
|
|
4
|
+
import { getConfigValue } from './api/config'
|
|
4
5
|
|
|
5
6
|
export function isRetargetingAllowed(): boolean {
|
|
6
|
-
if (!
|
|
7
|
+
if (!getConfigValue('allow_retargeting_pixels')) return false
|
|
7
8
|
|
|
8
9
|
if (!hasConsentedTo('pixels')) return false
|
|
9
10
|
|
package/src/lib/routes.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getConfigValue } from './api/config'
|
|
1
2
|
import { playPilotBaseUrl } from './constants'
|
|
2
3
|
import type { ParticipantData } from './types/participant'
|
|
3
4
|
import type { TitleData } from './types/title'
|
|
@@ -11,5 +12,5 @@ export function participantUrl(participant: ParticipantData): string {
|
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export function exploreModalUrl(sid: string): string {
|
|
14
|
-
return
|
|
15
|
+
return getConfigValue('explore_navigation_path') + `?route=modal&sid=${sid}`
|
|
15
16
|
}
|
package/src/lib/user.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getConfigValue } from './api/config'
|
|
1
2
|
import { hasConsentedTo } from './consent'
|
|
2
3
|
import { generateRandomHash } from './hash'
|
|
3
4
|
|
|
@@ -33,5 +34,5 @@ export function getSessionId(): string | null {
|
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
export function isUserTrackingAllowed(): boolean {
|
|
36
|
-
return !!
|
|
37
|
+
return !!getConfigValue('allow_user_id_tracking') && hasConsentedTo('tracking')
|
|
37
38
|
}
|
package/src/routes/+page.svelte
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { isCrawler } from '$lib/crawler'
|
|
8
8
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
9
9
|
import { fetchAds } from '$lib/api/ads'
|
|
10
|
-
import { fetchConfig } from '$lib/api/config'
|
|
10
|
+
import { fetchConfig, getConfigValue } from '$lib/api/config'
|
|
11
11
|
import { insertExplore, insertExploreIntoNavigation } from '$lib/explore'
|
|
12
12
|
import { authorize, getAuthToken, isEditorialModeEnabled, removeAuthCookie, setEditorialParamInUrl } from '$lib/api/auth'
|
|
13
13
|
import { getPageTextAndElements } from '$lib/injectionElements'
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
fireQueuedTrackingEvents()
|
|
56
56
|
track(TrackingEvent.ArticlePageView)
|
|
57
57
|
|
|
58
|
-
const explorePath =
|
|
58
|
+
const explorePath = getConfigValue('explore_navigation_path')
|
|
59
59
|
|
|
60
60
|
if ((!aiInjections.length && !manualInjections.length) && !(explorePath && document.location.href.includes(explorePath))) return
|
|
61
61
|
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
loading = false
|
|
103
103
|
|
|
104
104
|
if (!response) return
|
|
105
|
-
if (
|
|
105
|
+
if (getConfigValue('disable_public_injections') && !(isEditorialMode && authorized)) return
|
|
106
106
|
|
|
107
107
|
setTrackingSids({ organizationSid: response.organization_sid, domainSid: response.domain_sid })
|
|
108
108
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { getConfigValue } from '$lib/api/config'
|
|
2
3
|
import { fetchLinkInjections } from '$lib/api/externalPages'
|
|
3
4
|
import { Language } from '$lib/enums/Language'
|
|
4
5
|
import { SplitTest } from '$lib/enums/SplitTest'
|
|
@@ -131,7 +132,7 @@
|
|
|
131
132
|
|
|
132
133
|
<hr />
|
|
133
134
|
|
|
134
|
-
{#if !!(
|
|
135
|
+
{#if !!(getConfigValue('exclude_urls_pattern') && getFullUrlPath().match(getConfigValue('exclude_urls_pattern')!))}
|
|
135
136
|
<span class="error">The current URL is excluded via the config</span>
|
|
136
137
|
<hr />
|
|
137
138
|
{/if}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { getConfigValue } from '$lib/api/config'
|
|
2
3
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
3
4
|
import { track } from '$lib/tracking'
|
|
4
5
|
import IconArrow from '../Icons/IconArrow.svelte'
|
|
5
6
|
|
|
6
7
|
const src = 'https://cdn.jsdelivr.net/npm/@playpilot/tpi@latest/src/lib/images/titles-list.webp'
|
|
7
|
-
const href =
|
|
8
|
+
const href = getConfigValue('explore_navigation_path')
|
|
8
9
|
</script>
|
|
9
10
|
|
|
10
11
|
<a class="call-to-action" {href} onclick={() => track(TrackingEvent.CardToExploreCta)}>
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { exploreParentSelector } from '$lib/explore'
|
|
7
7
|
import { onMount, setContext } from 'svelte'
|
|
8
8
|
import { isRetargetingAllowed } from '$lib/retargeting'
|
|
9
|
+
import { getConfigValue } from '$lib/api/config'
|
|
9
10
|
import { trackViaPixel } from '@playpilot/retargeting-tracking'
|
|
10
11
|
import Modal from './Modal.svelte'
|
|
11
12
|
import Title from '../Title.svelte'
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
|
|
25
26
|
const topScrollAd = getFirstAdOfType('top_scroll')
|
|
26
27
|
const displayAd = getFirstAdOfType('card')
|
|
27
|
-
const insertExploreCta =
|
|
28
|
+
const insertExploreCta = getConfigValue('explore_insert_cta_in_tpi')
|
|
28
29
|
const useBubble = !!topScrollAd || (insertExploreCta && !document.querySelector(exploreParentSelector))
|
|
29
30
|
|
|
30
31
|
let hasTrackedScrolling = false
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { trackClickViaPixel, trackViewViaPixel } from '@playpilot/retargeting-tracking'
|
|
9
9
|
import { MetaEvent, MetaSource } from '$lib/enums/TrackingEvent'
|
|
10
10
|
import { isRetargetingAllowed } from '$lib/retargeting'
|
|
11
|
+
import { getConfigValue } from '$lib/api/config'
|
|
11
12
|
|
|
12
13
|
interface Props {
|
|
13
14
|
playlink: PlaylinkData
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
37
38
|
<svelte:element
|
|
38
39
|
{onclick}
|
|
39
|
-
this={!
|
|
40
|
+
this={!getConfigValue('require_affiliate_consent') || hasConsentedTo('affiliate') ? 'a' : 'span'}
|
|
40
41
|
{@attach usePixel ? trackViewViaPixel(MetaEvent.ProviderInterest, { provider: playlink.slug, source: MetaSource.Card }) : null}
|
|
41
42
|
{@attach usePixel ? trackClickViaPixel(MetaEvent.ProviderClick, { provider: playlink.slug }) : null}
|
|
42
43
|
href={url}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import Playlink from './Playlink.svelte'
|
|
12
12
|
import Button from '../Button.svelte'
|
|
13
13
|
import PlaylinksDisclaimer from './PlaylinksDisclaimer.svelte'
|
|
14
|
+
import { getConfigValue } from '$lib/api/config'
|
|
14
15
|
|
|
15
16
|
type Category = PlaylinkCategory | '' | 'Other'
|
|
16
17
|
type CategorizedPlaylinks = Partial<Record<Category, PlaylinkData[]>>
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
const isModal = getContext('scope') === 'modal'
|
|
28
29
|
const type = getContext('type')
|
|
29
30
|
const displayAd = getFirstAdOfType('card')
|
|
30
|
-
const categorize = !!
|
|
31
|
+
const categorize = !!getConfigValue('categorize_playlinks')
|
|
31
32
|
|
|
32
33
|
let outerWidth = $state(0)
|
|
33
34
|
let limited = $state(!categorize)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { getConfigValue } from '$lib/api/config'
|
|
2
3
|
import { mobileBreakpoint } from '$lib/constants'
|
|
3
4
|
import { onDestroy } from 'svelte'
|
|
4
5
|
import { SvelteSet } from 'svelte/reactivity'
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
onDestroy(destroyAllPosters)
|
|
18
19
|
|
|
19
20
|
function onscroll(): void {
|
|
20
|
-
if (
|
|
21
|
+
if (getConfigValue('disable_scroll_reveal_posters')) return
|
|
21
22
|
if (!isMobile) return
|
|
22
23
|
|
|
23
24
|
setScrollTimeout()
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import ParticipantImage from '../Participants/ParticipantImage.svelte'
|
|
12
12
|
import Rail from './Rail.svelte'
|
|
13
13
|
import { exploreModalUrl } from '$lib/routes'
|
|
14
|
+
import { getConfigValue } from '$lib/api/config'
|
|
14
15
|
|
|
15
16
|
interface Props {
|
|
16
17
|
title: TitleData
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
async function onclick(event: MouseEvent, participant: ParticipantData): Promise<void> {
|
|
46
47
|
track(TrackingEvent.ParticipantClick, null, { title_source: title.original_title || title.title, participant: participant.name })
|
|
47
48
|
|
|
48
|
-
if (!
|
|
49
|
+
if (!getConfigValue('open_tpi_links_in_explore') || window.location.href.includes(getConfigValue('explore_navigation_path') || '')) {
|
|
49
50
|
const fetchedParticipant = await fetchParticipantBySid(participant.sid)
|
|
50
51
|
|
|
51
52
|
openModal({ event, type: 'participant', data: fetchedParticipant })
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { getConfigValue } from '$lib/api/config'
|
|
2
3
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
3
4
|
import { t } from '$lib/localization'
|
|
4
5
|
import { track } from '$lib/tracking'
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
<TitlesRail
|
|
39
40
|
{titles}
|
|
40
41
|
{heading}
|
|
41
|
-
navigateToExplore={!!
|
|
42
|
+
navigateToExplore={!!getConfigValue('open_tpi_links_in_explore')}
|
|
42
43
|
onclick={(title) => track(TrackingEvent.WidgetArticleRailTitleClick, title)} />
|
|
43
44
|
</div>
|
|
44
45
|
{/if}
|
|
@@ -19,9 +19,14 @@ vi.mock('$lib/api/externalPages', () => ({
|
|
|
19
19
|
pollLinkInjections: vi.fn(() => {}),
|
|
20
20
|
}))
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
vi.mock(import('$lib/api/config'), async (importOriginal) => {
|
|
24
|
+
const actual = await importOriginal()
|
|
25
|
+
return {
|
|
26
|
+
...actual,
|
|
27
|
+
fetchConfig: vi.fn(() => {}),
|
|
28
|
+
}
|
|
29
|
+
})
|
|
25
30
|
|
|
26
31
|
// @ts-ignore
|
|
27
32
|
vi.mock(import('$lib/api/session'), async (importOriginal) => {
|