@streamscloud/embeddable 5.1.3 → 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.
- package/dist/ads/ad-card/mapper.js +1 -1
- package/dist/core/continuation-token.d.ts +1 -0
- package/dist/core/continuation-token.js +3 -0
- package/dist/core/locale.d.ts +0 -1
- package/dist/core/locale.js +0 -12
- package/dist/core/media/media-item-url.service.d.ts +1 -1
- package/dist/core/media/media-item-url.service.js +1 -6
- package/dist/media-center/data-provider/index.d.ts +2 -0
- package/dist/media-center/data-provider/index.js +1 -0
- package/dist/media-center/data-provider/internal-media-center-data-provider.svelte.d.ts +8 -0
- package/dist/media-center/data-provider/internal-media-center-data-provider.svelte.js +44 -0
- package/dist/media-center/data-provider/operations.generated.d.ts +89 -0
- package/dist/media-center/data-provider/operations.generated.js +275 -0
- package/dist/media-center/data-provider/operations.graphql +25 -0
- package/dist/media-center/data-provider/types.d.ts +24 -0
- package/dist/media-center/data-provider/types.js +1 -0
- package/dist/media-center/index.d.ts +1 -0
- package/dist/media-center/index.js +1 -0
- package/dist/media-center/media-center/cmp.media-center.svelte +336 -0
- package/dist/media-center/media-center/cmp.media-center.svelte.d.ts +20 -0
- package/dist/media-center/media-center/index.d.ts +3 -0
- package/dist/media-center/media-center/index.js +2 -0
- package/dist/media-center/media-center/media-center-localization.d.ts +11 -0
- package/dist/media-center/media-center/media-center-localization.js +15 -0
- package/dist/media-center/media-center/overview.svelte +142 -0
- package/dist/media-center/media-center/overview.svelte.d.ts +13 -0
- package/dist/media-center/media-center/short-video-resources-generator.d.ts +8 -0
- package/dist/media-center/media-center/short-video-resources-generator.js +26 -0
- package/dist/media-center/media-center/types.d.ts +10 -0
- package/dist/media-center/media-center/types.js +5 -0
- package/dist/products/product-card/cmp.product-card.svelte +11 -6
- package/dist/products/product-card/mapper.js +3 -3
- package/dist/short-videos/short-video-card/cmp.short-video-card.svelte +118 -0
- package/dist/short-videos/short-video-card/cmp.short-video-card.svelte.d.ts +11 -0
- package/dist/short-videos/short-video-card/index.d.ts +2 -0
- package/dist/short-videos/short-video-card/index.js +1 -0
- package/dist/short-videos/short-video-card/types.d.ts +5 -0
- package/dist/short-videos/short-video-card/types.js +1 -0
- package/dist/short-videos/short-video-viewer/cmp.short-video-controls.svelte +3 -3
- package/dist/short-videos/short-video-viewer/cmp.short-video-controls.svelte.d.ts +2 -2
- package/dist/short-videos/short-video-viewer/cmp.short-video-viewer.svelte +8 -26
- package/dist/short-videos/short-video-viewer/cmp.short-video-viewer.svelte.d.ts +2 -3
- package/dist/short-videos/short-video-viewer/index.d.ts +1 -1
- package/dist/short-videos/short-video-viewer/mapper.js +6 -3
- package/dist/short-videos/short-video-viewer/types.d.ts +8 -6
- package/dist/short-videos/short-video-viewer/ui-manager.svelte.d.ts +0 -5
- package/dist/short-videos/short-video-viewer/ui-manager.svelte.js +0 -11
- package/dist/short-videos/short-videos-player/cmp.short-videos-player.svelte +16 -12
- package/dist/short-videos/short-videos-player/cmp.short-videos-player.svelte.d.ts +5 -15
- package/dist/short-videos/short-videos-player/controls.svelte +34 -3
- package/dist/short-videos/short-videos-player/controls.svelte.d.ts +3 -2
- package/dist/short-videos/short-videos-player/fade-mixins.scss +12 -0
- package/dist/short-videos/short-videos-player/index.d.ts +66 -36
- package/dist/short-videos/short-videos-player/index.js +40 -104
- package/dist/short-videos/short-videos-player/internal-short-video-player-provider.d.ts +17 -0
- package/dist/short-videos/short-videos-player/internal-short-video-player-provider.js +59 -0
- package/dist/short-videos/short-videos-player/operations.generated.d.ts +1 -0
- package/dist/short-videos/short-videos-player/operations.generated.js +2 -1
- package/dist/short-videos/short-videos-player/operations.graphql +1 -0
- package/dist/short-videos/short-videos-player/short-videos-player-view.svelte +36 -55
- package/dist/short-videos/short-videos-player/short-videos-player-view.svelte.d.ts +12 -15
- package/dist/short-videos/short-videos-player/types.d.ts +8 -29
- package/dist/short-videos/short-videos-player/types.js +1 -6
- package/dist/short-videos/short-videos-player/ui-manager.svelte.d.ts +6 -6
- package/dist/short-videos/short-videos-player/ui-manager.svelte.js +28 -16
- package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte +6 -1
- package/dist/streams/stream-page-viewer/index.d.ts +1 -0
- package/dist/streams/stream-page-viewer/index.js +1 -0
- package/dist/streams/stream-player/controls.svelte +2 -2
- package/dist/streams/stream-player/controls.svelte.d.ts +2 -2
- package/dist/streams/stream-player/index.d.ts +84 -27
- package/dist/streams/stream-player/index.js +46 -48
- package/dist/streams/stream-player/internal-stream-analytics-handler.d.ts +12 -0
- package/dist/streams/stream-player/internal-stream-analytics-handler.js +17 -0
- package/dist/streams/stream-player/internal-stream-player-data-provider.d.ts +10 -0
- package/dist/streams/stream-player/internal-stream-player-data-provider.js +48 -0
- package/dist/streams/stream-player/mapper.js +2 -0
- package/dist/streams/stream-player/operations.generated.d.ts +0 -2
- package/dist/streams/stream-player/operations.generated.js +2 -4
- package/dist/streams/stream-player/operations.graphql +0 -1
- package/dist/streams/stream-player/stream-player-buffer.svelte.d.ts +5 -5
- package/dist/streams/stream-player/stream-player-buffer.svelte.js +12 -27
- package/dist/streams/stream-player/{cmp.stream-player.svelte → stream-player.svelte} +19 -37
- package/dist/streams/stream-player/stream-player.svelte.d.ts +4 -0
- package/dist/streams/stream-player/types.d.ts +40 -0
- package/dist/ui/player/index.d.ts +1 -1
- package/dist/ui/player/player-buffer.svelte.d.ts +3 -3
- package/package.json +5 -1
- 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
|
|
8
|
-
private
|
|
9
|
-
private
|
|
10
|
-
|
|
11
|
-
|
|
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: ${
|
|
6
|
-
`--short-videos-player--
|
|
7
|
-
`--short-videos-player--controls--
|
|
8
|
-
`--short-videos-player--
|
|
9
|
-
`--short-videos-player--
|
|
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.
|
|
14
|
-
viewInitialized = $derived.by(() => !!this.
|
|
15
|
-
showShortVideoOverlay = $derived.by(() => this.viewInitialized && (this.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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.
|
|
24
|
-
this.
|
|
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
|
|
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';
|
|
@@ -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,
|
|
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={
|
|
61
|
+
socialInteractionsHandler={postSocialInteractionsHandler}
|
|
62
62
|
on={{ attachmentsClicked: changeShowShortVideoAttachments }} />
|
|
63
63
|
</div>
|
|
64
64
|
{/if}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { type
|
|
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
|
-
|
|
8
|
+
postSocialInteractionsHandler?: IPostSocialInteractionsHandler;
|
|
9
9
|
localization: StreamPlayerLocalization;
|
|
10
10
|
on: {
|
|
11
11
|
closePlayer: () => void;
|
|
@@ -1,41 +1,98 @@
|
|
|
1
|
-
import type
|
|
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
|
-
|
|
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
|
|
7
|
+
* Opens the stream player modal.
|
|
6
8
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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
|
-
* @
|
|
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
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
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
|
|
28
|
-
|
|
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
|
-
|
|
31
|
-
|
|
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 {
|
|
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 {
|
|
4
|
-
import {
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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(
|
|
25
|
+
const mounted = mount(MediaCenter, {
|
|
33
26
|
target: shadowHost.shadowRoot,
|
|
34
27
|
props: {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type StreamPageViewerModel } from '../stream-page-viewer';
|
|
2
2
|
import type { IPlayerBuffer } from '../../ui/player';
|
|
3
|
-
import type {
|
|
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
|
-
|
|
14
|
+
private _pagesLoader;
|
|
15
|
+
constructor(init: {
|
|
16
16
|
streamId: string;
|
|
17
|
-
|
|
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
|
-
|
|
20
|
-
|
|
15
|
+
_pagesLoader;
|
|
16
|
+
constructor(init) {
|
|
17
|
+
const { streamId, dataProvider } = init;
|
|
21
18
|
this._pagesLoader = new CursorDataLoader({
|
|
22
19
|
loadPage: async (continuationToken) => {
|
|
23
|
-
const
|
|
24
|
-
|
|
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(
|
|
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.
|
|
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.
|
|
62
|
+
await this.loadMore();
|
|
78
63
|
if (this._currentIndex < 0) {
|
|
79
64
|
if (this.loaded.length > 0) {
|
|
80
65
|
this._currentIndex = 0;
|