@streamscloud/embeddable 12.2.0 → 13.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 (162) hide show
  1. package/dist/content-player/content-player-config.svelte.d.ts +2 -13
  2. package/dist/content-player/content-player-config.svelte.js +1 -1
  3. package/dist/content-player/content-player-settings.svelte.d.ts +16 -0
  4. package/dist/content-player/content-player-settings.svelte.js +27 -0
  5. package/dist/content-player/index.d.ts +1 -0
  6. package/dist/content-player/index.js +1 -0
  7. package/dist/core/theme/index.d.ts +1 -0
  8. package/dist/core/theme/theme-store.svelte.d.ts +3 -2
  9. package/dist/external-api/data-providers/index.d.ts +6 -0
  10. package/dist/external-api/data-providers/index.js +6 -0
  11. package/dist/external-api/data-providers/internal-media-center-data-provider.svelte.d.ts +15 -0
  12. package/dist/{media-center/config/internal-media-center-config.js → external-api/data-providers/internal-media-center-data-provider.svelte.js} +33 -17
  13. package/dist/{posts/handlers → external-api/data-providers}/internal-post-analytics-handler.d.ts +1 -1
  14. package/dist/{short-videos → external-api}/data-providers/internal-short-video-player-items-provider.js +1 -1
  15. package/dist/{streams/streams-player → external-api/data-providers}/internal-stream-analytics-handler.d.ts +1 -1
  16. package/dist/{streams/streams-player → external-api/data-providers}/internal-streams-player-data-provider.d.ts +1 -1
  17. package/dist/{streams/streams-player → external-api/data-providers}/internal-streams-player-data-provider.js +1 -1
  18. package/dist/{media-center/config → external-api/data-providers}/operations.generated.d.ts +6 -0
  19. package/dist/{media-center/config → external-api/data-providers}/operations.generated.js +13 -0
  20. package/dist/{media-center/config → external-api/data-providers}/operations.graphql +6 -0
  21. package/dist/{posts/data-loaders → external-api/data-providers/post-data-loaders}/mapper.d.ts +1 -1
  22. package/dist/{posts/data-loaders → external-api/data-providers/post-data-loaders}/mapper.js +2 -2
  23. package/dist/{posts/data-loaders → external-api/data-providers/post-data-loaders}/operations.generated.d.ts +1 -1
  24. package/dist/{posts/data-loaders → external-api/data-providers/post-data-loaders}/posts-loader.d.ts +2 -2
  25. package/dist/{posts/data-loaders → external-api/data-providers/post-data-loaders}/posts-loader.js +1 -1
  26. package/dist/{streams/data-loaders → external-api/data-providers/stream-data-loaders}/mapper.d.ts +1 -1
  27. package/dist/{streams/data-loaders → external-api/data-providers/stream-data-loaders}/mapper.js +1 -1
  28. package/dist/{streams/data-loaders → external-api/data-providers/stream-data-loaders}/operations.generated.d.ts +1 -1
  29. package/dist/{streams/data-loaders → external-api/data-providers/stream-data-loaders}/stream-pages-loader.d.ts +1 -1
  30. package/dist/{streams/data-loaders → external-api/data-providers/stream-data-loaders}/stream-pages-loader.js +2 -2
  31. package/dist/{streams/data-loaders → external-api/data-providers/stream-data-loaders}/streams-loader.d.ts +2 -2
  32. package/dist/{streams/data-loaders → external-api/data-providers/stream-data-loaders}/streams-loader.js +1 -1
  33. package/dist/external-api/index.d.ts +3 -0
  34. package/dist/external-api/index.js +3 -0
  35. package/dist/external-api/media-page/index.d.ts +83 -0
  36. package/dist/external-api/media-page/index.js +82 -0
  37. package/dist/{short-videos → external-api}/short-videos-player/index.d.ts +27 -12
  38. package/dist/{short-videos → external-api}/short-videos-player/index.js +35 -28
  39. package/dist/external-api/streams-player/index.d.ts +105 -0
  40. package/dist/external-api/streams-player/index.js +110 -0
  41. package/dist/media-center/config/types.d.ts +28 -27
  42. package/dist/media-center/index.d.ts +3 -1
  43. package/dist/media-center/media-center/cmp.media-center-proxy.svelte +4 -4
  44. package/dist/media-center/media-center/cmp.media-center-proxy.svelte.d.ts +7 -4
  45. package/dist/media-center/media-center/discover/community-features-localization.d.ts +8 -0
  46. package/dist/media-center/media-center/discover/community-features-localization.js +31 -0
  47. package/dist/media-center/media-center/discover/community-features.svelte +171 -0
  48. package/dist/media-center/media-center/discover/community-features.svelte.d.ts +11 -0
  49. package/dist/media-center/media-center/discover/data-loading.d.ts +3 -3
  50. package/dist/media-center/media-center/discover/data-loading.js +5 -5
  51. package/dist/media-center/media-center/discover/discover-header.svelte +7 -56
  52. package/dist/media-center/media-center/discover/discover-view-handler.svelte.d.ts +3 -3
  53. package/dist/media-center/media-center/discover/discover-view-handler.svelte.js +4 -4
  54. package/dist/media-center/media-center/feed/feed-handler.svelte.d.ts +5 -3
  55. package/dist/media-center/media-center/feed/feed-handler.svelte.js +18 -10
  56. package/dist/media-center/media-center/feed/feed-providers-generator.d.ts +11 -5
  57. package/dist/media-center/media-center/feed/feed-providers-generator.js +13 -9
  58. package/dist/media-center/media-center/footer/index.d.ts +1 -0
  59. package/dist/media-center/media-center/footer/index.js +1 -0
  60. package/dist/media-center/media-center/handlers/categories-handler.svelte.d.ts +3 -5
  61. package/dist/media-center/media-center/handlers/categories-handler.svelte.js +16 -13
  62. package/dist/media-center/media-center/handlers/media-center-settings-handler.svelte.d.ts +18 -7
  63. package/dist/media-center/media-center/handlers/media-center-settings-handler.svelte.js +18 -25
  64. package/dist/media-center/media-center/{header-footer → header}/index.d.ts +0 -1
  65. package/dist/media-center/media-center/{header-footer → header}/index.js +0 -1
  66. package/dist/media-center/media-center/{header-footer → header}/media-center-header.svelte +133 -28
  67. package/dist/media-center/media-center/{header-footer → header}/media-center-header.svelte.d.ts +2 -0
  68. package/dist/media-center/media-center/index.d.ts +1 -0
  69. package/dist/media-center/media-center/index.js +1 -0
  70. package/dist/media-center/media-center/media-center-context.svelte.d.ts +15 -9
  71. package/dist/media-center/media-center/media-center-context.svelte.js +57 -19
  72. package/dist/media-center/media-center/media-center-settings.svelte.d.ts +11 -0
  73. package/dist/media-center/media-center/media-center-settings.svelte.js +23 -0
  74. package/dist/media-center/media-center/media-center-view.svelte +11 -3
  75. package/dist/media-center/media-center/media-center-view.svelte.d.ts +2 -0
  76. package/dist/media-center/media-center/menu/category-following-wrapper.svelte.d.ts +1 -1
  77. package/dist/media-center/media-center/menu/menu.svelte +15 -14
  78. package/dist/media-center/media-center/menu/popular-streams-panel-handler.svelte.d.ts +3 -3
  79. package/dist/media-center/media-center/menu/popular-streams-panel-handler.svelte.js +4 -4
  80. package/dist/media-center/media-center/moments/cmp.moments-circle.svelte +22 -9
  81. package/dist/media-center/media-center/moments/index.d.ts +1 -0
  82. package/dist/media-center/media-center/moments/index.js +1 -0
  83. package/dist/media-center/media-center/moments/moments-feed-handler.svelte.d.ts +26 -0
  84. package/dist/media-center/media-center/moments/moments-feed-handler.svelte.js +49 -0
  85. package/dist/media-center/media-center/moments/moments-state.svelte.d.ts +20 -0
  86. package/dist/media-center/media-center/moments/moments-state.svelte.js +82 -0
  87. package/dist/media-center/media-center/streams-in-category/streams-in-category-panel-handler.svelte.d.ts +3 -3
  88. package/dist/media-center/media-center/streams-in-category/streams-in-category-panel-handler.svelte.js +4 -4
  89. package/dist/media-center/media-center/types.d.ts +3 -3
  90. package/dist/media-center/membership/index.d.ts +1 -0
  91. package/dist/media-center/membership/index.js +1 -0
  92. package/dist/media-center/membership/mock-membership-handler.svelte.d.ts +10 -0
  93. package/dist/media-center/membership/mock-membership-handler.svelte.js +21 -0
  94. package/dist/media-center/membership/types.d.ts +10 -0
  95. package/dist/media-center/membership/types.js +1 -0
  96. package/dist/media-center/navigation/index.d.ts +2 -0
  97. package/dist/media-center/navigation/index.js +1 -0
  98. package/dist/media-center/navigation/media-center-state.d.ts +19 -0
  99. package/dist/media-center/navigation/media-center-state.js +1 -0
  100. package/dist/media-center/navigation/mock-navigation-handler.svelte.d.ts +6 -0
  101. package/dist/media-center/navigation/mock-navigation-handler.svelte.js +6 -0
  102. package/dist/media-center/navigation/types.d.ts +5 -0
  103. package/dist/media-center/navigation/types.js +1 -0
  104. package/dist/media-page/cmp.media-page.svelte +10 -4
  105. package/dist/media-page/cmp.media-page.svelte.d.ts +6 -5
  106. package/dist/media-page/index.d.ts +40 -58
  107. package/dist/media-page/index.js +129 -16
  108. package/dist/posts/posts-player/index.d.ts +31 -33
  109. package/dist/posts/posts-player/index.js +90 -35
  110. package/dist/posts/posts-player/posts-player-view.svelte +1 -1
  111. package/dist/posts/posts-player/types.d.ts +2 -1
  112. package/dist/streams/layout/styles-transformer.d.ts +1 -1
  113. package/dist/streams/streams-player/index.d.ts +17 -83
  114. package/dist/streams/streams-player/index.js +84 -64
  115. package/dist/streams/streams-player/streams-player-buffer.svelte.js +2 -1
  116. package/dist/streams/streams-player/streams-player-view.svelte +1 -1
  117. package/dist/streams/streams-player/types.d.ts +3 -1
  118. package/dist/ui/button/cmp.options-button.svelte +123 -0
  119. package/dist/ui/button/cmp.options-button.svelte.d.ts +20 -0
  120. package/dist/ui/button/index.d.ts +1 -0
  121. package/dist/ui/button/index.js +1 -0
  122. package/dist/ui/button/resources/button-theme.svelte +16 -2
  123. package/dist/ui/player/colors/index.d.ts +1 -1
  124. package/dist/ui/player/colors/index.js +1 -1
  125. package/dist/ui/player/colors/player-colors.d.ts +14 -1
  126. package/dist/ui/player/colors/player-colors.js +24 -1
  127. package/dist/ui/player/providers/default-chunks-player-buffer.svelte.d.ts +1 -0
  128. package/dist/ui/player/providers/default-chunks-player-buffer.svelte.js +7 -1
  129. package/dist/ui/player/providers/default-feed-player-buffer.svelte.d.ts +1 -0
  130. package/dist/ui/player/providers/default-feed-player-buffer.svelte.js +7 -1
  131. package/dist/ui/player/providers/types.d.ts +3 -1
  132. package/dist/ui/shadow-dom/cmp.shadow-root.svelte +6 -4
  133. package/dist/ui/shadow-dom/colors.scss +6 -4
  134. package/package.json +5 -1
  135. package/dist/content-player/content-player-settings.d.ts +0 -12
  136. package/dist/content-player/content-player-settings.js +0 -23
  137. package/dist/media-center/config/internal-media-center-config.d.ts +0 -14
  138. package/dist/media-center/media-center/discover/discover-header-localization.d.ts +0 -6
  139. package/dist/media-center/media-center/discover/discover-header-localization.js +0 -15
  140. package/dist/posts/handlers/index.d.ts +0 -1
  141. package/dist/posts/handlers/index.js +0 -1
  142. package/dist/short-videos/data-providers/index.d.ts +0 -1
  143. package/dist/short-videos/data-providers/index.js +0 -1
  144. /package/dist/{media-center/config → external-api/data-providers}/internal-media-center-analytics-handler.d.ts +0 -0
  145. /package/dist/{media-center/config → external-api/data-providers}/internal-media-center-analytics-handler.js +0 -0
  146. /package/dist/{posts/handlers → external-api/data-providers}/internal-post-analytics-handler.js +0 -0
  147. /package/dist/{short-videos → external-api}/data-providers/internal-short-video-player-items-provider.d.ts +0 -0
  148. /package/dist/{streams/streams-player → external-api/data-providers}/internal-stream-analytics-handler.js +0 -0
  149. /package/dist/{posts/data-loaders → external-api/data-providers/post-data-loaders}/index.d.ts +0 -0
  150. /package/dist/{posts/data-loaders → external-api/data-providers/post-data-loaders}/index.js +0 -0
  151. /package/dist/{posts/data-loaders → external-api/data-providers/post-data-loaders}/operations.generated.js +0 -0
  152. /package/dist/{posts/data-loaders → external-api/data-providers/post-data-loaders}/operations.graphql +0 -0
  153. /package/dist/{streams/data-loaders → external-api/data-providers/stream-data-loaders}/index.d.ts +0 -0
  154. /package/dist/{streams/data-loaders → external-api/data-providers/stream-data-loaders}/index.js +0 -0
  155. /package/dist/{streams/data-loaders → external-api/data-providers/stream-data-loaders}/operations.generated.js +0 -0
  156. /package/dist/{streams/data-loaders → external-api/data-providers/stream-data-loaders}/operations.graphql +0 -0
  157. /package/dist/media-center/media-center/{header-footer → footer}/media-center-footer.svelte +0 -0
  158. /package/dist/media-center/media-center/{header-footer → footer}/media-center-footer.svelte.d.ts +0 -0
  159. /package/dist/media-center/media-center/{header-footer → header}/media-center-header-localization.d.ts +0 -0
  160. /package/dist/media-center/media-center/{header-footer → header}/media-center-header-localization.js +0 -0
  161. /package/dist/media-center/media-center/{header-footer → header}/media-center-header-mobile.svelte +0 -0
  162. /package/dist/media-center/media-center/{header-footer → header}/media-center-header-mobile.svelte.d.ts +0 -0
