@streamscloud/embeddable 14.0.0-rc.0 → 14.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 (165) hide show
  1. package/dist/core/analytics.profile-id.d.ts +5 -0
  2. package/dist/core/{analytics.installation-id.js → analytics.profile-id.js} +10 -20
  3. package/dist/external-api/data-providers/internal-media-center-analytics-handler.d.ts +14 -14
  4. package/dist/external-api/data-providers/internal-media-center-analytics-handler.js +19 -170
  5. package/dist/external-api/data-providers/internal-media-center-data-provider.svelte.js +6 -6
  6. package/dist/external-api/data-providers/internal-post-analytics-handler.d.ts +7 -7
  7. package/dist/external-api/data-providers/internal-post-analytics-handler.js +11 -72
  8. package/dist/external-api/data-providers/internal-stream-analytics-handler.d.ts +13 -12
  9. package/dist/external-api/data-providers/internal-stream-analytics-handler.js +18 -162
  10. package/dist/external-api/data-providers/mocks/index.d.ts +5 -0
  11. package/dist/external-api/data-providers/mocks/index.js +5 -0
  12. package/dist/{media-center/categories-following → external-api/data-providers/mocks}/mock-categories-following-handler.svelte.d.ts +1 -1
  13. package/dist/external-api/data-providers/mocks/mock-content-management-handler.svelte.d.ts +29 -0
  14. package/dist/external-api/data-providers/mocks/mock-content-management-handler.svelte.js +61 -0
  15. package/dist/{media-center/membership → external-api/data-providers/mocks}/mock-membership-handler.svelte.d.ts +1 -1
  16. package/dist/{media-center/navigation → external-api/data-providers/mocks}/mock-navigation-handler.svelte.d.ts +1 -2
  17. package/dist/{posts/social-interactions → external-api/data-providers/mocks}/mock-post-social-interactions-handler.svelte.d.ts +1 -2
  18. package/dist/{posts/social-interactions → external-api/data-providers/mocks}/mock-post-social-interactions-handler.svelte.js +17 -6
  19. package/dist/external-api/data-providers/mocks/operations.generated.d.ts +115 -0
  20. package/dist/external-api/data-providers/mocks/operations.generated.js +377 -0
  21. package/dist/external-api/data-providers/mocks/operations.graphql +18 -0
  22. package/dist/external-api/data-providers/post-data-loaders/mapper.js +3 -1
  23. package/dist/media-center/config/types.d.ts +7 -1
  24. package/dist/media-center/content-management/index.d.ts +1 -0
  25. package/dist/media-center/content-management/index.js +1 -0
  26. package/dist/media-center/content-management/types.d.ts +24 -0
  27. package/dist/media-center/content-management/types.js +1 -0
  28. package/dist/media-center/index.d.ts +2 -1
  29. package/dist/media-center/media-center/cmp.media-center-proxy.svelte +2 -2
  30. package/dist/media-center/media-center/discover/data-loading.d.ts +3 -0
  31. package/dist/media-center/media-center/discover/data-loading.js +13 -2
  32. package/dist/media-center/media-center/discover/discover-view-handler.svelte.d.ts +23 -0
  33. package/dist/media-center/media-center/discover/discover-view-handler.svelte.js +88 -0
  34. package/dist/media-center/media-center/discover/discover-view.svelte +90 -47
  35. package/dist/media-center/media-center/discover/discover-view.svelte.d.ts +2 -2
  36. package/dist/media-center/media-center/footer/media-center-footer.svelte +1 -1
  37. package/dist/media-center/media-center/handlers/index.d.ts +1 -0
  38. package/dist/media-center/media-center/handlers/index.js +1 -0
  39. package/dist/media-center/media-center/handlers/media-center-content-handler.svelte.d.ts +62 -0
  40. package/dist/media-center/media-center/handlers/media-center-content-handler.svelte.js +144 -0
  41. package/dist/media-center/media-center/header/media-center-header-mobile.svelte +10 -7
  42. package/dist/media-center/media-center/header/media-center-header.svelte +1 -1
  43. package/dist/media-center/media-center/media-center-context.svelte.d.ts +3 -2
  44. package/dist/media-center/media-center/media-center-context.svelte.js +30 -11
  45. package/dist/media-center/media-center/media-center-view.svelte +31 -13
  46. package/dist/media-center/media-center/menu/menu.svelte +16 -7
  47. package/dist/media-center/media-center/menu/menu.svelte.d.ts +1 -0
  48. package/dist/media-center/media-center/menu/popular-streams-panel-handler.svelte.d.ts +7 -0
  49. package/dist/media-center/media-center/menu/popular-streams-panel-handler.svelte.js +23 -8
  50. package/dist/media-center/media-center/moments/moments-feed-handler.svelte.d.ts +19 -2
  51. package/dist/media-center/media-center/moments/moments-feed-handler.svelte.js +51 -6
  52. package/dist/media-center/media-center/moments/moments-state.svelte.d.ts +2 -0
  53. package/dist/media-center/media-center/moments/moments-state.svelte.js +16 -1
  54. package/dist/media-center/media-center/posts-feed/posts-feed-handler.svelte.d.ts +24 -4
  55. package/dist/media-center/media-center/posts-feed/posts-feed-handler.svelte.js +90 -9
  56. package/dist/media-center/media-center/streams-feed/streams-feed-handler.svelte.d.ts +18 -3
  57. package/dist/media-center/media-center/streams-feed/streams-feed-handler.svelte.js +64 -9
  58. package/dist/media-center/media-center/streams-in-category/streams-in-category-panel.svelte +2 -6
  59. package/dist/posts/controls/index.d.ts +2 -1
  60. package/dist/posts/controls/index.js +2 -1
  61. package/dist/posts/controls/post-actions-generator.svelte.d.ts +20 -0
  62. package/dist/posts/controls/post-actions-generator.svelte.js +27 -0
  63. package/dist/posts/controls/post-actions-handler.svelte.d.ts +26 -0
  64. package/dist/posts/controls/post-actions-handler.svelte.js +56 -0
  65. package/dist/posts/index.d.ts +1 -0
  66. package/dist/posts/model/types.d.ts +1 -0
  67. package/dist/posts/post-viewer/cmp.post-viewer.svelte +6 -7
  68. package/dist/posts/post-viewer/cmp.post-viewer.svelte.d.ts +2 -2
  69. package/dist/posts/post-viewer/mapper.js +1 -0
  70. package/dist/posts/posts-player/cmp.posts-player.svelte +2 -1
  71. package/dist/posts/posts-player/cmp.posts-player.svelte.d.ts +2 -0
  72. package/dist/posts/posts-player/index.d.ts +2 -0
  73. package/dist/posts/posts-player/index.js +2 -1
  74. package/dist/posts/posts-player/posts-player-proxy.svelte +2 -1
  75. package/dist/posts/posts-player/posts-player-proxy.svelte.d.ts +3 -1
  76. package/dist/posts/posts-player/posts-player-view.svelte +132 -34
  77. package/dist/posts/posts-player/types.d.ts +13 -3
  78. package/dist/posts/sharing/index.d.ts +1 -0
  79. package/dist/posts/sharing/index.js +1 -0
  80. package/dist/posts/sharing/types.d.ts +5 -0
  81. package/dist/posts/sharing/types.js +1 -0
  82. package/dist/posts/social-interactions/types.d.ts +0 -1
  83. package/dist/streams/controls/index.d.ts +1 -0
  84. package/dist/streams/controls/index.js +1 -0
  85. package/dist/streams/controls/stream-actions-generator.svelte.d.ts +31 -0
  86. package/dist/streams/controls/stream-actions-generator.svelte.js +42 -0
  87. package/dist/streams/index.d.ts +1 -0
  88. package/dist/streams/index.js +1 -0
  89. package/dist/streams/layout/cmp.layout.svelte +4 -1
  90. package/dist/streams/layout/cmp.layout.svelte.d.ts +1 -0
  91. package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte +1 -0
  92. package/dist/streams/layout/models/mapper.js +1 -0
  93. package/dist/streams/sharing/index.d.ts +1 -0
  94. package/dist/streams/sharing/index.js +1 -0
  95. package/dist/streams/sharing/types.d.ts +5 -0
  96. package/dist/streams/sharing/types.js +1 -0
  97. package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte +43 -1
  98. package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte.d.ts +9 -0
  99. package/dist/streams/streams-player/cmp.streams-player.svelte +2 -1
  100. package/dist/streams/streams-player/cmp.streams-player.svelte.d.ts +2 -0
  101. package/dist/streams/streams-player/index.d.ts +2 -0
  102. package/dist/streams/streams-player/index.js +2 -1
  103. package/dist/streams/streams-player/streams-player-proxy.svelte +2 -1
  104. package/dist/streams/streams-player/streams-player-proxy.svelte.d.ts +2 -0
  105. package/dist/streams/streams-player/streams-player-view.svelte +150 -34
  106. package/dist/streams/streams-player/types.d.ts +8 -0
  107. package/dist/ui/button/resources/button-theme.svelte +2 -4
  108. package/dist/ui/card-actions/card-action-container.d.ts +2 -0
  109. package/dist/ui/card-actions/card-action-container.js +17 -0
  110. package/dist/ui/card-actions/cmp.card-action.svelte +28 -0
  111. package/dist/ui/card-actions/cmp.card-action.svelte.d.ts +10 -0
  112. package/dist/ui/card-actions/cmp.card-actions.svelte +71 -0
  113. package/dist/ui/card-actions/cmp.card-actions.svelte.d.ts +9 -0
  114. package/dist/ui/card-actions/index.d.ts +4 -0
  115. package/dist/ui/card-actions/index.js +3 -0
  116. package/dist/ui/card-actions/types.d.ts +9 -0
  117. package/dist/ui/card-actions/types.js +1 -0
  118. package/dist/ui/icon/cmp.icon.svelte +1 -1
  119. package/dist/ui/player/button/cmp.player-button.svelte +1 -3
  120. package/dist/ui/player/button/cmp.player-buttons-group.svelte +1 -3
  121. package/dist/ui/player/button/cmp.responsive-player-buttons-group.svelte +53 -0
  122. package/dist/ui/player/button/cmp.responsive-player-buttons-group.svelte.d.ts +10 -0
  123. package/dist/ui/player/button/index.d.ts +1 -0
  124. package/dist/ui/player/button/index.js +1 -0
  125. package/dist/{content-player → ui/player/content-player}/cmp.content-player.svelte +7 -29
  126. package/dist/{content-player → ui/player/content-player}/cmp.content-player.svelte.d.ts +11 -15
  127. package/dist/ui/player/content-player/content-player-config.svelte.d.ts +29 -0
  128. package/dist/ui/player/content-player/content-player-config.svelte.js +27 -0
  129. package/dist/{content-player → ui/player/content-player}/content-player-settings.svelte.d.ts +3 -3
  130. package/dist/{content-player → ui/player/content-player}/content-player-settings.svelte.js +2 -2
  131. package/dist/{content-player → ui/player/content-player}/controls-and-attachments.svelte +18 -65
  132. package/dist/{content-player → ui/player/content-player}/controls-and-attachments.svelte.d.ts +11 -14
  133. package/dist/{content-player → ui/player/content-player}/overview-panel.svelte +2 -4
  134. package/dist/{content-player → ui/player/content-player}/overview-panel.svelte.d.ts +5 -14
  135. package/dist/{content-player → ui/player/content-player}/ui-manager.svelte.d.ts +3 -2
  136. package/dist/{content-player → ui/player/content-player}/ui-manager.svelte.js +3 -2
  137. package/dist/ui/player/providers/chunks-player-buffer/player-chunk-item.svelte.d.ts +0 -2
  138. package/dist/ui/player/providers/chunks-player-buffer/player-chunk-item.svelte.js +1 -3
  139. package/dist/ui/player/providers/chunks-player-buffer/player-chunk.svelte.d.ts +3 -2
  140. package/dist/ui/player/providers/chunks-player-buffer/player-chunk.svelte.js +11 -5
  141. package/dist/ui/player/providers/chunks-player-buffer/player-chunks-manager.svelte.d.ts +3 -0
  142. package/dist/ui/player/providers/chunks-player-buffer/player-chunks-manager.svelte.js +74 -8
  143. package/dist/ui/player/providers/default-chunks-player-buffer.svelte.d.ts +2 -0
  144. package/dist/ui/player/providers/default-chunks-player-buffer.svelte.js +15 -4
  145. package/dist/ui/player/providers/default-feed-player-buffer.svelte.d.ts +1 -0
  146. package/dist/ui/player/providers/default-feed-player-buffer.svelte.js +27 -5
  147. package/dist/ui/player/providers/types.d.ts +1 -0
  148. package/dist/ui/player/slider/cmp.player-slider.svelte.d.ts +5 -14
  149. package/dist/ui/player/slider-horizontal/cmp.slider.svelte +2 -6
  150. package/dist/ui/player/slider-horizontal/cmp.slider.svelte.d.ts +5 -12
  151. package/dist/ui/shadow-dom/cmp.shadow-root.svelte +11 -6
  152. package/dist/ui/shadow-dom/colors.scss +2 -0
  153. package/package.json +7 -3
  154. package/dist/content-player/content-player-config.svelte.d.ts +0 -51
  155. package/dist/content-player/content-player-config.svelte.js +0 -48
  156. package/dist/core/analytics.installation-id.d.ts +0 -5
  157. package/dist/external-api/data-providers/mapper.d.ts +0 -3
  158. package/dist/external-api/data-providers/mapper.js +0 -18
  159. package/dist/posts/controls/cmp.controls.svelte +0 -120
  160. package/dist/posts/controls/cmp.controls.svelte.d.ts +0 -16
  161. /package/dist/{media-center/categories-following → external-api/data-providers/mocks}/mock-categories-following-handler.svelte.js +0 -0
  162. /package/dist/{media-center/membership → external-api/data-providers/mocks}/mock-membership-handler.svelte.js +0 -0
  163. /package/dist/{media-center/navigation → external-api/data-providers/mocks}/mock-navigation-handler.svelte.js +0 -0
  164. /package/dist/{content-player → ui/player/content-player}/index.d.ts +0 -0
  165. /package/dist/{content-player → ui/player/content-player}/index.js +0 -0
