@streamscloud/embeddable 13.3.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 (145) hide show
  1. package/dist/external-api/data-providers/internal-media-center-data-provider.svelte.js +6 -6
  2. package/dist/external-api/data-providers/mocks/index.d.ts +5 -0
  3. package/dist/external-api/data-providers/mocks/index.js +5 -0
  4. package/dist/{media-center/categories-following → external-api/data-providers/mocks}/mock-categories-following-handler.svelte.d.ts +1 -1
  5. package/dist/external-api/data-providers/mocks/mock-content-management-handler.svelte.d.ts +29 -0
  6. package/dist/external-api/data-providers/mocks/mock-content-management-handler.svelte.js +61 -0
  7. package/dist/{media-center/membership → external-api/data-providers/mocks}/mock-membership-handler.svelte.d.ts +1 -1
  8. package/dist/{media-center/navigation → external-api/data-providers/mocks}/mock-navigation-handler.svelte.d.ts +1 -2
  9. package/dist/{posts/social-interactions → external-api/data-providers/mocks}/mock-post-social-interactions-handler.svelte.d.ts +1 -2
  10. package/dist/{posts/social-interactions → external-api/data-providers/mocks}/mock-post-social-interactions-handler.svelte.js +17 -6
  11. package/dist/external-api/data-providers/mocks/operations.generated.d.ts +115 -0
  12. package/dist/external-api/data-providers/mocks/operations.generated.js +377 -0
  13. package/dist/external-api/data-providers/mocks/operations.graphql +18 -0
  14. package/dist/media-center/config/types.d.ts +7 -1
  15. package/dist/media-center/content-management/index.d.ts +1 -0
  16. package/dist/media-center/content-management/index.js +1 -0
  17. package/dist/media-center/content-management/types.d.ts +24 -0
  18. package/dist/media-center/content-management/types.js +1 -0
  19. package/dist/media-center/index.d.ts +2 -1
  20. package/dist/media-center/media-center/cmp.media-center-proxy.svelte +2 -2
  21. package/dist/media-center/media-center/discover/data-loading.d.ts +3 -0
  22. package/dist/media-center/media-center/discover/data-loading.js +13 -2
  23. package/dist/media-center/media-center/discover/discover-view-handler.svelte.d.ts +23 -0
  24. package/dist/media-center/media-center/discover/discover-view-handler.svelte.js +88 -0
  25. package/dist/media-center/media-center/discover/discover-view.svelte +79 -14
  26. package/dist/media-center/media-center/discover/discover-view.svelte.d.ts +2 -2
  27. package/dist/media-center/media-center/footer/media-center-footer.svelte +1 -1
  28. package/dist/media-center/media-center/handlers/index.d.ts +1 -0
  29. package/dist/media-center/media-center/handlers/index.js +1 -0
  30. package/dist/media-center/media-center/handlers/media-center-content-handler.svelte.d.ts +62 -0
  31. package/dist/media-center/media-center/handlers/media-center-content-handler.svelte.js +144 -0
  32. package/dist/media-center/media-center/header/media-center-header-mobile.svelte +10 -7
  33. package/dist/media-center/media-center/header/media-center-header.svelte +1 -1
  34. package/dist/media-center/media-center/media-center-context.svelte.d.ts +3 -2
  35. package/dist/media-center/media-center/media-center-context.svelte.js +30 -11
  36. package/dist/media-center/media-center/media-center-view.svelte +31 -13
  37. package/dist/media-center/media-center/menu/menu.svelte +13 -2
  38. package/dist/media-center/media-center/menu/menu.svelte.d.ts +1 -0
  39. package/dist/media-center/media-center/menu/popular-streams-panel-handler.svelte.d.ts +7 -0
  40. package/dist/media-center/media-center/menu/popular-streams-panel-handler.svelte.js +23 -8
  41. package/dist/media-center/media-center/moments/moments-feed-handler.svelte.d.ts +19 -2
  42. package/dist/media-center/media-center/moments/moments-feed-handler.svelte.js +51 -6
  43. package/dist/media-center/media-center/moments/moments-state.svelte.d.ts +2 -0
  44. package/dist/media-center/media-center/moments/moments-state.svelte.js +16 -1
  45. package/dist/media-center/media-center/posts-feed/posts-feed-handler.svelte.d.ts +24 -4
  46. package/dist/media-center/media-center/posts-feed/posts-feed-handler.svelte.js +90 -9
  47. package/dist/media-center/media-center/streams-feed/streams-feed-handler.svelte.d.ts +18 -3
  48. package/dist/media-center/media-center/streams-feed/streams-feed-handler.svelte.js +64 -9
  49. package/dist/posts/controls/index.d.ts +2 -1
  50. package/dist/posts/controls/index.js +2 -1
  51. package/dist/posts/controls/post-actions-generator.svelte.d.ts +20 -0
  52. package/dist/posts/controls/post-actions-generator.svelte.js +27 -0
  53. package/dist/posts/controls/post-actions-handler.svelte.d.ts +26 -0
  54. package/dist/posts/controls/post-actions-handler.svelte.js +56 -0
  55. package/dist/posts/index.d.ts +1 -0
  56. package/dist/posts/model/types.d.ts +1 -0
  57. package/dist/posts/post-viewer/cmp.post-viewer.svelte +6 -7
  58. package/dist/posts/post-viewer/cmp.post-viewer.svelte.d.ts +2 -2
  59. package/dist/posts/post-viewer/mapper.js +1 -0
  60. package/dist/posts/posts-player/cmp.posts-player.svelte +2 -1
  61. package/dist/posts/posts-player/cmp.posts-player.svelte.d.ts +2 -0
  62. package/dist/posts/posts-player/index.d.ts +2 -0
  63. package/dist/posts/posts-player/index.js +2 -1
  64. package/dist/posts/posts-player/posts-player-proxy.svelte +2 -1
  65. package/dist/posts/posts-player/posts-player-proxy.svelte.d.ts +3 -1
  66. package/dist/posts/posts-player/posts-player-view.svelte +127 -32
  67. package/dist/posts/posts-player/types.d.ts +8 -0
  68. package/dist/posts/sharing/index.d.ts +1 -0
  69. package/dist/posts/sharing/index.js +1 -0
  70. package/dist/posts/sharing/types.d.ts +5 -0
  71. package/dist/posts/sharing/types.js +1 -0
  72. package/dist/posts/social-interactions/types.d.ts +0 -1
  73. package/dist/streams/controls/index.d.ts +1 -0
  74. package/dist/streams/controls/index.js +1 -0
  75. package/dist/streams/controls/stream-actions-generator.svelte.d.ts +31 -0
  76. package/dist/streams/controls/stream-actions-generator.svelte.js +42 -0
  77. package/dist/streams/index.d.ts +1 -0
  78. package/dist/streams/index.js +1 -0
  79. package/dist/streams/layout/cmp.layout.svelte +4 -1
  80. package/dist/streams/layout/cmp.layout.svelte.d.ts +1 -0
  81. package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte +1 -0
  82. package/dist/streams/layout/models/mapper.js +1 -0
  83. package/dist/streams/sharing/index.d.ts +1 -0
  84. package/dist/streams/sharing/index.js +1 -0
  85. package/dist/streams/sharing/types.d.ts +5 -0
  86. package/dist/streams/sharing/types.js +1 -0
  87. package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte +43 -1
  88. package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte.d.ts +9 -0
  89. package/dist/streams/streams-player/cmp.streams-player.svelte +2 -1
  90. package/dist/streams/streams-player/cmp.streams-player.svelte.d.ts +2 -0
  91. package/dist/streams/streams-player/index.d.ts +2 -0
  92. package/dist/streams/streams-player/index.js +2 -1
  93. package/dist/streams/streams-player/streams-player-proxy.svelte +2 -1
  94. package/dist/streams/streams-player/streams-player-proxy.svelte.d.ts +2 -0
  95. package/dist/streams/streams-player/streams-player-view.svelte +147 -34
  96. package/dist/streams/streams-player/types.d.ts +7 -0
  97. package/dist/ui/card-actions/card-action-container.d.ts +2 -0
  98. package/dist/ui/card-actions/card-action-container.js +17 -0
  99. package/dist/ui/card-actions/cmp.card-action.svelte +28 -0
  100. package/dist/ui/card-actions/cmp.card-action.svelte.d.ts +10 -0
  101. package/dist/ui/card-actions/cmp.card-actions.svelte +71 -0
  102. package/dist/ui/card-actions/cmp.card-actions.svelte.d.ts +9 -0
  103. package/dist/ui/card-actions/index.d.ts +4 -0
  104. package/dist/ui/card-actions/index.js +3 -0
  105. package/dist/ui/card-actions/types.d.ts +9 -0
  106. package/dist/ui/card-actions/types.js +1 -0
  107. package/dist/ui/player/button/cmp.responsive-player-buttons-group.svelte +53 -0
  108. package/dist/ui/player/button/cmp.responsive-player-buttons-group.svelte.d.ts +10 -0
  109. package/dist/ui/player/button/index.d.ts +1 -0
  110. package/dist/ui/player/button/index.js +1 -0
  111. package/dist/{content-player → ui/player/content-player}/cmp.content-player.svelte +7 -29
  112. package/dist/{content-player → ui/player/content-player}/cmp.content-player.svelte.d.ts +6 -1
  113. package/dist/ui/player/content-player/content-player-config.svelte.d.ts +29 -0
  114. package/dist/ui/player/content-player/content-player-config.svelte.js +27 -0
  115. package/dist/{content-player → ui/player/content-player}/content-player-settings.svelte.d.ts +3 -3
  116. package/dist/{content-player → ui/player/content-player}/content-player-settings.svelte.js +2 -2
  117. package/dist/{content-player → ui/player/content-player}/controls-and-attachments.svelte +18 -65
  118. package/dist/{content-player → ui/player/content-player}/controls-and-attachments.svelte.d.ts +6 -0
  119. package/dist/{content-player → ui/player/content-player}/overview-panel.svelte +1 -1
  120. package/dist/{content-player → ui/player/content-player}/ui-manager.svelte.d.ts +3 -2
  121. package/dist/{content-player → ui/player/content-player}/ui-manager.svelte.js +3 -2
  122. package/dist/ui/player/providers/chunks-player-buffer/player-chunk-item.svelte.d.ts +0 -2
  123. package/dist/ui/player/providers/chunks-player-buffer/player-chunk-item.svelte.js +1 -3
  124. package/dist/ui/player/providers/chunks-player-buffer/player-chunk.svelte.d.ts +3 -2
  125. package/dist/ui/player/providers/chunks-player-buffer/player-chunk.svelte.js +11 -5
  126. package/dist/ui/player/providers/chunks-player-buffer/player-chunks-manager.svelte.d.ts +3 -0
  127. package/dist/ui/player/providers/chunks-player-buffer/player-chunks-manager.svelte.js +74 -8
  128. package/dist/ui/player/providers/default-chunks-player-buffer.svelte.d.ts +2 -0
  129. package/dist/ui/player/providers/default-chunks-player-buffer.svelte.js +15 -4
  130. package/dist/ui/player/providers/default-feed-player-buffer.svelte.d.ts +1 -0
  131. package/dist/ui/player/providers/default-feed-player-buffer.svelte.js +27 -5
  132. package/dist/ui/player/providers/types.d.ts +1 -0
  133. package/dist/ui/shadow-dom/cmp.shadow-root.svelte +9 -4
  134. package/dist/ui/shadow-dom/colors.scss +2 -0
  135. package/package.json +6 -2
  136. package/dist/content-player/content-player-config.svelte.d.ts +0 -51
  137. package/dist/content-player/content-player-config.svelte.js +0 -48
  138. package/dist/posts/controls/cmp.controls.svelte +0 -120
  139. package/dist/posts/controls/cmp.controls.svelte.d.ts +0 -16
  140. /package/dist/{media-center/categories-following → external-api/data-providers/mocks}/mock-categories-following-handler.svelte.js +0 -0
  141. /package/dist/{media-center/membership → external-api/data-providers/mocks}/mock-membership-handler.svelte.js +0 -0
  142. /package/dist/{media-center/navigation → external-api/data-providers/mocks}/mock-navigation-handler.svelte.js +0 -0
  143. /package/dist/{content-player → ui/player/content-player}/index.d.ts +0 -0
  144. /package/dist/{content-player → ui/player/content-player}/index.js +0 -0
  145. /package/dist/{content-player → ui/player/content-player}/overview-panel.svelte.d.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  import { Utils } from '../../../core/utils';
