@streamscloud/embeddable 5.1.2 → 6.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 (89) hide show
  1. package/dist/ads/ad-card/mapper.js +1 -1
  2. package/dist/core/continuation-token.d.ts +1 -0
  3. package/dist/core/continuation-token.js +3 -0
  4. package/dist/core/locale.d.ts +0 -1
  5. package/dist/core/locale.js +0 -12
  6. package/dist/core/media/media-item-url.service.d.ts +1 -1
  7. package/dist/core/media/media-item-url.service.js +1 -6
  8. package/dist/media-center/data-provider/index.d.ts +2 -0
  9. package/dist/media-center/data-provider/index.js +1 -0
  10. package/dist/media-center/data-provider/internal-media-center-data-provider.svelte.d.ts +8 -0
  11. package/dist/media-center/data-provider/internal-media-center-data-provider.svelte.js +44 -0
  12. package/dist/media-center/data-provider/operations.generated.d.ts +89 -0
  13. package/dist/media-center/data-provider/operations.generated.js +275 -0
  14. package/dist/media-center/data-provider/operations.graphql +25 -0
  15. package/dist/media-center/data-provider/types.d.ts +24 -0
  16. package/dist/media-center/data-provider/types.js +1 -0
  17. package/dist/media-center/index.d.ts +1 -0
  18. package/dist/media-center/index.js +1 -0
  19. package/dist/media-center/media-center/cmp.media-center.svelte +336 -0
  20. package/dist/media-center/media-center/cmp.media-center.svelte.d.ts +20 -0
  21. package/dist/media-center/media-center/index.d.ts +3 -0
  22. package/dist/media-center/media-center/index.js +2 -0
  23. package/dist/media-center/media-center/media-center-localization.d.ts +11 -0
  24. package/dist/media-center/media-center/media-center-localization.js +15 -0
  25. package/dist/media-center/media-center/overview.svelte +142 -0
  26. package/dist/media-center/media-center/overview.svelte.d.ts +13 -0
  27. package/dist/media-center/media-center/short-video-resources-generator.d.ts +8 -0
  28. package/dist/media-center/media-center/short-video-resources-generator.js +26 -0
  29. package/dist/media-center/media-center/types.d.ts +10 -0
  30. package/dist/media-center/media-center/types.js +5 -0
  31. package/dist/products/product-card/cmp.product-card.svelte +11 -6
  32. package/dist/products/product-card/mapper.js +3 -3
  33. package/dist/short-videos/short-video-card/cmp.short-video-card.svelte +118 -0
  34. package/dist/short-videos/short-video-card/cmp.short-video-card.svelte.d.ts +11 -0
  35. package/dist/short-videos/short-video-card/index.d.ts +2 -0
  36. package/dist/short-videos/short-video-card/index.js +1 -0
  37. package/dist/short-videos/short-video-card/types.d.ts +5 -0
  38. package/dist/short-videos/short-video-card/types.js +1 -0
  39. package/dist/short-videos/short-video-viewer/cmp.short-video-controls.svelte +3 -3
  40. package/dist/short-videos/short-video-viewer/cmp.short-video-controls.svelte.d.ts +2 -2
  41. package/dist/short-videos/short-video-viewer/cmp.short-video-viewer.svelte +8 -26
  42. package/dist/short-videos/short-video-viewer/cmp.short-video-viewer.svelte.d.ts +2 -3
  43. package/dist/short-videos/short-video-viewer/index.d.ts +1 -1
  44. package/dist/short-videos/short-video-viewer/mapper.js +6 -3
  45. package/dist/short-videos/short-video-viewer/types.d.ts +8 -6
  46. package/dist/short-videos/short-video-viewer/ui-manager.svelte.d.ts +0 -5
  47. package/dist/short-videos/short-video-viewer/ui-manager.svelte.js +0 -11
  48. package/dist/short-videos/short-videos-player/cmp.short-videos-player.svelte +16 -12
  49. package/dist/short-videos/short-videos-player/cmp.short-videos-player.svelte.d.ts +5 -15
  50. package/dist/short-videos/short-videos-player/controls.svelte +34 -3
  51. package/dist/short-videos/short-videos-player/controls.svelte.d.ts +3 -2
  52. package/dist/short-videos/short-videos-player/fade-mixins.scss +12 -0
  53. package/dist/short-videos/short-videos-player/index.d.ts +66 -36
  54. package/dist/short-videos/short-videos-player/index.js +40 -104
  55. package/dist/short-videos/short-videos-player/internal-short-video-player-provider.d.ts +17 -0
  56. package/dist/short-videos/short-videos-player/internal-short-video-player-provider.js +59 -0
  57. package/dist/short-videos/short-videos-player/operations.generated.d.ts +1 -0
  58. package/dist/short-videos/short-videos-player/operations.generated.js +2 -1
  59. package/dist/short-videos/short-videos-player/operations.graphql +1 -0
  60. package/dist/short-videos/short-videos-player/short-videos-player-view.svelte +36 -55
  61. package/dist/short-videos/short-videos-player/short-videos-player-view.svelte.d.ts +12 -15
  62. package/dist/short-videos/short-videos-player/types.d.ts +8 -29
  63. package/dist/short-videos/short-videos-player/types.js +1 -6
  64. package/dist/short-videos/short-videos-player/ui-manager.svelte.d.ts +6 -6
  65. package/dist/short-videos/short-videos-player/ui-manager.svelte.js +28 -16
  66. package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte +6 -1
  67. package/dist/streams/stream-page-viewer/index.d.ts +1 -0
  68. package/dist/streams/stream-page-viewer/index.js +1 -0
  69. package/dist/streams/stream-player/controls.svelte +2 -2
  70. package/dist/streams/stream-player/controls.svelte.d.ts +2 -2
  71. package/dist/streams/stream-player/index.d.ts +84 -27
  72. package/dist/streams/stream-player/index.js +46 -48
  73. package/dist/streams/stream-player/internal-stream-analytics-handler.d.ts +12 -0
  74. package/dist/streams/stream-player/internal-stream-analytics-handler.js +17 -0
  75. package/dist/streams/stream-player/internal-stream-player-data-provider.d.ts +10 -0
  76. package/dist/streams/stream-player/internal-stream-player-data-provider.js +48 -0
  77. package/dist/streams/stream-player/mapper.js +2 -0
  78. package/dist/streams/stream-player/operations.generated.d.ts +0 -2
  79. package/dist/streams/stream-player/operations.generated.js +2 -4
  80. package/dist/streams/stream-player/operations.graphql +0 -1
  81. package/dist/streams/stream-player/stream-player-buffer.svelte.d.ts +5 -5
  82. package/dist/streams/stream-player/stream-player-buffer.svelte.js +12 -27
  83. package/dist/streams/stream-player/{cmp.stream-player.svelte → stream-player.svelte} +19 -37
  84. package/dist/streams/stream-player/stream-player.svelte.d.ts +4 -0
  85. package/dist/streams/stream-player/types.d.ts +40 -0
  86. package/dist/ui/player/index.d.ts +1 -1
  87. package/dist/ui/player/player-buffer.svelte.d.ts +3 -3
  88. package/package.json +5 -1
  89. package/dist/streams/stream-player/cmp.stream-player.svelte.d.ts +0 -22
