@streamscloud/embeddable 8.2.0 → 8.3.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/ads/ad-card/cmp.ad-card.svelte +8 -5
- package/dist/ads/ad-card/cmp.ad-card.svelte.d.ts +2 -0
- package/dist/content-player/cmp.content-player.svelte +1 -0
- package/dist/content-player/content-player-config.svelte.d.ts +8 -0
- package/dist/content-player/content-player-config.svelte.js +9 -1
- package/dist/content-player/controls-and-attachments.svelte +1 -0
- package/dist/core/enums.d.ts +5 -1
- package/dist/core/enums.js +4 -0
- package/dist/marketing-tracking/index.d.ts +2 -0
- package/dist/marketing-tracking/index.js +1 -0
- package/dist/marketing-tracking/service.d.ts +11 -0
- package/dist/marketing-tracking/service.js +35 -0
- package/dist/marketing-tracking/types.d.ts +5 -0
- package/dist/marketing-tracking/types.js +1 -0
- package/dist/media-center/media-center/discover-panel-handler.svelte.d.ts +2 -0
- package/dist/media-center/media-center/discover-panel-handler.svelte.js +6 -2
- package/dist/media-center/media-center/discover-panel.svelte +1 -1
- package/dist/posts/attachments/cmp.attachments.svelte +14 -2
- package/dist/posts/attachments/cmp.attachments.svelte.d.ts +2 -0
- package/dist/posts/model/post-model.d.ts +2 -0
- package/dist/posts/model/post-model.js +3 -0
- package/dist/posts/model/types.d.ts +2 -1
- package/dist/posts/model/types.js +1 -1
- package/dist/posts/post-viewer/attachments-horizontal.svelte +5 -4
- package/dist/posts/post-viewer/attachments-horizontal.svelte.d.ts +2 -0
- package/dist/posts/post-viewer/cmp.post-viewer.svelte +13 -2
- package/dist/posts/post-viewer/cmp.post-viewer.svelte.d.ts +2 -0
- package/dist/posts/post-viewer/mapper.js +18 -1
- package/dist/products/product-card/cmp.product-card.svelte +10 -7
- package/dist/products/product-card/cmp.product-card.svelte.d.ts +2 -0
- package/dist/products/product-card/mapper.d.ts +3 -1
- package/dist/products/product-card/mapper.js +2 -2
- package/dist/streams/layout/cmp.slot-content.svelte +14 -6
- package/dist/streams/layout/cmp.slot-content.svelte.d.ts +2 -0
- package/dist/streams/layout/element-views/cmp.container-stream-element.svelte +7 -2
- package/dist/streams/layout/element-views/cmp.container-stream-element.svelte.d.ts +2 -0
- package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte +8 -2
- package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte.d.ts +2 -0
- package/dist/streams/layout/element-views/cmp.stream-element.svelte +3 -2
- package/dist/streams/layout/element-views/cmp.stream-element.svelte.d.ts +2 -0
- package/dist/streams/layout/index.d.ts +1 -0
- package/dist/streams/layout/models/mapper.js +2 -1
- package/dist/streams/layout/serializer.svelte.js +0 -1
- package/dist/streams/layout/types.d.ts +4 -0
- package/dist/streams/layout/types.js +1 -0
- package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte +2 -2
- package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte.d.ts +2 -0
- package/dist/streams/stream-player/stream-player-view.svelte +15 -3
- package/package.json +1 -1
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
<script lang="ts">
|
|
1
|
+
<script lang="ts">var _a;
|
|
2
|
+
import { enrichAdLinkWithTracking } from '../../marketing-tracking';
|
|
3
|
+
import { toPriceRepresentation } from '../../products/price-helper';
|
|
2
4
|
import { Button, ButtonSize } from '../../ui/button';
|
|
3
5
|
import { Image } from '../../ui/image';
|
|
4
6
|
import { LineClamp } from '../../ui/line-clamp';
|
|
5
|
-
let { ad, inert = false, on } = $props();
|
|
7
|
+
let { ad, trackingParams, inert = false, on } = $props();
|
|
6
8
|
const trackImpression = (node) => {
|
|
7
9
|
if (on === null || on === void 0 ? void 0 : on.impression) {
|
|
8
10
|
const observer = new IntersectionObserver((entries) => {
|
|
@@ -22,12 +24,13 @@ const trackImpression = (node) => {
|
|
|
22
24
|
};
|
|
23
25
|
}
|
|
24
26
|
};
|
|
27
|
+
const enrichedLink = $derived(((_a = ad.ctaButton) === null || _a === void 0 ? void 0 : _a.url) ? enrichAdLinkWithTracking({ link: ad.ctaButton.url, adId: ad.id, trackingParams }) : null);
|
|
25
28
|
const handleAdClick = () => {
|
|
26
29
|
if (on === null || on === void 0 ? void 0 : on.click) {
|
|
27
30
|
on.click(ad.id);
|
|
28
31
|
}
|
|
29
|
-
if (
|
|
30
|
-
window.open(
|
|
32
|
+
if (enrichedLink) {
|
|
33
|
+
window.open(enrichedLink, '_blank', 'noopener noreferrer');
|
|
31
34
|
}
|
|
32
35
|
};
|
|
33
36
|
</script>
|
|
@@ -60,7 +63,7 @@ const handleAdClick = () => {
|
|
|
60
63
|
{/if}
|
|
61
64
|
</div>
|
|
62
65
|
<div class="ad-card__button-container">
|
|
63
|
-
{#if ad.ctaButton &&
|
|
66
|
+
{#if ad.ctaButton && enrichedLink && ad.ctaButton.text}
|
|
64
67
|
<div class="ad-card__button">
|
|
65
68
|
<Button
|
|
66
69
|
size={ButtonSize.Standard}
|
|
@@ -171,6 +171,7 @@ const variables = $derived.by(() => {
|
|
|
171
171
|
{#if postModel}
|
|
172
172
|
<PostViewer
|
|
173
173
|
model={postModel}
|
|
174
|
+
trackingParams={config.trackingParams}
|
|
174
175
|
socialInteractionsHandler={config.socialInteractionsHandler}
|
|
175
176
|
enableAttachments={config.uiManager.showPostOverlayAttachments}
|
|
176
177
|
enableControls={config.uiManager.showPostOverlayControls}
|
|
@@ -15,6 +15,7 @@ export declare class ContentPlayerConfig<T extends {
|
|
|
15
15
|
readonly socialInteractionsHandler: IPostSocialInteractionsHandler | undefined;
|
|
16
16
|
readonly uiManager: ContentPlayerUIManager;
|
|
17
17
|
private _mediaCenterData;
|
|
18
|
+
private _trackingParams;
|
|
18
19
|
private _mappers;
|
|
19
20
|
private mappedPostsCache;
|
|
20
21
|
constructor(init: {
|
|
@@ -25,16 +26,19 @@ export declare class ContentPlayerConfig<T extends {
|
|
|
25
26
|
settings?: ContentPlayerSettings;
|
|
26
27
|
callbacks?: ContentPlayerCallbacks;
|
|
27
28
|
playerSliderCallbacks?: PlayerSliderCallbacks<T>;
|
|
29
|
+
trackingParams?: ContentPlayerTrackingParams | null;
|
|
28
30
|
});
|
|
29
31
|
get mediaCenterControlsPanel(): MediaCenterData['controlsPanel'] | null;
|
|
30
32
|
get mediaCenterCallbacks(): MediaCenterData['callbacks'] | null;
|
|
31
33
|
get playerLogo(): string | null;
|
|
32
34
|
get fadeContent(): boolean;
|
|
35
|
+
get trackingParams(): ContentPlayerConfig<T>['_trackingParams'];
|
|
33
36
|
itemAsPostViewerModel: (item: T & {
|
|
34
37
|
mediaIndex?: number;
|
|
35
38
|
}) => PostModel | null;
|
|
36
39
|
setBackgroundImageUrl: (imageUrl: string | null) => void;
|
|
37
40
|
updateMediaCenterData: (data: MediaCenterData | undefined) => void;
|
|
41
|
+
updateTrackingParams: (data: ContentPlayerTrackingParams | null) => void;
|
|
38
42
|
}
|
|
39
43
|
export type ContentPlayerMappers<T> = {
|
|
40
44
|
postModelFromCurrentItem: (item: T) => IPostModel | null;
|
|
@@ -47,3 +51,7 @@ export type ContentPlayerCallbacks = {
|
|
|
47
51
|
adClick?: (adId: string, postId: string) => void;
|
|
48
52
|
adImpression?: (adId: string, postId: string) => void;
|
|
49
53
|
};
|
|
54
|
+
export type ContentPlayerTrackingParams = {
|
|
55
|
+
streamId?: string;
|
|
56
|
+
campaignId?: string;
|
|
57
|
+
} | false;
|
|
@@ -9,11 +9,13 @@ export class ContentPlayerConfig {
|
|
|
9
9
|
socialInteractionsHandler;
|
|
10
10
|
uiManager = new ContentPlayerUIManager();
|
|
11
11
|
_mediaCenterData = $state.raw(null);
|
|
12
|
+
_trackingParams = $state.raw(null);
|
|
12
13
|
_mappers;
|
|
13
14
|
mappedPostsCache = new Map();
|
|
14
15
|
constructor(init) {
|
|
15
|
-
const { playerBuffer, mappers, socialInteractionsHandler, mediaCenterData, settings, callbacks, playerSliderCallbacks } = init;
|
|
16
|
+
const { playerBuffer, trackingParams, mappers, socialInteractionsHandler, mediaCenterData, settings, callbacks, playerSliderCallbacks } = init;
|
|
16
17
|
this.playerBuffer = playerBuffer;
|
|
18
|
+
this._trackingParams = trackingParams ?? null;
|
|
17
19
|
this.settings = settings || new ContentPlayerSettings();
|
|
18
20
|
this._mediaCenterData = mediaCenterData || null;
|
|
19
21
|
this.callbacks = callbacks || null;
|
|
@@ -33,6 +35,9 @@ export class ContentPlayerConfig {
|
|
|
33
35
|
get fadeContent() {
|
|
34
36
|
return this._mediaCenterData?.overlayIsActive || false;
|
|
35
37
|
}
|
|
38
|
+
get trackingParams() {
|
|
39
|
+
return this._trackingParams;
|
|
40
|
+
}
|
|
36
41
|
itemAsPostViewerModel = (item) => {
|
|
37
42
|
if (this.mappedPostsCache.has(item.id)) {
|
|
38
43
|
return this.mappedPostsCache.get(item.id) || null;
|
|
@@ -52,4 +57,7 @@ export class ContentPlayerConfig {
|
|
|
52
57
|
updateMediaCenterData = (data) => {
|
|
53
58
|
this._mediaCenterData = data ?? null;
|
|
54
59
|
};
|
|
60
|
+
updateTrackingParams = (data) => {
|
|
61
|
+
this._trackingParams = data ?? null;
|
|
62
|
+
};
|
|
55
63
|
}
|
|
@@ -75,6 +75,7 @@ const variables = $derived.by(() => {
|
|
|
75
75
|
<div class="controls-and-attachments__post-attachments" transition:slideHorizontally|local>
|
|
76
76
|
<PostAttachments
|
|
77
77
|
model={currentItemPostContainer}
|
|
78
|
+
trackingParams={config.trackingParams}
|
|
78
79
|
locale={config.settings.locale}
|
|
79
80
|
on={{
|
|
80
81
|
productClick: (id) => config.callbacks?.productClick?.(id, currentItemPostContainer.id),
|
package/dist/core/enums.d.ts
CHANGED
|
@@ -33,7 +33,11 @@ export declare enum ProfileType {
|
|
|
33
33
|
Organization = "ORGANIZATION"
|
|
34
34
|
}
|
|
35
35
|
export declare enum PostType {
|
|
36
|
-
|
|
36
|
+
Article = "ARTICLE",
|
|
37
|
+
Media = "MEDIA",
|
|
38
|
+
Moment = "MOMENT",
|
|
39
|
+
ShortVideo = "SHORT_VIDEO",
|
|
40
|
+
Video = "VIDEO"
|
|
37
41
|
}
|
|
38
42
|
export declare enum Status {
|
|
39
43
|
Published = "PUBLISHED"
|
package/dist/core/enums.js
CHANGED
|
@@ -41,7 +41,11 @@ export var ProfileType;
|
|
|
41
41
|
})(ProfileType || (ProfileType = {}));
|
|
42
42
|
export var PostType;
|
|
43
43
|
(function (PostType) {
|
|
44
|
+
PostType["Article"] = "ARTICLE";
|
|
45
|
+
PostType["Media"] = "MEDIA";
|
|
46
|
+
PostType["Moment"] = "MOMENT";
|
|
44
47
|
PostType["ShortVideo"] = "SHORT_VIDEO";
|
|
48
|
+
PostType["Video"] = "VIDEO";
|
|
45
49
|
})(PostType || (PostType = {}));
|
|
46
50
|
export var Status;
|
|
47
51
|
(function (Status) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { enrichAdLinkWithTracking, enrichProductLinkWithTracking } from './service';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TrackingParams } from './types';
|
|
2
|
+
export declare const enrichProductLinkWithTracking: (data: {
|
|
3
|
+
link: string | URL;
|
|
4
|
+
productId: string;
|
|
5
|
+
trackingParams: TrackingParams | false | null | undefined;
|
|
6
|
+
}) => URL;
|
|
7
|
+
export declare const enrichAdLinkWithTracking: (data: {
|
|
8
|
+
link: string | URL;
|
|
9
|
+
adId: string;
|
|
10
|
+
trackingParams: TrackingParams | false | null | undefined;
|
|
11
|
+
}) => URL;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const enrichProductLinkWithTracking = (data) => {
|
|
2
|
+
const { link, productId, trackingParams } = data;
|
|
3
|
+
const url = link instanceof URL ? link : new URL(link);
|
|
4
|
+
if (trackingParams === false) {
|
|
5
|
+
return url;
|
|
6
|
+
}
|
|
7
|
+
url.searchParams.set('utm_source', 'streams');
|
|
8
|
+
url.searchParams.set('streams_product_id', productId);
|
|
9
|
+
return addTrackingParamsToUrl(url, trackingParams);
|
|
10
|
+
};
|
|
11
|
+
export const enrichAdLinkWithTracking = (data) => {
|
|
12
|
+
const { link, adId, trackingParams } = data;
|
|
13
|
+
const url = link instanceof URL ? link : new URL(link);
|
|
14
|
+
if (trackingParams === false) {
|
|
15
|
+
return url;
|
|
16
|
+
}
|
|
17
|
+
url.searchParams.set('utm_source', 'streams');
|
|
18
|
+
url.searchParams.set('streams_ad_id', adId);
|
|
19
|
+
return addTrackingParamsToUrl(url, trackingParams);
|
|
20
|
+
};
|
|
21
|
+
const addTrackingParamsToUrl = (url, trackingParams) => {
|
|
22
|
+
if (!trackingParams) {
|
|
23
|
+
return url;
|
|
24
|
+
}
|
|
25
|
+
if (trackingParams.campaignId) {
|
|
26
|
+
url.searchParams.set('utm_id', trackingParams.campaignId);
|
|
27
|
+
}
|
|
28
|
+
if (trackingParams.shortVideoId) {
|
|
29
|
+
url.searchParams.set('streams_short_video_id', trackingParams.shortVideoId);
|
|
30
|
+
}
|
|
31
|
+
if (trackingParams.streamId) {
|
|
32
|
+
url.searchParams.set('streams_stream_id', trackingParams.streamId);
|
|
33
|
+
}
|
|
34
|
+
return url;
|
|
35
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TrackingParams } from '../../marketing-tracking';
|
|
1
2
|
import type { ProductCardModel } from '../../products/product-card';
|
|
2
3
|
import type { IMediaCenterConfig, ShortVideoPlayerModel } from '../../short-videos/short-videos-player';
|
|
3
4
|
import type { MediaCenterStreamModel } from './types';
|
|
@@ -25,5 +26,6 @@ type ShortVideoSectionItemType = {
|
|
|
25
26
|
} | {
|
|
26
27
|
kind: 'product';
|
|
27
28
|
data: ProductCardModel;
|
|
29
|
+
trackingParams: TrackingParams;
|
|
28
30
|
};
|
|
29
31
|
export {};
|
|
@@ -24,7 +24,9 @@ export class DiscoverPanelHandler {
|
|
|
24
24
|
result.push({ kind: 'video', data: vids.shift() });
|
|
25
25
|
}
|
|
26
26
|
else if (want === 'product' && prods.length > 0) {
|
|
27
|
-
|
|
27
|
+
const productModel = prods.shift();
|
|
28
|
+
const shortVideoId = this._shortVideos.find((v) => v.products.some((p) => p.id === productModel.id))?.id;
|
|
29
|
+
result.push({ kind: 'product', data: productModel, trackingParams: { shortVideoId } });
|
|
28
30
|
}
|
|
29
31
|
else {
|
|
30
32
|
// temporary "empty" position - will fill later
|
|
@@ -38,7 +40,9 @@ export class DiscoverPanelHandler {
|
|
|
38
40
|
result[i] = { kind: 'video', data: vids.shift() };
|
|
39
41
|
}
|
|
40
42
|
else if (prods.length > 0) {
|
|
41
|
-
|
|
43
|
+
const productModel = prods.shift();
|
|
44
|
+
const shortVideoId = this._shortVideos.find((v) => v.products.some((p) => p.id === productModel.id))?.id;
|
|
45
|
+
result[i] = { kind: 'product', data: productModel, trackingParams: { shortVideoId } };
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
}
|
|
@@ -36,7 +36,7 @@ let { handler, localization, on } = $props();
|
|
|
36
36
|
</div>
|
|
37
37
|
{:else if item.kind === 'product'}
|
|
38
38
|
<div class="media-center-overview__card-wrapper" data-theme="dark">
|
|
39
|
-
<ProductCard product={item.data} locale={localization.locale} />
|
|
39
|
+
<ProductCard product={item.data} trackingParams={item.trackingParams} locale={localization.locale} />
|
|
40
40
|
</div>
|
|
41
41
|
{/if}
|
|
42
42
|
{/each}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
<script lang="ts">import {
|
|
1
|
+
<script lang="ts">import { PostType } from '../..';
|
|
2
|
+
import { AdCard } from '../../ads/ad-card';
|
|
2
3
|
import { PostModel } from '../model';
|
|
3
4
|
import { ProductCard } from '../../products/product-card';
|
|
4
|
-
let { model, locale = 'en', on } = $props();
|
|
5
|
+
let { model, trackingParams: externalTrackingParams, locale = 'en', on } = $props();
|
|
6
|
+
const trackingParams = $derived.by(() => {
|
|
7
|
+
if (externalTrackingParams || externalTrackingParams === false) {
|
|
8
|
+
return externalTrackingParams;
|
|
9
|
+
}
|
|
10
|
+
if (model.postType === PostType.ShortVideo) {
|
|
11
|
+
return { shortVideoId: model.id };
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
});
|
|
5
15
|
</script>
|
|
6
16
|
|
|
7
17
|
{#if model.attachments}
|
|
@@ -10,6 +20,7 @@ let { model, locale = 'en', on } = $props();
|
|
|
10
20
|
{#each model.attachments.ads as ad (ad.id)}
|
|
11
21
|
<AdCard
|
|
12
22
|
ad={ad}
|
|
23
|
+
trackingParams={trackingParams}
|
|
13
24
|
on={{
|
|
14
25
|
click: on?.adClick,
|
|
15
26
|
impression: on?.adImpression
|
|
@@ -21,6 +32,7 @@ let { model, locale = 'en', on } = $props();
|
|
|
21
32
|
{#each model.attachments.products as product (product.id)}
|
|
22
33
|
<ProductCard
|
|
23
34
|
product={product}
|
|
35
|
+
trackingParams={trackingParams}
|
|
24
36
|
locale={locale}
|
|
25
37
|
on={{
|
|
26
38
|
click: on?.productClick,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Locale } from '../../core/locale';
|
|
2
|
+
import type { TrackingParams } from '../../marketing-tracking';
|
|
2
3
|
import { PostModel } from '../model';
|
|
3
4
|
type Props = {
|
|
4
5
|
model: PostModel;
|
|
6
|
+
trackingParams: TrackingParams | null;
|
|
5
7
|
locale?: Locale;
|
|
6
8
|
on?: {
|
|
7
9
|
productClick?: (productId: string) => void;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { PostType } from '../../core/enums';
|
|
1
2
|
import { PostViewerMediaModel } from './post-media-model.svelte';
|
|
2
3
|
import type { IPostModel, IPostAdCardModel, IPostHeadingModel, IPostProductCardModel } from './types';
|
|
3
4
|
export declare class PostModel {
|
|
4
5
|
id: string;
|
|
5
6
|
media: PostViewerMediaModel;
|
|
7
|
+
postType: PostType | null;
|
|
6
8
|
texts: {
|
|
7
9
|
kicker: string | null;
|
|
8
10
|
title: string | null;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import { PostType } from '../../core/enums';
|
|
1
2
|
import { PostViewerMediaModel } from './post-media-model.svelte';
|
|
2
3
|
export class PostModel {
|
|
3
4
|
id;
|
|
4
5
|
media;
|
|
6
|
+
postType;
|
|
5
7
|
texts;
|
|
6
8
|
heading;
|
|
7
9
|
enableSocialInteractions;
|
|
8
10
|
attachments;
|
|
9
11
|
constructor(init) {
|
|
10
12
|
this.id = init.id;
|
|
13
|
+
this.postType = init.postType;
|
|
11
14
|
this.media = new PostViewerMediaModel({ media: init.media, mediaFit: init.mediaFit, mediaIndex: init.mediaIndex });
|
|
12
15
|
this.texts = {
|
|
13
16
|
kicker: init.kicker,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { AdType, type Currency } from '../../core/enums';
|
|
1
|
+
import { type AdType, type Currency, type PostType } from '../../core/enums';
|
|
2
2
|
export type IPostModel = {
|
|
3
3
|
id: string;
|
|
4
|
+
postType: PostType | null;
|
|
4
5
|
media: IPostMediaItemModel[];
|
|
5
6
|
mediaFit: PostModelMediaFit;
|
|
6
7
|
kicker: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {} from '../../core/enums';
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
<script lang="ts">import { horizontalWheelScroll, swallowTouch } from '../../core/actions';
|
|
2
2
|
import { Currency } from '../../core/enums';
|
|
3
|
+
import { enrichAdLinkWithTracking, enrichProductLinkWithTracking } from '../../marketing-tracking';
|
|
3
4
|
import { PostModel } from '../model';
|
|
4
5
|
import { toPriceRepresentation } from '../../products/price-helper';
|
|
5
6
|
import { Icon, IconColor } from '../../ui/icon';
|
|
6
7
|
import { ImageRounded } from '../../ui/image';
|
|
7
8
|
import { PostViewerUiManager } from './ui-manager.svelte';
|
|
8
9
|
import IconTargetArrow from '@fluentui/svg-icons/icons/target_arrow_20_regular.svg?raw';
|
|
9
|
-
let { model, uiManager, on } = $props();
|
|
10
|
+
let { model, trackingParams, uiManager, on } = $props();
|
|
10
11
|
const attachmentsToShow = $derived.by(() => {
|
|
11
12
|
if (!model.attachments) {
|
|
12
13
|
return [];
|
|
@@ -16,7 +17,7 @@ const attachmentsToShow = $derived.by(() => {
|
|
|
16
17
|
.map((p) => ({
|
|
17
18
|
isAd: false,
|
|
18
19
|
image: p.image,
|
|
19
|
-
link: p.link,
|
|
20
|
+
link: p.link ? enrichProductLinkWithTracking({ link: p.link, productId: p.id, trackingParams }) : null,
|
|
20
21
|
productId: p.id,
|
|
21
22
|
adId: null,
|
|
22
23
|
price: {
|
|
@@ -33,7 +34,7 @@ const attachmentsToShow = $derived.by(() => {
|
|
|
33
34
|
return ({
|
|
34
35
|
isAd: true,
|
|
35
36
|
image: a.image,
|
|
36
|
-
link: ((_a = a.ctaButton) === null || _a === void 0 ? void 0 : _a.url)
|
|
37
|
+
link: ((_a = a.ctaButton) === null || _a === void 0 ? void 0 : _a.url) ? enrichAdLinkWithTracking({ link: a.ctaButton.url, adId: a.id, trackingParams }) : null,
|
|
37
38
|
productId: null,
|
|
38
39
|
adId: a.id,
|
|
39
40
|
price: a.price && a.currency
|
|
@@ -58,7 +59,7 @@ const handleAttachmentClick = (attachment) => {
|
|
|
58
59
|
on.adClick(attachment.adId);
|
|
59
60
|
}
|
|
60
61
|
if (attachment.link) {
|
|
61
|
-
window.open(attachment.link, '_blank');
|
|
62
|
+
window.open(attachment.link, '_blank', 'noopener noreferrer');
|
|
62
63
|
}
|
|
63
64
|
};
|
|
64
65
|
let attachmentElements = $state({});
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { type TrackingParams } from '../../marketing-tracking';
|
|
1
2
|
import { PostModel } from '../model';
|
|
2
3
|
import { PostViewerUiManager } from './ui-manager.svelte';
|
|
3
4
|
type Props = {
|
|
4
5
|
model: PostModel;
|
|
6
|
+
trackingParams: TrackingParams;
|
|
5
7
|
uiManager: PostViewerUiManager;
|
|
6
8
|
on?: {
|
|
7
9
|
productClick?: (productId: string) => void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
<script lang="ts">import {
|
|
1
|
+
<script lang="ts">import { PostType } from '../..';
|
|
2
|
+
import { PostControls } from '../controls';
|
|
2
3
|
import { PostModel } from '../model';
|
|
3
4
|
import { default as AttachmentsHorizontal } from './attachments-horizontal.svelte';
|
|
4
5
|
import { default as Heading } from './heading.svelte';
|
|
@@ -6,13 +7,22 @@ import { default as PostMedia } from './media/post-media.svelte';
|
|
|
6
7
|
import { default as Texts } from './post-texts.svelte';
|
|
7
8
|
import { PostViewerLocalization } from './post-viewer-localization';
|
|
8
9
|
import { PostViewerUiManager } from './ui-manager.svelte';
|
|
9
|
-
let { model, socialInteractionsHandler, enableAttachments = true, enableControls = true, autoplay = 'on-appearance', locale = 'en', on } = $props();
|
|
10
|
+
let { model, socialInteractionsHandler, trackingParams: externalTrackingParams, enableAttachments = true, enableControls = true, autoplay = 'on-appearance', locale = 'en', on } = $props();
|
|
10
11
|
const localization = $derived(new PostViewerLocalization(locale));
|
|
11
12
|
const uiManager = new PostViewerUiManager();
|
|
12
13
|
$effect(() => {
|
|
13
14
|
uiManager.enableAttachments = enableAttachments;
|
|
14
15
|
uiManager.enableControls = enableControls;
|
|
15
16
|
});
|
|
17
|
+
const trackingParams = $derived.by(() => {
|
|
18
|
+
if (externalTrackingParams || externalTrackingParams === false) {
|
|
19
|
+
return externalTrackingParams;
|
|
20
|
+
}
|
|
21
|
+
if (model.postType === PostType.ShortVideo) {
|
|
22
|
+
return { shortVideoId: model.id };
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
});
|
|
16
26
|
const viewerMounted = (node) => {
|
|
17
27
|
const resizeObserver = new ResizeObserver(() => {
|
|
18
28
|
uiManager.isMobileView = node.clientWidth <= 576;
|
|
@@ -56,6 +66,7 @@ const variables = $derived.by(() => {
|
|
|
56
66
|
{#if uiManager.showAttachments && model.attachments}
|
|
57
67
|
<AttachmentsHorizontal
|
|
58
68
|
model={model}
|
|
69
|
+
trackingParams={trackingParams}
|
|
59
70
|
uiManager={uiManager}
|
|
60
71
|
on={{
|
|
61
72
|
productClick: on?.productClick,
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { Locale } from '../../core/locale';
|
|
2
|
+
import type { TrackingParams } from '../../marketing-tracking';
|
|
2
3
|
import { PostModel } from '../model';
|
|
3
4
|
import type { IPostSocialInteractionsHandler } from '../social-interactions';
|
|
4
5
|
type Props = {
|
|
5
6
|
model: PostModel;
|
|
6
7
|
socialInteractionsHandler?: IPostSocialInteractionsHandler;
|
|
8
|
+
trackingParams: TrackingParams | null | false;
|
|
7
9
|
enableAttachments?: boolean;
|
|
8
10
|
enableControls?: boolean;
|
|
9
11
|
autoplay?: true | false | 'on-appearance';
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { MediaType } from '../../core/enums';
|
|
1
|
+
import { MediaType, PostType } from '../../core/enums';
|
|
2
2
|
import { getMediaItemImageUrl } from '../../core/media';
|
|
3
3
|
import { shouldUseSalePrice } from '../../products/price-helper';
|
|
4
4
|
export const mapToPostModel = (payload) => {
|
|
5
5
|
return {
|
|
6
6
|
id: payload.id,
|
|
7
|
+
postType: mapToPostType(payload.postData),
|
|
7
8
|
media: mapToPostViewerMediaModel(payload.postData),
|
|
8
9
|
mediaFit: mediaFitFromPostType(payload.postData),
|
|
9
10
|
kicker: extractPostKicker(payload.postData),
|
|
@@ -22,6 +23,22 @@ export const mapToPostModel = (payload) => {
|
|
|
22
23
|
// )
|
|
23
24
|
};
|
|
24
25
|
};
|
|
26
|
+
const mapToPostType = (payload) => {
|
|
27
|
+
switch (true) {
|
|
28
|
+
case !!payload.shortVideoData:
|
|
29
|
+
return PostType.ShortVideo;
|
|
30
|
+
case !!payload.momentData:
|
|
31
|
+
return PostType.Moment;
|
|
32
|
+
case !!payload.articleData:
|
|
33
|
+
return PostType.Article;
|
|
34
|
+
case !!payload.videoData:
|
|
35
|
+
return PostType.Video;
|
|
36
|
+
case !!payload.mediaData:
|
|
37
|
+
return PostType.Media;
|
|
38
|
+
default:
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
25
42
|
const mediaFitFromPostType = (payload) => {
|
|
26
43
|
return payload.shortVideoData || payload.momentData ? 'cover' : 'contain';
|
|
27
44
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
<script lang="ts">import {
|
|
1
|
+
<script lang="ts">import { enrichProductLinkWithTracking } from '../../marketing-tracking';
|
|
2
|
+
import { toPriceRepresentation } from '../price-helper';
|
|
2
3
|
import { Image } from '../../ui/image';
|
|
3
4
|
import { LineClamp } from '../../ui/line-clamp';
|
|
4
5
|
import { ProportionalContainer } from '../../ui/proportional-container';
|
|
5
6
|
import { ProductCardLocalization } from './product-card-localization';
|
|
6
|
-
let { product, includeBeforeNowPrefix, inert = false, locale = 'en', on } = $props();
|
|
7
|
+
let { product, includeBeforeNowPrefix, trackingParams, inert = false, locale = 'en', on } = $props();
|
|
7
8
|
const localization = $derived(new ProductCardLocalization(locale));
|
|
8
9
|
const shortDescriptionPresented = $derived(product.shortDescription && product.shortDescription.length > 0);
|
|
9
10
|
const trackImpression = (node) => {
|
|
@@ -25,16 +26,16 @@ const trackImpression = (node) => {
|
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
};
|
|
29
|
+
const enrichedLink = $derived(product.link ? enrichProductLinkWithTracking({ link: product.link, productId: product.id, trackingParams }) : null);
|
|
28
30
|
const onProductClicked = (event) => {
|
|
29
31
|
event.preventDefault();
|
|
30
32
|
event.stopPropagation();
|
|
31
33
|
if (on === null || on === void 0 ? void 0 : on.click) {
|
|
32
34
|
on.click(product.id);
|
|
33
35
|
}
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
+
if (enrichedLink) {
|
|
37
|
+
window.open(enrichedLink, '_blank', 'noopener noreferrer');
|
|
36
38
|
}
|
|
37
|
-
window.open(product.link, '_blank', 'noopener noreferrer');
|
|
38
39
|
};
|
|
39
40
|
</script>
|
|
40
41
|
|
|
@@ -68,8 +69,10 @@ const onProductClicked = (event) => {
|
|
|
68
69
|
</div>
|
|
69
70
|
</div>
|
|
70
71
|
|
|
71
|
-
{#if
|
|
72
|
-
<a href={
|
|
72
|
+
{#if enrichedLink}
|
|
73
|
+
<a href={enrichedLink.href} onclick={onProductClicked} target="_blank" rel="noopener noreferrer" class="product-card__link" aria-label="none"> </a>
|
|
74
|
+
{:else if on?.click}
|
|
75
|
+
<button type="button" onclick={onProductClicked} class="product-card__link" aria-label="none"> </button>
|
|
73
76
|
{/if}
|
|
74
77
|
</div>
|
|
75
78
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { Locale } from '../../core/locale';
|
|
2
|
+
import { type TrackingParams } from '../../marketing-tracking';
|
|
2
3
|
import type { ProductCardModel } from './types';
|
|
3
4
|
type Props = {
|
|
4
5
|
product: ProductCardModel;
|
|
5
6
|
locale?: Locale;
|
|
6
7
|
includeBeforeNowPrefix?: boolean;
|
|
7
8
|
inert?: boolean;
|
|
9
|
+
trackingParams: TrackingParams;
|
|
8
10
|
on?: {
|
|
9
11
|
click?: (id: string) => void;
|
|
10
12
|
impression?: (id: string) => void;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { ProductCardPayloadFragment } from './operations.generated';
|
|
2
2
|
import type { ProductCardModel } from './types';
|
|
3
|
-
export declare const mapToProductCard: (payload: ProductCardPayloadFragment,
|
|
3
|
+
export declare const mapToProductCard: (payload: ProductCardPayloadFragment, options?: Partial<{
|
|
4
|
+
referenceDate: string | null;
|
|
5
|
+
}>) => ProductCardModel;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { getMediaItemImageUrl } from '../../core/media';
|
|
2
2
|
import { shouldUseSalePrice } from '../price-helper';
|
|
3
|
-
export const mapToProductCard = (payload,
|
|
3
|
+
export const mapToProductCard = (payload, options) => {
|
|
4
4
|
const effectiveSalePrice = payload.priceAndAvailability.productSalePrices?.find((x) => shouldUseSalePrice({
|
|
5
5
|
price: payload.priceAndAvailability.price,
|
|
6
6
|
salePrice: x.salePrice,
|
|
7
7
|
effectiveDateFrom: x.salePriceEffectiveDateFrom,
|
|
8
8
|
effectiveDateTo: x.salePriceEffectiveDateTo,
|
|
9
|
-
referenceDate
|
|
9
|
+
referenceDate: options?.referenceDate
|
|
10
10
|
}));
|
|
11
11
|
return {
|
|
12
12
|
id: payload.id,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script lang="ts">import { Utils } from '../../core/utils';
|
|
2
|
+
import { enrichProductLinkWithTracking } from '../../marketing-tracking';
|
|
2
3
|
import { StreamElementView } from './element-views';
|
|
3
4
|
import { StreamComponentDataType } from './enums';
|
|
4
|
-
let { model, locale, on } = $props();
|
|
5
|
+
let { model, locale, trackingParams, on } = $props();
|
|
5
6
|
const component = $derived.by(() => {
|
|
6
7
|
return model.components.find((c) => (model.data ? c.dataType === model.data.type : c.dataType === StreamComponentDataType.NoData));
|
|
7
8
|
});
|
|
@@ -27,6 +28,13 @@ const productModel = $derived.by(() => {
|
|
|
27
28
|
var _a;
|
|
28
29
|
return ((_a = model.data) === null || _a === void 0 ? void 0 : _a.type) === StreamComponentDataType.Product ? model.data.product : undefined;
|
|
29
30
|
});
|
|
31
|
+
const enrichedLink = $derived((productModel === null || productModel === void 0 ? void 0 : productModel.link)
|
|
32
|
+
? enrichProductLinkWithTracking({
|
|
33
|
+
link: productModel.link,
|
|
34
|
+
productId: productModel.id,
|
|
35
|
+
trackingParams
|
|
36
|
+
})
|
|
37
|
+
: null);
|
|
30
38
|
const handleProductClick = (e) => {
|
|
31
39
|
e.preventDefault();
|
|
32
40
|
if (!productModel) {
|
|
@@ -35,8 +43,8 @@ const handleProductClick = (e) => {
|
|
|
35
43
|
if (productModel.id && (on === null || on === void 0 ? void 0 : on.productClick)) {
|
|
36
44
|
on.productClick(productModel.id);
|
|
37
45
|
}
|
|
38
|
-
if (
|
|
39
|
-
window.open(
|
|
46
|
+
if (enrichedLink) {
|
|
47
|
+
window.open(enrichedLink, '_blank', 'noopener noreferrer');
|
|
40
48
|
}
|
|
41
49
|
};
|
|
42
50
|
const productLinkMounted = (node, productModel) => {
|
|
@@ -65,14 +73,14 @@ const productLinkMounted = (node, productModel) => {
|
|
|
65
73
|
{#snippet slotContent()}
|
|
66
74
|
{#if component && (!model.data || dataIsFilled)}
|
|
67
75
|
{#each component.elements as element (element)}
|
|
68
|
-
<StreamElementView model={element} data={model.data} locale={locale} on={on} />
|
|
76
|
+
<StreamElementView model={element} data={model.data} trackingParams={trackingParams} locale={locale} on={on} />
|
|
69
77
|
{/each}
|
|
70
78
|
{/if}
|
|
71
79
|
{/snippet}
|
|
72
|
-
{#if productModel
|
|
80
|
+
{#if productModel && enrichedLink}
|
|
73
81
|
<a
|
|
74
82
|
class="stream-slot-content-product-link"
|
|
75
|
-
href={
|
|
83
|
+
href={enrichedLink.href}
|
|
76
84
|
onclick={handleProductClick}
|
|
77
85
|
target="_blank"
|
|
78
86
|
rel="noopener noreferrer"
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { Locale } from '../../core/locale';
|
|
2
|
+
import type { StreamTrackingParams } from './types';
|
|
2
3
|
import type { StreamSlot } from './slot';
|
|
3
4
|
type Props = {
|
|
4
5
|
model: StreamSlot;
|
|
5
6
|
locale: Locale;
|
|
7
|
+
trackingParams: StreamTrackingParams;
|
|
6
8
|
on?: {
|
|
7
9
|
productClick: (productId: string) => void;
|
|
8
10
|
productImpression?: (productId: string) => void;
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
<script lang="ts">import { StreamElementStyleDirection } from '../enums';
|
|
2
2
|
import { generateContainerStyles } from '../styles-transformer';
|
|
3
3
|
import { default as StreamElement } from './cmp.stream-element.svelte';
|
|
4
|
-
let { model, data, locale } = $props();
|
|
4
|
+
let { model, data, trackingParams, locale } = $props();
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<div class="container-stream-element" style={generateContainerStyles(model.styles)}>
|
|
8
8
|
{#each model.elements as element (element)}
|
|
9
|
-
<StreamElement
|
|
9
|
+
<StreamElement
|
|
10
|
+
model={element}
|
|
11
|
+
data={data}
|
|
12
|
+
trackingParams={trackingParams}
|
|
13
|
+
constainerDirection={model.styles?.direction ?? StreamElementStyleDirection.Vertical}
|
|
14
|
+
locale={locale} />
|
|
10
15
|
{/each}
|
|
11
16
|
</div>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { Locale } from '../../../core/locale';
|
|
2
|
+
import type { StreamTrackingParams } from '..';
|
|
2
3
|
import type { ContainerStreamElementModel } from '../elements';
|
|
3
4
|
import type { StreamSlotData } from '../slot-data';
|
|
4
5
|
type Props = {
|
|
5
6
|
model: ContainerStreamElementModel;
|
|
6
7
|
data: StreamSlotData | null;
|
|
8
|
+
trackingParams: StreamTrackingParams;
|
|
7
9
|
locale: Locale;
|
|
8
10
|
};
|
|
9
11
|
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
import { PostViewer } from '../../../posts/post-viewer';
|
|
3
3
|
import { ShortVideoStreamElementLocalization } from './short-video-stream-element-localization';
|
|
4
4
|
import { mapToPostModel } from '../models';
|
|
5
|
-
let { data, locale, on } = $props();
|
|
5
|
+
let { data, trackingParams, locale, on } = $props();
|
|
6
6
|
const localization = $derived(new ShortVideoStreamElementLocalization(locale));
|
|
7
7
|
</script>
|
|
8
8
|
|
|
9
|
-
<PostViewer
|
|
9
|
+
<PostViewer
|
|
10
|
+
model={new PostModel(mapToPostModel(data))}
|
|
11
|
+
trackingParams={trackingParams ? { streamId: trackingParams.streamId, campaignId: trackingParams.campaignId } : false}
|
|
12
|
+
autoplay={false}
|
|
13
|
+
enableControls={false}
|
|
14
|
+
locale={localization.shortVideoViewerLocale}
|
|
15
|
+
on={on} />
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Locale } from '../../../core/locale';
|
|
2
|
+
import type { StreamTrackingParams } from '..';
|
|
2
3
|
import { type StreamLayoutShortVideoModel } from '../models';
|
|
3
4
|
type Props = {
|
|
4
5
|
data: StreamLayoutShortVideoModel;
|
|
6
|
+
trackingParams: StreamTrackingParams;
|
|
5
7
|
locale: Locale;
|
|
6
8
|
on?: {
|
|
7
9
|
progress?: (progress: number) => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">import { AnnotationStreamElementView, ContainerStreamElementView, ImageRefStreamElementView, ImagesStreamElementView, PriceStreamElementView, ShortVideoStreamElementView, SpacerStreamElementView, StockStreamElementView, TextRefStreamElementView, TextStreamElementView, WebViewStreamElementView } from '.';
|
|
2
2
|
import { StreamElementLocalization } from './stream-element-localization';
|
|
3
3
|
import { StreamComponentDataType, StreamElementStyleDirection, StreamElementType } from '../enums';
|
|
4
|
-
let { model, data, constainerDirection = StreamElementStyleDirection.Vertical, locale, on } = $props();
|
|
4
|
+
let { model, data, trackingParams, constainerDirection = StreamElementStyleDirection.Vertical, locale, on } = $props();
|
|
5
5
|
const localization = $derived(new StreamElementLocalization(locale));
|
|
6
6
|
const shortVideoModel = $derived.by(() => {
|
|
7
7
|
if (!data) {
|
|
@@ -44,7 +44,7 @@ const productModel = $derived.by(() => {
|
|
|
44
44
|
{#if model.type === StreamElementType.Annotation}
|
|
45
45
|
<AnnotationStreamElementView model={model} />
|
|
46
46
|
{:else if model.type === StreamElementType.Container}
|
|
47
|
-
<ContainerStreamElementView model={model} data={data} locale={locale} />
|
|
47
|
+
<ContainerStreamElementView model={model} data={data} trackingParams={trackingParams} locale={locale} />
|
|
48
48
|
{:else if model.type === StreamElementType.ImageRef && data}
|
|
49
49
|
<ImageRefStreamElementView model={model} data={data} />
|
|
50
50
|
{:else if model.type === StreamElementType.Images && imagesModel?.length}
|
|
@@ -54,6 +54,7 @@ const productModel = $derived.by(() => {
|
|
|
54
54
|
{:else if model.type === StreamElementType.ShortVideo && shortVideoModel}
|
|
55
55
|
<ShortVideoStreamElementView
|
|
56
56
|
data={shortVideoModel}
|
|
57
|
+
trackingParams={trackingParams}
|
|
57
58
|
locale={localization.shortVideoElementLocalization}
|
|
58
59
|
on={on
|
|
59
60
|
? {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { Locale } from '../../../core/locale';
|
|
2
|
+
import type { StreamTrackingParams } from '..';
|
|
2
3
|
import type { StreamElementModel } from '../elements';
|
|
3
4
|
import { StreamElementStyleDirection } from '../enums';
|
|
4
5
|
import type { StreamSlotData } from '../slot-data';
|
|
5
6
|
type Props = {
|
|
6
7
|
model: StreamElementModel;
|
|
7
8
|
data: StreamSlotData | null;
|
|
9
|
+
trackingParams: StreamTrackingParams;
|
|
8
10
|
constainerDirection?: StreamElementStyleDirection;
|
|
9
11
|
locale: Locale;
|
|
10
12
|
on?: {
|
|
@@ -7,6 +7,7 @@ export { default as StreamLayoutSlot } from './cmp.slot.svelte';
|
|
|
7
7
|
export { default as StreamLayoutSlotContent } from './cmp.slot-content.svelte';
|
|
8
8
|
export * from './layout';
|
|
9
9
|
export * from './svg-attributes';
|
|
10
|
+
export type { StreamTrackingParams } from './types';
|
|
10
11
|
export { parseToStreamLayout, parseToStreamLayoutTemplate, stringifyToStreamLayoutInput, IdPopulator } from './serializer.svelte';
|
|
11
12
|
export declare const getAllowedDataTypesForSlot: (slot: StreamSlot) => StreamComponentDataType[];
|
|
12
13
|
export declare const getSingleShortVideoFromLayout: (layout: StreamLayout) => StreamLayoutShortVideoModel | null;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { MediaType } from '../../../core/enums';
|
|
1
|
+
import { MediaType, PostType } from '../../../core/enums';
|
|
2
2
|
import {} from '../../../posts/model';
|
|
3
3
|
export const mapToPostModel = (model) => {
|
|
4
4
|
return {
|
|
5
5
|
id: model.id,
|
|
6
|
+
postType: PostType.ShortVideo,
|
|
6
7
|
media: [
|
|
7
8
|
model.media.type === MediaType.Image
|
|
8
9
|
? { isImage: true, url: model.media.url }
|
|
@@ -79,7 +79,6 @@ export class IdPopulator {
|
|
|
79
79
|
}
|
|
80
80
|
static populateElementId(element) {
|
|
81
81
|
element.$id = nanoid(10);
|
|
82
|
-
// Рекурсивно обрабатываем дочерние элементы
|
|
83
82
|
if (element.type === StreamElementType.Container && element.elements) {
|
|
84
83
|
element.elements.forEach((element) => IdPopulator.populateElementId(element));
|
|
85
84
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">import { StreamLayoutSlot, StreamPageLayout, StreamLayoutSlotContent } from '../layout';
|
|
2
2
|
import { StreamPageViewerLocalization } from './stream-page-viewer-localization';
|
|
3
|
-
let { page, locale, on } = $props();
|
|
3
|
+
let { page, trackingParams, locale, on } = $props();
|
|
4
4
|
const localization = $derived(new StreamPageViewerLocalization(locale));
|
|
5
5
|
</script>
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ const localization = $derived(new StreamPageViewerLocalization(locale));
|
|
|
8
8
|
<StreamPageLayout model={page.layout}>
|
|
9
9
|
{#each page.layout.slots as slot (slot)}
|
|
10
10
|
<StreamLayoutSlot model={slot}>
|
|
11
|
-
<StreamLayoutSlotContent model={slot} on={on} locale={localization.elementsLocale} />
|
|
11
|
+
<StreamLayoutSlotContent model={slot} trackingParams={trackingParams} on={on} locale={localization.elementsLocale} />
|
|
12
12
|
</StreamLayoutSlot>
|
|
13
13
|
{/each}
|
|
14
14
|
</StreamPageLayout>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Locale } from '../../core/locale';
|
|
2
|
+
import { type StreamTrackingParams } from '../layout';
|
|
2
3
|
import type { StreamPageViewerModel } from './types';
|
|
3
4
|
type Props = {
|
|
4
5
|
page: StreamPageViewerModel;
|
|
6
|
+
trackingParams: StreamTrackingParams;
|
|
5
7
|
locale: Locale;
|
|
6
8
|
on?: {
|
|
7
9
|
productClick: (productId: string) => void;
|
|
@@ -29,9 +29,6 @@ let isActive = true;
|
|
|
29
29
|
let activityTimeout = null;
|
|
30
30
|
let trackingInterval = null;
|
|
31
31
|
let maxPageIndexViewed = 0;
|
|
32
|
-
if (amplificationParameters) {
|
|
33
|
-
console.warn(`amplificationParameters: ${JSON.stringify(amplificationParameters)}`);
|
|
34
|
-
}
|
|
35
32
|
$effect(() => {
|
|
36
33
|
void streamId;
|
|
37
34
|
untrack(() => {
|
|
@@ -51,6 +48,20 @@ $effect(() => {
|
|
|
51
48
|
};
|
|
52
49
|
});
|
|
53
50
|
$effect(() => contentPlayerConfig.updateMediaCenterData(mediaCenterData));
|
|
51
|
+
$effect(() => contentPlayerConfig.updateTrackingParams(currentStreamModel
|
|
52
|
+
? {
|
|
53
|
+
streamId: currentStreamModel.id,
|
|
54
|
+
campaignId: amplificationParameters === null || amplificationParameters === void 0 ? void 0 : amplificationParameters.campaignId
|
|
55
|
+
}
|
|
56
|
+
: null));
|
|
57
|
+
const streamTrackingParams = $derived.by(() => {
|
|
58
|
+
return currentStreamModel
|
|
59
|
+
? {
|
|
60
|
+
streamId: currentStreamModel.id,
|
|
61
|
+
campaignId: amplificationParameters === null || amplificationParameters === void 0 ? void 0 : amplificationParameters.campaignId
|
|
62
|
+
}
|
|
63
|
+
: false;
|
|
64
|
+
});
|
|
54
65
|
const initNewStream = (streamId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
55
66
|
var _a, _b;
|
|
56
67
|
const stream = yield dataProvider.getStream(streamId);
|
|
@@ -201,6 +212,7 @@ const stopActivityTracking = () => {
|
|
|
201
212
|
{#if item.type === 'general'}
|
|
202
213
|
<StreamPageViewer
|
|
203
214
|
page={item}
|
|
215
|
+
trackingParams={streamTrackingParams}
|
|
204
216
|
locale={localization.locale}
|
|
205
217
|
on={{
|
|
206
218
|
progress: (videoId, progress) => onProgress(item.id, videoId, progress),
|