@@ -1,45 +1,38 @@
1
1
  import { Theme } from '../../../core/theme';
2
- import { untrack } from 'svelte';
2
+ import { PlayerColors } from '../../../ui/player/colors';
3
3
  export class MediaCenterSettingsHandler {
4
4
  _backgroundImageUrl = $state(null);
5
- _contentPlayerSettings = $state({});
6
- _colorsMap = {
7
- light: null,
8
- dark: null
9
- };
10
- constructor(settings) {
11
- this._contentPlayerSettings = settings ?? {};
12
- $effect(() => {
13
- const theme = Theme.get();
14
- untrack(() => {
15
- this._contentPlayerSettings.playerColors = this._colorsMap[theme];
16
- });
17
- });
5
+ _mediaCenterSettings;
6
+ _dataProvider;
7
+ _contentPlayerSettings = $derived.by(() => ({
8
+ locale: this._mediaCenterSettings.locale,
9
+ playerColors: this._dataProvider.model?.playerColors,
10
+ showStreamsCloudWatermark: this._mediaCenterSettings.showStreamsCloudWatermark
11
+ }));
12
+ constructor(init) {
13
+ this._mediaCenterSettings = init.settings;
14
+ this._dataProvider = init.dataProvider;
18
15
  }
19
16
  get playerSettings() {
20
17
  return this._contentPlayerSettings;
21
18
  }
19
+ get actualMediaCenterColors() {
20
+ return this._dataProvider.model?.playerColors?.[Theme.get()] || new PlayerColors(null);
21
+ }
22
22
  get locale() {
23
- return this._contentPlayerSettings.locale || 'en';
23
+ return this._mediaCenterSettings.locale;
24
24
  }
25
25
  get backgroundWrapperProps() {
26
26
  return {
27
- backgroundDisabled: this._contentPlayerSettings.disableBackground === true,
27
+ backgroundDisabled: this._mediaCenterSettings.disableBackground,
28
28
  backgroundImageUrl: this._backgroundImageUrl,
29
- backgroundColor: this._contentPlayerSettings.playerColors?.playerBackground
29
+ backgroundColor: this.actualMediaCenterColors.playerBackground
30
30
  };
31
31
  }
32
32
  get backgroundImageLoadedHandler() {
33
- return this._contentPlayerSettings.disableBackground === true ? undefined : (url) => this.updateBackgroundImageUrl(url);
33
+ return this._mediaCenterSettings.disableBackground ? undefined : (url) => this.updateBackgroundImageUrl(url);
34
34
  }
35
35
  updateBackgroundImageUrl = (url) => {
36
36
  this._backgroundImageUrl = url;
37
37
  };
38
- updatePlayerColors = (colors) => {
39
- this._colorsMap = {
40
- light: null,
41
- dark: colors
42
- };
43
- this._contentPlayerSettings.playerColors = this._colorsMap[Theme.get()];
44
- };
45
38
  }
@@ -1,3 +1,2 @@
1
- export { default as MediaCenterFooter } from './media-center-footer.svelte';
2
1
  export { default as MediaCenterHeaderMobile } from './media-center-header-mobile.svelte';
3
2
  export { default as MediaCenterHeader } from './media-center-header.svelte';
@@ -1,3 +1,2 @@
1
- export { default as MediaCenterFooter } from './media-center-footer.svelte';
2
1
  export { default as MediaCenterHeaderMobile } from './media-center-header-mobile.svelte';
3
2
  export { default as MediaCenterHeader } from './media-center-header.svelte';
@@ -10,13 +10,18 @@ import IconReOrderDotsHorizontal from '@fluentui/svg-icons/icons/re_order_dots_h
10
10
  import IconScreenSearch from '@fluentui/svg-icons/icons/screen_search_20_regular.svg?raw';
11
11
  import IconSearch from '@fluentui/svg-icons/icons/search_20_regular.svg?raw';
12
12
  const SCROLL_MASK_OFFSET = 32;
13
- let { context, on } = $props();
13
+ const HEADER_CONTENT_MAX_WIDTH = 1180;
14
+ const HEADER_SIDE_SPACER_MIN_WIDTH = 30;
15
+ let { context, on, dynamicActions } = $props();
14
16
  const localization = $derived(new MediaCenterHeaderLocalization(context.locale));
17
+ let headerRef = $state(null);
15
18
  let scrollAreaRef = $state(null);
16
19
  const headerMounted = (node) => {
20
+ headerRef = node;
17
21
  const heightResizeObserver = new ResizeObserver(() => {
18
22
  const headerHeight = node.clientHeight;
19
23
  on.headerHeightChanged(headerHeight);
24
+ calcHeaderGridProportions();
20
25
  });
21
26
  heightResizeObserver.observe(node);
22
27
  return {
@@ -26,6 +31,62 @@ const headerMounted = (node) => {
26
31
  }
27
32
  };
28
33
  };
34
+ const handleCloseButtonMounted = (_) => {
35
+ calcHeaderGridProportions();
36
+ };
37
+ const handleDynamicActionsMounted = (node) => {
38
+ const resizeObserver = new ResizeObserver(() => {
39
+ calcHeaderGridProportions();
40
+ });
41
+ resizeObserver.observe(node);
42
+ return {
43
+ destroy: () => {
44
+ resizeObserver.disconnect();
45
+ }
46
+ };
47
+ };
48
+ const calcHeaderGridProportions = () => {
49
+ if (!headerRef) {
50
+ return;
51
+ }
52
+ const children = Array.from(headerRef.children);
53
+ if (children.length !== 3) {
54
+ console.warn('Media Center header structure is unexpected. Cannot calculate grid proportions.');
55
+ return;
56
+ }
57
+ const headerWidth = headerRef.clientWidth;
58
+ const minRequiredSpacerWidth = Math.max(HEADER_SIDE_SPACER_MIN_WIDTH, (headerWidth - HEADER_CONTENT_MAX_WIDTH) / 2);
59
+ const calcSpacerMinWidth = (container) => {
60
+ container.style.width = ``;
61
+ const children = Array.from(container.children);
62
+ const { paddingLeft, paddingRight } = window.getComputedStyle(container);
63
+ const paddingsWidth = parseFloat(paddingLeft) + parseFloat(paddingRight);
64
+ if (children.length === 0) {
65
+ return paddingsWidth;
66
+ }
67
+ const containerRect = container.getBoundingClientRect();
68
+ let minLeft = Infinity;
69
+ let maxRight = -Infinity;
70
+ children.forEach((child) => {
71
+ const rect = child.getBoundingClientRect();
72
+ const relativeLeft = rect.left - containerRect.left;
73
+ const relativeRight = rect.right - containerRect.left;
74
+ minLeft = Math.min(minLeft, relativeLeft);
75
+ maxRight = Math.max(maxRight, relativeRight);
76
+ });
77
+ return maxRight - minLeft + paddingsWidth;
78
+ };
79
+ const leftSpacer = children[0];
80
+ const leftSpacerMinWidth = calcSpacerMinWidth(leftSpacer);
81
+ const adjustedLeftSpacerMinWidth = Math.max(leftSpacerMinWidth, minRequiredSpacerWidth);
82
+ const rightSpacer = children[2];
83
+ const rightSpacerMinWidth = calcSpacerMinWidth(rightSpacer);
84
+ const adjustedRightSpacerMinWidth = Math.max(rightSpacerMinWidth, minRequiredSpacerWidth);
85
+ const content = children[1];
86
+ leftSpacer.style.width = `${adjustedLeftSpacerMinWidth}px`;
87
+ rightSpacer.style.width = `${adjustedRightSpacerMinWidth}px`;
88
+ content.style.width = `${headerWidth - adjustedLeftSpacerMinWidth - adjustedRightSpacerMinWidth}px`;
89
+ };
29
90
  const onScrollMounted = (node) => {
30
91
  scrollAreaRef = node;
31
92
  scrollAreaRef.style.setProperty('--scroll-area--mask-offset', `${SCROLL_MASK_OFFSET}px`);
@@ -52,23 +113,26 @@ const updateScrollShadows = (scrollArea) => {
52
113
  scrollArea.classList.toggle('has-both-masks', scrollHasRight && scrollHasLeft);
53
114
  };
54
115
  const styles = $derived.by(() => {
55
- var _a, _b;
56
116
  const values = [];
57
- if ((_a = context.playerColors) === null || _a === void 0 ? void 0 : _a.button) {
58
- values.push(`--media-center-header--button-color: ${context.playerColors.button}`);
117
+ if (context.mediaCenterColors.button) {
118
+ values.push(`--media-center-header--button-color: ${context.mediaCenterColors.button}`);
119
+ }
120
+ if (context.mediaCenterColors.buttonInactive) {
121
+ values.push(`--media-center-header--button-color--inactive: ${context.mediaCenterColors.buttonInactive}`);
59
122
  }
60
- if ((_b = context.playerColors) === null || _b === void 0 ? void 0 : _b.buttonInactive) {
61
- values.push(`--media-center-header--button-color--inactive: ${context.playerColors.buttonInactive}`);
123
+ if (context.mediaCenterColors.brand) {
124
+ values.push(`--media-center-header--button-indicator: ${context.mediaCenterColors.brand}`);
62
125
  }
63
126
  return values.join(';');
64
127
  });
65
128
  </script>
66
129
 
67
130
  <div class="media-center-header-container" use:headerMounted>
131
+ <div class="spacer"></div>
68
132
  <div class="media-center-header" style={styles}>
69
- {#if context.targetData?.logo}
133
+ {#if context.model?.logo}
70
134
  <div class="media-center-header__logo-wrap">
71
- <img src={context.targetData.logo} class="media-center-header__logo" alt={context.targetData?.name} />
135
+ <img src={context.model.logo} class="media-center-header__logo" alt={context.model?.name} />
72
136
  </div>
73
137
  {/if}
74
138
  <button type="button" class="control-button control-button--trigger" class:control-button--active={context.menuActive} onclick={context.toggleMenu}>
@@ -106,7 +170,12 @@ const styles = $derived.by(() => {
106
170
  {localization.buttons.cart}
107
171
  </span>
108
172
  </button>
109
- <button type="button" class="control-button" class:control-button--active={false} onclick={() => ({})}>
173
+ <button
174
+ type="button"
175
+ class="control-button"
176
+ class:control-button--active={context.momentsFeedHandler.active}
177
+ class:control-button--indicator={context.momentsFeedHandler.hasUnwatchedMoments}
178
+ onclick={() => context.playMoments()}>
110
179
  <span class="control-button__value">
111
180
  {localization.buttons.moments}
112
181
  </span>
@@ -138,16 +207,25 @@ const styles = $derived.by(() => {
138
207
  </div>
139
208
  </div>
140
209
  </div>
141
- {#if context.closeOrchestrator.closeTriggerVisible}
142
- <div class="close-button">
143
- <PlayerButton
144
- icon={IconDismiss}
145
- zoom={0.8}
146
- activeColor={context.playerColors?.button ?? null}
147
- inactiveColor={context.playerColors?.buttonInactive ?? null}
148
- on={{ click: context.closeOrchestrator.requestClose }} />
149
- </div>
150
- {/if}
210
+ <div class="spacer spacer--right">
211
+ {#if dynamicActions}
212
+ <div class="dynamic-actions" use:handleDynamicActionsMounted>
213
+ <div class="dynamic-actions__content">
214
+ {@render dynamicActions()}
215
+ </div>
216
+ </div>
217
+ {/if}
218
+ {#if context.closeOrchestrator.closeTriggerVisible}
219
+ <div class="close-button" use:handleCloseButtonMounted>
220
+ <PlayerButton
221
+ icon={IconDismiss}
222
+ zoom={0.8}
223
+ activeColor={context.mediaCenterColors.button}
224
+ inactiveColor={context.mediaCenterColors.buttonInactive}
225
+ on={{ click: context.closeOrchestrator.requestClose }} />
226
+ </div>
227
+ {/if}
228
+ </div>
151
229
  </div>
152
230
 
153
231
  <style>@keyframes fadeIn {
@@ -162,24 +240,30 @@ const styles = $derived.by(() => {
162
240
  }
163
241
  }
164
242
  .media-center-header-container {
165
- padding-top: 2.1875rem;
166
- padding-inline: 4.375rem;
167
- pointer-events: none;
168
243
  z-index: 1;
169
244
  display: flex;
170
- justify-content: center;
171
245
  position: relative;
172
246
  }
173
247
 
248
+ .spacer {
249
+ flex: 1 1 auto;
250
+ display: flex;
251
+ padding-inline: 0.9375rem;
252
+ gap: 0.9375rem;
253
+ }
254
+ .spacer--right {
255
+ justify-content: flex-end;
256
+ }
257
+
174
258
  .media-center-header {
175
259
  --_media-center-header--button-color: var(--media-center-header--button-color, var(--sc-mc-color--button-player));
176
260
  --_media-center-header--button-color--inactive: var(
177
261
  --media-center-header--button-color--inactive,
178
262
  rgb(from var(--_media-center-header--button-color, var(--sc-mc-color--button-player)) r g b / 60%)
179
263
  );
264
+ --_media-center-header--button-indicator: var(--media-center-header--button-indicator, var(--sc-mc-color--icon-success));
265
+ padding-top: 2.1875rem;
180
266
  width: 73.75rem;
181
- max-width: 100%;
182
- margin: 0 auto;
183
267
  display: flex;
184
268
  align-items: center;
185
269
  gap: 1.5rem;
@@ -280,6 +364,17 @@ const styles = $derived.by(() => {
280
364
  background-color: var(--_media-center-header--button-color);
281
365
  color: var(--sc-mc-color--text-white);
282
366
  }
367
+ .control-button--indicator::after {
368
+ content: "";
369
+ position: absolute;
370
+ top: 0rem;
371
+ right: 0rem;
372
+ width: 0.875rem;
373
+ height: 0.875rem;
374
+ transform: translate(20%, -20%);
375
+ background-color: var(--_media-center-header--button-indicator);
376
+ border-radius: 50%;
377
+ }
283
378
  .control-button:hover:not(.control-button--active) {
284
379
  background-color: var(--_media-center-header--button-color);
285
380
  }
@@ -303,9 +398,19 @@ const styles = $derived.by(() => {
303
398
  min-width: 0;
304
399
  }
305
400
 
401
+ .dynamic-actions {
402
+ display: flex;
403
+ padding-top: 2.1875rem;
404
+ }
405
+ .dynamic-actions__content {
406
+ display: flex;
407
+ justify-content: center;
408
+ }
409
+
306
410
  .close-button {
307
- position: absolute;
308
- top: 0.9375rem;
309
- right: 1.25rem;
411
+ justify-self: flex-end;
412
+ flex-shrink: 0;
413
+ padding-block: 0.9375rem;
414
+ padding-right: 0.3125rem;
310
415
  z-index: 1;
311
416
  }</style>
@@ -1,9 +1,11 @@
1
1
  import type { MediaCenterContext } from '../media-center-context.svelte';
2
+ import type { Snippet } from 'svelte';
2
3
  type Props = {
3
4
  context: MediaCenterContext;
4
5
  on: {
5
6
  headerHeightChanged: (height: number) => void;
6
7
  };
8
+ dynamicActions?: Snippet;
7
9
  };
8
10
  declare const MediaCenterHeader: import("svelte").Component<Props, {}, "">;
9
11
  type MediaCenterHeader = ReturnType<typeof MediaCenterHeader>;
@@ -1 +1,2 @@
1
1
  export { default as MediaCenterProxy } from './cmp.media-center-proxy.svelte';
2
+ export { MediaCenterSettings } from './media-center-settings.svelte';
@@ -1 +1,2 @@
1
1
  export { default as MediaCenterProxy } from './cmp.media-center-proxy.svelte';
2
+ export { MediaCenterSettings } from './media-center-settings.svelte';
@@ -1,12 +1,13 @@
1
- import type { IContentCategoryFollowingHandler } from '../categories-following/types';
2
- import type { IMediaCenterConfig } from '../config/types';
1
+ import type { IMediaCenterDataProvider } from '../config/types';
3
2
  import type { ICloseOrchestrator } from '../../ui/player/close-orchestrator';
4
3
  import { DiscoverViewHandler } from './discover';
5
4
  import { FeedHandler } from './feed';
6
5
  import { CategoriesHandler, MediaCenterSettingsHandler } from './handlers';
6
+ import type { MediaCenterSettings } from './media-center-settings.svelte';
7
7
  import { PopularStreamsPanelHandler } from './menu';
8
+ import { MomentsFeedHandler } from './moments';
8
9
  import { StreamsInCategoryPanelHandler } from './streams-in-category';
9
- import type { MediaCenterMode, MediaCenterSettings } from './types';
10
+ import type { MediaCenterMode } from './types';
10
11
  export declare class MediaCenterContext {
11
12
  initializing: boolean;
12
13
  initialized: boolean;
@@ -14,21 +15,21 @@ export declare class MediaCenterContext {
14
15
  menuActive: boolean;
15
16
  categoriesHandler: CategoriesHandler;
16
17
  feedHandler: FeedHandler;
18
+ momentsFeedHandler: MomentsFeedHandler;
17
19
  discoverHandler: DiscoverViewHandler;
18
20
  popularStreamsHandler: PopularStreamsPanelHandler;
19
21
  streamsInCategoryHandler: StreamsInCategoryPanelHandler;
20
- categoryFollowingHandler: IContentCategoryFollowingHandler | null;
21
22
  settingsHandler: MediaCenterSettingsHandler;
22
23
  closeOrchestrator: ICloseOrchestrator;
23
- private _targetData;
24
+ private _dataProvider;
24
25
  constructor(data: {
25
- config: IMediaCenterConfig;
26
+ dataProvider: IMediaCenterDataProvider;
26
27
  closeOrchestrator: ICloseOrchestrator;
27
- settings?: MediaCenterSettings;
28
+ settings: MediaCenterSettings;
28
29
  on: MediaCenterContextInitializationCallbacks;
29
30
  });
30
- get targetData(): import("../config/types").MediaCenterTargetDataModel | null;
31
- get playerColors(): import("../../ui/player/colors").PlayerColors | undefined;
31
+ get model(): import("../config/types").MediaCenterModel | null;
32
+ get mediaCenterColors(): import("../../ui/player/colors").PlayerColors;
32
33
  get loading(): boolean;
33
34
  get overlayIsActive(): boolean;
34
35
  get backgroundWrapperProps(): {
@@ -37,6 +38,10 @@ export declare class MediaCenterContext {
37
38
  backgroundColor?: string | null;
38
39
  };
39
40
  get feedPlayerProps(): import("./types").PlayerProps | null;
41
+ get momentsPlayerProps(): import("../../posts/posts-player/types").PostsPlayerProps | null;
42
+ get membershipHandler(): import("..").IMediaCenterMembershipHandler | null;
43
+ get navigationHandler(): import("..").IMediaCenterNavigationHandler | null;
44
+ get categoriesFollowingHandler(): import("..").IContentCategoryFollowingHandler | null;
40
45
  get locale(): import("../../core/locale").Locale;
41
46
  toggleMenu: () => void;
42
47
  showMenu: () => void;
@@ -46,6 +51,7 @@ export declare class MediaCenterContext {
46
51
  }) => Promise<void>;
47
52
  playPostsFeed: (options: Parameters<FeedHandler["activatePostsFeed"]>[0]) => Promise<void>;
48
53
  playStreamsFeed: (options: Parameters<FeedHandler["activateStreamsFeed"]>[0]) => Promise<void>;
54
+ playMoments: () => Promise<void>;
49
55
  playRootFeed: () => Promise<void>;
50
56
  tryActivateStreamsInCategory: (categoryId: string) => Promise<void>;
51
57
  private deactivateOtherThanFeed;
@@ -2,6 +2,7 @@ import { DiscoverViewHandler } from './discover';
2
2
  import { FeedHandler } from './feed';
3
3
  import { CategoriesHandler, MediaCenterSettingsHandler } from './handlers';
4
4
  import { PopularStreamsPanelHandler } from './menu';
5
+ import { MomentsFeedHandler } from './moments';
5
6
  import { StreamsInCategoryPanelHandler } from './streams-in-category';
6
7
  export class MediaCenterContext {
7
8
  initializing = $state(true);
@@ -10,35 +11,50 @@ export class MediaCenterContext {
10
11
  if (this.discoverHandler.activated) {
11
12
  return 'discover';
12
13
  }
14
+ if (this.momentsFeedHandler.active) {
15
+ return 'moments';
16
+ }
13
17
  return 'feed';
14
18
  });
15
19
  menuActive = $state(false);
16
- categoriesHandler = new CategoriesHandler();
20
+ categoriesHandler;
17
21
  feedHandler;
22
+ momentsFeedHandler;
18
23
  discoverHandler;
19
24
  popularStreamsHandler;
20
25
  streamsInCategoryHandler;
21
- categoryFollowingHandler = $state.raw(null);
22
26
  settingsHandler;
23
27
  closeOrchestrator;
24
- _targetData = $state.raw(null);
28
+ _dataProvider;
25
29
  constructor(data) {
26
- const { config, closeOrchestrator, settings, on } = data;
30
+ const { dataProvider, closeOrchestrator, settings, on } = data;
31
+ this._dataProvider = dataProvider;
27
32
  this.closeOrchestrator = closeOrchestrator;
28
33
  this.closeOrchestrator.setCloseTriggerAttached(true);
29
- this.settingsHandler = new MediaCenterSettingsHandler(settings);
30
- this.feedHandler = new FeedHandler({ config, mediaCenterSettingsHandler: this.settingsHandler, closeOrchestrator });
31
- this.discoverHandler = new DiscoverViewHandler(config);
32
- this.popularStreamsHandler = new PopularStreamsPanelHandler(config);
33
- this.streamsInCategoryHandler = new StreamsInCategoryPanelHandler(config);
34
- this.categoryFollowingHandler = config.handlers?.categoriesFollowingHandler ?? null;
35
- this.init(config, on);
34
+ this.settingsHandler = new MediaCenterSettingsHandler({ settings, dataProvider });
35
+ this.feedHandler = new FeedHandler({
36
+ dataProvider,
37
+ mediaCenterSettingsHandler: this.settingsHandler,
38
+ closeOrchestrator,
39
+ onPlayerReachedEnd: () => this.activateDiscover({ categoryId: this.categoriesHandler.selectedCategoryId })
40
+ });
41
+ this.categoriesHandler = new CategoriesHandler(dataProvider);
42
+ this.discoverHandler = new DiscoverViewHandler(dataProvider);
43
+ this.popularStreamsHandler = new PopularStreamsPanelHandler(dataProvider);
44
+ this.streamsInCategoryHandler = new StreamsInCategoryPanelHandler(dataProvider);
45
+ this.momentsFeedHandler = new MomentsFeedHandler({
46
+ dataProvider,
47
+ mediaCenterSettingsHandler: this.settingsHandler,
48
+ closeOrchestrator,
49
+ onPlayerReachedEnd: () => this.activateDiscover({ categoryId: this.categoriesHandler.selectedCategoryId })
50
+ });
51
+ this.init(dataProvider, on);
36
52
  }
37
- get targetData() {
38
- return this._targetData;
53
+ get model() {
54
+ return this._dataProvider.model;
39
55
  }
40
- get playerColors() {
41
- return this.settingsHandler.playerSettings.playerColors;
56
+ get mediaCenterColors() {
57
+ return this.settingsHandler.actualMediaCenterColors;
42
58
  }
43
59
  get loading() {
44
60
  return this.discoverHandler.loading || this.streamsInCategoryHandler.loading;
@@ -52,6 +68,18 @@ export class MediaCenterContext {
52
68
  get feedPlayerProps() {
53
69
  return this.feedHandler.feedPlayerProps;
54
70
  }
71
+ get momentsPlayerProps() {
72
+ return this.momentsFeedHandler.momentsPlayerProps;
73
+ }
74
+ get membershipHandler() {
75
+ return this._dataProvider.handlers?.membershipHandler || null;
76
+ }
77
+ get navigationHandler() {
78
+ return this._dataProvider.handlers?.navigationHandler || null;
79
+ }
80
+ get categoriesFollowingHandler() {
81
+ return this._dataProvider.handlers?.categoriesFollowingHandler || null;
82
+ }
55
83
  get locale() {
56
84
  return this.settingsHandler.locale;
57
85
  }
@@ -74,6 +102,7 @@ export class MediaCenterContext {
74
102
  this.settingsHandler.updateBackgroundImageUrl('not-applicable');
75
103
  this.hideMenu();
76
104
  this.feedHandler.deactivate();
105
+ this.momentsFeedHandler.deactivate();
77
106
  this.streamsInCategoryHandler.deactivate();
78
107
  this.categoriesHandler.selectedCategoryId = options.categoryId;
79
108
  const childCategories = this.categoriesHandler.allCategories.filter((c) => c.parentId === this.categoriesHandler.selectedCategoryId);
@@ -92,6 +121,16 @@ export class MediaCenterContext {
92
121
  this.categoriesHandler.selectedCategoryId = options.filter?.categoryId ?? null;
93
122
  this.feedHandler.activateStreamsFeed(options);
94
123
  };
124
+ playMoments = async () => {
125
+ if (!this.momentsFeedHandler.hasMoments) {
126
+ return;
127
+ }
128
+ this.hideMenu();
129
+ this.feedHandler.deactivate();
130
+ this.discoverHandler.deactivate();
131
+ this.streamsInCategoryHandler.deactivate();
132
+ this.momentsFeedHandler.activateMoments();
133
+ };
95
134
  playRootFeed = async () => {
96
135
  this.deactivateOtherThanFeed();
97
136
  this.categoriesHandler.selectedCategoryId = null;
@@ -107,24 +146,23 @@ export class MediaCenterContext {
107
146
  await this.streamsInCategoryHandler.activate(selectedCategoryData);
108
147
  this.hideMenu();
109
148
  this.feedHandler.deactivate();
149
+ this.momentsFeedHandler.deactivate();
110
150
  this.discoverHandler.deactivate();
111
151
  this.categoriesHandler.selectedCategoryId = categoryId;
112
152
  };
113
153
  deactivateOtherThanFeed = () => {
114
154
  this.hideMenu();
155
+ this.momentsFeedHandler.deactivate();
115
156
  this.discoverHandler.deactivate();
116
157
  this.streamsInCategoryHandler.deactivate();
117
158
  };
118
159
  init = async (config, on) => {
119
160
  try {
120
- const configModel = await config.getConfig();
161
+ const configModel = await config.fetchModel();
121
162
  if (!configModel) {
122
163
  on.failed();
123
164
  return;
124
165
  }
125
- this.categoriesHandler.init({ categories: configModel.contentCategories, tagAssociations: configModel.categoryTagAssociations });
126
- this.settingsHandler.updatePlayerColors(configModel.playerColors);
127
- this._targetData = configModel.targetData;
128
166
  on.initialized(this);
129
167
  this.initialized = true;
130
168
  }
@@ -0,0 +1,11 @@
1
+ import type { Locale } from '../../core/locale';
2
+ import type { ThemeValue } from '../../core/theme';
3
+ import type { IMediaCenterSettings } from './types';
4
+ export declare class MediaCenterSettings {
5
+ locale: Locale;
6
+ showStreamsCloudWatermark: boolean;
7
+ disableBackground: boolean;
8
+ theme: ThemeValue;
9
+ constructor(init: IMediaCenterSettings | undefined);
10
+ patch: (data: Partial<IMediaCenterSettings> | undefined) => void;
11
+ }
@@ -0,0 +1,23 @@
1
+ export class MediaCenterSettings {
2
+ locale = $state('en');
3
+ showStreamsCloudWatermark = $state(true);
4
+ disableBackground = $state(false);
5
+ theme = $state('dark');
6
+ constructor(init) {
7
+ this.patch(init);
8
+ }
9
+ patch = (data) => {
10
+ if (data?.locale !== undefined) {
11
+ this.locale = data.locale;
12
+ }
13
+ if (data?.showStreamsCloudWatermark !== undefined) {
14
+ this.showStreamsCloudWatermark = data.showStreamsCloudWatermark;
15
+ }
16
+ if (data?.disableBackground !== undefined) {
17
+ this.disableBackground = data.disableBackground;
18
+ }
19
+ if (data?.theme !== undefined) {
20
+ this.theme = data.theme;
21
+ }
22
+ };
23
+ }
@@ -12,12 +12,13 @@ import { default as PostsPlayerView } from '../../posts/posts-player/posts-playe
12
12
  import { default as StreamsPlayerView } from '../../streams/streams-player/streams-player-view.svelte';
13
13
  import { Loading } from '../../ui/loading';
14
14
  import { DiscoverPanel } from './discover';
15
- import { MediaCenterHeader, MediaCenterFooter, MediaCenterHeaderMobile } from './header-footer';
15
+ import { MediaCenterFooter } from './footer';
16
+ import { MediaCenterHeader, MediaCenterHeaderMobile } from './header';
16
17
  import { MediaCenterContext } from './media-center-context.svelte';
17
18
  import { Menu } from './menu';
18
19
  import { StreamsInCategoryPanel } from './streams-in-category';
19
20
  import { fade } from 'svelte/transition';
20
- let { context } = $props();
21
+ let { context, dynamicActions } = $props();
21
22
  let headerHeight = $state(0);
22
23
  let isMobileView = $state(false);
23
24
  const selectCategory = (categoryId) => __awaiter(void 0, void 0, void 0, function* () {
@@ -43,6 +44,9 @@ const selectCategory = (categoryId) => __awaiter(void 0, void 0, void 0, functio
43
44
  case 'discover':
44
45
  context.activateDiscover({ categoryId });
45
46
  break;
47
+ case 'moments':
48
+ context.playPostsFeed({ filter: { categoryId } });
49
+ break;
46
50
  default:
47
51
  Utils.assertUnreachable(context.mediaCenterMode);
48
52
  }
@@ -129,7 +133,7 @@ const swipeToOpen = (node) => {
129
133
  <div class="media-center" use:onWidthAnchorMounted>
130
134
  <div class="media-center__header-and-content">
131
135
  {#if !isMobileView}
132
- <MediaCenterHeader context={context} on={{ headerHeightChanged: onHeaderHeightChanged }} />
136
+ <MediaCenterHeader context={context} dynamicActions={dynamicActions} on={{ headerHeightChanged: onHeaderHeightChanged }} />
133
137
  {:else}
134
138
  <MediaCenterHeaderMobile context={context} on={{ headerHeightChanged: onHeaderHeightChanged }} />
135
139
  {/if}
@@ -152,6 +156,10 @@ const swipeToOpen = (node) => {
152
156
  streamSelected: (stream) => activateSelectedStreamPlayer(stream)
153
157
  }} />
154
158
  </div>
159
+ {:else if context.mediaCenterMode === 'moments' && context.momentsPlayerProps}
160
+ <div class="media-center__content" class:media-center__content--faded={context.overlayIsActive} transition:fade={{ duration: 300 }}>
161
+ <PostsPlayerView {...context.momentsPlayerProps} />
162
+ </div>
155
163
  {/if}
156
164
  </div>
157
165
 
@@ -1,6 +1,8 @@
1
1
  import { MediaCenterContext } from './media-center-context.svelte';
2
+ import type { Snippet } from 'svelte';
2
3
  type Props = {
3
4
  context: MediaCenterContext;
5
+ dynamicActions?: Snippet;
4
6
  };
5
7
  declare const MediaCenterView: import("svelte").Component<Props, {}, "">;
6
8
  type MediaCenterView = ReturnType<typeof MediaCenterView>;
@@ -2,7 +2,7 @@ import type { MediaCenterContext } from '../media-center-context.svelte';
2
2
  import { type Snippet } from 'svelte';
3
3
  type Props = {
4
4
  categoryId: string;
5
- followingHandler?: MediaCenterContext['categoryFollowingHandler'];
5
+ followingHandler?: MediaCenterContext['categoriesFollowingHandler'];
6
6
  children: Snippet;
7
7
  invertedOrientation?: boolean;
8
8
  };