@streamscloud/embeddable 14.0.4 → 14.1.1
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/media-center/media-center/discover/discover-view-handler.svelte.js +1 -1
- package/dist/media-center/media-center/handlers/media-center-settings-handler.svelte.d.ts +12 -5
- package/dist/media-center/media-center/handlers/media-center-settings-handler.svelte.js +17 -5
- package/dist/media-center/media-center/header/media-center-header-mobile.svelte +4 -2
- package/dist/media-center/media-center/header/media-center-header.svelte +4 -2
- package/dist/media-center/media-center/media-center-view.svelte +7 -3
- package/dist/media-center/media-center/menu/menu.svelte +1 -1
- package/dist/posts/post-viewer/cmp.post-viewer.svelte +4 -1
- package/dist/posts/post-viewer/cmp.post-viewer.svelte.d.ts +2 -0
- package/dist/streams/layout/cmp.layout.svelte +4 -1
- package/dist/streams/layout/cmp.layout.svelte.d.ts +1 -0
- package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte +2 -2
- package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte.d.ts +2 -0
- package/dist/streams/streams-player/streams-player-view.svelte +166 -46
- package/dist/streams/streams-player/types.d.ts +1 -0
- package/dist/ui/player/progress/cmp.chunks-progress.svelte +64 -0
- package/dist/ui/player/progress/cmp.chunks-progress.svelte.d.ts +9 -0
- package/dist/ui/player/progress/index.d.ts +1 -0
- package/dist/ui/player/progress/index.js +1 -0
- package/dist/ui/player/providers/chunks-player-buffer/player-chunks-manager.svelte.js +2 -2
- package/package.json +1 -1
|
@@ -12,11 +12,7 @@ export declare class MediaCenterSettingsHandler {
|
|
|
12
12
|
readonly dataProvider: IMediaCenterDataProvider;
|
|
13
13
|
settings: MediaCenterSettings;
|
|
14
14
|
});
|
|
15
|
-
get playerSettings():
|
|
16
|
-
locale?: Locale;
|
|
17
|
-
showStreamsCloudWatermark?: boolean;
|
|
18
|
-
playerColors?: Record<ThemeValue, PlayerColors>;
|
|
19
|
-
};
|
|
15
|
+
get playerSettings(): ContentPlayerSettingsLocal;
|
|
20
16
|
get actualMediaCenterColors(): PlayerColors;
|
|
21
17
|
get locale(): Locale;
|
|
22
18
|
get backgroundWrapperProps(): {
|
|
@@ -25,8 +21,19 @@ export declare class MediaCenterSettingsHandler {
|
|
|
25
21
|
backgroundColor?: string | null;
|
|
26
22
|
};
|
|
27
23
|
get backgroundImageLoadedHandler(): ((url: string | null) => void) | undefined;
|
|
24
|
+
setMinOverlayOffsetTop: (value: number) => void;
|
|
28
25
|
updateBackgroundImageUrl: (url: string | null | "not-applicable") => void;
|
|
29
26
|
}
|
|
30
27
|
export type MediaCenterSettingsWithColors = MediaCenterSettings & {
|
|
31
28
|
playerColors?: PlayerColors;
|
|
32
29
|
};
|
|
30
|
+
declare class ContentPlayerSettingsLocal {
|
|
31
|
+
private settings;
|
|
32
|
+
private dataProvider;
|
|
33
|
+
locale?: Locale;
|
|
34
|
+
showStreamsCloudWatermark?: boolean;
|
|
35
|
+
playerColors?: Record<ThemeValue, PlayerColors>;
|
|
36
|
+
overlayMinOffsetTop?: number;
|
|
37
|
+
constructor(settings: MediaCenterSettings, dataProvider: IMediaCenterDataProvider);
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
@@ -4,14 +4,11 @@ export class MediaCenterSettingsHandler {
|
|
|
4
4
|
_backgroundImageUrl = $state(null);
|
|
5
5
|
_mediaCenterSettings;
|
|
6
6
|
_dataProvider;
|
|
7
|
-
_contentPlayerSettings
|
|
8
|
-
locale: this._mediaCenterSettings.locale,
|
|
9
|
-
playerColors: this._dataProvider.model?.playerColors,
|
|
10
|
-
showStreamsCloudWatermark: this._mediaCenterSettings.showStreamsCloudWatermark
|
|
11
|
-
}));
|
|
7
|
+
_contentPlayerSettings;
|
|
12
8
|
constructor(init) {
|
|
13
9
|
this._mediaCenterSettings = init.settings;
|
|
14
10
|
this._dataProvider = init.dataProvider;
|
|
11
|
+
this._contentPlayerSettings = new ContentPlayerSettingsLocal(this._mediaCenterSettings, this._dataProvider);
|
|
15
12
|
}
|
|
16
13
|
get playerSettings() {
|
|
17
14
|
return this._contentPlayerSettings;
|
|
@@ -32,7 +29,22 @@ export class MediaCenterSettingsHandler {
|
|
|
32
29
|
get backgroundImageLoadedHandler() {
|
|
33
30
|
return this._mediaCenterSettings.disableBackground ? undefined : (url) => this.updateBackgroundImageUrl(url);
|
|
34
31
|
}
|
|
32
|
+
setMinOverlayOffsetTop = (value) => {
|
|
33
|
+
this._contentPlayerSettings.overlayMinOffsetTop = value;
|
|
34
|
+
};
|
|
35
35
|
updateBackgroundImageUrl = (url) => {
|
|
36
36
|
this._backgroundImageUrl = url;
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
+
class ContentPlayerSettingsLocal {
|
|
40
|
+
settings;
|
|
41
|
+
dataProvider;
|
|
42
|
+
locale = $derived.by(() => this.settings.locale);
|
|
43
|
+
showStreamsCloudWatermark = $derived.by(() => this.settings.showStreamsCloudWatermark);
|
|
44
|
+
playerColors = $derived.by(() => this.dataProvider.model?.playerColors);
|
|
45
|
+
overlayMinOffsetTop = $state(0);
|
|
46
|
+
constructor(settings, dataProvider) {
|
|
47
|
+
this.settings = settings;
|
|
48
|
+
this.dataProvider = dataProvider;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -6,13 +6,15 @@ let { context, locale = 'en', on } = $props();
|
|
|
6
6
|
const localization = $derived(new MediaCenterHeaderLocalization(locale));
|
|
7
7
|
const headerMounted = (node) => {
|
|
8
8
|
const heightResizeObserver = new ResizeObserver(() => {
|
|
9
|
+
var _a;
|
|
9
10
|
const headerHeight = node.clientHeight;
|
|
10
|
-
on.headerHeightChanged(headerHeight);
|
|
11
|
+
(_a = on === null || on === void 0 ? void 0 : on.headerHeightChanged) === null || _a === void 0 ? void 0 : _a.call(on, headerHeight);
|
|
11
12
|
});
|
|
12
13
|
heightResizeObserver.observe(node);
|
|
13
14
|
return {
|
|
14
15
|
destroy: () => {
|
|
15
|
-
|
|
16
|
+
var _a;
|
|
17
|
+
(_a = on === null || on === void 0 ? void 0 : on.headerHeightChanged) === null || _a === void 0 ? void 0 : _a.call(on, 0);
|
|
16
18
|
heightResizeObserver.disconnect();
|
|
17
19
|
}
|
|
18
20
|
};
|
|
@@ -19,14 +19,16 @@ let scrollAreaRef = $state(null);
|
|
|
19
19
|
const headerMounted = (node) => {
|
|
20
20
|
headerRef = node;
|
|
21
21
|
const heightResizeObserver = new ResizeObserver(() => {
|
|
22
|
+
var _a;
|
|
22
23
|
const headerHeight = node.clientHeight;
|
|
23
|
-
on.headerHeightChanged(headerHeight);
|
|
24
|
+
(_a = on === null || on === void 0 ? void 0 : on.headerHeightChanged) === null || _a === void 0 ? void 0 : _a.call(on, headerHeight);
|
|
24
25
|
calcHeaderGridProportions();
|
|
25
26
|
});
|
|
26
27
|
heightResizeObserver.observe(node);
|
|
27
28
|
return {
|
|
28
29
|
destroy: () => {
|
|
29
|
-
|
|
30
|
+
var _a;
|
|
31
|
+
(_a = on === null || on === void 0 ? void 0 : on.headerHeightChanged) === null || _a === void 0 ? void 0 : _a.call(on, 0);
|
|
30
32
|
heightResizeObserver.disconnect();
|
|
31
33
|
}
|
|
32
34
|
};
|
|
@@ -69,9 +69,13 @@ const activateSelectedStreamPlayer = (stream, categoryId) => {
|
|
|
69
69
|
const activateSelectedStreamOfCategoryPlayer = (id, prefetchedStreams, categoryId) => {
|
|
70
70
|
context.playStreamsFeed({ filter: { categoryId }, init: { prefetchedStreams, initialStreamId: id } });
|
|
71
71
|
};
|
|
72
|
-
const
|
|
72
|
+
const onDesktopHeaderHeightChanged = (height) => {
|
|
73
73
|
headerHeight = height;
|
|
74
74
|
};
|
|
75
|
+
const onMobileHeaderHeightChanged = (height) => {
|
|
76
|
+
headerHeight = height;
|
|
77
|
+
context.settingsHandler.setMinOverlayOffsetTop(height);
|
|
78
|
+
};
|
|
75
79
|
const onWidthAnchorMounted = (node) => {
|
|
76
80
|
const resizeObserver = new ResizeObserver(() => {
|
|
77
81
|
isMobileView = node.clientWidth <= 576;
|
|
@@ -142,9 +146,9 @@ const swipeToOpen = (node) => {
|
|
|
142
146
|
<div class="media-center" use:onWidthAnchorMounted>
|
|
143
147
|
<div class="media-center__header-and-content">
|
|
144
148
|
{#if !isMobileView}
|
|
145
|
-
<MediaCenterHeader context={context} dynamicActions={dynamicActions} on={{ headerHeightChanged:
|
|
149
|
+
<MediaCenterHeader context={context} dynamicActions={dynamicActions} on={{ headerHeightChanged: onDesktopHeaderHeightChanged }} />
|
|
146
150
|
{:else}
|
|
147
|
-
<MediaCenterHeaderMobile context={context} on={{ headerHeightChanged:
|
|
151
|
+
<MediaCenterHeaderMobile context={context} on={{ headerHeightChanged: onMobileHeaderHeightChanged }} />
|
|
148
152
|
{/if}
|
|
149
153
|
|
|
150
154
|
<div class="media-center__content-container" use:swipeToOpen>
|
|
@@ -7,7 +7,7 @@ import { default as PostMedia } from './media/post-media.svelte';
|
|
|
7
7
|
import { default as Texts } from './post-texts.svelte';
|
|
8
8
|
import { PostViewerLocalization } from './post-viewer-localization';
|
|
9
9
|
import { PostViewerUiManager } from './ui-manager.svelte';
|
|
10
|
-
let { model, trackingParams: externalTrackingParams, controlsColors = null, enableAttachments = true, controlActions, enableControls = true, autoplay = 'on-appearance', locale = 'en', on } = $props();
|
|
10
|
+
let { model, trackingParams: externalTrackingParams, controlsColors = null, enableAttachments = true, controlActions, enableControls = true, autoplay = 'on-appearance', locale = 'en', on, overlay } = $props();
|
|
11
11
|
const localization = $derived(new PostViewerLocalization(locale));
|
|
12
12
|
const uiManager = new PostViewerUiManager();
|
|
13
13
|
$effect(() => {
|
|
@@ -88,6 +88,9 @@ const variables = $derived.by(() => {
|
|
|
88
88
|
scaleEffect={true} />
|
|
89
89
|
</div>
|
|
90
90
|
{/if}
|
|
91
|
+
{#if overlay}
|
|
92
|
+
{@render overlay()}
|
|
93
|
+
{/if}
|
|
91
94
|
</div>
|
|
92
95
|
|
|
93
96
|
<style>@keyframes fadeIn {
|
|
@@ -2,6 +2,7 @@ import type { Locale } from '../../core/locale';
|
|
|
2
2
|
import type { TrackingParams } from '../../marketing-tracking';
|
|
3
3
|
import { PostModel } from '../model';
|
|
4
4
|
import { type PlayerButtonDef } from '../../ui/player/button';
|
|
5
|
+
import type { Snippet } from 'svelte';
|
|
5
6
|
type Props = {
|
|
6
7
|
model: PostModel;
|
|
7
8
|
trackingParams: TrackingParams | null;
|
|
@@ -21,6 +22,7 @@ type Props = {
|
|
|
21
22
|
adClick?: (adId: string) => void;
|
|
22
23
|
adImpression?: (adId: string) => void;
|
|
23
24
|
};
|
|
25
|
+
overlay?: Snippet;
|
|
24
26
|
};
|
|
25
27
|
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
26
28
|
type Cmp = ReturnType<typeof Cmp>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">import { ProportionalContainer } from '../../ui/proportional-container';
|
|
2
2
|
import { generateStreamLayoutStyles } from './styles-transformer';
|
|
3
|
-
let { model, children, controls } = $props();
|
|
3
|
+
let { model, children, controls, overlay } = $props();
|
|
4
4
|
</script>
|
|
5
5
|
|
|
6
6
|
<ProportionalContainer ratio={9 / 16}>
|
|
@@ -9,6 +9,9 @@ let { model, children, controls } = $props();
|
|
|
9
9
|
{#if controls}
|
|
10
10
|
{@render controls()}
|
|
11
11
|
{/if}
|
|
12
|
+
{#if overlay}
|
|
13
|
+
{@render overlay()}
|
|
14
|
+
{/if}
|
|
12
15
|
</div>
|
|
13
16
|
</ProportionalContainer>
|
|
14
17
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script lang="ts">import { StreamLayoutSlot, StreamPageLayout, StreamLayoutSlotContent } from '../layout';
|
|
2
2
|
import { ResponsivePlayerButtonsGroup } from '../../ui/player/button';
|
|
3
3
|
import { StreamPageViewerLocalization } from './stream-page-viewer-localization';
|
|
4
|
-
let { page, trackingParams, overlayControls, locale, on } = $props();
|
|
4
|
+
let { page, trackingParams, overlayControls, locale, on, overlay } = $props();
|
|
5
5
|
const localization = $derived(new StreamPageViewerLocalization(locale));
|
|
6
6
|
</script>
|
|
7
7
|
|
|
8
8
|
{#if page.type === 'general'}
|
|
9
|
-
<StreamPageLayout model={page.layout}>
|
|
9
|
+
<StreamPageLayout model={page.layout} overlay={overlay}>
|
|
10
10
|
{#each page.layout.slots as slot (slot)}
|
|
11
11
|
<StreamLayoutSlot model={slot}>
|
|
12
12
|
<StreamLayoutSlotContent model={slot} trackingParams={trackingParams} on={on} locale={localization.elementsLocale} />
|
|
@@ -2,6 +2,7 @@ import type { Locale } from '../../core/locale';
|
|
|
2
2
|
import { type StreamTrackingParams } from '../layout';
|
|
3
3
|
import { type PlayerButtonDef } from '../../ui/player/button';
|
|
4
4
|
import type { StreamPageViewerModel } from './types';
|
|
5
|
+
import type { Snippet } from 'svelte';
|
|
5
6
|
type Props = {
|
|
6
7
|
page: StreamPageViewerModel;
|
|
7
8
|
trackingParams: StreamTrackingParams;
|
|
@@ -19,6 +20,7 @@ type Props = {
|
|
|
19
20
|
productImpression?: (productId: string) => void;
|
|
20
21
|
progress?: (videoId: string, progress: number) => void;
|
|
21
22
|
};
|
|
23
|
+
overlay?: Snippet;
|
|
22
24
|
};
|
|
23
25
|
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
24
26
|
type Cmp = ReturnType<typeof Cmp>;
|
|
@@ -17,6 +17,7 @@ import { mapToPostModel } from '../layout/models';
|
|
|
17
17
|
import { StreamPageViewer } from '../stream-page-viewer';
|
|
18
18
|
import { IconColor } from '../../ui/icon';
|
|
19
19
|
import { Player, PlayerConfig, PlayerSettings } from '../../ui/player';
|
|
20
|
+
import { ChunksProgress } from '../../ui/player/progress';
|
|
20
21
|
import { default as Overview } from './stream-overview.svelte';
|
|
21
22
|
import { StreamPlayerLocalization } from './stream-player-localization';
|
|
22
23
|
import { StreamsPlayerBuffer } from './streams-player-buffer.svelte';
|
|
@@ -235,6 +236,49 @@ const currentItemActions = $derived.by(() => {
|
|
|
235
236
|
}
|
|
236
237
|
return result;
|
|
237
238
|
});
|
|
239
|
+
const handlePageViewMounted = (node) => {
|
|
240
|
+
const updatePosition = () => {
|
|
241
|
+
var _a;
|
|
242
|
+
const progressElement = node.querySelector('[id^="chunk-progress-"]');
|
|
243
|
+
if (!progressElement) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const overlayMinOffsetTop = (_a = playerSettings === null || playerSettings === void 0 ? void 0 : playerSettings.overlayMinOffsetTop) !== null && _a !== void 0 ? _a : 0;
|
|
247
|
+
if (!overlayMinOffsetTop) {
|
|
248
|
+
progressElement.style.top = '';
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const contentElement = node.firstElementChild;
|
|
252
|
+
if (!contentElement) {
|
|
253
|
+
progressElement.style.top = '';
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const nodeRect = node.getBoundingClientRect();
|
|
257
|
+
const contentRect = contentElement.getBoundingClientRect();
|
|
258
|
+
const contentOffsetTop = contentRect.top - nodeRect.top;
|
|
259
|
+
if (contentOffsetTop <= 0) {
|
|
260
|
+
progressElement.style.top = `${overlayMinOffsetTop}px`;
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const overlayOverlap = overlayMinOffsetTop - contentOffsetTop;
|
|
264
|
+
if (overlayOverlap > 0) {
|
|
265
|
+
progressElement.style.top = `${overlayOverlap}px`;
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
progressElement.style.top = '';
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
updatePosition();
|
|
272
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
273
|
+
updatePosition();
|
|
274
|
+
});
|
|
275
|
+
resizeObserver.observe(node);
|
|
276
|
+
return {
|
|
277
|
+
destroy() {
|
|
278
|
+
resizeObserver.disconnect();
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
};
|
|
238
282
|
//#region Activity Tracking
|
|
239
283
|
const resetInactivityTimer = () => {
|
|
240
284
|
if (!isActive) {
|
|
@@ -300,59 +344,85 @@ const stopActivityTracking = () => {
|
|
|
300
344
|
}} />
|
|
301
345
|
{/if}
|
|
302
346
|
{/snippet}
|
|
347
|
+
{#snippet overlay()}
|
|
348
|
+
{#if buffer?.activeChunk && buffer.activeChunk.chunkItems.length > 1}
|
|
349
|
+
<div class="stream-progress" id="chunk-progress-{buffer.activeChunk.model.id}">
|
|
350
|
+
{#snippet info()}
|
|
351
|
+
<div class="stream-progress-info">
|
|
352
|
+
<div class="stream-progress-info__title">
|
|
353
|
+
{buffer?.activeChunk.model.title}
|
|
354
|
+
</div>
|
|
355
|
+
{#if buffer?.activeChunk.model.subTitle}
|
|
356
|
+
<div class="stream-progress-info__sub-title">
|
|
357
|
+
{buffer.activeChunk.model.subTitle}
|
|
358
|
+
</div>
|
|
359
|
+
{/if}
|
|
360
|
+
</div>
|
|
361
|
+
{/snippet}
|
|
362
|
+
<ChunksProgress
|
|
363
|
+
totalItems={buffer.activeChunk.model.pagesCount}
|
|
364
|
+
activeItemIndex={buffer.activeChunk.activeItemIndex}
|
|
365
|
+
chunkInfo={info} />
|
|
366
|
+
</div>
|
|
367
|
+
{/if}
|
|
368
|
+
{/snippet}
|
|
303
369
|
<Player
|
|
304
370
|
config={contentPlayerConfig}
|
|
305
371
|
itemActions={currentItemActions}
|
|
306
372
|
attachmentsView={buffer?.current && itemAsPostModel(buffer.current)?.attachments ? attachmentsView : undefined}>
|
|
307
373
|
{#snippet itemView({ item })}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
progress: (videoId, progress) => onProgress(item.id, videoId, progress),
|
|
325
|
-
productClick: (productId) => onStreamProductClick(productId),
|
|
326
|
-
productImpression: (productId) => onStreamProductImpression(productId)
|
|
327
|
-
}} />
|
|
328
|
-
{:else}
|
|
329
|
-
{@const postModel = itemAsPostModel(item)}
|
|
330
|
-
{#if postModel}
|
|
331
|
-
{@const handler = buffer?.activeChunk
|
|
332
|
-
? streamActionsGenerator.getPostActionsHandler({
|
|
333
|
-
model: postModel,
|
|
334
|
-
streamId: buffer.activeChunk.model.id,
|
|
335
|
-
streamPageId: item.id
|
|
336
|
-
})
|
|
337
|
-
: null}
|
|
338
|
-
<PostViewer
|
|
339
|
-
model={postModel}
|
|
340
|
-
controlsColors={{ active: contentPlayerConfig.playerColors.button, inactive: contentPlayerConfig.playerColors.buttonInactive }}
|
|
341
|
-
trackingParams={trackingParams}
|
|
342
|
-
enableAttachments={contentPlayerConfig.uiManager.showAttachmentsOverlay}
|
|
343
|
-
enableControls={contentPlayerConfig.uiManager.showControlsOverlay}
|
|
344
|
-
controlActions={handler?.actions ?? []}
|
|
345
|
-
autoplay="on-appearance"
|
|
346
|
-
locale={contentPlayerConfig.settings.locale}
|
|
374
|
+
<div class="page-view" use:handlePageViewMounted>
|
|
375
|
+
{#if item.type === 'general'}
|
|
376
|
+
<StreamPageViewer
|
|
377
|
+
page={item}
|
|
378
|
+
trackingParams={streamTrackingParams}
|
|
379
|
+
locale={localization.locale}
|
|
380
|
+
overlayControls={{
|
|
381
|
+
enabled: contentPlayerConfig.uiManager.showControlsOverlay,
|
|
382
|
+
colors: {
|
|
383
|
+
active: contentPlayerConfig.playerColors.button,
|
|
384
|
+
inactive: contentPlayerConfig.playerColors.buttonInactive
|
|
385
|
+
},
|
|
386
|
+
actions: buffer?.activeChunk
|
|
387
|
+
? streamActionsGenerator.getGeneralStreamPageActions({ streamId: buffer.activeChunk.model.id, streamPageId: item.id })
|
|
388
|
+
: []
|
|
389
|
+
}}
|
|
347
390
|
on={{
|
|
348
|
-
progress: (progress) =>
|
|
349
|
-
productClick: (productId) =>
|
|
350
|
-
productImpression: (productId) =>
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
391
|
+
progress: (videoId, progress) => onProgress(item.id, videoId, progress),
|
|
392
|
+
productClick: (productId) => onStreamProductClick(productId),
|
|
393
|
+
productImpression: (productId) => onStreamProductImpression(productId)
|
|
394
|
+
}}
|
|
395
|
+
overlay={overlay} />
|
|
396
|
+
{:else}
|
|
397
|
+
{@const postModel = itemAsPostModel(item)}
|
|
398
|
+
{#if postModel}
|
|
399
|
+
{@const handler = buffer?.activeChunk
|
|
400
|
+
? streamActionsGenerator.getPostActionsHandler({
|
|
401
|
+
model: postModel,
|
|
402
|
+
streamId: buffer.activeChunk.model.id,
|
|
403
|
+
streamPageId: item.id
|
|
404
|
+
})
|
|
405
|
+
: null}
|
|
406
|
+
<PostViewer
|
|
407
|
+
model={postModel}
|
|
408
|
+
controlsColors={{ active: contentPlayerConfig.playerColors.button, inactive: contentPlayerConfig.playerColors.buttonInactive }}
|
|
409
|
+
trackingParams={trackingParams}
|
|
410
|
+
enableAttachments={contentPlayerConfig.uiManager.showAttachmentsOverlay}
|
|
411
|
+
enableControls={contentPlayerConfig.uiManager.showControlsOverlay}
|
|
412
|
+
controlActions={handler?.actions ?? []}
|
|
413
|
+
autoplay="on-appearance"
|
|
414
|
+
locale={contentPlayerConfig.settings.locale}
|
|
415
|
+
on={{
|
|
416
|
+
progress: (progress) => onShortVideoProgress(item.id, postModel.id, progress),
|
|
417
|
+
productClick: (productId) => onShortVideoProductClick(productId, postModel.id),
|
|
418
|
+
productImpression: (productId) => onShortVideoProductImpression(productId, postModel.id),
|
|
419
|
+
adClick: (adId) => onShortVideoAdClick(adId),
|
|
420
|
+
adImpression: (adId) => onShortVideoAdImpression(adId)
|
|
421
|
+
}}
|
|
422
|
+
overlay={overlay} />
|
|
423
|
+
{/if}
|
|
354
424
|
{/if}
|
|
355
|
-
|
|
425
|
+
</div>
|
|
356
426
|
{/snippet}
|
|
357
427
|
{#snippet overviewPanelContent()}
|
|
358
428
|
{#if buffer}
|
|
@@ -365,3 +435,53 @@ const stopActivityTracking = () => {
|
|
|
365
435
|
{/if}
|
|
366
436
|
{/snippet}
|
|
367
437
|
</Player>
|
|
438
|
+
|
|
439
|
+
<style>@keyframes fadeIn {
|
|
440
|
+
0% {
|
|
441
|
+
opacity: 1;
|
|
442
|
+
}
|
|
443
|
+
50% {
|
|
444
|
+
opacity: 0.4;
|
|
445
|
+
}
|
|
446
|
+
100% {
|
|
447
|
+
opacity: 1;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
.page-view {
|
|
451
|
+
width: 100%;
|
|
452
|
+
height: 100%;
|
|
453
|
+
position: relative;
|
|
454
|
+
display: flex;
|
|
455
|
+
justify-content: center;
|
|
456
|
+
align-items: center;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.stream-progress {
|
|
460
|
+
position: absolute;
|
|
461
|
+
top: 0.75rem;
|
|
462
|
+
left: 1rem;
|
|
463
|
+
right: 1rem;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
.stream-progress-info {
|
|
467
|
+
color: var(--sc-mc-color--text-white);
|
|
468
|
+
text-shadow: var(--sc-mc-color--text-white-shadow);
|
|
469
|
+
display: flex;
|
|
470
|
+
flex-direction: column;
|
|
471
|
+
min-width: 0;
|
|
472
|
+
gap: 0.25rem;
|
|
473
|
+
}
|
|
474
|
+
.stream-progress-info__title {
|
|
475
|
+
font-size: 1.125rem;
|
|
476
|
+
text-overflow: ellipsis;
|
|
477
|
+
width: 100%;
|
|
478
|
+
white-space: nowrap;
|
|
479
|
+
overflow: hidden;
|
|
480
|
+
}
|
|
481
|
+
.stream-progress-info__sub-title {
|
|
482
|
+
font-size: 0.875rem;
|
|
483
|
+
text-overflow: ellipsis;
|
|
484
|
+
width: 100%;
|
|
485
|
+
white-space: nowrap;
|
|
486
|
+
overflow: hidden;
|
|
487
|
+
}</style>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script lang="ts">let { totalItems, activeItemIndex, chunkInfo } = $props();
|
|
2
|
+
export {};
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<div class="chunks-progress">
|
|
6
|
+
<div
|
|
7
|
+
class="chunks"
|
|
8
|
+
class:chunks--few={totalItems <= 3}
|
|
9
|
+
class:chunks--common={totalItems > 3 && totalItems <= 6}
|
|
10
|
+
class:chunks--many={totalItems > 6}>
|
|
11
|
+
{#each Array(totalItems) as _, i (i)}
|
|
12
|
+
<div class="chunk" class:active={i <= activeItemIndex} aria-label={`Item ${i}`}></div>
|
|
13
|
+
{/each}
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
{#if chunkInfo}
|
|
17
|
+
<div class="info">
|
|
18
|
+
{@render chunkInfo()}
|
|
19
|
+
</div>
|
|
20
|
+
{/if}
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<style>@keyframes fadeIn {
|
|
24
|
+
0% {
|
|
25
|
+
opacity: 1;
|
|
26
|
+
}
|
|
27
|
+
50% {
|
|
28
|
+
opacity: 0.4;
|
|
29
|
+
}
|
|
30
|
+
100% {
|
|
31
|
+
opacity: 1;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
.chunks-progress {
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
gap: 0.5rem;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.chunks {
|
|
41
|
+
display: flex;
|
|
42
|
+
}
|
|
43
|
+
.chunks--few {
|
|
44
|
+
gap: 0.75rem;
|
|
45
|
+
}
|
|
46
|
+
.chunks--common {
|
|
47
|
+
gap: 0.5625rem;
|
|
48
|
+
}
|
|
49
|
+
.chunks--many {
|
|
50
|
+
gap: 0.375rem;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.chunk {
|
|
54
|
+
flex: 1;
|
|
55
|
+
height: 0.125rem;
|
|
56
|
+
border-radius: 1px;
|
|
57
|
+
background-color: rgb(from #6b7280 r g b/40%);
|
|
58
|
+
transition: background-color 0.2s ease;
|
|
59
|
+
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 6px rgba(0, 0, 0, 0.05);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.chunk.active {
|
|
63
|
+
background-color: rgb(from #fafafa r g b/60%);
|
|
64
|
+
}</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ChunksProgress } from './cmp.chunks-progress.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ChunksProgress } from './cmp.chunks-progress.svelte';
|
|
@@ -122,8 +122,6 @@ export class PlayerChunksManager {
|
|
|
122
122
|
? this.provider.initialData.startItemIndex
|
|
123
123
|
: 0;
|
|
124
124
|
this.setActiveChunkIndex(firstFilledChunkIndex, initialStartItemIndex);
|
|
125
|
-
// Start background warm-up after initialization
|
|
126
|
-
this.warmUp();
|
|
127
125
|
};
|
|
128
126
|
setActiveChunkIndex = async (index, chunkItemIndex) => {
|
|
129
127
|
this._activeChunkIndex = index;
|
|
@@ -148,6 +146,8 @@ export class PlayerChunksManager {
|
|
|
148
146
|
}
|
|
149
147
|
else {
|
|
150
148
|
this.activeChunk.setActiveItemIndex(this.activeChunk.chunkItems.indexOf(nextItem));
|
|
149
|
+
// Don't wait for warm up to be finished, it runs in the background
|
|
150
|
+
this.warmUp();
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
153
|
warmUp = async () => {
|