@@ -0,0 +1,56 @@
1
+ import { IconColor } from '../../ui/icon';
2
+ import { MediaVolumeManager } from '../../ui/media-playback';
3
+ import IconHeartFilled from '@fluentui/svg-icons/icons/heart_32_filled.svg?raw';
4
+ import IconHeart from '@fluentui/svg-icons/icons/heart_32_regular.svg?raw';
5
+ import IconShare from '@fluentui/svg-icons/icons/share_48_regular.svg?raw';
6
+ import IconShoppingBag from '@fluentui/svg-icons/icons/shopping_bag_32_regular.svg?raw';
7
+ import IconSpeaker2 from '@fluentui/svg-icons/icons/speaker_2_32_regular.svg?raw';
8
+ import IconSpeakerMute from '@fluentui/svg-icons/icons/speaker_mute_32_regular.svg?raw';
9
+ export class PostActionsHandler {
10
+ actions = $derived.by(() => {
11
+ const result = [];
12
+ if (this.post.attachments) {
13
+ result.push({ icon: IconShoppingBag, callback: this.callbacks.attachmentClicked });
14
+ }
15
+ if (this.post.enableSocialInteractions && this.socialInteractionsHandler) {
16
+ result.push({
17
+ icon: this.isLikedStore.isLiked ? IconHeartFilled : IconHeart,
18
+ iconColor: this.isLikedStore.isLiked ? IconColor.Red : undefined,
19
+ callback: () => this.socialInteractionsHandler?.toggleLike(this.post.id)
20
+ });
21
+ }
22
+ if (this.callbacks.shareClicked) {
23
+ result.push({
24
+ icon: IconShare,
25
+ callback: () => this.callbacks.shareClicked?.()
26
+ });
27
+ }
28
+ if (this.post.media && !this.post.media.currentItem.isImage) {
29
+ result.push({
30
+ icon: MediaVolumeManager.isMuted ? IconSpeakerMute : IconSpeaker2,
31
+ callback: () => (MediaVolumeManager.isMuted = !MediaVolumeManager.isMuted)
32
+ });
33
+ }
34
+ return result;
35
+ });
36
+ post;
37
+ socialInteractionsHandler;
38
+ callbacks;
39
+ isLikedStore = $state.raw({
40
+ get isLiked() {
41
+ return false;
42
+ }
43
+ });
44
+ constructor(init) {
45
+ this.post = init.post;
46
+ this.socialInteractionsHandler = init.socialInteractionsHandler;
47
+ this.callbacks = init.callbacks;
48
+ this.initIsLikedStore();
49
+ }
50
+ initIsLikedStore = async () => {
51
+ if (!this.socialInteractionsHandler) {
52
+ return;
53
+ }
54
+ this.isLikedStore = await this.socialInteractionsHandler.getIsLiked(this.post.id);
55
+ };
56
+ }
@@ -1,2 +1,3 @@
1
1
  export type { IPostSocialInteractionsHandler } from './social-interactions';
