@playpilot/tpi 6.6.1 → 6.6.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/dist/link-injections.js +8 -8
- package/package.json +2 -1
- package/src/lib/tracking.ts +5 -0
- package/src/lib/types/config.d.ts +5 -0
- package/src/routes/components/Genres.svelte +2 -2
- package/src/routes/components/Playlinks/Playlink.svelte +7 -4
- package/src/tests/lib/tracking.test.js +38 -1
- package/src/tests/routes/components/Playlinks/Playlink.test.js +1 -0
- package/src/tests/routes/components/Playlinks/Playlinks.test.js +1 -0
- package/src/tests/routes/components/Title.test.js +1 -0
- package/src/tests/routes/components/TitleModal.test.js +1 -0
- package/src/tests/routes/components/TitlePopover.test.js +1 -0
- package/vite.config.js +21 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playpilot/tpi",
|
|
3
|
-
"version": "6.6.
|
|
3
|
+
"version": "6.6.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"@types/node": "^25.2.0",
|
|
24
24
|
"@typescript-eslint/eslint-plugin": "^8.32.1",
|
|
25
25
|
"@typescript-eslint/parser": "^8.32.1",
|
|
26
|
+
"dotenv": "^16.4.7",
|
|
26
27
|
"eslint": "^9.27.0",
|
|
27
28
|
"eslint-config-prettier": "^9.1.0",
|
|
28
29
|
"eslint-plugin-svelte": "^3.15.0",
|
package/src/lib/tracking.ts
CHANGED
|
@@ -98,3 +98,8 @@ export function fireQueuedTrackingEvents(): void {
|
|
|
98
98
|
|
|
99
99
|
window.PlayPilotLinkInjections.queued_tracking_events = []
|
|
100
100
|
}
|
|
101
|
+
|
|
102
|
+
export function isPixelAllowed(): boolean {
|
|
103
|
+
if (!window.PlayPilotLinkInjections.config?.allow_retargeting_pixels) return false
|
|
104
|
+
return hasConsentedTo('pixels')
|
|
105
|
+
}
|
|
@@ -44,6 +44,11 @@ export type ConfigResponse = {
|
|
|
44
44
|
*/
|
|
45
45
|
playlinks_disclaimer_text?: string
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Whether or not we can insert retargeting pixels. Not all third parties allow this and it is disabled by default
|
|
49
|
+
*/
|
|
50
|
+
allow_retargeting_pixels?: boolean
|
|
51
|
+
|
|
47
52
|
/**
|
|
48
53
|
* The following options are all relevant for in text disclaimers, which renders as a disclaimer text within the article,
|
|
49
54
|
* rather than only inside of title cards.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { hasConsentedTo } from '$lib/consent'
|
|
3
2
|
import genreData from '$lib/data/genres.json'
|
|
4
3
|
import { MetaEvent } from '$lib/enums/TrackingEvent'
|
|
5
4
|
import { t } from '$lib/localization'
|
|
5
|
+
import { isPixelAllowed } from '$lib/tracking'
|
|
6
6
|
import { trackViewViaPixel } from '@playpilot/retargeting-tracking'
|
|
7
7
|
|
|
8
8
|
interface Props {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
{@const genreName = genreData.find(g => g.slug === genre)?.name}
|
|
20
20
|
|
|
21
21
|
{#if genreName}
|
|
22
|
-
<div class="genre" {@attach
|
|
22
|
+
<div class="genre" {@attach isPixelAllowed() ? trackViewViaPixel(MetaEvent.GenreInterest, { genre: genreName }) : null}>
|
|
23
23
|
{t(genreName)}
|
|
24
24
|
</div>
|
|
25
25
|
{/if}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { PlaylinkData } from '$lib/types/playlink'
|
|
8
8
|
import { trackClickViaPixel, trackViewViaPixel } from '@playpilot/retargeting-tracking'
|
|
9
9
|
import { MetaEvent } from '$lib/enums/TrackingEvent'
|
|
10
|
+
import { isPixelAllowed } from '$lib/tracking'
|
|
10
11
|
|
|
11
12
|
interface Props {
|
|
12
13
|
playlink: PlaylinkData
|
|
@@ -19,7 +20,7 @@
|
|
|
19
20
|
|
|
20
21
|
const { name, url, logo_url, highlighted, cta_text, action_text, pixels, extra_info: { category } } = $derived(playlink)
|
|
21
22
|
|
|
22
|
-
const usePixel = $derived(
|
|
23
|
+
const usePixel = $derived(isPixelAllowed() && !highlighted)
|
|
23
24
|
|
|
24
25
|
const categoryStrings = {
|
|
25
26
|
SVOD: t('Stream'),
|
|
@@ -27,6 +28,8 @@
|
|
|
27
28
|
RENT: t('Rent'),
|
|
28
29
|
TVOD: t('Rent Or Buy'),
|
|
29
30
|
}
|
|
31
|
+
|
|
32
|
+
let actionWidth = $state(0)
|
|
30
33
|
</script>
|
|
31
34
|
|
|
32
35
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
@@ -44,7 +47,7 @@
|
|
|
44
47
|
data-playlink={name}
|
|
45
48
|
rel="sponsored">
|
|
46
49
|
|
|
47
|
-
<div class="playlink-content">
|
|
50
|
+
<div class="playlink-content" style:--action-width={actionWidth ? `${actionWidth}px` : null}>
|
|
48
51
|
<img src={removeImageUrlPrefix(logo_url)} alt="" height="36" width="36" />
|
|
49
52
|
|
|
50
53
|
<span class="name">{name}</span>
|
|
@@ -57,7 +60,7 @@
|
|
|
57
60
|
<span class="cta">{cta_text}</span>
|
|
58
61
|
{/if}
|
|
59
62
|
|
|
60
|
-
<div class="action">
|
|
63
|
+
<div class="action" bind:clientWidth={actionWidth}>
|
|
61
64
|
{action_text || t('Watch')}
|
|
62
65
|
</div>
|
|
63
66
|
|
|
@@ -161,7 +164,7 @@
|
|
|
161
164
|
z-index: 5;
|
|
162
165
|
display: grid;
|
|
163
166
|
grid-template-areas: "image name action" "image category action";
|
|
164
|
-
grid-template-columns: $image-size auto margin(6);
|
|
167
|
+
grid-template-columns: $image-size auto var(--action-width, margin(6));
|
|
165
168
|
align-items: center;
|
|
166
169
|
gap: 0 margin(0.75);
|
|
167
170
|
padding: margin(0.75);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import { fireQueuedTrackingEvents, queueTrackingEvent, setTrackingSids, track } from '$lib/tracking'
|
|
3
|
+
import { fireQueuedTrackingEvents, isPixelAllowed, 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'
|
|
@@ -241,4 +241,41 @@ describe('$lib/tracking', () => {
|
|
|
241
241
|
expect(global.fetch).toHaveBeenCalledTimes(2)
|
|
242
242
|
})
|
|
243
243
|
})
|
|
244
|
+
|
|
245
|
+
describe('isPixelAllow', () => {
|
|
246
|
+
it('Should return false if no config object is set', () => {
|
|
247
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
248
|
+
window.PlayPilotLinkInjections.config = null
|
|
249
|
+
|
|
250
|
+
expect(isPixelAllowed()).toBe(false)
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
it('Should return false if config object is without allow_retargeting_pixels', () => {
|
|
254
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
255
|
+
window.PlayPilotLinkInjections.config = { something: true }
|
|
256
|
+
|
|
257
|
+
expect(isPixelAllowed()).toBe(false)
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
it('Should return false if config object is allow_retargeting_pixels is false', () => {
|
|
261
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
262
|
+
window.PlayPilotLinkInjections.config = { allow_retargeting_pixels: false }
|
|
263
|
+
|
|
264
|
+
expect(isPixelAllowed()).toBe(false)
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
it('Should return true if config object is allow_retargeting_pixels is true', () => {
|
|
268
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
269
|
+
window.PlayPilotLinkInjections.config = { allow_retargeting_pixels: true }
|
|
270
|
+
|
|
271
|
+
expect(isPixelAllowed()).toBe(true)
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
it('Should return true if config object is allow_retargeting_pixels is true but hasConsentedTo is false', () => {
|
|
275
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => false)
|
|
276
|
+
window.PlayPilotLinkInjections.config = { allow_retargeting_pixels: true }
|
|
277
|
+
|
|
278
|
+
expect(isPixelAllowed()).toBe(false)
|
|
279
|
+
})
|
|
280
|
+
})
|
|
244
281
|
})
|
package/vite.config.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
|
+
import * as dotenv from 'dotenv'
|
|
2
3
|
import { defineConfig } from 'vitest/config'
|
|
3
4
|
import { sveltekit } from '@sveltejs/kit/vite'
|
|
4
5
|
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
|
5
6
|
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
|
|
6
7
|
import packageJson from './package.json'
|
|
7
8
|
|
|
9
|
+
dotenv.config({ path: '.env' })
|
|
10
|
+
|
|
8
11
|
export default defineConfig(({ command }) => ({
|
|
9
12
|
plugins: [
|
|
10
13
|
command === 'build' ? svelte() : sveltekit(),
|
|
11
14
|
command === 'build' && cssInjectedByJsPlugin(),
|
|
15
|
+
command === 'build' && injectEnvVariables,
|
|
12
16
|
],
|
|
13
17
|
|
|
14
18
|
build: {
|
|
@@ -19,7 +23,6 @@ export default defineConfig(({ command }) => ({
|
|
|
19
23
|
name: 'PlayPilotLinkInjections',
|
|
20
24
|
entryFileNames: 'link-injections.js',
|
|
21
25
|
},
|
|
22
|
-
external: ['$env/static/public'],
|
|
23
26
|
},
|
|
24
27
|
},
|
|
25
28
|
|
|
@@ -44,3 +47,20 @@ export default defineConfig(({ command }) => ({
|
|
|
44
47
|
__SCRIPT_VERSION__: JSON.stringify(packageJson.version),
|
|
45
48
|
},
|
|
46
49
|
}))
|
|
50
|
+
|
|
51
|
+
const injectEnvVariables = {
|
|
52
|
+
name: 'resolve-env-variables',
|
|
53
|
+
/** @param {string} id */
|
|
54
|
+
resolveId(id) {
|
|
55
|
+
if (id === '$env/static/public') return '\0$env/static/public'
|
|
56
|
+
},
|
|
57
|
+
/** @param {string} id */
|
|
58
|
+
load(id) {
|
|
59
|
+
if (id === '\0$env/static/public') {
|
|
60
|
+
return Object.entries(process.env)
|
|
61
|
+
.filter(([key]) => key.startsWith('PUBLIC_'))
|
|
62
|
+
.map(([key, value]) => `export const ${key} = ${JSON.stringify(value)};`)
|
|
63
|
+
.join('\n')
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
}
|