2
2
  import { StreamsPlayerBuffer } from '../../../streams/streams-player/streams-player-buffer.svelte';
3
- import { MediaCenterSettingsHandler } from '../handlers';
3
+ import { MediaCenterContentHandler, MediaCenterSettingsHandler } from '../handlers';
4
4
  import { FeedProvidersGenerator } from './feed-providers-generator';
5
5
  export class StreamsFeedHandler {
6
6
  _state = $state('inactive');
@@ -8,12 +8,14 @@ export class StreamsFeedHandler {
8
8
  _feedPlayerData = $state.raw(null);
9
9
  _dataProvider;
10
10
  _mediaCenterSettingsHandler;
11
+ _mediaCenterContentHandler;
11
12
  _closeOrchestrator;
12
13
  _callbacks;
13
14
  constructor(data) {
14
- const { dataProvider, mediaCenterSettingsHandler, closeOrchestrator, on } = data;
15
+ const { dataProvider, mediaCenterSettingsHandler, mediaCenterContentHandler, closeOrchestrator, on } = data;
15
16
  this._providersGenerator = new FeedProvidersGenerator(dataProvider);
16
17
  this._mediaCenterSettingsHandler = mediaCenterSettingsHandler;
18
+ this._mediaCenterContentHandler = mediaCenterContentHandler;
17
19
  this._dataProvider = dataProvider;
18
20
  this._closeOrchestrator = closeOrchestrator;
19
21
  this._callbacks = on;
@@ -30,11 +32,43 @@ export class StreamsFeedHandler {
30
32
  get feedPlayerProps() {
31
33
  return this._feedPlayerData?.props || null;
32
34
  }
35
+ get feedBuffer() {
36
+ if (!this._feedPlayerData) {
37
+ return null;
38
+ }
39
+ const buffer = this._feedPlayerData.props.dataProvider.type === 'buffer' ? this._feedPlayerData.props.dataProvider.buffer : null;
40
+ return buffer;
41
+ }
42
+ get managementActions() {
43
+ return {
44
+ editStream: this._mediaCenterContentHandler.editStream,
45
+ deleteStreamPage: this._mediaCenterContentHandler.deleteStreamPage
46
+ };
47
+ }
48
+ get canReload() {
49
+ switch (this._state) {
50
+ case 'ready': {
51
+ if (!this.feedBuffer) {
52
+ return true;
53
+ }
54
+ return this.feedBuffer.currentIndex > 0;
55
+ }
56
+ case 'inactive': {
57
+ return true;
58
+ }
59
+ case 'loading': {
60
+ return false;
61
+ }
62
+ default: {
63
+ Utils.assertUnreachable(this._state);
64
+ }
65
+ }
66
+ }
33
67
  deactivate = () => {
34
68
  this._state = 'inactive';
35
69
  this._feedPlayerData = null;
36
70
  };
37
- activateWithExistingProvider = async (data) => {
71
+ activateWithDataProvider = async (data) => {
38
72
  const { dataProvider, onStreamActivated } = data;
39
73
  const on = {
40
74
  streamActivated: (data) => {
@@ -60,8 +94,8 @@ export class StreamsFeedHandler {
60
94
  }
61
95
  };
62
96
  activate = async (options) => {
63
- const { filter, init } = options;
64
- if (init?.initialStreamPageId && this.tryRestoreState(init.initialStreamPageId, filter)) {
97
+ const { filter, init, tryRestoreState } = options;
98
+ if (tryRestoreState && init?.initialStreamPageId && this.tryRestoreState(init.initialStreamPageId, filter)) {
65
99
  // Already active with the requested buffer
66
100
  return;
67
101
  }
@@ -83,22 +117,43 @@ export class StreamsFeedHandler {
83
117
  this._state = 'ready';
84
118
  }
85
119
  };
120
+ onStreamModified = (data) => {
121
+ if (this._state !== 'ready') {
122
+ return false;
123
+ }
124
+ const streamStillInTheFeed = data.isPublished && (!this._feedPlayerData?.filter.categoryId || data.categories.includes(this._feedPlayerData.filter.categoryId));
125
+ if (streamStillInTheFeed) {
126
+ this.activate({
127
+ filter: this._feedPlayerData?.filter,
128
+ init: { initialStreamId: data.stream.id, prefetchedStreams: [data.stream] }
129
+ });
130
+ }
131
+ else {
132
+ this.feedBuffer?.removeChunkById(data.stream.id);
133
+ }
134
+ };
135
+ onStreamPageDeleted = (data) => {
136
+ if (this._state !== 'ready') {
137
+ return false;
138
+ }
139
+ this.feedBuffer?.removeItemById(data.id);
140
+ };
86
141
  tryRestoreState = (initialStreamPageId, filter) => {
87
142
  if (this._state !== 'ready' || !this._feedPlayerData || !Utils.areEqual(this._feedPlayerData.filter, filter)) {
88
143
  return false;
89
144
  }
90
- const buffer = this._feedPlayerData.props.dataProvider.type === 'buffer' ? this._feedPlayerData.props.dataProvider.buffer : null;
91
- if (!buffer) {
145
+ if (!this.feedBuffer) {
92
146
  return false;
93
147
  }
94
- return buffer.tryActivateItemById(initialStreamPageId);
148
+ return this.feedBuffer.tryActivateItemById(initialStreamPageId);
95
149
  };
96
150
  makeStreamsPlayerProps = (data) => {
97
151
  const { dataProvider, on } = data;
98
152
  return {
99
153
  dataProvider: { type: 'buffer', buffer: new StreamsPlayerBuffer(dataProvider) },
100
154
  analyticsHandler: this._dataProvider.handlers?.analyticsHandler,
101
- postSocialInteractionsHandler: this._dataProvider.handlers?.socialInteractionsHandler,
155
+ postSocialInteractionsHandler: this._dataProvider.handlers?.postSocialInteractionsHandler,
156
+ sharingHandler: this._dataProvider.handlers?.streamSharingHandler,
102
157
  playerSettings: this._mediaCenterSettingsHandler.playerSettings,
103
158
  closeOrchestrator: this._closeOrchestrator,
104
159
  on: {
@@ -1 +1,2 @@
1
- export { default as PostControls } from './cmp.controls.svelte';
1
+ export { PostActionsGenerator } from './post-actions-generator.svelte';
2
+ export { PostActionsHandler } from './post-actions-handler.svelte';
@@ -1 +1,2 @@
1
- export { default as PostControls } from './cmp.controls.svelte';
1
+ export { PostActionsGenerator } from './post-actions-generator.svelte';
2
+ export { PostActionsHandler } from './post-actions-handler.svelte';
@@ -0,0 +1,20 @@
1
+ import type { PostModel } from '../model';
2
+ import type { IPostSharingHandler } from '../sharing';
3
+ import type { IPostSocialInteractionsHandler } from '../social-interactions';
4
+ import { PostActionsHandler } from './post-actions-handler.svelte';
5
+ export declare class PostActionsGenerator {
6
+ private socialInteractionsHandler;
7
+ private sharingHandler;
8
+ private callbacks;
9
+ private handlers;
10
+ constructor(init: {
11
+ socialInteractionsHandler: IPostSocialInteractionsHandler | undefined;
12
+ sharingHandler: IPostSharingHandler | undefined;
13
+ on: PostActionCallbacks;
14
+ });
15
+ getPostActionsHandler: (model: PostModel) => PostActionsHandler;
16
+ }
17
+ type PostActionCallbacks = {
18
+ attachmentClicked: () => void;
19
+ };
20
+ export {};
@@ -0,0 +1,27 @@
1
+ import { PostActionsHandler } from './post-actions-handler.svelte';
2
+ export class PostActionsGenerator {
3
+ socialInteractionsHandler;
4
+ sharingHandler;
5
+ callbacks;
6
+ handlers = new Map();
7
+ constructor(init) {
8
+ this.socialInteractionsHandler = init.socialInteractionsHandler ?? null;
9
+ this.sharingHandler = init.sharingHandler ?? null;
10
+ this.callbacks = init.on;
11
+ }
12
+ getPostActionsHandler = (model) => {
13
+ let handler = this.handlers.get(model.id);
14
+ if (!handler) {
15
+ handler = new PostActionsHandler({
16
+ post: model,
17
+ socialInteractionsHandler: this.socialInteractionsHandler,
18
+ callbacks: {
19
+ attachmentClicked: this.callbacks.attachmentClicked,
20
+ shareClicked: this.sharingHandler ? () => this.sharingHandler?.share(model.id) : undefined
21
+ }
22
+ });
23
+ this.handlers.set(model.id, handler);
24
+ }
25
+ return handler;
26
+ };
27
+ }
@@ -0,0 +1,26 @@
1
+ import type { PostModel } from '../model';
2
+ import type { IPostSocialInteractionsHandler } from '../social-interactions';
3
+ import { IconColor } from '../../ui/icon';
4
+ export declare class PostActionsHandler {
5
+ readonly actions: PostAction[];
6
+ private post;
7
+ private socialInteractionsHandler;
8
+ private callbacks;
9
+ private isLikedStore;
10
+ constructor(init: {
11
+ post: PostModel;
12
+ socialInteractionsHandler: IPostSocialInteractionsHandler | null;
13
+ callbacks: PostActionCallbacks;
14
+ });
15
+ private initIsLikedStore;
16
+ }
17
+ type PostAction = {
18
+ icon: string;
19
+ iconColor?: IconColor;
20
+ callback: () => void;
21
+ };
22
+ type PostActionCallbacks = {
23
+ attachmentClicked: () => void;
24
+ shareClicked?: () => void;
25
+ };
26
+ export {};
@@ -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;
@@ -96,6 +82,115 @@ const contentPlayerConfig = new ContentPlayerConfig({
96
82
  }
97
83
  }
98
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
+ });
99
151
  </script>
100
152
 
101
- <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>