@streamscloud/embeddable 8.2.0 → 9.0.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.
Files changed (97) hide show
  1. package/dist/ads/ad-card/cmp.ad-card.svelte +8 -5
  2. package/dist/ads/ad-card/cmp.ad-card.svelte.d.ts +2 -0
  3. package/dist/content-player/cmp.content-player.svelte +1 -0
  4. package/dist/content-player/content-player-config.svelte.d.ts +8 -0
  5. package/dist/content-player/content-player-config.svelte.js +9 -1
  6. package/dist/content-player/controls-and-attachments.svelte +1 -0
  7. package/dist/core/enums.d.ts +5 -1
  8. package/dist/core/enums.js +4 -0
  9. package/dist/marketing-tracking/index.d.ts +2 -0
  10. package/dist/marketing-tracking/index.js +1 -0
  11. package/dist/marketing-tracking/service.d.ts +11 -0
  12. package/dist/marketing-tracking/service.js +35 -0
  13. package/dist/marketing-tracking/types.d.ts +5 -0
  14. package/dist/media-center/config/internal-media-center-analytics-handler.d.ts +3 -2
  15. package/dist/media-center/config/internal-media-center-analytics-handler.js +1 -0
  16. package/dist/media-center/config/internal-media-center-config.d.ts +1 -1
  17. package/dist/media-center/config/internal-media-center-config.js +11 -11
  18. package/dist/media-center/config/operations.generated.d.ts +4 -4
  19. package/dist/media-center/config/operations.generated.js +5 -8
  20. package/dist/media-center/config/operations.graphql +3 -3
  21. package/dist/media-center/config/types.d.ts +7 -5
  22. package/dist/media-center/config/types.js +1 -1
  23. package/dist/media-center/media-center/cmp.media-center.svelte +74 -17
  24. package/dist/media-center/media-center/cmp.media-center.svelte.d.ts +3 -3
  25. package/dist/media-center/media-center/discover-panel-handler.svelte.d.ts +5 -2
  26. package/dist/media-center/media-center/discover-panel-handler.svelte.js +8 -3
  27. package/dist/media-center/media-center/discover-panel.svelte +1 -1
  28. package/dist/media-center/media-center/discover-panel.svelte.d.ts +2 -2
  29. package/dist/media-center/media-center/post-player-provider-generator.d.ts +8 -0
  30. package/dist/media-center/media-center/{short-video-resources-generator.js → post-player-provider-generator.js} +8 -3
  31. package/dist/media-center/media-center/types.d.ts +1 -1
  32. package/dist/posts/attachments/cmp.attachments.svelte +14 -2
  33. package/dist/posts/attachments/cmp.attachments.svelte.d.ts +2 -0
  34. package/dist/posts/handlers/index.d.ts +1 -0
  35. package/dist/posts/handlers/index.js +1 -0
  36. package/dist/{short-videos/short-videos-player/internal-short-video-analytics-handler.d.ts → posts/handlers/internal-post-analytics-handler.d.ts} +3 -2
  37. package/dist/{short-videos/short-videos-player/internal-short-video-analytics-handler.js → posts/handlers/internal-post-analytics-handler.js} +2 -1
  38. package/dist/posts/model/post-model.d.ts +2 -0
  39. package/dist/posts/model/post-model.js +3 -0
  40. package/dist/posts/model/types.d.ts +2 -1
  41. package/dist/posts/model/types.js +1 -1
  42. package/dist/posts/post-viewer/attachments-horizontal.svelte +5 -4
  43. package/dist/posts/post-viewer/attachments-horizontal.svelte.d.ts +2 -0
  44. package/dist/posts/post-viewer/cmp.post-viewer.svelte +13 -2
  45. package/dist/posts/post-viewer/cmp.post-viewer.svelte.d.ts +2 -0
  46. package/dist/posts/post-viewer/mapper.js +18 -1
  47. package/dist/{short-videos/short-videos-player/cmp.short-videos-player.svelte → posts/posts-player/cmp.posts-player.svelte} +3 -3
  48. package/dist/posts/posts-player/cmp.posts-player.svelte.d.ts +4 -0
  49. package/dist/posts/posts-player/index.d.ts +31 -17
  50. package/dist/posts/posts-player/index.js +48 -31
  51. package/dist/posts/posts-player/mapper.d.ts +3 -0
  52. package/dist/{short-videos/short-videos-player → posts/posts-player}/mapper.js +2 -2
  53. package/dist/posts/posts-player/operations.generated.d.ts +80 -0
  54. package/dist/posts/posts-player/operations.generated.js +229 -0
  55. package/dist/posts/posts-player/operations.graphql +7 -0
  56. package/dist/posts/posts-player/posts-player-view.svelte +38 -4
  57. package/dist/posts/posts-player/posts-player-view.svelte.d.ts +5 -1
  58. package/dist/posts/posts-player/types.d.ts +7 -1
  59. package/dist/products/product-card/cmp.product-card.svelte +10 -7
  60. package/dist/products/product-card/cmp.product-card.svelte.d.ts +2 -0
  61. package/dist/products/product-card/mapper.d.ts +3 -1
  62. package/dist/products/product-card/mapper.js +2 -2
  63. package/dist/short-videos/data-providers/index.d.ts +1 -0
  64. package/dist/short-videos/data-providers/index.js +1 -0
  65. package/dist/short-videos/{short-videos-player/internal-short-video-player-provider.d.ts → data-providers/internal-short-video-player-items-provider.d.ts} +4 -4
  66. package/dist/short-videos/{short-videos-player/internal-short-video-player-provider.js → data-providers/internal-short-video-player-items-provider.js} +3 -3
  67. package/dist/short-videos/{short-videos-player → data-providers}/operations.generated.d.ts +0 -78
  68. package/dist/short-videos/{short-videos-player → data-providers}/operations.generated.js +2 -234
  69. package/dist/short-videos/{short-videos-player → data-providers}/operations.graphql +1 -9
  70. package/dist/short-videos/short-videos-player/index.d.ts +13 -62
  71. package/dist/short-videos/short-videos-player/index.js +76 -30
  72. package/dist/streams/layout/cmp.slot-content.svelte +14 -6
  73. package/dist/streams/layout/cmp.slot-content.svelte.d.ts +2 -0
  74. package/dist/streams/layout/element-views/cmp.container-stream-element.svelte +7 -2
  75. package/dist/streams/layout/element-views/cmp.container-stream-element.svelte.d.ts +2 -0
  76. package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte +8 -2
  77. package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte.d.ts +2 -0
  78. package/dist/streams/layout/element-views/cmp.stream-element.svelte +3 -2
  79. package/dist/streams/layout/element-views/cmp.stream-element.svelte.d.ts +2 -0
  80. package/dist/streams/layout/index.d.ts +1 -0
  81. package/dist/streams/layout/models/mapper.js +2 -1
  82. package/dist/streams/layout/serializer.svelte.js +0 -1
  83. package/dist/streams/layout/types.d.ts +4 -0
  84. package/dist/streams/layout/types.js +1 -0
  85. package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte +2 -2
  86. package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte.d.ts +2 -0
  87. package/dist/streams/stream-player/stream-player-view.svelte +15 -3
  88. package/dist/ui/player-slider/player-buffer.svelte.d.ts +1 -0
  89. package/dist/ui/swipe-indicator/cmp.swipe-indicator.svelte +7 -8
  90. package/package.json +1 -1
  91. package/dist/media-center/media-center/short-video-resources-generator.d.ts +0 -8
  92. package/dist/short-videos/short-videos-player/cmp.short-videos-player.svelte.d.ts +0 -4
  93. package/dist/short-videos/short-videos-player/mapper.d.ts +0 -3
  94. package/dist/short-videos/short-videos-player/short-videos-player-view.svelte +0 -82
  95. package/dist/short-videos/short-videos-player/short-videos-player-view.svelte.d.ts +0 -8
  96. package/dist/short-videos/short-videos-player/types.d.ts +0 -26
  97. /package/dist/{short-videos/short-videos-player → marketing-tracking}/types.js +0 -0
