@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,4 +1,5 @@
1
1
  import { Deferred } from '../../../core/deferred';
2
+ import { PostType } from '../../../core/enums';
2
3
  import { DiscoverDataLoader } from './data-loading';
3
4
  import { ShortVideosInCategory, StreamsInCategory } from './types.svelte';
4
5
  export class DiscoverViewHandler {
@@ -111,4 +112,91 @@ export class DiscoverViewHandler {
111
112
  this._state = 'inactive';
112
113
  this._shortVideosLoadingDeferred = null;
113
114
  };
115
+ onPostCreated = (data) => {
116
+ if (!data.isPublished || data.post.postType !== PostType.ShortVideo) {
117
+ return;
118
+ }
119
+ const affectedHolders = this._shortVideosInCategoryCache.filter((x) => data.categories.includes(x.categoryId) && x.continuationToken !== undefined);
120
+ for (const holder of affectedHolders) {
121
+ holder.shortVideos = [data.post, ...holder.shortVideos];
122
+ }
123
+ };
124
+ onPostModified = (data) => {
125
+ const { post, categories, isPublished } = data;
126
+ for (const holder of this._shortVideosInCategory.filter((h) => h.continuationToken !== undefined)) {
127
+ const index = holder.shortVideos.findIndex((x) => x.id === post.id);
128
+ const isInCategory = categories.includes(holder.categoryId);
129
+ if (index !== -1) {
130
+ // Post exists in holder
131
+ if (isInCategory && isPublished) {
132
+ // Post remains in category and is published - update it
133
+ const clone = [...holder.shortVideos];
134
+ clone[index] = post;
135
+ holder.shortVideos = clone;
136
+ }
137
+ else {
138
+ // Post no longer in category or unpublished - remove it
139
+ holder.shortVideos = holder.shortVideos.filter((x) => x.id !== post.id);
140
+ if (holder.shortVideos.length < this._dataLoader.minItemsPerLoad) {
141
+ this._dataLoader.loadShortVideos(holder);
142
+ }
143
+ }
144
+ }
145
+ else {
146
+ // Post doesn't exist in holder
147
+ if (isInCategory && isPublished) {
148
+ // Post should be in this category - reset and reload
149
+ holder.continuationToken = undefined;
150
+ this._dataLoader.reloadShortVideos(holder);
151
+ }
152
+ }
153
+ }
154
+ };
155
+ onPostDeleted = (data) => {
156
+ for (const holder of this._shortVideosInCategoryCache) {
157
+ holder.shortVideos = holder.shortVideos.filter((x) => x.id !== data.id);
158
+ if (holder.shortVideos.length < this._dataLoader.minItemsPerLoad) {
159
+ this._dataLoader.loadShortVideos(holder);
160
+ }
161
+ }
162
+ };
163
+ onStreamModified = (data) => {
164
+ const { stream, categories, isPublished } = data;
165
+ for (const holder of this._streamsInCategoryCache.filter((h) => h.continuationToken !== undefined)) {
166
+ const index = holder.streams.findIndex((x) => x.id === stream.id);
167
+ const isInCategory = holder.categoryId === null || categories.includes(holder.categoryId);
168
+ if (index !== -1) {
169
+ // Stream exists in holder
170
+ if (isInCategory && isPublished) {
171
+ // Stream remains in category and is published - update it
172
+ const clone = [...holder.streams];
173
+ clone[index] = stream;
174
+ holder.streams = clone;
175
+ }
176
+ else {
177
+ // Stream no longer in category or unpublished - remove it
178
+ holder.streams = holder.streams.filter((x) => x.id !== stream.id);
179
+ if (holder.streams.length < this._dataLoader.minItemsPerLoad) {
180
+ this._dataLoader.loadStreams(holder);
181
+ }
182
+ }
183
+ }
184
+ else {
185
+ // Stream doesn't exist in holder
186
+ if (isInCategory && isPublished) {
187
+ // Stream should be in this category - reset and reload
188
+ holder.continuationToken = undefined;
189
+ this._dataLoader.loadStreams(holder);
190
+ }
191
+ }
192
+ }
193
+ };
194
+ onStreamDeleted = (data) => {
195
+ for (const holder of this._streamsInCategoryCache) {
196
+ holder.streams = holder.streams.filter((x) => x.id !== data.id);
197
+ if (holder.streams.length < this._dataLoader.minItemsPerLoad) {
198
+ this._dataLoader.loadStreams(holder);
199
+ }
200
+ }
201
+ };
114
202
  }