@@ -4,14 +4,14 @@ export declare class ShortVideosPlayerUiManager {
4
4
  isMobileView: boolean;
5
5
  viewInitialized: boolean;
6
6
  showShortVideoOverlay: boolean;
7
- private readonly buttonSize;
8
- private readonly iconSize;
9
- private readonly controlsOffsetHorizontal;
10
- private readonly controlsOffsetVertical;
11
- private viewTotalWidth;
12
- private mainViewColumnWidth;
7
+ private _viewTotalWidth;
8
+ private _mainViewColumnWidth;
9
+ private _mediaCenterHeaderHeight;
10
+ get viewTotalWidth(): number;
11
+ get mainViewColumnWidth(): number;
13
12
  updateDimensions: (dimensions: {
14
13
  viewTotalWidth: number;
15
14
  mainViewColumnWidth: number;
16
15
  }) => void;
16
+ updateMediaCenterHeaderHeight: (height: number) => void;
17
17
  }
@@ -1,26 +1,38 @@
1
+ const CONTROLS_PADDING_HORIZONTAL = 28;
2
+ const CONTROLS_PADDING_VERTICAL = 28;
3
+ const PLAYER_PADDING_VERTICAL = 10;
4
+ const BUTTON_SIZE = 48;
5
+ const ICON_SIZE = 28;
1
6
  export class ShortVideosPlayerUiManager {
2
7
  showAttachments = $state(true);
3
8
  globalCssVariables = $derived.by(() => {
4
9
  const values = [
5
- `--short-videos-player--button--size: ${this.buttonSize}px`,
6
- `--short-videos-player--icon--size: ${this.iconSize}px`,
7
- `--short-videos-player--controls--offset-horizontal: ${this.controlsOffsetHorizontal}px`,
8
- `--short-videos-player--controls--offset-vertical: ${this.controlsOffsetVertical}px`,
9
- `--short-videos-player--sidebar--available-space: ${(this.viewTotalWidth - this.mainViewColumnWidth) / 2}px`
10
+ `--short-videos-player--button--size: ${BUTTON_SIZE}px`,
11
+ `--short-videos-player--controls--available-space: ${(this._viewTotalWidth - this._mainViewColumnWidth) / 2}px`,
12
+ `--short-videos-player--controls--padding: ${this._mediaCenterHeaderHeight ? 0 : CONTROLS_PADDING_VERTICAL}px ${CONTROLS_PADDING_HORIZONTAL}px ${CONTROLS_PADDING_VERTICAL}px`,
13
+ `--short-videos-player--icon--size: ${ICON_SIZE}px`,
14
+ `--short-videos-player--media-center-header--height: ${this._mediaCenterHeaderHeight}px`,
15
+ `--short-videos-player--padding: ${this._mediaCenterHeaderHeight ? this._mediaCenterHeaderHeight : PLAYER_PADDING_VERTICAL}px 0 ${PLAYER_PADDING_VERTICAL}px`
10
16
  ];
11
17
  return values.join(';');
12
18
  });
13
- isMobileView = $derived.by(() => this.viewTotalWidth <= 576);
14
- viewInitialized = $derived.by(() => !!this.viewTotalWidth && !!this.mainViewColumnWidth);
15
- showShortVideoOverlay = $derived.by(() => this.viewInitialized && (this.viewTotalWidth - this.mainViewColumnWidth) / 2 <= 85);
16
- buttonSize = 48;
17
- iconSize = 28;
18
- controlsOffsetHorizontal = 28;
19
- controlsOffsetVertical = 28;
20
- viewTotalWidth = $state(0);
21
- mainViewColumnWidth = $state(0);
19
+ isMobileView = $derived.by(() => this._viewTotalWidth <= 576);
20
+ viewInitialized = $derived.by(() => !!this._viewTotalWidth && !!this._mainViewColumnWidth);
21
+ showShortVideoOverlay = $derived.by(() => this.viewInitialized && (this._viewTotalWidth - this._mainViewColumnWidth) / 2 <= 85);
22
+ _viewTotalWidth = $state(0);
23
+ _mainViewColumnWidth = $state(0);
24
+ _mediaCenterHeaderHeight = $state(0);
25
+ get viewTotalWidth() {
26
+ return this._viewTotalWidth;
27
+ }
28
+ get mainViewColumnWidth() {
29
+ return this._mainViewColumnWidth;
30
+ }
22
31
  updateDimensions = (dimensions) => {
23
- this.viewTotalWidth = dimensions.viewTotalWidth;
24
- this.mainViewColumnWidth = dimensions.mainViewColumnWidth;
32
+ this._viewTotalWidth = dimensions.viewTotalWidth;
33
+ this._mainViewColumnWidth = dimensions.mainViewColumnWidth;
34
+ };
35
+ updateMediaCenterHeaderHeight = (height) => {
36
+ this._mediaCenterHeaderHeight = height;
25
37
  };
26
38
  }
