@playpilot/tpi 5.6.0-beta.video.7 → 5.7.0-beta.display-2

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 (38) hide show
  1. package/dist/link-injections.js +9 -9
  2. package/events.md +8 -2
  3. package/package.json +1 -1
  4. package/src/lib/ads.ts +38 -0
  5. package/src/lib/constants.ts +2 -1
  6. package/src/lib/enums/ImageDimensions.ts +7 -0
  7. package/src/lib/enums/SplitTest.ts +23 -0
  8. package/src/lib/enums/TrackingEvent.ts +3 -0
  9. package/src/lib/image.ts +12 -0
  10. package/src/lib/linkInjection.ts +36 -2
  11. package/src/lib/splitTest.ts +19 -14
  12. package/src/lib/types/campaign.d.ts +45 -0
  13. package/src/lib/types/playlink.d.ts +2 -0
  14. package/src/lib/types/script.d.ts +5 -0
  15. package/src/main.ts +6 -0
  16. package/src/routes/+layout.svelte +4 -0
  17. package/src/routes/+page.svelte +13 -2
  18. package/src/routes/components/Ads/Display.svelte +140 -0
  19. package/src/routes/components/Ads/TopScroll.svelte +240 -0
  20. package/src/routes/components/DragHandle.svelte +105 -0
  21. package/src/routes/components/Modal.svelte +125 -30
  22. package/src/routes/components/Playlink.svelte +185 -0
  23. package/src/routes/components/Playlinks.svelte +34 -168
  24. package/src/routes/components/Popover.svelte +30 -2
  25. package/src/routes/components/Title.svelte +13 -43
  26. package/src/routes/components/TitleModal.svelte +24 -10
  27. package/src/routes/components/TitlePopover.svelte +12 -6
  28. package/src/tests/lib/ads.test.js +55 -0
  29. package/src/tests/lib/splitTest.test.js +97 -18
  30. package/src/tests/routes/+page.test.js +33 -0
  31. package/src/tests/routes/components/Ads/Display.test.js +109 -0
  32. package/src/tests/routes/components/Ads/TopScroll.test.js +104 -0
  33. package/src/tests/routes/components/Playlink.test.js +95 -0
  34. package/src/tests/routes/components/Playlinks.test.js +0 -30
  35. package/src/tests/routes/components/TitleModal.test.js +36 -0
  36. package/src/tests/routes/components/TitlePopover.test.js +20 -0
  37. package/src/routes/components/Ads/FloatingPlaylink.svelte +0 -62
  38. package/src/routes/components/Ads/VideoBackground.svelte +0 -28
@@ -49,21 +49,6 @@ describe('Playlinks.svelte', () => {
49
49
  expect(queryByTestId('commission-disclaimer')).not.toBeTruthy()
50
50
  })
51
51
 
52
- it('Should render category as words', () => {
53
- const playlinks = [
54
- { name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
55
- { name: 'Some buy playlink', logo_url: 'logo', extra_info: { category: 'BUY' } },
56
- { name: 'Some rent playlink', logo_url: 'logo', extra_info: { category: 'RENT' } },
57
- { name: 'Some other playlink', logo_url: 'logo', extra_info: { category: 'other' } },
58
- ]
59
- // @ts-ignore
60
- const { getByText, getAllByText } = render(Playlinks, { playlinks, title })
61
-
62
- expect(getAllByText('Stream')).toHaveLength(2)
63
- expect(getByText('Buy')).toBeTruthy()
64
- expect(getByText('Rent')).toBeTruthy()
65
- })
66
-
67
52
  it('Should call track function when clicked', async () => {
68
53
  const playlinks = [
69
54
  { name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
@@ -103,19 +88,4 @@ describe('Playlinks.svelte', () => {
103
88
 
104
89
  expect(getAllByText('Some playlink')).toHaveLength(1)
105
90
  })
106
-
107
- it('Should highlight and show category text for playlinks that have highlighted as true', () => {
108
- const playlinks = [
109
- { name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
110
- { name: 'Some other playlink', logo_url: 'logo', highlighted: true, cta_text: '', extra_info: { category: 'BUY' } },
111
- { name: 'Some highlighted playlink', logo_url: 'logo', highlighted: true, cta_text: 'Some CTA', extra_info: { category: 'BUY' } },
112
- ]
113
- // @ts-ignore
114
- const { getByText } = render(Playlinks, { playlinks, title })
115
-
116
- expect(getByText('Some playlink').closest('.playlink')?.classList).not.toContain('highlighted')
117
- expect(getByText('Some other playlink').closest('.playlink')?.classList).not.toContain('highlighted')
118
- expect(getByText('Some highlighted playlink').closest('.playlink')?.classList).toContain('highlighted')
119
- expect(getByText('Some CTA')).toBeTruthy()
120
- })
121
91
  })
@@ -45,4 +45,40 @@ describe('TitleModal.svelte', () => {
45
45
 
46
46
  expect(track).toHaveBeenCalledWith(TrackingEvent.TitleModalClose, title, { time_spent: 200 })
47
47
  })
48
+
49
+ it('Should render top scroll ad when given', () => {
50
+ // @ts-ignore
51
+ window.PlayPilotLinkInjections = { ads: [{ campaign_format: 'top_scroll', content: {}, cta: {} }] }
52
+
53
+ const { container } = render(TitleModal, { onclose, title })
54
+
55
+ expect(container.querySelector('.top-scroll')).toBeTruthy()
56
+ })
57
+
58
+ it('Should not render top scroll ad when not given', () => {
59
+ // @ts-ignore
60
+ window.PlayPilotLinkInjections = { ads: null }
61
+
62
+ const { container } = render(TitleModal, { onclose, title })
63
+
64
+ expect(container.querySelector('.top-scroll')).not.toBeTruthy()
65
+ })
66
+
67
+ it('Should render display ad when given', () => {
68
+ // @ts-ignore
69
+ window.PlayPilotLinkInjections = { ads: [{ campaign_format: 'card', content: {}, cta: {} }] }
70
+
71
+ const { container } = render(TitleModal, { onclose, title })
72
+
73
+ expect(container.querySelector('.display')).toBeTruthy()
74
+ })
75
+
76
+ it('Should not render top scroll ad when not given', () => {
77
+ // @ts-ignore
78
+ window.PlayPilotLinkInjections = { ads: null }
79
+
80
+ const { container } = render(TitleModal, { onclose, title })
81
+
82
+ expect(container.querySelector('.display')).not.toBeTruthy()
83
+ })
48
84
  })
@@ -37,4 +37,24 @@ describe('TitlePopover.svelte', () => {
37
37
 
38
38
  expect(track).toHaveBeenCalledWith(TrackingEvent.TitlePopoverClose, title, { time_spent: 200 })
39
39
  })
40
+
41
+ it('Should render top scroll ad when given', () => {
42
+ // @ts-ignore
43
+ window.PlayPilotLinkInjections = { ads: [{ campaign_format: 'top_scroll', content: {}, cta: {} }] }
44
+
45
+ const event = new MouseEvent('mouseenter')
46
+ const { container } = render(TitlePopover, { event, title })
47
+
48
+ expect(container.querySelector('.top-scroll')).toBeTruthy()
49
+ })
50
+
51
+ it('Should not render top scroll ad when not given', () => {
52
+ // @ts-ignore
53
+ window.PlayPilotLinkInjections = { ads: null }
54
+
55
+ const event = new MouseEvent('mouseenter')
56
+ const { container } = render(TitlePopover, { event, title })
57
+
58
+ expect(container.querySelector('.top-scroll')).not.toBeTruthy()
59
+ })
40
60
  })