2
+ export type { IPostSharingHandler } from './sharing';
2
3
  export type { IPostModel, IPostProductCardModel, IPostHeadingModel, IPostAdCardModel, IPostMediaItemModel } from './model/types';
@@ -12,6 +12,7 @@ export type IPostModel = {
12
12
  readMoreUrl?: string;
13
13
  heading: IPostHeadingModel | null;
14
14
  enableSocialInteractions: boolean;
15
+ articleId: string | null;
15
16
  products: IPostProductCardModel[];
16
17
  ads: IPostAdCardModel[];
17
18
  };
@@ -1,13 +1,13 @@
1
1
  <script lang="ts">import { PostType } from '../..';
2
- import { PostControls } from '../controls';
3
2
  import { PostModel } from '../model';
3
+ import { ResponsivePlayerButtonsGroup } from '../../ui/player/button';
4
4
  import { default as AttachmentsHorizontal } from './attachments-horizontal.svelte';
5
5
  import { default as Heading } from './heading.svelte';
6
6
  import { default as PostMedia } from './media/post-media.svelte';
7
7
  import { default as Texts } from './post-texts.svelte';
8
8
  import { PostViewerLocalization } from './post-viewer-localization';
9
9
  import { PostViewerUiManager } from './ui-manager.svelte';