@@ -5,4 +5,9 @@ let { data, localization: localizationInit, on } = $props();
5
5
  const localization = $derived(new ShortVideoStreamElementLocalization(localizationInit));
6
6
  </script>
7
7
 
8
- <ShortVideoViewer model={mapToShortVideoViewerModel(data)} autoplay={false} localization={localization.shortVideoViewerLocalization} on={on} />
8
+ <ShortVideoViewer
9
+ model={mapToShortVideoViewerModel(data)}
10
+ autoplay={false}
11
+ showControls={false}
12
+ localization={localization.shortVideoViewerLocalization}
13
+ on={on} />
@@ -1,3 +1,4 @@
1
1
  export { default as StreamPageViewer } from './cmp.stream-page-viewer.svelte';
2
2
  export type { StreamPageViewerModel } from './types';
3
3
  export type { IStreamPageViewerLocalization } from './stream-page-viewer-localization';
4
+ export { mapToStreamPageViewerModel } from './mapper';
@@ -1 +1,2 @@
1
1
  export { default as StreamPageViewer } from './cmp.stream-page-viewer.svelte';
2
+ export { mapToStreamPageViewerModel } from './mapper';
@@ -9,7 +9,7 @@ import { StreamPlayerLocalization } from './stream-player-localization';
9
9
  import IconChevronDown from '@fluentui/svg-icons/icons/chevron_down_28_regular.svg?raw';
10
10
  import IconChevronUp from '@fluentui/svg-icons/icons/chevron_up_28_regular.svg?raw';
11
11
  import IconDismiss from '@fluentui/svg-icons/icons/dismiss_28_regular.svg?raw';
12
- let { buffer, uiManager, shortVideoSocialInteractionsHandler, localization, on } = $props();
12
+ let { buffer, uiManager, postSocialInteractionsHandler, localization, on } = $props();
13
13
  const shortVideo = $derived(((_a = buffer.current) === null || _a === void 0 ? void 0 : _a.type) === 'short-video' && ((_b = buffer.current) === null || _b === void 0 ? void 0 : _b.shortVideo) ? mapToShortVideoViewerModel(buffer.current.shortVideo) : null);