@@ -1,12 +1,71 @@
1
- <script lang="ts">import { getPostCoverImage } from '../../../posts/model';
1
+ <script lang="ts">var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { getPostCoverImage } from '../../../posts/model';
2
11
  import { ShortVideoCard } from '../../../short-videos/short-video-card';
3
12
  import { StreamCard } from '../../../streams/stream-card';
13
+ import { cardActionContainer, CardActions } from '../../../ui/card-actions';
14
+ import { IconColor } from '../../../ui/icon';
4
15
  import { InfiniteScrolling } from '../../../ui/infinite-scrolling';
5
16
  import { default as Header } from './discover-header.svelte';
6
17
  import { DiscoverViewLocalization } from './discover-view-localization';
18
+ import IconDelete from '@fluentui/svg-icons/icons/delete_20_regular.svg?raw';
19
+ import IconEdit from '@fluentui/svg-icons/icons/edit_20_regular.svg?raw';
7
20
  let { context, on } = $props();
8
21
  const handler = $derived(context.discoverHandler);
9
22
  const localization = $derived(new DiscoverViewLocalization(context.locale));
23
+ const generateShortVideoActions = (id) => {
24
+ const actions = [];
25
+ if (context.contentManagementHandler.editPost) {
26
+ actions.push({
27
+ icon: IconEdit,
28
+ callback: () => __awaiter(void 0, void 0, void 0, function* () {
29
+ var _a, _b;
30
+ (_b = (_a = context.contentManagementHandler).editPost) === null || _b === void 0 ? void 0 : _b.call(_a, id);
31
+ })
32
+ });
33
+ }
34
+ if (context.contentManagementHandler.deletePost) {
35
+ actions.push({
36
+ icon: IconDelete,
37
+ iconColor: IconColor.Red,
38
+ callback: () => __awaiter(void 0, void 0, void 0, function* () {
39
+ var _a, _b;
40
+ (_b = (_a = context.contentManagementHandler).deletePost) === null || _b === void 0 ? void 0 : _b.call(_a, id);
41
+ })
42
+ });
43
+ }
44
+ return actions;
45
+ };
46
+ const genereateStreamActions = (id) => {
47
+ const actions = [];
48
+ if (context.contentManagementHandler.editStream) {
49
+ actions.push({
50
+ icon: IconEdit,
51
+ callback: () => {
52
+ var _a, _b;
53
+ (_b = (_a = context.contentManagementHandler).editStream) === null || _b === void 0 ? void 0 : _b.call(_a, id);
54
+ }
55
+ });
56
+ }
57
+ if (context.contentManagementHandler.deleteStream) {
58
+ actions.push({
59
+ icon: IconDelete,
60
+ iconColor: IconColor.Red,
61
+ callback: () => __awaiter(void 0, void 0, void 0, function* () {
62
+ var _a, _b;
63
+ (_b = (_a = context.contentManagementHandler).deleteStream) === null || _b === void 0 ? void 0 : _b.call(_a, id);
64
+ })
65
+ });
66
+ }
67
+ return actions;
68
+ };
10
69
  </script>
11
70
 
12
71
  <div class="media-center-discover">
@@ -17,9 +76,12 @@ const localization = $derived(new DiscoverViewLocalization(context.locale));
17
76
  <div class="media-center-discover__section-header">
18
77
  {localization.latestStreamsSectionTitle}
