@playpilot/tpi 8.7.1 → 8.8.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 +8 -8
- package/dist/link-injections.js +1 -1
- package/dist/mount.js +8 -8
- package/package.json +1 -1
- package/src/lib/enums/TrackingEvent.ts +5 -0
- package/src/lib/injection.ts +1 -0
- package/src/lib/pixel.ts +6 -0
- package/src/lib/tracking.ts +0 -5
- package/src/lib/types/injection.d.ts +1 -0
- package/src/routes/+page.svelte +5 -0
- package/src/routes/components/Explore/Filter/Filter.svelte +5 -1
- package/src/routes/components/Genres.svelte +3 -3
- package/src/routes/components/Playlinks/Playlink.svelte +3 -3
- package/src/routes/components/TrackingPixelsForTitleDataPerLink.svelte +61 -0
- package/src/routes/components/UserJourney.svelte +1 -1
- package/src/tests/lib/pixel.test.js +53 -0
- package/src/tests/lib/tracking.test.js +1 -38
- package/src/tests/routes/components/Modals/TitleModal.test.js +3 -0
- package/src/tests/routes/components/Playlinks/Playlink.test.js +3 -0
- package/src/tests/routes/components/Playlinks/Playlinks.test.js +3 -0
- package/src/tests/routes/components/Title.test.js +3 -0
- package/src/tests/routes/components/TitlePopover.test.js +3 -0
package/package.json
CHANGED
package/src/lib/injection.ts
CHANGED
package/src/lib/pixel.ts
ADDED
package/src/lib/tracking.ts
CHANGED
|
@@ -103,8 +103,3 @@ export function fireQueuedTrackingEvents(): void {
|
|
|
103
103
|
|
|
104
104
|
window.PlayPilotLinkInjections.queued_tracking_events = []
|
|
105
105
|
}
|
|
106
|
-
|
|
107
|
-
export function isPixelAllowed(): boolean {
|
|
108
|
-
if (!window.PlayPilotLinkInjections.config?.allow_retargeting_pixels) return false
|
|
109
|
-
return hasConsentedTo('pixels')
|
|
110
|
-
}
|
package/src/routes/+page.svelte
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import Debugger from './components/Debugger.svelte'
|
|
21
21
|
import UserJourney from './components/UserJourney.svelte'
|
|
22
22
|
import PostersScrollReveal from './components/PostersScrollReveal.svelte'
|
|
23
|
+
import TrackingPixelsForTitleDataPerLink from './components/TrackingPixelsForTitleDataPerLink.svelte'
|
|
23
24
|
|
|
24
25
|
let elements: HTMLElement[] = $state([])
|
|
25
26
|
|
|
@@ -230,6 +231,10 @@
|
|
|
230
231
|
<TrackingPixels pixels={response.pixels} />
|
|
231
232
|
{/if}
|
|
232
233
|
|
|
234
|
+
{#if linkInjections.length}
|
|
235
|
+
<TrackingPixelsForTitleDataPerLink {linkInjections} />
|
|
236
|
+
{/if}
|
|
237
|
+
|
|
233
238
|
{#key linkInjections}
|
|
234
239
|
<UserJourney />
|
|
235
240
|
<PostersScrollReveal />
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
}, {
|
|
29
29
|
label: t('Genres'),
|
|
30
30
|
param: 'genres',
|
|
31
|
-
data: genres.filter(genre => parseInt(genre.slug) < 900).map(genre => ({ label: genre.name, value: genre.slug })),
|
|
31
|
+
data: genres.filter(genre => parseInt(genre.slug) < 900).map(genre => ({ label: t(genre.name), value: genre.slug })),
|
|
32
32
|
}, {
|
|
33
33
|
label: t('IMDb'),
|
|
34
34
|
param: 'imdb_score',
|
|
@@ -106,4 +106,8 @@
|
|
|
106
106
|
margin-top: margin(0.5);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
.sorting {
|
|
111
|
+
margin-top: margin(0.1);
|
|
112
|
+
}
|
|
109
113
|
</style>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import genreData from '$lib/data/genres.json'
|
|
3
|
-
import { MetaEvent } from '$lib/enums/TrackingEvent'
|
|
3
|
+
import { MetaEvent, MetaSource } from '$lib/enums/TrackingEvent'
|
|
4
4
|
import { t } from '$lib/localization'
|
|
5
|
-
import { isPixelAllowed } from '$lib/
|
|
5
|
+
import { isPixelAllowed } from '$lib/pixel'
|
|
6
6
|
import { trackViewViaPixel } from '@playpilot/retargeting-tracking'
|
|
7
7
|
|
|
8
8
|
interface Props {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
{@const genreName = genreData.find(g => g.slug === genre)?.name}
|
|
21
21
|
|
|
22
22
|
{#if genreName}
|
|
23
|
-
<div class="genre" {@attach isPixelAllowed() ? trackViewViaPixel(MetaEvent.GenreInterest, { genre: genreName }) : null}>
|
|
23
|
+
<div class="genre" {@attach isPixelAllowed() ? trackViewViaPixel(MetaEvent.GenreInterest, { genre: genreName, source: MetaSource.Card }) : null}>
|
|
24
24
|
{t(genreName)}
|
|
25
25
|
</div>
|
|
26
26
|
{/if}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
import { t } from '$lib/localization'
|
|
7
7
|
import type { PlaylinkData } from '$lib/types/playlink'
|
|
8
8
|
import { trackClickViaPixel, trackViewViaPixel } from '@playpilot/retargeting-tracking'
|
|
9
|
-
import { MetaEvent } from '$lib/enums/TrackingEvent'
|
|
10
|
-
import { isPixelAllowed } from '$lib/
|
|
9
|
+
import { MetaEvent, MetaSource } from '$lib/enums/TrackingEvent'
|
|
10
|
+
import { isPixelAllowed } from '$lib/pixel'
|
|
11
11
|
|
|
12
12
|
interface Props {
|
|
13
13
|
playlink: PlaylinkData
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<svelte:element
|
|
38
38
|
{onclick}
|
|
39
39
|
this={!window.PlayPilotLinkInjections?.config?.require_affiliate_consent || hasConsentedTo('affiliate') ? 'a' : 'span'}
|
|
40
|
-
{@attach usePixel ? trackViewViaPixel(MetaEvent.ProviderInterest, { provider: playlink.slug }) : null}
|
|
40
|
+
{@attach usePixel ? trackViewViaPixel(MetaEvent.ProviderInterest, { provider: playlink.slug, source: MetaSource.Card }) : null}
|
|
41
41
|
{@attach usePixel ? trackClickViaPixel(MetaEvent.ProviderClick, { provider: playlink.slug }) : null}
|
|
42
42
|
href={url}
|
|
43
43
|
target="_blank"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import genreData from '$lib/data/genres.json'
|
|
3
|
+
import { MetaEvent, MetaSource } from '$lib/enums/TrackingEvent'
|
|
4
|
+
import { keyDataAttribute } from '$lib/injection'
|
|
5
|
+
import { isPixelAllowed } from '$lib/pixel'
|
|
6
|
+
import type { LinkInjection } from '$lib/types/injection'
|
|
7
|
+
import type { TitleData } from '$lib/types/title'
|
|
8
|
+
import { trackViaPixel } from '@playpilot/retargeting-tracking'
|
|
9
|
+
import { onMount } from 'svelte'
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
linkInjections: LinkInjection[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { linkInjections }: Props = $props()
|
|
16
|
+
|
|
17
|
+
const previouslyTrackingTitles: string[] = []
|
|
18
|
+
|
|
19
|
+
onMount(() => {
|
|
20
|
+
if (!isPixelAllowed()) return
|
|
21
|
+
|
|
22
|
+
const observer = new IntersectionObserver((entries) => {
|
|
23
|
+
entries.forEach(entry => {
|
|
24
|
+
if (!entry.isIntersecting) return
|
|
25
|
+
|
|
26
|
+
observer!.unobserve(entry.target)
|
|
27
|
+
|
|
28
|
+
const key = entry.target.getAttribute(keyDataAttribute)
|
|
29
|
+
const matchingInjection = linkInjections.find(injection => injection.key === key)
|
|
30
|
+
const title = matchingInjection?.title_details
|
|
31
|
+
|
|
32
|
+
if (!key || !matchingInjection || !title) return
|
|
33
|
+
if (previouslyTrackingTitles.includes(title.sid)) return
|
|
34
|
+
|
|
35
|
+
trackPixelsForTitle(title)
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
linkInjections.forEach(injection => {
|
|
40
|
+
if (injection.matchingElement) observer.observe(injection.matchingElement)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
return () => observer.disconnect()
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
function trackPixelsForTitle({ sid, genres, participants, providers }: TitleData): void {
|
|
47
|
+
previouslyTrackingTitles.push(sid)
|
|
48
|
+
|
|
49
|
+
genres.slice(0, 3).forEach(genre => {
|
|
50
|
+
trackViaPixel(MetaEvent.GenreInterest, { genre: genreData.find(g => g.slug === genre)?.name, source: MetaSource.Link })
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
participants?.slice(0, 5).forEach(participant => {
|
|
54
|
+
trackViaPixel(MetaEvent.ParticipantInterest, { participant: participant.name, source: MetaSource.Link })
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
providers?.forEach(provider => {
|
|
58
|
+
trackViaPixel(MetaEvent.ProviderInterest, { provider: provider.name, source: MetaSource.Link })
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { hasConsentedTo } from '$lib/consent'
|
|
2
|
+
import { isPixelAllowed } from '$lib/pixel'
|
|
3
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
4
|
+
|
|
5
|
+
vi.mock('$lib/consent', () => ({
|
|
6
|
+
hasConsentedTo: vi.fn(() => true),
|
|
7
|
+
}))
|
|
8
|
+
|
|
9
|
+
describe('pixel.ts', () => {
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
window.PlayPilotLinkInjections = {}
|
|
13
|
+
|
|
14
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
describe('isPixelAllow', () => {
|
|
18
|
+
it('Should return false if no config object is set', () => {
|
|
19
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
20
|
+
window.PlayPilotLinkInjections.config = null
|
|
21
|
+
|
|
22
|
+
expect(isPixelAllowed()).toBe(false)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('Should return false if config object is without allow_retargeting_pixels', () => {
|
|
26
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
27
|
+
window.PlayPilotLinkInjections.config = { something: true }
|
|
28
|
+
|
|
29
|
+
expect(isPixelAllowed()).toBe(false)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('Should return false if config object is allow_retargeting_pixels is false', () => {
|
|
33
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
34
|
+
window.PlayPilotLinkInjections.config = { allow_retargeting_pixels: false }
|
|
35
|
+
|
|
36
|
+
expect(isPixelAllowed()).toBe(false)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('Should return true if config object is allow_retargeting_pixels is true', () => {
|
|
40
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
41
|
+
window.PlayPilotLinkInjections.config = { allow_retargeting_pixels: true }
|
|
42
|
+
|
|
43
|
+
expect(isPixelAllowed()).toBe(true)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('Should return true if config object is allow_retargeting_pixels is true but hasConsentedTo is false', () => {
|
|
47
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => false)
|
|
48
|
+
window.PlayPilotLinkInjections.config = { allow_retargeting_pixels: true }
|
|
49
|
+
|
|
50
|
+
expect(isPixelAllowed()).toBe(false)
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import { fireQueuedTrackingEvents,
|
|
3
|
+
import { fireQueuedTrackingEvents, queueTrackingEvent, setTrackingSids, track } from '$lib/tracking'
|
|
4
4
|
import { title } from '$lib/fakeData'
|
|
5
5
|
import { getFullUrlPath } from '$lib/url'
|
|
6
6
|
import { fakeFetch } from '../helpers'
|
|
@@ -299,41 +299,4 @@ describe('$lib/tracking', () => {
|
|
|
299
299
|
expect(global.fetch).toHaveBeenCalledTimes(2)
|
|
300
300
|
})
|
|
301
301
|
})
|
|
302
|
-
|
|
303
|
-
describe('isPixelAllow', () => {
|
|
304
|
-
it('Should return false if no config object is set', () => {
|
|
305
|
-
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
306
|
-
window.PlayPilotLinkInjections.config = null
|
|
307
|
-
|
|
308
|
-
expect(isPixelAllowed()).toBe(false)
|
|
309
|
-
})
|
|
310
|
-
|
|
311
|
-
it('Should return false if config object is without allow_retargeting_pixels', () => {
|
|
312
|
-
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
313
|
-
window.PlayPilotLinkInjections.config = { something: true }
|
|
314
|
-
|
|
315
|
-
expect(isPixelAllowed()).toBe(false)
|
|
316
|
-
})
|
|
317
|
-
|
|
318
|
-
it('Should return false if config object is allow_retargeting_pixels is false', () => {
|
|
319
|
-
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
320
|
-
window.PlayPilotLinkInjections.config = { allow_retargeting_pixels: false }
|
|
321
|
-
|
|
322
|
-
expect(isPixelAllowed()).toBe(false)
|
|
323
|
-
})
|
|
324
|
-
|
|
325
|
-
it('Should return true if config object is allow_retargeting_pixels is true', () => {
|
|
326
|
-
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
327
|
-
window.PlayPilotLinkInjections.config = { allow_retargeting_pixels: true }
|
|
328
|
-
|
|
329
|
-
expect(isPixelAllowed()).toBe(true)
|
|
330
|
-
})
|
|
331
|
-
|
|
332
|
-
it('Should return true if config object is allow_retargeting_pixels is true but hasConsentedTo is false', () => {
|
|
333
|
-
vi.mocked(hasConsentedTo).mockImplementation(() => false)
|
|
334
|
-
window.PlayPilotLinkInjections.config = { allow_retargeting_pixels: true }
|
|
335
|
-
|
|
336
|
-
expect(isPixelAllowed()).toBe(false)
|
|
337
|
-
})
|
|
338
|
-
})
|
|
339
302
|
})
|