@@ -1,62 +0,0 @@
1
- <script lang="ts">
2
- import { removeImageUrlPrefix } from '$lib/image'
3
- import type { PlaylinkData } from '$lib/types/playlink'
4
- import { prefersReducedMotion } from 'svelte/motion'
5
- import { fly } from 'svelte/transition'
6
-
7
- interface Props {
8
- playlink: PlaylinkData
9
- }
10
-
11
- const { playlink }: Props = $props()
12
-
13
- const { name, url, logo_url, cta_text } = $derived(playlink)
14
- </script>
15
-
16
- <a href={url} target="_blank" class="floating-playlink" rel="sponsored" transition:fly|global={{ x: -100, duration: prefersReducedMotion.current ? 0 : 500, delay: 2000 }}>
17
- <img src={removeImageUrlPrefix(logo_url)} alt="" height="24" width="24" />
18
-
19
- <div>
20
- <span class="name">{name}</span>
21
- <div class="cta">{cta_text || 'Free trial for 30 days!'}</div>
22
- </div>
23
- </a>
24
-
25
- <style lang="scss">
26
- .floating-playlink {
27
- z-index: 1;
28
- position: absolute;
29
- top: margin(1);
30
- left: margin(1);
31
- display: flex;
32
- align-items: center;
33
- gap: margin(0.75);
34
- padding: margin(0.5) margin(0.75);
35
- outline: 2px solid rgba(255, 255, 255, 0.5);
36
- border-radius: margin(0.5);
37
- background: linear-gradient(to right, var(--playpilot-content), transparent);
38
- font-family: inherit;
39
- color: var(--playpilot-text-color) !important;
40
- text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.35);
41
- font-size: margin(0.875);
42
- font-style: normal !important;
43
- line-height: 1.2;
44
- text-decoration: none;
45
-
46
- &:hover {
47
- outline: 2px solid rgba(255, 255, 255, 0.75);
48
- }
49
-
50
- img {
51
- border-radius: margin(0.25);
52
- }
53
- }
54
-
55
- .name {
56
- font-weight: 500;
57
- }
58
-
59
- .cta {
60
- font-size: margin(0.75);
61
- }
62
- </style>
@@ -1,28 +0,0 @@
1
- <script lang="ts">
2
- const sources = [
3
- 'https://pub-6f03bccd9247476c9b84407f45af8155.r2.dev/apple-tv-plus-the-morning-show-cropped.mp4',
4
- ]
5
-
6
- const src = sources[Math.floor(Math.random() * sources.length)]
7
- </script>
8
-
9
- <div class="video-background">
10
- <video class="video" autoplay muted playsinline loop>
11
- <source {src} type="video/mp4">
12
- <track kind="captions" />
13
- </video>
14
- </div>
15
-
16
- <style lang="scss">
17
- .video-background {
18
- height: 100%;
19
- }
20
-
21
- .video {
22
- position: absolute;
23
- object-fit: cover;
24
- object-position: center;
25
- height: 100%;
26
- width: 100%;
27
- }
28
- </style>