@@ -1,5 +1,7 @@
1
+ import type { TrackingParams } from '../../marketing-tracking';
2
+ import type { IMediaCenterConfig } from '..';
3
+ import type { PostPlayerModel } from '../../posts/posts-player';
1
4
  import type { ProductCardModel } from '../../products/product-card';
2
- import type { IMediaCenterConfig, ShortVideoPlayerModel } from '../../short-videos/short-videos-player';
3
5
  import type { MediaCenterStreamModel } from './types';
4
6
  export declare class DiscoverPanelHandler {
5
7
  private readonly config;
@@ -21,9 +23,10 @@ export declare class DiscoverPanelHandler {
21
23
  }
22
24
  type ShortVideoSectionItemType = {
23
25
  kind: 'video';
24
- data: ShortVideoPlayerModel;
26
+ data: PostPlayerModel;
25
27
  } | {
26
28
  kind: 'product';
27
29
  data: ProductCardModel;
30
+ trackingParams: TrackingParams;
28
31
  };
29
32
  export {};
@@ -1,3 +1,4 @@
1
+ import { PostType } from '../../core/enums';
1
2
  export class DiscoverPanelHandler {
2
3
  config;
3
4
  _activated = $state(false);
@@ -24,7 +25,9 @@ export class DiscoverPanelHandler {
24
25
  result.push({ kind: 'video', data: vids.shift() });
25
26
  }
26
27
  else if (want === 'product' && prods.length > 0) {
27
- result.push({ kind: 'product', data: prods.shift() });
28
+ const productModel = prods.shift();
29
+ const shortVideoId = this._shortVideos.find((v) => v.products.some((p) => p.id === productModel.id))?.id;
30
+ result.push({ kind: 'product', data: productModel, trackingParams: { shortVideoId } });
28
31
  }
29
32
  else {
30
33
  // temporary "empty" position - will fill later
@@ -38,7 +41,9 @@ export class DiscoverPanelHandler {
38
41
  result[i] = { kind: 'video', data: vids.shift() };
39
42
  }
40
43
  else if (prods.length > 0) {
41
- result[i] = { kind: 'product', data: prods.shift() };
44
+ const productModel = prods.shift();
45
+ const shortVideoId = this._shortVideos.find((v) => v.products.some((p) => p.id === productModel.id))?.id;
46
+ result[i] = { kind: 'product', data: productModel, trackingParams: { shortVideoId } };
42
47
  }
43
48
  }
44
49
  }
@@ -61,7 +66,7 @@ export class DiscoverPanelHandler {
61
66
  if (this._state === 'not-initialized') {
62
67
  this._state = 'loading';
63
68
  try {
64
- const shortVideosResponse = await this.config.shortVideosPlayer.getShortVideosCursor({ filter: {}, limit: 5 });
69
+ const shortVideosResponse = await this.config.postsPlayer.getPostsCursor({ filter: { types: [PostType.ShortVideo] }, limit: 5 });
65
70
  const streamsResponse = await this.config.streamPlayer.getStreamsCursor({ filter: {}, limit: 5 });
66
71
  this._shortVideos = shortVideosResponse.items;
67
72
  this._products = this._uniqueById(shortVideosResponse.items.flatMap((i) => i.products)).slice(0, 2);
@@ -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,11 +1,11 @@
1
- import type { ShortVideoPlayerModel } from '../../short-videos/short-videos-player';
1
+ import type { PostPlayerModel } from '../../posts/posts-player';
2
2
  import { DiscoverPanelHandler } from './discover-panel-handler.svelte';
3
3
  import { MediaCenterLocalization } from './media-center-localization';
4
4
  type Props = {
5
5
  handler: DiscoverPanelHandler;
6
6
  localization: MediaCenterLocalization;
7
7
  on: {
8
- shortVideoSelected: (shortVideo: ShortVideoPlayerModel) => void;
8
+ shortVideoSelected: (shortVideo: PostPlayerModel) => void;
9
9
  streamSelected: (id: string) => void;
10
10
  };
11
11
  };
@@ -0,0 +1,8 @@
1
+ import type { PostPlayerModel } from '../../posts/posts-player';
2
+ import type { IPlayerItemsProvider } from '../../ui/player-slider';
3
+ import type { IMediaCenterConfig } from '../config/types';
4
+ export declare const makePostPlayerItemsProvider: (data: {
5
+ config: IMediaCenterConfig;
6
+ categoryId?: string;
7
+ prefetchedItems?: PostPlayerModel[];
8
+ }) => IPlayerItemsProvider<PostPlayerModel>;
@@ -1,11 +1,16 @@
1
+ import { PostType } from '../..';
1
2
  import { ContinuationToken } from '../../core/continuation-token';
2
3
  import { CursorDataLoader } from '../../core/data-loaders';
3
- export const makeShortVideosProvider = (data) => {
4
+ export const makePostPlayerItemsProvider = (data) => {
4
5
  const { config, categoryId, prefetchedItems = [] } = data;
5
6
  const loader = new CursorDataLoader({
6
7
  loadPage: async (continuationToken) => {
7
- const result = await config.shortVideosPlayer.getShortVideosCursor({
8
- filter: { categoryId, excludeIds: prefetchedItems.length ? prefetchedItems.map((i) => i.id) : undefined },
8
+ const result = await config.postsPlayer.getPostsCursor({
9
+ filter: {
10
+ types: [PostType.Article, PostType.Media, PostType.ShortVideo, PostType.Video],
11
+ categoryId,
12
+ excludeIds: prefetchedItems.length ? prefetchedItems.map((i) => i.id) : undefined
13
+ },
9
14
  continuationToken: continuationToken.toNextChunkString(),
10
15
  limit: 20
11
16
  });
@@ -1,4 +1,4 @@
1
- export type MediaCenterMode = 'short-videos' | 'stream';
1
+ export type MediaCenterMode = 'stream' | 'posts';
2
2
  export type MediaCenterStreamModel = {
3
3
  id: string;
4
4
  title: string;
@@ -1,7 +1,17 @@
1
- <script lang="ts">import { AdCard } from '../../ads/ad-card';
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;
@@ -0,0 +1 @@
1
+ export { InternalPostAnalyticsHandler } from './internal-post-analytics-handler';
@@ -0,0 +1 @@
1
+ export { InternalPostAnalyticsHandler } from './internal-post-analytics-handler';
@@ -1,7 +1,8 @@
1
- import type { IShortVideoAnalyticsHandler } from './types';
2
- export declare class InternalShortVideoAnalyticsHandler implements IShortVideoAnalyticsHandler {
1
+ import type { IPostAnalyticsHandler } from '../posts-player';
2
+ export declare class InternalPostAnalyticsHandler implements IPostAnalyticsHandler {
3
3
  constructor(graphqlOrigin: string | undefined);
4
4
  setOrganizationId: (organizationId: string) => void;
5
+ trackPostOpened: (postId: string, ownerId: string) => void;
5
6
  trackShortVideoView: (videoId: string) => void;
6
7
  trackShortVideoProductImpression: (productId: string, videoId: string) => void;
7
8
  trackShortVideoProductClick: (productId: string, videoId: string) => void;
@@ -1,12 +1,13 @@
1
1
  import { getOrCreateProfileId } from '../../core/analytics.profile-id';
2
2
  import { constructGraphQLUrl } from '../../core/graphql';
3
3
  import { AppEventsTracker } from '@streamscloud/streams-analytics-collector';
4
- export class InternalShortVideoAnalyticsHandler {
4
+ export class InternalPostAnalyticsHandler {
5
5
  constructor(graphqlOrigin) {
6
6
  AppEventsTracker.setEndpoint(constructGraphQLUrl(graphqlOrigin));
7
7
  AppEventsTracker.setProfileId(getOrCreateProfileId());
8
8
  }
9
9
  setOrganizationId = (organizationId) => AppEventsTracker.setOrganizationId(organizationId);
10
+ trackPostOpened = (postId, ownerId) => AppEventsTracker.trackPostOpened(postId, ownerId);
10
11
  trackShortVideoView = (videoId) => AppEventsTracker.trackShortVideoView(videoId);
11
12
  trackShortVideoProductImpression = (productId, videoId) => AppEventsTracker.trackShortVideoProductImpression(productId, videoId);
12
13
  trackShortVideoProductClick = (productId, videoId) => AppEventsTracker.trackShortVideoProductClick(productId, videoId);
@@ -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 { AdType } from '../../core/enums';
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) || null,
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 { PostControls } from '../controls';
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,10 +1,10 @@
1
1
  <script lang="ts">import { createShadowRoot } from '../../ui/shadow-dom';
2
- import { default as ShortVideoPlayerView } from './short-videos-player-view.svelte';
2
+ import { default as PostsPlayerView } from './posts-player-view.svelte';
3
3
  import { mount, unmount } from 'svelte';
4
4
  let { dataProvider, socialInteractionsHandler, playerSettings, analyticsHandler, on } = $props();
5
5
  const initHost = (node) => {
6
6
  const shadowRoot = createShadowRoot(node);
7
- const mounted = mount(ShortVideoPlayerView, {
7
+ const mounted = mount(PostsPlayerView, {
8
8
  target: shadowRoot,
9
9
  props: {
10
10
  dataProvider,
@@ -23,5 +23,5 @@ const initHost = (node) => {
23
23
  </script>
24
24
 
25
25
  {#key dataProvider}
26
- <div class="short-videos-player-host" use:initHost></div>
26
+ <div class="posts-player-host" use:initHost></div>
27
27
  {/key}
@@ -0,0 +1,4 @@
1
+ import type { PostPlayerProps } from './types';
2
+ declare const Cmp: import("svelte").Component<PostPlayerProps, {}, "">;
3
+ type Cmp = ReturnType<typeof Cmp>;
4
+ export default Cmp;
@@ -1,73 +1,87 @@
1
+ import { type IMediaCenterConfig } from '../../media-center/config/types';
1
2
  import type { IPostSocialInteractionsHandler } from '../social-interactions';
2
3
  import type { IPlayerItemsProvider } from '../../ui/player-slider';
4
+ import { default as PostsPlayer } from './cmp.posts-player.svelte';
5
+ import { mapToPostPlayerModel } from './mapper';
3
6
  import type { IPostAnalyticsHandler, PostPlayerModel, PostPlayerSettings } from './types';
4
- export { type PostPlayerModel };
5
- export type { IPlayerItemsProvider, IPostAnalyticsHandler };
7
+ export { PostsPlayer, type PostPlayerModel };
8
+ export type { IMediaCenterConfig, IPlayerItemsProvider, IPostAnalyticsHandler };
9
+ export { mapToPostPlayerModel };
6
10
  /**
7
11
  * Opens the posts player modal.
8
12
  *
9
- * This version works only with a posts provider and removes legacy IDs/GraphQL modes.
10
- *
11
13
  * @param init Configuration options.
12
14
  *
13
- * Required
15
+ * Data provider (required)
14
16
  * @param {IPlayerItemsProvider<PostPlayerModel>} init.postsProvider
15
17
  * Provider that supplies post items to the player.
16
18
  *
17
- * Optional
19
+ * Media center (optional)
20
+ * @param {IMediaCenterConfig} [init.mediaCenterConfig]
21
+ * Optional media-center config passed to MediaCenter.
22
+ *
23
+ * Analytics (optional)
18
24
  * @param {IPostAnalyticsHandler} [init.analyticsHandler]
19
- * Analytics events handler.
25
+ * Custom analytics handler for posts player events.
26
+ *
27
+ * Social interactions (optional)
20
28
  * @param {IPostSocialInteractionsHandler} [init.socialInteractionsHandler]
21
29
  * Handler for social interactions (like, share, etc.).
22
- * @param {ContentPlayerSettings} [init.playerSettings]
23
- * Player UI and behavior settings.
24
30
  *
25
- * Fields of ContentPlayerSettings:
31
+ * Player settings
32
+ * @param {PostPlayerSettings} [init.playerSettings]
33
+ * Player UI and behavior settings.
34
+ * Fields of PostPlayerSettings:
26
35
  * - {boolean} [disableBackground]
27
36
  * If true, hides the player's background image.
28
37
  * - {boolean} [hideCloseButton]
29
38
  * If true, hides the close button.
30
- * - {Locale} [locale='en']
31
- * Localization for the player UI. Supported values: 'en' | 'no'.
32
- * If omitted, the default locale 'en' is used.
39
+ * - {'en'|'no'} [locale='en']
40
+ * Localization for the player UI. Default is 'en'; use 'no' for Norwegian.
33
41
  * - {boolean} [showStreamsCloudWatermark]
34
42
  * If true, shows the StreamsCloud watermark.
35
43
  *
36
44
  * Events
37
- * @param {{ playerClosed?: () => void }} [init.on]
45
+ * @param {{ playerClosed?: () => void; postActivated?: (id: string) => void }} [init.on]
38
46
  * Optional event handlers.
39
47
  * @param {() => void} [init.on.playerClosed]
40
48
  * Called after the player is fully closed (after unmount and removal from the DOM).
49
+ * @param {(id: string) => void} [init.on.postActivated]
50
+ * Called when a post becomes active (receives the post's id).
41
51
  *
42
52
  * @returns {void}
43
53
  *
44
54
  * @example
45
55
  * ```ts
46
- * import { openPostsPlayer } from '@streamscloud/embeddable/short-videos-player';
56
+ * import { openPostsPlayer } from '@streamscloud/embeddable/posts-player';
47
57
  *
48
58
  * openPostsPlayer({
49
59
  * postsProvider: myPostsProvider,
60
+ * mediaCenterConfig: myMediaCenterConfig,
50
61
  * analyticsHandler: myAnalyticsHandler,
51
62
  * socialInteractionsHandler: mySocialHandler,
52
63
  * playerSettings: {
64
+ * // Default locale is 'en'; set 'no' to switch to Norwegian:
65
+ * locale: 'no',
53
66
  * disableBackground: false,
54
67
  * hideCloseButton: false,
55
- * // Locale is 'en' by default; set 'no' to switch to Norwegian:
56
- * locale: 'no',
57
68
  * showStreamsCloudWatermark: true,
58
69
  * },
59
70
  * on: {
60
71
  * playerClosed: () => console.log('Player closed'),
72
+ * postActivated: (id) => console.log('Activated post', id),
61
73
  * },
62
74
  * });
63
75
  * ```
64
76
  */
65
77
  export declare function openPostsPlayer(init: {
66
78
  postsProvider: IPlayerItemsProvider<PostPlayerModel>;
79
+ mediaCenterConfig?: IMediaCenterConfig;
67
80
  analyticsHandler?: IPostAnalyticsHandler;
68
81
  socialInteractionsHandler?: IPostSocialInteractionsHandler;
69
82
  playerSettings?: PostPlayerSettings;
70
83
  on?: {
71
84
  playerClosed?: () => void;
85
+ postActivated?: (id: string) => void;
72
86
  };
73
87
  }): void;