10
- let { model, socialInteractionsHandler, trackingParams: externalTrackingParams, controlsColors = null, enableAttachments = true, enableControls = true, autoplay = 'on-appearance', locale = 'en', on } = $props();
10
+ let { model, trackingParams: externalTrackingParams, controlsColors = null, enableAttachments = true, controlActions, enableControls = true, autoplay = 'on-appearance', locale = 'en', on } = $props();
11
11
  const localization = $derived(new PostViewerLocalization(locale));
12
12
  const uiManager = new PostViewerUiManager();
13
13
  $effect(() => {
@@ -81,12 +81,11 @@ const variables = $derived.by(() => {
81
81
 
82
82
  {#if uiManager.showControls}
83
83
  <div class="post-viewer__controls-panel" use:trackControlsPanelSize>
84
- <PostControls
85
- model={model}
84
+ <ResponsivePlayerButtonsGroup
85
+ actions={controlActions}
86
86
  activeColor={controlsColors?.active ?? null}
87
- inactiveColor={controlsColors?.inactive ?? null}
88
- socialInteractionsHandler={socialInteractionsHandler}
89
- on={{ attachmentsClicked: () => (uiManager.canShowAttachments = !uiManager.canShowAttachments) }} />
87
+ backgroundColor={controlsColors?.inactive ?? null}
88
+ scaleEffect={true} />
90
89
  </div>
91
90
  {/if}
92
91
  </div>
@@ -1,10 +1,9 @@
1
1
  import type { Locale } from '../../core/locale';
2
2
  import type { TrackingParams } from '../../marketing-tracking';
3
3
  import { PostModel } from '../model';
4
- import type { IPostSocialInteractionsHandler } from '../social-interactions';
4
+ import { type PlayerButtonDef } from '../../ui/player/button';
5
5
  type Props = {
6
6
  model: PostModel;
7
- socialInteractionsHandler?: IPostSocialInteractionsHandler;
8
7
  trackingParams: TrackingParams | null | false;
9
8
  enableAttachments?: boolean;
10
9
  enableControls?: boolean;
@@ -12,6 +11,7 @@ type Props = {
12
11
  active: string | null;
13
12
  inactive: string | null;
14
13
  } | null;
14
+ controlActions: PlayerButtonDef[];
15
15
  autoplay?: true | false | 'on-appearance';
16
16
  locale?: Locale;
17
17
  on?: {
@@ -14,6 +14,7 @@ export const mapToPostModel = (payload) => {
14
14
  viewsCount: payload.viewsCount,
15
15
  displayDate: payload.displayDate,
16
16
  heading: null,
17
+ articleId: payload.postData.articleData?.articleId ?? null,
17
18
  ads: payload.ad ? [mapToPostViewerAdCardModel(payload.ad)] : [],
18
19
  products: payload.allProducts.map((x) => mapToPostViewerProductCard(x))
19
20
  // uncomment if you want to test many products behavior
@@ -11,7 +11,7 @@ import { CloseOrchestrator } from '../../ui/player/close-orchestrator';
11
11
  import { createShadowRoot } from '../../ui/shadow-dom';
12
12
  import { default as PostsPlayerProxy } from './posts-player-proxy.svelte';
13
13
  import { mount, unmount } from 'svelte';
14
- let { dataProvider, socialInteractionsHandler, playerSettings, analyticsHandler, on } = $props();
14
+ let { dataProvider, socialInteractionsHandler, sharingHandler, playerSettings, analyticsHandler, on } = $props();
15
15
  const initHost = (node) => {
16
16
  const shadowRoot = createShadowRoot(node);
17
17
  const mounted = mount(PostsPlayerProxy, {
@@ -19,6 +19,7 @@ const initHost = (node) => {
19
19
  props: {
20
20
  dataProvider,
21
21
  socialInteractionsHandler,
22
+ sharingHandler,
22
23
  playerSettings,
23
24
  analyticsHandler,
24
25
  closeOrchestrator: new CloseOrchestrator({
@@ -1,10 +1,12 @@
1
1
  import type { Locale } from '../../core/locale';
2
2
  import type { IPostSocialInteractionsHandler } from '..';
3
+ import type { IPostSharingHandler } from '../sharing';
3
4
  import type { IPlayerDataProvider } from '../../ui/player/providers';
4
5
  import type { IPostAnalyticsHandler, PostPlayerModel } from './types';
5
6
  type Props = {
6
7
  dataProvider: IPlayerDataProvider<PostPlayerModel>;
7
8
  socialInteractionsHandler?: IPostSocialInteractionsHandler;
9
+ sharingHandler?: IPostSharingHandler;
8
10
  analyticsHandler?: IPostAnalyticsHandler;
9
11
  playerSettings?: {
10
12
  locale?: Locale;
@@ -1,5 +1,6 @@
1
1
  import type { Locale } from '../../core/locale';
2
2
  import { type IMediaCenterDataProvider } from '../../media-center/config/types';
3
+ import type { IPostSharingHandler } from '../sharing';
3
4
  import type { IPostSocialInteractionsHandler } from '../social-interactions';
4
5
  import { default as PostsPlayer } from './cmp.posts-player.svelte';
5
6
  import type { IPostAnalyticsHandler, PostPlayerModel } from './types';
@@ -85,6 +86,7 @@ export declare function openPostsPlayer(init: {
85
86
  postsProvider: IPostsPlayerDataProvider;
86
87
  analyticsHandler?: IPostAnalyticsHandler;
87
88
  socialInteractionsHandler?: IPostSocialInteractionsHandler;
89
+ sharingHandler?: IPostSharingHandler;
88
90
  playerSettings?: {
89
91
  disableBackground?: boolean;
90
92
  locale?: Locale;
@@ -82,7 +82,7 @@ export { PostsPlayer };
82
82
  * ```
83
83
  */
84
84
  export function openPostsPlayer(init) {
85
- const { postsProvider: dataProvider, analyticsHandler, socialInteractionsHandler, playerSettings, on } = init;
85
+ const { postsProvider: dataProvider, analyticsHandler, socialInteractionsHandler, sharingHandler, playerSettings, on } = init;
86
86
  const shadowHost = new ModalShadowHost();
87
87
  let mounted = null;
88
88
  const makeCloseOrchestrator = () => new CloseOrchestrator({
@@ -100,6 +100,7 @@ export function openPostsPlayer(init) {
100
100
  props: {
101
101
  dataProvider,
102
102
  socialInteractionsHandler,
103
+ sharingHandler,
103
104
  analyticsHandler,
104
105
  playerSettings,
105
106
  closeOrchestrator: makeCloseOrchestrator(),
@@ -3,7 +3,7 @@ import {} from '../../ui/player/close-orchestrator';
3
3
  import { ShadowRoot } from '../../ui/shadow-dom';
4
4
  import { default as PostsPlayerView } from './posts-player-view.svelte';
5
5
  import { untrack } from 'svelte';
6
- let { dataProvider, socialInteractionsHandler, closeOrchestrator, playerSettings, analyticsHandler, on } = $props();
6
+ let { dataProvider, socialInteractionsHandler, sharingHandler, closeOrchestrator, playerSettings, analyticsHandler, on } = $props();
7
7
  let backgroundImageUrl = $state(null);
8
8
  const handleBackgroundImagedLoaded = (url) => {
9
9
  backgroundImageUrl = url;
@@ -21,6 +21,7 @@ $effect(() => {
21
21
  <PostsPlayerView
22
22
  dataProvider={{ type: 'provider', provider: dataProvider }}
23
23
  socialInteractionsHandler={socialInteractionsHandler}
24
+ sharingHandler={sharingHandler}
24
25
  playerSettings={playerSettings}
25
26
  analyticsHandler={analyticsHandler}
26
27
  closeOrchestrator={closeOrchestrator}
@@ -1,11 +1,13 @@
1
1
  import type { Locale } from '../../core/locale';
2
- import type { IPostSocialInteractionsHandler } from '..';
2
+ import type { IPostSharingHandler } from '../sharing';
3
+ import type { IPostSocialInteractionsHandler } from '../social-interactions';
3
4
  import { type ICloseOrchestrator } from '../../ui/player/close-orchestrator';
4
5
  import type { IPlayerDataProvider } from '../../ui/player/providers';
5
6
  import type { IPostAnalyticsHandler, PostPlayerModel } from './types';
6
7
  type Props = {
7
8
  dataProvider: IPlayerDataProvider<PostPlayerModel>;
8
9
  socialInteractionsHandler?: IPostSocialInteractionsHandler;
10
+ sharingHandler?: IPostSharingHandler;
9
11
  analyticsHandler?: IPostAnalyticsHandler;
10
12
  closeOrchestrator: ICloseOrchestrator;
11
13
  playerSettings?: {
@@ -7,19 +7,28 @@
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { PostType } from '../..';
11
- import { ContentPlayer, ContentPlayerConfig } from '../../content-player';
12
- import { ContentPlayerSettings } from '../../content-player/content-player-settings.svelte';
10
+ import { PostType } from '../../core/enums';
13
11
  import { preloadImage } from '../../core/image-preloader';
14
- import { getPostCoverImage } from '../model';
12
+ import { PostAttachments } from '../attachments';
13
+ import { PostActionsGenerator } from '../controls';
14
+ import { getPostCoverImage, PostModel } from '../model';
15
+ import { PostViewer } from '../post-viewer';
16
+ import { IconColor } from '../../ui/icon';
17
+ import { ContentPlayer, ContentPlayerConfig, ContentPlayerSettings } from '../../ui/player/content-player';
15
18
  import {} from '../../ui/player/providers';
16
19
  import { initBufferFromProvider } from '../../ui/player/providers/service';
20
+ import IconDelete from '@fluentui/svg-icons/icons/delete_32_regular.svg?raw';
21
+ import IconEdit from '@fluentui/svg-icons/icons/edit_32_regular.svg?raw';
17
22
  import { untrack } from 'svelte';
18
- let { dataProvider, socialInteractionsHandler, playerSettings, analyticsHandler, closeOrchestrator, on } = $props();
23
+ let { dataProvider, socialInteractionsHandler, sharingHandler, playerSettings, analyticsHandler, managementActions, closeOrchestrator, on } = $props();
24
+ let buffer = $state.raw(null);
25
+ let mappedPostsCache = new Map();
19
26
  $effect(() => {
20
27
  void dataProvider;
21
28
  untrack(() => {
22
29
  contentPlayerConfig.playerBuffer = null;
30
+ buffer = null;
31
+ mappedPostsCache = new Map();
23
32
  initBuffer(dataProvider);
24
33
  });
25
34
  });
@@ -37,42 +46,19 @@ const initBuffer = (dataProvider) => __awaiter(void 0, void 0, void 0, function*
37
46
  yield preloadImage(coverUrl);
38
47
  on.backgroundImageLoaded(coverUrl);
39
48
  }
49
+ buffer = newBuffer;
40
50
  contentPlayerConfig.playerBuffer = newBuffer;
41
51
  });
42
52
  const getLoadedItemById = (id) => {
43
- if (!contentPlayerConfig.playerBuffer) {
53
+ if (!buffer) {
44
54
  return null;
45
55
  }
46
- return contentPlayerConfig.playerBuffer.loaded.find((item) => item.id === id) || null;
56
+ return buffer.loaded.find((item) => item.id === id) || null;
47
57
  };
48
58
  const contentPlayerConfig = new ContentPlayerConfig({
49
59
  playerBuffer: null,
50
- mappers: {
51
- postModelFromCurrentItem: (item) => item
52
- },
53
- socialInteractionsHandler,
54
60
  settings: new ContentPlayerSettings(playerSettings),
55
61
  closeOrchestrator,
56
- callbacks: {
57
- productClick: (id, postId) => {
58
- var _a;
59
- if (((_a = getLoadedItemById(postId)) === null || _a === void 0 ? void 0 : _a.postType) === PostType.ShortVideo) {
60
- analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.trackShortVideoProductClick(id, postId);
61
- }
62
- },
63
- productImpression: (id, postId) => {
64
- var _a;
65
- if (((_a = getLoadedItemById(postId)) === null || _a === void 0 ? void 0 : _a.postType) === PostType.ShortVideo) {
66
- analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.trackShortVideoProductImpression(id, postId);
67
- }
68
- },
69
- adClick: (id) => {
70
- analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.trackAdClick(id);
71
- },
72
- adImpression: (id) => {
73
- analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.trackAdImpression(id);
74
- }
75
- },
76
62
  playerSliderCallbacks: {
77
63
  itemActivated: (id) => {
78
64
  var _a;
@@ -83,16 +69,128 @@ const contentPlayerConfig = new ContentPlayerConfig({
83
69
  if (on === null || on === void 0 ? void 0 : on.backgroundImageLoaded) {
84
70
  on.backgroundImageLoaded(getPostCoverImage(post));
85
71
  }
72
+ if (post.analyticsOrganizationId) {
73
+ analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.setOrganizationId(post.analyticsOrganizationId);
74
+ }
86
75
  if (post.postType === PostType.ShortVideo) {
87
76
  analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.trackShortVideoView(id);
88
77
  }
89
- else if (post.postType) {
90
- analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.trackPostOpened(post.postType, id);
78
+ else if (post.analyticsOrganizationId) {
79
+ analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.trackPostOpened(id, post.analyticsOrganizationId);
91
80
  }
92
81
  (_a = on === null || on === void 0 ? void 0 : on.postActivated) === null || _a === void 0 ? void 0 : _a.call(on, id);
93
82
  }
94
83
  }
95
84
  });
85
+ const postActionsGenerator = new PostActionsGenerator({
86
+ socialInteractionsHandler,
87
+ sharingHandler,
88
+ on: { attachmentClicked: () => (contentPlayerConfig.uiManager.attachmentsCollapsed = !contentPlayerConfig.uiManager.attachmentsCollapsed) }
89
+ });
90
+ const onProductClick = (id, postId) => {
91
+ var _a;
92
+ if (((_a = getLoadedItemById(postId)) === null || _a === void 0 ? void 0 : _a.postType) === PostType.ShortVideo) {
93
+ analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.trackShortVideoProductClick(id, postId);
94
+ }
95
+ };
96
+ const onProductImpression = (id, postId) => {
97
+ var _a;
98
+ if (((_a = getLoadedItemById(postId)) === null || _a === void 0 ? void 0 : _a.postType) === PostType.ShortVideo) {
99
+ analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.trackShortVideoProductImpression(id, postId);
100
+ }
101
+ };
102
+ const onAdClick = (id) => {
103
+ analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.trackAdClick(id);
104
+ };
105
+ const onAdImpression = (id) => {
106
+ analyticsHandler === null || analyticsHandler === void 0 ? void 0 : analyticsHandler.trackAdImpression(id);
107
+ };
108
+ const itemAsPostModel = (item) => {
109
+ if (mappedPostsCache.has(item.id)) {
110
+ return mappedPostsCache.get(item.id);
111
+ }
112
+ const postModel = new PostModel(item);
113
+ mappedPostsCache.set(item.id, postModel);
114
+ return postModel;
115
+ };
116
+ const currentItemActions = $derived.by(() => {
117
+ if (!(buffer === null || buffer === void 0 ? void 0 : buffer.current)) {
118
+ return [];
119
+ }
120
+ const result = [];
121
+ const postModel = itemAsPostModel(buffer.current);
122
+ const handler = postActionsGenerator.getPostActionsHandler(postModel);
123
+ result.push(...handler.actions);
124
+ if ((managementActions === null || managementActions === void 0 ? void 0 : managementActions.editPost) && postModel.postType !== PostType.Article) {
125
+ result.push({
126
+ icon: IconEdit,
127
+ callback: () => __awaiter(void 0, void 0, void 0, function* () {
128
+ yield managementActions.editPost(buffer.current.id);
129
+ })
130
+ });
131
+ }
132
+ if ((managementActions === null || managementActions === void 0 ? void 0 : managementActions.editArticle) && postModel.postType === PostType.Article && buffer.current.articleId) {
133
+ result.push({
134
+ icon: IconEdit,
135
+ callback: () => __awaiter(void 0, void 0, void 0, function* () {
136
+ yield managementActions.editArticle(buffer.current.articleId);
137
+ })
138
+ });
139
+ }
140
+ if (managementActions === null || managementActions === void 0 ? void 0 : managementActions.deletePost) {
141
+ result.push({
142
+ icon: IconDelete,
143
+ iconColor: IconColor.Red,
144
+ callback: () => __awaiter(void 0, void 0, void 0, function* () {
145
+ yield managementActions.deletePost(buffer.current.id);
146
+ })
147
+ });
148
+ }
149
+ return result;
150
+ });
96
151
  </script>
97
152
 
98
- <ContentPlayer config={contentPlayerConfig} />
153
+ {#snippet attachmentsView(data: { item: PostPlayerModel })}
154
+ {@const postModel = itemAsPostModel(data.item)}
155
+
156
+ <PostAttachments
157
+ model={postModel}
158
+ colors={{
159
+ background: contentPlayerConfig.playerColors.cardBackground,
160
+ price: contentPlayerConfig.playerColors.price,
161
+ salePrice: contentPlayerConfig.playerColors.salePrice,
162
+ buttonBackground: contentPlayerConfig.playerColors.cardButton
163
+ }}
164
+ trackingParams={contentPlayerConfig.trackingParams}
165
+ locale={contentPlayerConfig.settings.locale}
166
+ on={{
167
+ productClick: (id) => onProductClick(id, postModel.id),
168
+ productImpression: (id) => onProductImpression(id, postModel.id),
169
+ adClick: (id) => onAdClick(id),
170
+ adImpression: (id) => onAdImpression(id)
171
+ }} />
172
+ {/snippet}
173
+ <ContentPlayer
174
+ config={contentPlayerConfig}
175
+ itemActions={currentItemActions}
176
+ attachmentsView={buffer?.current && itemAsPostModel(buffer.current).attachments ? attachmentsView : undefined}>
177
+ {#snippet itemView({ item })}
178
+ {@const postModel = itemAsPostModel(item)}
179
+ {@const handler = postActionsGenerator.getPostActionsHandler(postModel)}
180
+ <PostViewer
181
+ model={postModel}
182
+ controlsColors={{ active: contentPlayerConfig.playerColors.button, inactive: contentPlayerConfig.playerColors.buttonInactive }}
183
+ controlActions={handler.actions}
184
+ trackingParams={contentPlayerConfig.trackingParams}
185
+ enableAttachments={contentPlayerConfig.uiManager.showAttachmentsOverlay}
186
+ enableControls={contentPlayerConfig.uiManager.showControlsOverlay}
187
+ autoplay="on-appearance"
188
+ locale={contentPlayerConfig.settings.locale}
189
+ on={{
190
+ productClick: (productId) => onProductClick(productId, postModel.id),
191
+ productImpression: (productId) => onProductImpression(productId, postModel.id),
192
+ adClick: (adId) => onAdClick(adId),
193
+ adImpression: (adId) => onAdImpression(adId)
194
+ }} />
195
+ {/snippet}
196
+ </ContentPlayer>
@@ -1,20 +1,23 @@
1
- import type { PostType } from '../../core/enums';
2
1
  import type { Locale } from '../../core/locale';
3
2
  import type { ThemeValue } from '../../core/theme';
4
3
  import type { IPostModel } from '..';
4
+ import type { IPostSharingHandler } from '../sharing';
5
5
  import type { IPostSocialInteractionsHandler } from '../social-interactions';
6
6
  import type { ICloseOrchestrator } from '../../ui/player/close-orchestrator';
7
7
  import type { PlayerColors } from '../../ui/player/colors';
8
8
  import type { IPlayerBuffer, IPlayerDataProvider } from '../../ui/player/providers';
9
9
  export interface IPostAnalyticsHandler {
10
- trackPostOpened: (postType: PostType, postId: string) => void;
10
+ setOrganizationId: (organizationId: string) => void;
11
+ trackPostOpened: (postId: string, ownerId: string) => void;
11
12
  trackShortVideoView: (videoId: string) => void;
12
13
  trackShortVideoProductImpression: (productId: string, videoId: string) => void;
13
14
  trackShortVideoProductClick: (productId: string, videoId: string) => void;
14
15
  trackAdClick: (adId: string) => void;
15
16
  trackAdImpression: (adId: string) => void;
16
17
  }
17
- export type PostPlayerModel = IPostModel;
18
+ export type PostPlayerModel = IPostModel & {
19
+ analyticsOrganizationId: string | null;
20
+ };
18
21
  export type PostsPlayerProps = {
19
22
  dataProvider: {
20
23
  type: 'buffer';
@@ -24,7 +27,9 @@ export type PostsPlayerProps = {
24
27
  provider: IPlayerDataProvider<PostPlayerModel>;
25
28
  };
26
29
  socialInteractionsHandler?: IPostSocialInteractionsHandler;
30
+ sharingHandler?: IPostSharingHandler;
27
31
  analyticsHandler?: IPostAnalyticsHandler;
32
+ managementActions?: PostManagementActions;
28
33
  playerSettings?: PostPlayerSettings;
29
34
  closeOrchestrator: ICloseOrchestrator;
30
35
  on?: {
@@ -37,3 +42,8 @@ export type PostPlayerSettings = {
37
42
  showStreamsCloudWatermark?: boolean;
38
43
  playerColors?: Record<ThemeValue, PlayerColors>;
39
44
  };
45
+ export type PostManagementActions = {
46
+ editPost: ((id: string) => void) | null;
47
+ editArticle: ((id: string) => void) | null;
48
+ deletePost: ((id: string) => void) | null;
49
+ };
@@ -0,0 +1 @@
1
+ export type { IPostSharingHandler } from './types';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export interface IPostSharingHandler {
2
+ share: (postId: string) => PromiseLike<void>;
3
+ }
4
+ type PromiseLike<T> = T | Promise<T>;
5
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -3,7 +3,6 @@ export interface IPostSocialInteractionsHandler {
3
3
  readonly isLiked: boolean;
4
4
  }>;
5
5
  toggleLike: (postId: string) => PromiseLike<void>;
6
- share: (postId: string) => PromiseLike<void>;
7
6
  }
8
7
  type PromiseLike<T> = T | Promise<T>;
9
8
  export {};
@@ -0,0 +1 @@
1
+ export { StreamActionsGenerator } from './stream-actions-generator.svelte';
@@ -0,0 +1 @@
1
+ export { StreamActionsGenerator } from './stream-actions-generator.svelte';
@@ -0,0 +1,31 @@
1
+ import { PostActionsHandler } from '../../posts/controls';
2
+ import type { PostModel } from '../../posts/model';
3
+ import type { IPostSocialInteractionsHandler } from '../../posts/social-interactions';
4
+ import type { IStreamSharingHandler } from '../sharing';
5
+ export declare class StreamActionsGenerator {
6
+ private postSocialInteractionsHandler;
7
+ private sharingHandler;
8
+ private callbacks;
9
+ private handlers;
10
+ constructor(init: {
11
+ postSocialInteractionsHandler: IPostSocialInteractionsHandler | undefined;
12
+ sharingHandler: IStreamSharingHandler | undefined;
13
+ on: StreamActionCallbacks;
14
+ });
15
+ getPostActionsHandler: (data: {
16
+ model: PostModel;
17
+ streamId: string;
18
+ streamPageId: string;
19
+ }) => PostActionsHandler;
20
+ getGeneralStreamPageActions: (data: {
21
+ streamId: string;
22
+ streamPageId: string;
23
+ }) => {
24
+ icon: any;
25
+ callback: () => (void | Promise<void>) | undefined;
26
+ }[];
27
+ }
28
+ type StreamActionCallbacks = {
29
+ attachmentClicked: () => void;
30
+ };
31
+ export {};
@@ -0,0 +1,42 @@
1
+ import { PostActionsHandler } from '../../posts/controls';
2
+ import IconShare from '@fluentui/svg-icons/icons/share_48_regular.svg?raw';
3
+ export class StreamActionsGenerator {
4
+ postSocialInteractionsHandler;
5
+ sharingHandler;
6
+ callbacks;
7
+ handlers = new Map();
8
+ constructor(init) {
9
+ this.postSocialInteractionsHandler = init.postSocialInteractionsHandler ?? null;
10
+ this.sharingHandler = init.sharingHandler ?? null;
11
+ this.callbacks = init.on;
12
+ }
13
+ getPostActionsHandler = (data) => {
14
+ const { model, streamId, streamPageId } = data;
15
+ let handler = this.handlers.get(streamPageId);
16
+ if (!handler) {
17
+ handler = new PostActionsHandler({
18
+ post: model,
19
+ socialInteractionsHandler: this.postSocialInteractionsHandler,
20
+ callbacks: {
21
+ attachmentClicked: this.callbacks.attachmentClicked,
22
+ shareClicked: this.sharingHandler ? () => this.sharingHandler?.share(streamId) : undefined
23
+ }
24
+ });
25
+ this.handlers.set(streamPageId, handler);
26
+ }
27
+ return handler;
28
+ };
29
+ getGeneralStreamPageActions = (data) => {
30
+ if (!this.sharingHandler) {
31
+ return [];
32
+ }
33
+ const { streamId, streamPageId } = data;
34
+ void streamPageId;
35
+ return [
36
+ {
37
+ icon: IconShare,
38
+ callback: () => this.sharingHandler?.share(streamId)
39
+ }
40
+ ];
41
+ };
42
+ }
@@ -0,0 +1 @@
1
+ export type { IStreamSharingHandler } from './sharing';
@@ -0,0 +1 @@
1
+ export {};
@@ -1,11 +1,14 @@
1
1
  <script lang="ts">import { ProportionalContainer } from '../../ui/proportional-container';
2
2
  import { generateStreamLayoutStyles } from './styles-transformer';
3
- let { model, children } = $props();
3
+ let { model, children, controls } = $props();
4
4
  </script>
5
5
 
6
6
  <ProportionalContainer ratio={9 / 16}>
7
7
  <div class="stream-page-layout" style={generateStreamLayoutStyles(model.styles)}>
8
8
  {@render children()}
9
+ {#if controls}
10
+ {@render controls()}
11
+ {/if}
9
12
  </div>
10
13
  </ProportionalContainer>
11
14
 
@@ -5,6 +5,7 @@ type Props = {
5
5
  styles: StreamLayoutStyles | null;
6
6
  };
7
7
  children: Snippet;
8
+ controls?: Snippet;
8
9
  };
9
10
  declare const Cmp: import("svelte").Component<Props, {}, "">;
10
11
  type Cmp = ReturnType<typeof Cmp>;
@@ -12,5 +12,6 @@ const localization = $derived(new ShortVideoStreamElementLocalization(locale));
12
12
  trackingParams={trackingParams ? { streamId: trackingParams.streamId, campaignId: trackingParams.campaignId } : false}
13
13
  autoplay={false}
14
14
  enableControls={false}
15
+ controlActions={[]}
15
16
  locale={localization.shortVideoViewerLocale}
16
17
  on={on} />
@@ -22,6 +22,7 @@ export const mapToPostModel = (model) => {
22
22
  viewsCount: model.header.postViewsCount
23
23
  },
24
24
  enableSocialInteractions: model.enableSocialInteractions,
25
+ articleId: null,
25
26
  ads: model.ad ? [mapToAdViewModel(model.ad)] : [],
26
27
  products: model.products.map(mapToProductCardModel)
27
28
  // uncomment if you want to test many products behavior
@@ -0,0 +1 @@
1
+ export type { IStreamSharingHandler } from './types';
@@ -0,0 +1 @@
1
+ export {};