14
14
  const singleWebViewPage = $derived.by(() => {
15
15
  var _a;
@@ -58,7 +58,7 @@ const changeShowShortVideoAttachments = () => {
58
58
  {/if}
59
59
  <ShortVideoControls
60
60
  model={shortVideo}
61
- socialInteractionsHandler={shortVideoSocialInteractionsHandler}
61
+ socialInteractionsHandler={postSocialInteractionsHandler}
62
62
  on={{ attachmentsClicked: changeShowShortVideoAttachments }} />
63
63
  </div>
64
64
  {/if}
@@ -1,11 +1,11 @@
1
- import { type ShortVideoSocialInteractionsHandler } from '../../short-videos/short-video-viewer';
1
+ import { type IPostSocialInteractionsHandler } from '../../short-videos/short-video-viewer';
2
2
  import type { StreamPlayerBuffer } from './stream-player-buffer.svelte';
3
3
  import { StreamPlayerLocalization } from './stream-player-localization';
4
4
  import type { StreamPlayerUiManager } from './ui-manager.svelte';
5
5
  type Props = {
6
6
  buffer: StreamPlayerBuffer;
7
7
  uiManager: StreamPlayerUiManager;
8
- shortVideoSocialInteractionsHandler?: ShortVideoSocialInteractionsHandler;
8
+ postSocialInteractionsHandler?: IPostSocialInteractionsHandler;
9
9
  localization: StreamPlayerLocalization;
10
10
  on: {
11
11
  closePlayer: () => void;
@@ -1,41 +1,98 @@
1
- import type { ShortVideoSocialInteractionsHandler } from '../../short-videos/short-video-viewer';
1
+ import { type IMediaCenterDataProvider } from '../../media-center/data-provider';
2
+ import type { StreamPageViewerModel } from '../stream-page-viewer/types';
2
3
  import type { IStreamPlayerLocalization } from './stream-player-localization';
3
- export type { IStreamPlayerLocalization };
4
+ import type { IStreamAnalyticsHandler, IStreamPlayerDataProvider, PlayerSettings, StreamPlayerModel } from './types';
5
+ export type { IStreamPlayerLocalization, IStreamPlayerDataProvider, IStreamAnalyticsHandler, IMediaCenterDataProvider, StreamPlayerModel, StreamPageViewerModel };
4
6
  /**
5
- * Opens the stream player modal with the specified stream details.
7
+ * Opens the stream player modal.
6
8
  *
7
- * @param init - Configuration options.
8
- * @param {string} init.streamId - The ID of the stream to open.
9
- * @param {string} init.graphqlUrl - The URL of the GraphQL endpoint.
10
- * @param {IStreamPlayerLocalization} [init.localization] - Optional localization settings for the player UI.
11
- * @param init.on - Available callbacks.
9
+ * Two overloads (mutually exclusive; enforced by TypeScript):
10
+ * - Provider mode: openStreamPlayer({ dataProvider, mediaCenterDataProvider?, analyticsHandler?, ...common })
11
+ * - Internal provider mode: openStreamPlayer({ initiator, graphqlOrigin?, mediaPageId?, ...common })
12
12
  *
13
- * @example
13
+ * @param init Configuration options.
14
+ *
15
+ * Common (required)
16
+ * @param {string} init.streamId
17
+ * The ID of the stream to open.
18
+ *
19
+ * Provider mode (overload 1)
20
+ * @param {IStreamPlayerDataProvider} init.dataProvider
21
+ * Provider that supplies the stream data to the player.
22
+ * @param {IMediaCenterDataProvider} [init.mediaCenterDataProvider]
23
+ * Optional media-center data provider.
24
+ * @param {IStreamAnalyticsHandler} [init.analyticsHandler]
25
+ * Optional analytics handler to capture player/stream analytics events.
26
+ * If omitted in provider mode, analytics is not auto-initialized.
27
+ *
28
+ * Internal provider mode (overload 2)
29
+ * @param {string} init.initiator
30
+ * Initiator identifier (used for tracking/analytics and GraphQL).
31
+ * @param {string} [init.graphqlOrigin]
32
+ * Optional GraphQL origin (base URL). If omitted, the default origin is determined internally.
33
+ * @param {string} [init.mediaPageId]
34
+ * Optional media page ID used to construct an internal media-center data provider.
35
+ *
36
+ * Common (optional)
37
+ * @param {IStreamPlayerLocalization | Locale} [init.localization]
38
+ * Localization for the player UI. If omitted, 'en' is used.
39
+ * @param {boolean} [init.showStreamsCloudWatermark]
40
+ * If true, shows the StreamsCloud watermark.
41
+ * @param {IPostSocialInteractionsHandler} [init.postSocialInteractionsHandler]
42
+ * Handler for social interactions (like, share, etc.).
43
+ *
44
+ * Events
45
+ * @param {{ streamActivated?: (data: { title: string; image: string | null }) => void; playerClosed?: () => void }} [init.on]
46
+ * Optional event handlers.
47
+ * @param {(data: { title: string; image: string | null }) => void} [init.on.streamActivated]
48
+ * Called when the stream becomes active. Receives a subset of data with title and image.
49
+ * @param {() => void} [init.on.playerClosed]
50
+ * Called after the player is fully closed (after unmount and removal from the DOM).
51
+ *
52
+ * @returns {void}
53
+ *
54
+ * @example <caption>Provider mode</caption>
55
+ * ```ts
56
+ * import { openStreamPlayer } from '@streamscloud/embeddable/stream-player';
57
+ *
58
+ * openStreamPlayer({
59
+ * streamId: 'stream_123',
60
+ * dataProvider: myStreamProvider,
61
+ * mediaCenterDataProvider: myMediaCenterProvider,
62
+ * analyticsHandler: myAnalyticsHandler,
63
+ * localization: { play: 'Play', pause: 'Pause' },
64
+ * showStreamsCloudWatermark: true,
65
+ * on: {
66
+ * streamActivated: ({ title, image }) => console.log('Stream active:', title, image),
67
+ * playerClosed: () => console.log('Player closed')
68
+ * }
69
+ * });
70
+ * ```
71
+ *
72
+ * @example <caption>Internal provider mode</caption>
14
73
  * ```ts
15
74
  * import { openStreamPlayer } from '@streamscloud/embeddable/stream-player';
16
75
  *
17
76
  * openStreamPlayer({
18
- * streamId: '...',
77
+ * streamId: 'stream_123',
78
+ * initiator: 'marketing-campaign',
19
79
  * graphqlOrigin: 'https://api.example.com',
20
- * localization: {
21
- * play: 'Play',
22
- * pause: 'Pause'
80
+ * mediaPageId: 'media-page-123',
81
+ * localization: { play: 'Play', pause: 'Pause' },
82
+ * on: {
83
+ * streamActivated: ({ title, image }) => console.log('Stream active:', title, image),
84
+ * playerClosed: () => console.log('Player closed')
23
85
  * }
24
86
  * });
25
87
  * ```
26
88
  */
27
- export declare const openStreamPlayer: (init: {
28
- streamId: string;
89
+ export declare function openStreamPlayer(init: PlayerSettings & {
90
+ dataProvider: IStreamPlayerDataProvider;
91
+ mediaCenterDataProvider?: IMediaCenterDataProvider;
92
+ analyticsHandler?: IStreamAnalyticsHandler;
93
+ }): void;
94
+ export declare function openStreamPlayer(init: PlayerSettings & {
95
+ initiator: string;
29
96
  graphqlOrigin?: string;
30
- localization?: IStreamPlayerLocalization | "en" | "no";
31
- showStreamsCloudWatermark?: boolean;
32
- shortVideoSocialInteractionsHandler?: ShortVideoSocialInteractionsHandler;
33
- initiator?: string;
34
- on?: {
35
- streamActivated?: (data: {
36
- title: string;
37
- image: string | null;
38
- }) => void;
39
- playerClosed?: () => void;
40
- };
41
- }) => void;
97
+ mediaPageId?: string;
98
+ }): void;
@@ -1,59 +1,57 @@
1
- import { getLocale } from '../../core/locale';
1
+ import { toastrWarning } from '../../core/toastr';
2
+ import { InternalMediaCenterDataProvider } from '../../media-center/data-provider';
3
+ import { MediaCenter, MediaCenterMode } from '../../media-center/media-center';
2
4
  import { ModalShadowHost } from '../../ui/shadow-dom';
3
- import { default as StreamPlayer } from './cmp.stream-player.svelte';
4
- import { AppEventsTracker } from '@streamscloud/streams-analytics-collector';
5
+ import { InternalStreamAnalyticsHandler } from './internal-stream-analytics-handler';
6
+ import { InternalStreamPlayerDataProvider } from './internal-stream-player-data-provider';
5
7
  import { mount, unmount } from 'svelte';
6
- /**
7
- * Opens the stream player modal with the specified stream details.
8
- *
9
- * @param init - Configuration options.
10
- * @param {string} init.streamId - The ID of the stream to open.
11
- * @param {string} init.graphqlUrl - The URL of the GraphQL endpoint.
12
- * @param {IStreamPlayerLocalization} [init.localization] - Optional localization settings for the player UI.
13
- * @param init.on - Available callbacks.
14
- *
15
- * @example
16
- * ```ts
17
- * import { openStreamPlayer } from '@streamscloud/embeddable/stream-player';
18
- *
19
- * openStreamPlayer({
20
- * streamId: '...',
21
- * graphqlOrigin: 'https://api.example.com',
22
- * localization: {
23
- * play: 'Play',
24
- * pause: 'Pause'
25
- * }
26
- * });
27
- * ```
28
- */
29
- export const openStreamPlayer = (init) => {
30
- const { streamId, graphqlOrigin, localization, showStreamsCloudWatermark, shortVideoSocialInteractionsHandler, initiator } = init;
8
+ export function openStreamPlayer(init) {
9
+ const { streamId, graphqlOrigin, localization, showStreamsCloudWatermark, postSocialInteractionsHandler, initiator } = init;
10
+ const dataProvider = init.dataProvider ?? new InternalStreamPlayerDataProvider({ graphqlOrigin, initiator });
11
+ if (!dataProvider) {
12
+ toastrWarning('Data provider is not specified.');
13
+ return;
14
+ }
15
+ let mediaCenterDataProvider = init.mediaCenterDataProvider;
16
+ if (!mediaCenterDataProvider && init.mediaPageId) {
17
+ mediaCenterDataProvider = new InternalMediaCenterDataProvider(init.mediaPageId, graphqlOrigin);
18
+ }
19
+ let analyticsHandler = init.analyticsHandler;
20
+ if (!analyticsHandler && !init.dataProvider) {
21
+ // Only create internal analytics handler if using internal data provider
22
+ analyticsHandler = new InternalStreamAnalyticsHandler(graphqlOrigin);
23
+ }
31
24
  const shadowHost = new ModalShadowHost();
32
- const mounted = mount(StreamPlayer, {
25
+ const mounted = mount(MediaCenter, {
33
26
  target: shadowHost.shadowRoot,
34
27
  props: {
35
- streamId,
36
- graphqlOrigin,
37
- localization: getLocale(localization),
38
- showStreamsCloudWatermark,
39
- shortVideoSocialInteractionsHandler,
40
- initiator,
41
- on: {
42
- streamActivated: (data) => {
43
- AppEventsTracker.setOrganizationId(data.ownerId);
44
- if (init.on?.streamActivated) {
45
- init.on.streamActivated({ title: data.title, image: data.image });
28
+ dataProvider: mediaCenterDataProvider || null,
29
+ playerProps: {
30
+ type: MediaCenterMode.Stream,
31
+ props: {
32
+ streamId,
33
+ dataProvider,
34
+ analyticsHandler,
35
+ localization,
36
+ showStreamsCloudWatermark,
37
+ postSocialInteractionsHandler,
38
+ on: {
39
+ streamActivated: (data) => {
40
+ if (init.on?.streamActivated) {
41
+ init.on.streamActivated({ title: data.title, image: data.image });
42
+ }
43
+ },
44
+ playerClosed: async () => {
45
+ await unmount(mounted);
46
+ shadowHost.remove();
47
+ if (init.on?.playerClosed) {
48
+ init.on.playerClosed();
49
+ }
50
+ }
46
51
  }
47
- },
48
- closePlayer: async () => {
49
- if (init.on?.playerClosed) {
50
- init.on.playerClosed();
51
- }
52
- await unmount(mounted);
53
- shadowHost.remove();
54
52
  }
55
53
  }
56
54
  }
57
55
  });
58
56
  shadowHost.attachToBody();
59
- };
57
+ }
@@ -0,0 +1,12 @@
1
+ import type { IStreamAnalyticsHandler } from './types';
2
+ export declare class InternalStreamAnalyticsHandler implements IStreamAnalyticsHandler {
3
+ constructor(graphqlOrigin: string | undefined);
4
+ setOrganizationId: (organizationId: string) => void;
5
+ trackStreamView: (streamId: string) => void;
6
+ trackStreamPageView: (pageId: string, streamId: string) => void;
7
+ trackStreamProductClicked: (productId: string, streamId: string) => void;
8
+ trackStreamEngagementTime: (streamId: string, engagementTime: number) => void;
9
+ trackStreamScrollDepth: (streamId: string, scrollDepth: number) => void;
10
+ reportPageVideoViews: (videoId: string, streamId: string) => void;
11
+ trackShortVideoProgress: (pageId: string, videoId: string, progress: number, streamId: string) => void;
12
+ }
@@ -0,0 +1,17 @@
1
+ import { getOrCreateProfileId } from '../../core/analytics.profile-id';
2
+ import { constructGraphQLUrl } from '../../core/graphql';
3
+ import { AppEventsTracker } from '@streamscloud/streams-analytics-collector';
4
+ export class InternalStreamAnalyticsHandler {
5
+ constructor(graphqlOrigin) {
6
+ AppEventsTracker.setEndpoint(constructGraphQLUrl(graphqlOrigin));
7
+ AppEventsTracker.setProfileId(getOrCreateProfileId());
8
+ }
9
+ setOrganizationId = (organizationId) => AppEventsTracker.setOrganizationId(organizationId);
10
+ trackStreamView = (streamId) => AppEventsTracker.trackStreamView(streamId);
11
+ trackStreamPageView = (pageId, streamId) => AppEventsTracker.trackStreamPageView(pageId, streamId);
12
+ trackStreamProductClicked = (productId, streamId) => AppEventsTracker.trackStreamProductClicked(productId, streamId);
13
+ trackStreamEngagementTime = (streamId, engagementTime) => AppEventsTracker.trackStreamEngagementTime(streamId, engagementTime);
14
+ trackStreamScrollDepth = (streamId, scrollDepth) => AppEventsTracker.trackStreamScrollDepth(streamId, scrollDepth);
15
+ reportPageVideoViews = (videoId, streamId) => AppEventsTracker.reportPageVideoViews(videoId, streamId);
16
+ trackShortVideoProgress = (pageId, videoId, progress, streamId) => AppEventsTracker.trackShortVideoProgress(pageId, videoId, progress, streamId);
17
+ }
@@ -0,0 +1,10 @@
1
+ import type { IStreamPlayerDataProvider } from './types';
2
+ export declare class InternalStreamPlayerDataProvider implements IStreamPlayerDataProvider {
3
+ private graphql;
4
+ constructor(input: {
5
+ initiator?: string;
6
+ graphqlOrigin?: string;
7
+ });
8
+ getStream: IStreamPlayerDataProvider['getStream'];
9
+ getStreamPages: IStreamPlayerDataProvider['getStreamPages'];
10
+ }
@@ -0,0 +1,48 @@
1
+ import { ImageScale } from '../..';
2
+ import { createLocalGQLClient } from '../../core/graphql';
3
+ import { mapToStreamPageViewerModel } from '../stream-page-viewer';
4
+ import { mapToStreamPlayerModel } from './mapper';
5
+ import { GetStreamDocument, GetStreamPagesDocument } from './operations.generated';
6
+ export class InternalStreamPlayerDataProvider {
7
+ graphql;
8
+ constructor(input) {
9
+ const { graphqlOrigin, initiator } = input;
10
+ this.graphql = createLocalGQLClient(graphqlOrigin, initiator ? { 'x-initiator': initiator } : undefined);
11
+ }
12
+ getStream = async (id) => {
13
+ const streamPayload = await this.graphql.query(GetStreamDocument, { id }).toPromise();
14
+ if (!streamPayload.data?.stream) {
15
+ return null;
16
+ }
17
+ return mapToStreamPlayerModel(streamPayload.data.stream);
18
+ };
19
+ getStreamPages = async (streamId, continuationToken) => {
20
+ const emptyResult = { items: [], continuationToken: null };
21
+ if (continuationToken === null) {
22
+ return emptyResult;
23
+ }
24
+ try {
25
+ const payload = await this.graphql
26
+ .query(GetStreamPagesDocument, {
27
+ input: {
28
+ limit: 10,
29
+ continuationToken,
30
+ filter: { streamId }
31
+ },
32
+ image_scale: ImageScale.OriginalEncoded
33
+ })
34
+ .toPromise();
35
+ const data = payload.data?.streamPages;
36
+ if (!data) {
37
+ return emptyResult;
38
+ }
39
+ return {
40
+ items: data.items.map(mapToStreamPageViewerModel),
41
+ continuationToken: data.continuationToken
42
+ };
43
+ }
44
+ catch {
45
+ return emptyResult;
46
+ }
47
+ };
48
+ }
@@ -4,8 +4,10 @@ export const mapToStreamPlayerModel = (payload) => {
4
4
  id: payload.id,
5
5
  title: payload.title,
6
6
  subTitle: payload.subTitle || null,
7
+ cover: payload.cover?.url || null,
7
8
  createdAt: payload.createdAt,
8
9
  publishedAt: payload.publishedAt,
10
+ organizationId: payload.ownerProfile.id,
9
11
  header: {
10
12
  name: headerDataProvider.name,
11
13
  image: headerDataProvider.image
@@ -18,7 +18,6 @@ export type GetStreamQuery = {
18
18
  image: string | null;
19
19
  name: string;
20
20
  id: string;
21
- type: SchemaTypes.ProfileType;
22
21
  };
23
22
  availableFrom: {
24
23
  image: string;
@@ -57,7 +56,6 @@ export type StreamPlayerPayloadFragment = {
57
56
  image: string | null;
58
57
  name: string;
59
58
  id: string;
60
- type: SchemaTypes.ProfileType;
61
59
  };
62
60
  availableFrom: {
63
61
  image: string;
@@ -26,8 +26,7 @@ export const StreamPlayerPayloadFragmentDoc = {
26
26
  selections: [
27
27
  { kind: 'Field', name: { kind: 'Name', value: 'image' } },
28
28
  { kind: 'Field', name: { kind: 'Name', value: 'name' } },
29
- { kind: 'Field', name: { kind: 'Name', value: 'id' } },
30
- { kind: 'Field', name: { kind: 'Name', value: 'type' } }
29
+ { kind: 'Field', name: { kind: 'Name', value: 'id' } }
31
30
  ]
32
31
  }
33
32
  },
@@ -109,8 +108,7 @@ export const GetStreamDocument = {
109
108
  selections: [
110
109
  { kind: 'Field', name: { kind: 'Name', value: 'image' } },
111
110
  { kind: 'Field', name: { kind: 'Name', value: 'name' } },
112
- { kind: 'Field', name: { kind: 'Name', value: 'id' } },
113
- { kind: 'Field', name: { kind: 'Name', value: 'type' } }
111
+ { kind: 'Field', name: { kind: 'Name', value: 'id' } }
114
112
  ]
115
113
  }
116
114
  },
@@ -27,7 +27,6 @@ fragment StreamPlayerPayloadFragment on Stream {
27
27
  image
28
28
  name
29
29
  id
30
- type
31
30
  }
32
31
  availableFrom {
33
32
  image
@@ -1,6 +1,6 @@
1
1
  import { type StreamPageViewerModel } from '../stream-page-viewer';
2
2
  import type { IPlayerBuffer } from '../../ui/player';
3
- import type { Client } from '@urql/core';
3
+ import type { IStreamPlayerDataProvider } from './types';
4
4
  export declare class StreamPlayerBuffer implements IPlayerBuffer<StreamPageViewerModel> {
5
5
  readonly loaded: StreamPageViewerModel[];
6
6
  readonly currentIndex: number;
@@ -9,17 +9,17 @@ export declare class StreamPlayerBuffer implements IPlayerBuffer<StreamPageViewe
9
9
  readonly canLoadPrevious: boolean;
10
10
  readonly navigationDisabled: boolean;
11
11
  readonly animationDuration = 300;
12
- private _pagesLoader;
13
12
  private _currentIndex;
14
13
  private _loaded;
15
- constructor(data: {
14
+ private _pagesLoader;
15
+ constructor(init: {
16
16
  streamId: string;
17
- graphql: Client;
17
+ dataProvider: IStreamPlayerDataProvider;
18
18
  });
19
19
  loadMore: () => Promise<StreamPageViewerModel[]>;
20
20
  loadNext: () => Promise<void>;
21
21
  loadPrevious: () => Promise<void>;
22
22
  setIndex: (index: number) => void;
23
- reset: () => void;
23
+ reset: () => Promise<void>;
24
24
  private warmUpBuffer;
25
25
  }
@@ -1,10 +1,7 @@
1
1
  import { ContinuationToken } from '../../core/continuation-token';
2
2
  import { CursorDataLoader } from '../../core/data-loaders';
3
- import { ImageScale } from '../../core/enums';
4
3
  import { Utils } from '../../core/utils';
5
4
  import {} from '../stream-page-viewer';
6
- import { mapToStreamPageViewerModel } from '../stream-page-viewer/mapper';
7
- import { GetStreamPagesDocument } from './operations.generated';
8
5
  export class StreamPlayerBuffer {
9
6
  loaded = $derived.by(() => this._loaded);
10
7
  currentIndex = $derived.by(() => this._currentIndex);
@@ -13,34 +10,19 @@ export class StreamPlayerBuffer {
13
10
  canLoadPrevious = $derived(this.currentIndex > 0);
14
11
  navigationDisabled = $derived(!this.canLoadNext && !this.canLoadPrevious);
15
12
  animationDuration = 300;
16
- _pagesLoader;
17
13
  _currentIndex = $state(-1);
18
14
  _loaded = $state.raw([]);
19
- constructor(data) {
20
- const { streamId, graphql } = data;
15
+ _pagesLoader;
16
+ constructor(init) {
17
+ const { streamId, dataProvider } = init;
21
18
  this._pagesLoader = new CursorDataLoader({
22
19
  loadPage: async (continuationToken) => {
23
- const payload = await graphql
24
- .query(GetStreamPagesDocument, {
25
- input: {
26
- limit: 10,
27
- continuationToken,
28
- filter: {
29
- streamId
30
- }
31
- },
32
- image_scale: ImageScale.OriginalEncoded
33
- })
34
- .toPromise();
35
- const data = payload.data?.streamPages;
36
- if (!data) {
37
- return null;
38
- }
39
- const items = data.items.map(mapToStreamPageViewerModel);
20
+ const result = await dataProvider.getStreamPages(streamId, continuationToken.toRawFormat());
21
+ const items = result.items;
40
22
  this._loaded = [...this._loaded, ...items];
41
23
  return {
42
24
  items: items,
43
- continuationToken: ContinuationToken.fromPayload(data.continuationToken)
25
+ continuationToken: ContinuationToken.fromPayload(result.continuationToken)
44
26
  };
45
27
  }
46
28
  });
@@ -66,15 +48,18 @@ export class StreamPlayerBuffer {
66
48
  this._currentIndex = index;
67
49
  this.warmUpBuffer();
68
50
  };
69
- reset = () => {
70
- this._pagesLoader.reset();
51
+ reset = async () => {
52
+ this._loaded = [];
53
+ this._currentIndex = -1;
54
+ await this._pagesLoader.reset();
55
+ this.warmUpBuffer();
71
56
  };
72
57
  warmUpBuffer = async () => {
73
58
  const bufferSize = 2;
74
59
  if (this.loaded.length >= this.currentIndex + bufferSize) {
75
60
  return;
76
61
  }
77
- await this._pagesLoader.loadMore();
62
+ await this.loadMore();
78
63
  if (this._currentIndex < 0) {
79
64
  if (this.loaded.length > 0) {
80
65
  this._currentIndex = 0;