19
78
  </div>
20
- <div class="media-center-discover__section-content media-center-discover__section-content--5">
79
+ <div class="media-center-discover__section-content media-center-discover__section-content--5 media-center-discover__section-content--not-alone">
21
80
  {#each handler.streamsHolder.streams as item (item.id)}
22
- <StreamCard stream={item} on={{ click: () => on.streamSelected(item) }}></StreamCard>
81
+ <div use:cardActionContainer>
82
+ <StreamCard stream={item} on={{ click: () => on.streamSelected(item, handler.streamsHolder?.categoryId ?? null) }}></StreamCard>
83
+ <CardActions actions={genereateStreamActions(item.id)} />
84
+ </div>
23
85
  {/each}
24
86
  </div>
25
87
  </div>
@@ -39,17 +101,20 @@ const localization = $derived(new DiscoverViewLocalization(context.locale));
39
101
  class:media-center-discover__section-content--4={index % 2 === 0}
40
102
  class:media-center-discover__section-content--not-alone={handler.shortVideosHolders.length > 1}>
41
103
  {#each holder.shortVideos as item (item.id)}
42
- <ShortVideoCard
43
- shortVideo={{
44
- id: item.id,
45
- text: item.text,
46
- cover: getPostCoverImage(item),
47
- displayDate: item.displayDate,
48
- viewsCount: item.viewsCount,
49
- products: item.products
50
- }}
51
- locale={context.locale}
52
- on={{ click: () => on.shortVideoSelected(item) }} />
104
+ <div use:cardActionContainer>
105
+ <ShortVideoCard
106
+ shortVideo={{
107
+ id: item.id,
108
+ text: item.text,
109
+ cover: getPostCoverImage(item),
110
+ displayDate: item.displayDate,
111
+ viewsCount: item.viewsCount,
112
+ products: item.products
113
+ }}
114
+ locale={context.locale}
115
+ on={{ click: () => on.shortVideoSelected(item, holder.categoryId) }} />
116
+ <CardActions actions={generateShortVideoActions(item.id)} />
117
+ </div>
53
118
  {/each}
54
119
  </div>
55
120
  </div>
@@ -4,8 +4,8 @@ import type { MediaCenterContext } from '../media-center-context.svelte';
4
4
  type Props = {
5
5
  context: MediaCenterContext;
6
6
  on: {
7
- shortVideoSelected: (shortVideo: PostPlayerModel) => void;
8
- streamSelected: (stream: StreamPlayerModel) => void;
7
+ shortVideoSelected: (shortVideo: PostPlayerModel, categoryId: string | null) => void;
8
+ streamSelected: (stream: StreamPlayerModel, categoryId: string | null) => void;
9
9
  };
10
10
  };
11
11
  declare const DiscoverView: import("svelte").Component<Props, {}, "">;
@@ -12,7 +12,7 @@ let { context } = $props();
12
12
  type="button"
13
13
  class="media-center-footer__button"
14
14
  class:media-center-footer__button--active={context.postsFeedHandler.activated || context.streamsFeedHandler.activated}
15
- onclick={() => context.playRootFeed()}>
15
+ onclick={() => context.activateDefaultFeed()}>
16
16
  <Icon src={IconPhone} />
17
17
  </button>
18
18
  <div class="media-center-footer__spacer"></div>
@@ -1,3 +1,4 @@
1
1
  export { CategoriesHandler } from './categories-handler.svelte';
2
2
  export type { MediaCenterCategoryModel, MediaCenterSubCategoryModel, MediaCenterCategoryTagModel } from './categories-handler.svelte';
3
3
  export { MediaCenterSettingsHandler } from './media-center-settings-handler.svelte';
4
+ export { MediaCenterContentHandler } from './media-center-content-handler.svelte';
@@ -1,2 +1,3 @@
1
1
  export { CategoriesHandler } from './categories-handler.svelte';
2
2
  export { MediaCenterSettingsHandler } from './media-center-settings-handler.svelte';
3
+ export { MediaCenterContentHandler } from './media-center-content-handler.svelte';
@@ -0,0 +1,62 @@
1
+ import type { IMediaCenterDataProvider } from '../../config/types';
2
+ import type { PostPlayerModel } from '../../../posts/posts-player/types';
3
+ import type { StreamPlayerModel } from '../../../streams/streams-player/types';
4
+ export declare class MediaCenterContentHandler {
5
+ private readonly dataProvider;
6
+ private postCreatedListeners;
7
+ private postDeletedListeners;
8
+ private postModifiedListeners;
9
+ private streamModifiedListeners;
10
+ private streamDeletedListeners;
11
+ private streamPageDeletedListeners;
12
+ constructor(dataProvider: IMediaCenterDataProvider);
13
+ get editPost(): ((postId: string) => Promise<{
14
+ post: PostPlayerModel;
15
+ categories: string[];
16
+ isPublished: boolean;
17
+ } | null>) | null;
18
+ get deletePost(): ((postId: string) => Promise<boolean>) | null;
19
+ get editArticle(): ((postId: string) => Promise<{
20
+ post: PostPlayerModel;
21
+ categories: string[];
22
+ isPublished: boolean;
23
+ } | null>) | null;
24
+ get editStream(): ((streamId: string) => Promise<{
25
+ stream: StreamPlayerModel;
26
+ categories: string[];
27
+ isPublished: boolean;
28
+ } | null>) | null;
29
+ get deleteStream(): ((streamId: string) => Promise<boolean>) | null;
30
+ get deleteStreamPage(): ((streamPageId: string) => Promise<boolean>) | null;
31
+ addPostCreatedListener: (...callbacks: PostCreatedCallback[]) => void;
32
+ addPostModifiedListener: (...callbacks: PostModifiedCallback[]) => void;
33
+ addPostDeletedListener: (...callbacks: PostDeletedCallback[]) => void;
34
+ addStreamModifiedListener: (...callbacks: StreamModifiedCallback[]) => void;
35
+ addStreamDeletedListener: (...callbacks: StreamDeletedCallback[]) => void;
36
+ addStreamPageDeletedListener: (...callbacks: StreamPageDeletedCallback[]) => void;
37
+ }
38
+ type PostCreatedCallback = (data: {
39
+ post: PostPlayerModel;
40
+ categories: string[];
41
+ isPublished: boolean;
42
+ }) => void;
43
+ type PostModifiedCallback = (data: {
44
+ post: PostPlayerModel;
45
+ categories: string[];
46
+ isPublished: boolean;
47
+ }) => void;
48
+ type PostDeletedCallback = (data: {
49
+ id: string;
50
+ }) => void;
51
+ type StreamModifiedCallback = (data: {
52
+ stream: StreamPlayerModel;
53
+ categories: string[];
54
+ isPublished: boolean;
55
+ }) => void;
56
+ type StreamDeletedCallback = (data: {
57
+ id: string;
58
+ }) => void;
59
+ type StreamPageDeletedCallback = (data: {
60
+ id: string;
61
+ }) => void;
62
+ export {};
@@ -0,0 +1,144 @@
1
+ export class MediaCenterContentHandler {
2
+ dataProvider;
3
+ postCreatedListeners = [];
4
+ postDeletedListeners = [];
5
+ postModifiedListeners = [];
6
+ streamModifiedListeners = [];
7
+ streamDeletedListeners = [];
8
+ streamPageDeletedListeners = [];
9
+ constructor(dataProvider) {
10
+ this.dataProvider = dataProvider;
11
+ $effect(() => {
12
+ if (this.dataProvider.handlers?.contentManagementHandler) {
13
+ this.dataProvider.handlers.contentManagementHandler.onHandlerMounted({
14
+ postCreated: (result) => {
15
+ const { post, categories, isPublished } = result;
16
+ this.postCreatedListeners.forEach((callback) => {
17
+ callback({ post, categories, isPublished });
18
+ });
19
+ }
20
+ });
21
+ }
22
+ });
23
+ }
24
+ get editPost() {
25
+ const originalFn = this.dataProvider.handlers?.contentManagementHandler?.editPost;
26
+ if (!originalFn) {
27
+ return null;
28
+ }
29
+ return async (...args) => {
30
+ const result = await originalFn(...args);
31
+ if (result) {
32
+ this.postModifiedListeners.forEach((callback) => {
33
+ callback({
34
+ post: result.post,
35
+ categories: result.categories,
36
+ isPublished: result.isPublished
37
+ });
38
+ });
39
+ }
40
+ return result;
41
+ };
42
+ }
43
+ get deletePost() {
44
+ const originalFn = this.dataProvider.handlers?.contentManagementHandler?.deletePost;
45
+ if (!originalFn) {
46
+ return null;
47
+ }
48
+ return async (...args) => {
49
+ const result = await originalFn(...args);
50
+ if (result) {
51
+ this.postDeletedListeners.forEach((callback) => {
52
+ callback({ id: args[0] });
53
+ });
54
+ }
55
+ return result;
56
+ };
57
+ }
58
+ get editArticle() {
59
+ const originalFn = this.dataProvider.handlers?.contentManagementHandler?.editArticle;
60
+ if (!originalFn) {
61
+ return null;
62
+ }
63
+ return async (...args) => {
64
+ const result = await originalFn(...args);
65
+ if (result) {
66
+ this.postModifiedListeners.forEach((callback) => {
67
+ callback({
68
+ post: result.post,
69
+ categories: result.categories,
70
+ isPublished: result.isPublished
71
+ });
72
+ });
73
+ }
74
+ return result;
75
+ };
76
+ }
77
+ get editStream() {
78
+ const originalFn = this.dataProvider.handlers?.contentManagementHandler?.editStream;
79
+ if (!originalFn) {
80
+ return null;
81
+ }
82
+ return async (...args) => {
83
+ const result = await originalFn(...args);
84
+ if (result) {
85
+ this.streamModifiedListeners.forEach((callback) => {
86
+ callback({
87
+ stream: result.stream,
88
+ categories: result.categories,
89
+ isPublished: result.isPublished
90
+ });
91
+ });
92
+ }
93
+ return result;
94
+ };
95
+ }
96
+ get deleteStream() {
97
+ const originalFn = this.dataProvider.handlers?.contentManagementHandler?.deleteStream;
98
+ if (!originalFn) {
99
+ return null;
100
+ }
101
+ return async (...args) => {
102
+ const result = await originalFn(...args);
103
+ if (result) {
104
+ this.streamDeletedListeners.forEach((callback) => {
105
+ callback({ id: args[0] });
106
+ });
107
+ }
108
+ return result;
109
+ };
110
+ }
111
+ get deleteStreamPage() {
112
+ const originalFn = this.dataProvider.handlers?.contentManagementHandler?.deleteStreamPage;
113
+ if (!originalFn) {
114
+ return null;
115
+ }
116
+ return async (...args) => {
117
+ const result = await originalFn(...args);
118
+ if (result) {
119
+ this.streamPageDeletedListeners.forEach((callback) => {
120
+ callback({ id: args[0] });
121
+ });
122
+ }
123
+ return result;
124
+ };
125
+ }
126
+ addPostCreatedListener = (...callbacks) => {
127
+ this.postCreatedListeners.push(...callbacks);
128
+ };
129
+ addPostModifiedListener = (...callbacks) => {
130
+ this.postModifiedListeners.push(...callbacks);
131
+ };
132
+ addPostDeletedListener = (...callbacks) => {
133
+ this.postDeletedListeners.push(...callbacks);
134
+ };
135
+ addStreamModifiedListener = (...callbacks) => {
136
+ this.streamModifiedListeners.push(...callbacks);
137
+ };
138
+ addStreamDeletedListener = (...callbacks) => {
139
+ this.streamDeletedListeners.push(...callbacks);
140
+ };
141
+ addStreamPageDeletedListener = (...callbacks) => {
142
+ this.streamPageDeletedListeners.push(...callbacks);
143
+ };
144
+ }
@@ -20,13 +20,13 @@ const headerMounted = (node) => {
20
20
  </script>
21
21
 
22
22
  <div class="media-center-header-mobile" class:media-center-header-mobile--static={context.mediaCenterMode === 'discover'} use:headerMounted>
23
- {#if context.closeOrchestrator.closeTriggerVisible}
24
- <button type="button" class="media-center-header-mobile__button" onclick={context.closeOrchestrator.requestClose}>
25
- <Icon src={IconDismiss} />
26
- </button>
27
- {:else}
28
- <span><!--just a stub--></span>
29
- {/if}
23
+ <button
24
+ type="button"
25
+ class="media-center-header-mobile__button"
26
+ class:media-center-header-mobile__button--hidden={!context.closeOrchestrator.closeTriggerVisible}
27
+ onclick={context.closeOrchestrator.requestClose}>
28
+ <Icon src={IconDismiss} />
29
+ </button>
30
30
  {#if context.mediaCenterMode === 'discover'}
31
31
  <div class="media-center-header-mobile__title">
32
32
  {localization.discoverLabel}
@@ -78,4 +78,7 @@ const headerMounted = (node) => {
78
78
  --icon--color: var(--sc-mc-color--icon-overlay);
79
79
  --icon--filter: var(--sc-mc-color--icon-overlay-shadow);
80
80
  line-height: 0;
81
+ }
82
+ .media-center-header-mobile__button--hidden {
83
+ visibility: hidden;
81
84
  }</style>
@@ -146,7 +146,7 @@ const styles = $derived.by(() => {
146
146
  type="button"
147
147
  class="control-button"
148
148
  class:control-button--active={context.postsFeedHandler.activated || context.streamsFeedHandler.activated}
149
- onclick={() => context.playRootFeed()}>
149
+ onclick={() => context.activateDefaultFeed()}>
150
150
  <span class="control-button__icon" class:control-button__icon--active={context.postsFeedHandler.activated || context.streamsFeedHandler.activated}>
151
151
  <Icon src={IconPhone} />
152
152
  </span>
@@ -2,7 +2,7 @@ import type { IMediaCenterDataProvider } from '../config/types';
2
2
  import type { MediaCenterState } from '../navigation';
3
3
  import type { ICloseOrchestrator } from '../../ui/player/close-orchestrator';
4
4
  import { DiscoverViewHandler } from './discover';
5
- import { CategoriesHandler, MediaCenterSettingsHandler } from './handlers';
5
+ import { CategoriesHandler, MediaCenterContentHandler, MediaCenterSettingsHandler } from './handlers';
6
6
  import type { MediaCenterSettings } from './media-center-settings.svelte';
7
7
  import { PopularStreamsPanelHandler } from './menu';
8
8
  import { MomentsFeedHandler } from './moments';
@@ -23,6 +23,7 @@ export declare class MediaCenterContext {
23
23
  popularStreamsHandler: PopularStreamsPanelHandler;
24
24
  streamsInCategoryHandler: StreamsInCategoryPanelHandler;
25
25
  settingsHandler: MediaCenterSettingsHandler;
26
+ contentManagementHandler: MediaCenterContentHandler;
26
27
  closeOrchestrator: ICloseOrchestrator;
27
28
  private _dataProvider;
28
29
  private _currentState;
@@ -54,7 +55,7 @@ export declare class MediaCenterContext {
54
55
  playPostsFeed: (options: Parameters<PostsFeedHandler["activate"]>[0]) => Promise<void>;
55
56
  playStreamsFeed: (options: Parameters<StreamsFeedHandler["activate"]>[0]) => Promise<void>;
56
57
  playMoments: (options?: Parameters<MomentsFeedHandler["activate"]>[0]) => Promise<void>;
57
- playRootFeed: () => Promise<void>;
58
+ activateDefaultFeed: () => Promise<void>;
58
59
  tryActivateStreamsInCategory: (categoryId: string) => Promise<void>;
59
60
  restoreState: (state: MediaCenterState) => Promise<void>;
60
61
  handleNavigationStateChanged: (state: MediaCenterState) => void;
@@ -1,6 +1,6 @@
1
1
  import { Utils } from '../../core/utils';
2
2
  import { DiscoverViewHandler } from './discover';
3
- import { CategoriesHandler, MediaCenterSettingsHandler } from './handlers';
3
+ import { CategoriesHandler, MediaCenterContentHandler, MediaCenterSettingsHandler } from './handlers';
4
4
  import { PopularStreamsPanelHandler } from './menu';
5
5
  import { MomentsFeedHandler } from './moments';
6
6
  import { PostsFeedHandler } from './posts-feed';
@@ -34,6 +34,7 @@ export class MediaCenterContext {
34
34
  popularStreamsHandler;
35
35
  streamsInCategoryHandler;
36
36
  settingsHandler;
37
+ contentManagementHandler;
37
38
  closeOrchestrator;
38
39
  _dataProvider;
39
40
  _currentState = null;
@@ -43,15 +44,18 @@ export class MediaCenterContext {
43
44
  this.closeOrchestrator = closeOrchestrator;
44
45
  this.closeOrchestrator.setCloseTriggerAttached(true);
45
46
  this.settingsHandler = new MediaCenterSettingsHandler({ settings, dataProvider });
47
+ this.contentManagementHandler = new MediaCenterContentHandler(dataProvider);
46
48
  this.postsFeedHandler = new PostsFeedHandler({
47
49
  dataProvider,
48
50
  mediaCenterSettingsHandler: this.settingsHandler,
51
+ mediaCenterContentHandler: this.contentManagementHandler,
49
52
  closeOrchestrator,
50
53
  on: { playerReachedEnd: this.backToDiscover, navigationStateChanged: this.handleNavigationStateChanged }
51
54
  });
52
55
  this.streamsFeedHandler = new StreamsFeedHandler({
53
56
  dataProvider,
54
57
  mediaCenterSettingsHandler: this.settingsHandler,
58
+ mediaCenterContentHandler: this.contentManagementHandler,
55
59
  closeOrchestrator,
56
60
  on: { playerReachedEnd: this.backToDiscover, navigationStateChanged: this.handleNavigationStateChanged }
57
61
  });
@@ -62,9 +66,16 @@ export class MediaCenterContext {
62
66
  this.momentsFeedHandler = new MomentsFeedHandler({
63
67
  dataProvider,
64
68
  mediaCenterSettingsHandler: this.settingsHandler,
69
+ mediaCenterContentHandler: this.contentManagementHandler,
65
70
  closeOrchestrator,
66
71
  on: { playerReachedEnd: this.backToDiscover, navigationStateChanged: this.handleNavigationStateChanged }
67
72
  });
73
+ this.contentManagementHandler.addPostCreatedListener(this.discoverHandler.onPostCreated, this.postsFeedHandler.onPostCreated, this.momentsFeedHandler.onPostCreated);
74
+ this.contentManagementHandler.addPostModifiedListener(this.discoverHandler.onPostModified, this.postsFeedHandler.onPostModified, this.momentsFeedHandler.onPostModified);
75
+ this.contentManagementHandler.addPostDeletedListener(this.discoverHandler.onPostDeleted, this.postsFeedHandler.onPostDeleted, this.momentsFeedHandler.onPostDeleted);
76
+ this.contentManagementHandler.addStreamModifiedListener(this.discoverHandler.onStreamModified, this.streamsFeedHandler.onStreamModified, this.popularStreamsHandler.onStreamModified);
77
+ this.contentManagementHandler.addStreamDeletedListener(this.discoverHandler.onStreamDeleted, this.popularStreamsHandler.onStreamDeleted);
78
+ this.contentManagementHandler.addStreamPageDeletedListener(this.streamsFeedHandler.onStreamPageDeleted);
68
79
  $effect(() => {
69
80
  if (this.initialized) {
70
81
  void settings.state;
@@ -130,13 +141,21 @@ export class MediaCenterContext {
130
141
  };
131
142
  backToDiscover = () => this.activateDiscover({ categoryId: this.categoriesHandler.selectedCategoryId });
132
143
  playPostsFeed = async (options) => {
144
+ const categoryId = options.filter?.categoryId ?? null;
145
+ if (categoryId === this.categoriesHandler.selectedCategoryId && !this.postsFeedHandler.canReload) {
146
+ return;
147
+ }
133
148
  this.deactivateAllBut('posts-feed');
134
- this.categoriesHandler.selectedCategoryId = options.filter?.categoryId ?? null;
149
+ this.categoriesHandler.selectedCategoryId = categoryId;
135
150
  this.postsFeedHandler.activate(options);
136
151
  };
137
152
  playStreamsFeed = async (options) => {
153
+ const categoryId = options.filter?.categoryId ?? null;
154
+ if (categoryId === this.categoriesHandler.selectedCategoryId && !this.streamsFeedHandler.canReload) {
155
+ return;
156
+ }
138
157
  this.deactivateAllBut('streams-feed');
139
- this.categoriesHandler.selectedCategoryId = options.filter?.categoryId ?? null;
158
+ this.categoriesHandler.selectedCategoryId = categoryId;
140
159
  this.streamsFeedHandler.activate(options);
141
160
  };
142
161
  playMoments = async (options) => {
@@ -146,14 +165,13 @@ export class MediaCenterContext {
146
165
  this.deactivateAllBut('moments');
147
166
  this.momentsFeedHandler.activate(options);
148
167
  };
149
- playRootFeed = async () => {
168
+ activateDefaultFeed = async () => {
150
169
  this.categoriesHandler.selectedCategoryId = null;
151
- if (this.streamsFeedHandler.active) {
152
- this.streamsFeedHandler.activate({});
170
+ if (this.mediaCenterMode === 'streams-feed') {
171
+ this.playStreamsFeed({ filter: { categoryId: null } });
153
172
  }
154
173
  else {
155
- this.deactivateAllBut('posts-feed');
156
- this.postsFeedHandler.activate({});
174
+ this.playPostsFeed({ filter: { categoryId: null } });
157
175
  }
158
176
  };
159
177
  tryActivateStreamsInCategory = async (categoryId) => {
@@ -169,19 +187,20 @@ export class MediaCenterContext {
169
187
  this._currentState = state;
170
188
  switch (state.mode) {
171
189
  case 'posts-feed':
172
- await this.playPostsFeed({ filter: { categoryId: state.categoryId }, init: { initialPostId: state.postId } });
190
+ await this.playPostsFeed({ filter: { categoryId: state.categoryId }, init: { initialPostId: state.postId }, tryRestoreState: true });
173
191
  break;
174
192
  case 'streams-feed':
175
193
  await this.playStreamsFeed({
176
194
  filter: { categoryId: state.categoryId },
177
- init: { initialStreamId: state.streamId, initialStreamPageId: state.streamPageId }
195
+ init: { initialStreamId: state.streamId, initialStreamPageId: state.streamPageId },
196
+ tryRestoreState: true
178
197
  });
179
198
  break;
180
199
  case 'discover':
181
200
  await this.activateDiscover({ categoryId: state.categoryId });
182
201
  break;
183
202
  case 'moments':
184
- await this.playMoments({ initialMomentId: state.momentId });
203
+ await this.playMoments({ initialMomentId: state.momentId, tryRestoreState: true });
185
204
  break;
186
205
  }
187
206
  };