@streamscloud/embeddable 8.2.0 → 9.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/cmp.ad-card.svelte +8 -5
- package/dist/ads/ad-card/cmp.ad-card.svelte.d.ts +2 -0
- package/dist/content-player/cmp.content-player.svelte +1 -0
- package/dist/content-player/content-player-config.svelte.d.ts +8 -0
- package/dist/content-player/content-player-config.svelte.js +9 -1
- package/dist/content-player/controls-and-attachments.svelte +1 -0
- package/dist/core/enums.d.ts +5 -1
- package/dist/core/enums.js +4 -0
- package/dist/marketing-tracking/index.d.ts +2 -0
- package/dist/marketing-tracking/index.js +1 -0
- package/dist/marketing-tracking/service.d.ts +11 -0
- package/dist/marketing-tracking/service.js +35 -0
- package/dist/marketing-tracking/types.d.ts +5 -0
- package/dist/media-center/config/internal-media-center-analytics-handler.d.ts +3 -2
- package/dist/media-center/config/internal-media-center-analytics-handler.js +1 -0
- package/dist/media-center/config/internal-media-center-config.d.ts +1 -1
- package/dist/media-center/config/internal-media-center-config.js +11 -11
- package/dist/media-center/config/operations.generated.d.ts +4 -4
- package/dist/media-center/config/operations.generated.js +5 -8
- package/dist/media-center/config/operations.graphql +3 -3
- package/dist/media-center/config/types.d.ts +7 -5
- package/dist/media-center/config/types.js +1 -1
- package/dist/media-center/media-center/cmp.media-center.svelte +74 -17
- package/dist/media-center/media-center/cmp.media-center.svelte.d.ts +3 -3
- package/dist/media-center/media-center/discover-panel-handler.svelte.d.ts +5 -2
- package/dist/media-center/media-center/discover-panel-handler.svelte.js +8 -3
- package/dist/media-center/media-center/discover-panel.svelte +1 -1
- package/dist/media-center/media-center/discover-panel.svelte.d.ts +2 -2
- package/dist/media-center/media-center/post-player-provider-generator.d.ts +8 -0
- package/dist/media-center/media-center/{short-video-resources-generator.js → post-player-provider-generator.js} +8 -3
- package/dist/media-center/media-center/types.d.ts +1 -1
- package/dist/posts/attachments/cmp.attachments.svelte +14 -2
- package/dist/posts/attachments/cmp.attachments.svelte.d.ts +2 -0
- package/dist/posts/handlers/index.d.ts +1 -0
- package/dist/posts/handlers/index.js +1 -0
- package/dist/{short-videos/short-videos-player/internal-short-video-analytics-handler.d.ts → posts/handlers/internal-post-analytics-handler.d.ts} +3 -2
- package/dist/{short-videos/short-videos-player/internal-short-video-analytics-handler.js → posts/handlers/internal-post-analytics-handler.js} +2 -1
- package/dist/posts/model/post-model.d.ts +2 -0
- package/dist/posts/model/post-model.js +3 -0
- package/dist/posts/model/types.d.ts +2 -1
- package/dist/posts/model/types.js +1 -1
- package/dist/posts/post-viewer/attachments-horizontal.svelte +5 -4
- package/dist/posts/post-viewer/attachments-horizontal.svelte.d.ts +2 -0
- package/dist/posts/post-viewer/cmp.post-viewer.svelte +13 -2
- package/dist/posts/post-viewer/cmp.post-viewer.svelte.d.ts +2 -0
- package/dist/posts/post-viewer/mapper.js +18 -1
- package/dist/{short-videos/short-videos-player/cmp.short-videos-player.svelte → posts/posts-player/cmp.posts-player.svelte} +3 -3
- package/dist/posts/posts-player/cmp.posts-player.svelte.d.ts +4 -0
- package/dist/posts/posts-player/index.d.ts +31 -17
- package/dist/posts/posts-player/index.js +48 -31
- package/dist/posts/posts-player/mapper.d.ts +3 -0
- package/dist/{short-videos/short-videos-player → posts/posts-player}/mapper.js +2 -2
- package/dist/posts/posts-player/operations.generated.d.ts +80 -0
- package/dist/posts/posts-player/operations.generated.js +229 -0
- package/dist/posts/posts-player/operations.graphql +7 -0
- package/dist/posts/posts-player/posts-player-view.svelte +38 -4
- package/dist/posts/posts-player/posts-player-view.svelte.d.ts +5 -1
- package/dist/posts/posts-player/types.d.ts +7 -1
- package/dist/products/product-card/cmp.product-card.svelte +10 -7
- package/dist/products/product-card/cmp.product-card.svelte.d.ts +2 -0
- package/dist/products/product-card/mapper.d.ts +3 -1
- package/dist/products/product-card/mapper.js +2 -2
- package/dist/short-videos/data-providers/index.d.ts +1 -0
- package/dist/short-videos/data-providers/index.js +1 -0
- package/dist/short-videos/{short-videos-player/internal-short-video-player-provider.d.ts → data-providers/internal-short-video-player-items-provider.d.ts} +4 -4
- package/dist/short-videos/{short-videos-player/internal-short-video-player-provider.js → data-providers/internal-short-video-player-items-provider.js} +3 -3
- package/dist/short-videos/{short-videos-player → data-providers}/operations.generated.d.ts +0 -78
- package/dist/short-videos/{short-videos-player → data-providers}/operations.generated.js +2 -234
- package/dist/short-videos/{short-videos-player → data-providers}/operations.graphql +1 -9
- package/dist/short-videos/short-videos-player/index.d.ts +13 -62
- package/dist/short-videos/short-videos-player/index.js +76 -30
- package/dist/streams/layout/cmp.slot-content.svelte +14 -6
- package/dist/streams/layout/cmp.slot-content.svelte.d.ts +2 -0
- package/dist/streams/layout/element-views/cmp.container-stream-element.svelte +7 -2
- package/dist/streams/layout/element-views/cmp.container-stream-element.svelte.d.ts +2 -0
- package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte +8 -2
- package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte.d.ts +2 -0
- package/dist/streams/layout/element-views/cmp.stream-element.svelte +3 -2
- package/dist/streams/layout/element-views/cmp.stream-element.svelte.d.ts +2 -0
- package/dist/streams/layout/index.d.ts +1 -0
- package/dist/streams/layout/models/mapper.js +2 -1
- package/dist/streams/layout/serializer.svelte.js +0 -1
- package/dist/streams/layout/types.d.ts +4 -0
- package/dist/streams/layout/types.js +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/stream-player/stream-player-view.svelte +15 -3
- package/dist/ui/player-slider/player-buffer.svelte.d.ts +1 -0
- package/dist/ui/swipe-indicator/cmp.swipe-indicator.svelte +7 -8
- package/package.json +1 -1
- package/dist/media-center/media-center/short-video-resources-generator.d.ts +0 -8
- package/dist/short-videos/short-videos-player/cmp.short-videos-player.svelte.d.ts +0 -4
- package/dist/short-videos/short-videos-player/mapper.d.ts +0 -3
- package/dist/short-videos/short-videos-player/short-videos-player-view.svelte +0 -82
- package/dist/short-videos/short-videos-player/short-videos-player-view.svelte.d.ts +0 -8
- package/dist/short-videos/short-videos-player/types.d.ts +0 -26
- /package/dist/{short-videos/short-videos-player → marketing-tracking}/types.js +0 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
<script lang="ts">
|
|
1
|
+
<script lang="ts">var _a;
|
|
2
|
+
import { enrichAdLinkWithTracking } from '../../marketing-tracking';
|
|
3
|
+
import { toPriceRepresentation } from '../../products/price-helper';
|
|
2
4
|
import { Button, ButtonSize } from '../../ui/button';
|
|
3
5
|
import { Image } from '../../ui/image';
|
|
4
6
|
import { LineClamp } from '../../ui/line-clamp';
|
|
5
|
-
let { ad, inert = false, on } = $props();
|
|
7
|
+
let { ad, trackingParams, inert = false, on } = $props();
|
|
6
8
|
const trackImpression = (node) => {
|
|
7
9
|
if (on === null || on === void 0 ? void 0 : on.impression) {
|
|
8
10
|
const observer = new IntersectionObserver((entries) => {
|
|
@@ -22,12 +24,13 @@ const trackImpression = (node) => {
|
|
|
22
24
|
};
|
|
23
25
|
}
|
|
24
26
|
};
|
|
27
|
+
const enrichedLink = $derived(((_a = ad.ctaButton) === null || _a === void 0 ? void 0 : _a.url) ? enrichAdLinkWithTracking({ link: ad.ctaButton.url, adId: ad.id, trackingParams }) : null);
|
|
25
28
|
const handleAdClick = () => {
|
|
26
29
|
if (on === null || on === void 0 ? void 0 : on.click) {
|
|
27
30
|
on.click(ad.id);
|
|
28
31
|
}
|
|
29
|
-
if (
|
|
30
|
-
window.open(
|
|
32
|
+
if (enrichedLink) {
|
|
33
|
+
window.open(enrichedLink, '_blank', 'noopener noreferrer');
|
|
31
34
|
}
|
|
32
35
|
};
|
|
33
36
|
</script>
|
|
@@ -60,7 +63,7 @@ const handleAdClick = () => {
|
|
|
60
63
|
{/if}
|
|
61
64
|
</div>
|
|
62
65
|
<div class="ad-card__button-container">
|
|
63
|
-
{#if ad.ctaButton &&
|
|
66
|
+
{#if ad.ctaButton && enrichedLink && ad.ctaButton.text}
|
|
64
67
|
<div class="ad-card__button">
|
|
65
68
|
<Button
|
|
66
69
|
size={ButtonSize.Standard}
|
|
@@ -171,6 +171,7 @@ const variables = $derived.by(() => {
|
|
|
171
171
|
{#if postModel}
|
|
172
172
|
<PostViewer
|
|
173
173
|
model={postModel}
|
|
174
|
+
trackingParams={config.trackingParams}
|
|
174
175
|
socialInteractionsHandler={config.socialInteractionsHandler}
|
|
175
176
|
enableAttachments={config.uiManager.showPostOverlayAttachments}
|
|
176
177
|
enableControls={config.uiManager.showPostOverlayControls}
|
|
@@ -15,6 +15,7 @@ export declare class ContentPlayerConfig<T extends {
|
|
|
15
15
|
readonly socialInteractionsHandler: IPostSocialInteractionsHandler | undefined;
|
|
16
16
|
readonly uiManager: ContentPlayerUIManager;
|
|
17
17
|
private _mediaCenterData;
|
|
18
|
+
private _trackingParams;
|
|
18
19
|
private _mappers;
|
|
19
20
|
private mappedPostsCache;
|
|
20
21
|
constructor(init: {
|
|
@@ -25,16 +26,19 @@ export declare class ContentPlayerConfig<T extends {
|
|
|
25
26
|
settings?: ContentPlayerSettings;
|
|
26
27
|
callbacks?: ContentPlayerCallbacks;
|
|
27
28
|
playerSliderCallbacks?: PlayerSliderCallbacks<T>;
|
|
29
|
+
trackingParams?: ContentPlayerTrackingParams | null;
|
|
28
30
|
});
|
|
29
31
|
get mediaCenterControlsPanel(): MediaCenterData['controlsPanel'] | null;
|
|
30
32
|
get mediaCenterCallbacks(): MediaCenterData['callbacks'] | null;
|
|
31
33
|
get playerLogo(): string | null;
|
|
32
34
|
get fadeContent(): boolean;
|
|
35
|
+
get trackingParams(): ContentPlayerConfig<T>['_trackingParams'];
|
|
33
36
|
itemAsPostViewerModel: (item: T & {
|
|
34
37
|
mediaIndex?: number;
|
|
35
38
|
}) => PostModel | null;
|
|
36
39
|
setBackgroundImageUrl: (imageUrl: string | null) => void;
|
|
37
40
|
updateMediaCenterData: (data: MediaCenterData | undefined) => void;
|
|
41
|
+
updateTrackingParams: (data: ContentPlayerTrackingParams | null) => void;
|
|
38
42
|
}
|
|
39
43
|
export type ContentPlayerMappers<T> = {
|
|
40
44
|
postModelFromCurrentItem: (item: T) => IPostModel | null;
|
|
@@ -47,3 +51,7 @@ export type ContentPlayerCallbacks = {
|
|
|
47
51
|
adClick?: (adId: string, postId: string) => void;
|
|
48
52
|
adImpression?: (adId: string, postId: string) => void;
|
|
49
53
|
};
|
|
54
|
+
export type ContentPlayerTrackingParams = {
|
|
55
|
+
streamId?: string;
|
|
56
|
+
campaignId?: string;
|
|
57
|
+
} | false;
|
|
@@ -9,11 +9,13 @@ export class ContentPlayerConfig {
|
|
|
9
9
|
socialInteractionsHandler;
|
|
10
10
|
uiManager = new ContentPlayerUIManager();
|
|
11
11
|
_mediaCenterData = $state.raw(null);
|
|
12
|
+
_trackingParams = $state.raw(null);
|
|
12
13
|
_mappers;
|
|
13
14
|
mappedPostsCache = new Map();
|
|
14
15
|
constructor(init) {
|
|
15
|
-
const { playerBuffer, mappers, socialInteractionsHandler, mediaCenterData, settings, callbacks, playerSliderCallbacks } = init;
|
|
16
|
+
const { playerBuffer, trackingParams, mappers, socialInteractionsHandler, mediaCenterData, settings, callbacks, playerSliderCallbacks } = init;
|
|
16
17
|
this.playerBuffer = playerBuffer;
|
|
18
|
+
this._trackingParams = trackingParams ?? null;
|
|
17
19
|
this.settings = settings || new ContentPlayerSettings();
|
|
18
20
|
this._mediaCenterData = mediaCenterData || null;
|
|
19
21
|
this.callbacks = callbacks || null;
|
|
@@ -33,6 +35,9 @@ export class ContentPlayerConfig {
|
|
|
33
35
|
get fadeContent() {
|
|
34
36
|
return this._mediaCenterData?.overlayIsActive || false;
|
|
35
37
|
}
|
|
38
|
+
get trackingParams() {
|
|
39
|
+
return this._trackingParams;
|
|
40
|
+
}
|
|
36
41
|
itemAsPostViewerModel = (item) => {
|
|
37
42
|
if (this.mappedPostsCache.has(item.id)) {
|
|
38
43
|
return this.mappedPostsCache.get(item.id) || null;
|
|
@@ -52,4 +57,7 @@ export class ContentPlayerConfig {
|
|
|
52
57
|
updateMediaCenterData = (data) => {
|
|
53
58
|
this._mediaCenterData = data ?? null;
|
|
54
59
|
};
|
|
60
|
+
updateTrackingParams = (data) => {
|
|
61
|
+
this._trackingParams = data ?? null;
|
|
62
|
+
};
|
|
55
63
|
}
|
|
@@ -75,6 +75,7 @@ const variables = $derived.by(() => {
|
|
|
75
75
|
<div class="controls-and-attachments__post-attachments" transition:slideHorizontally|local>
|
|
76
76
|
<PostAttachments
|
|
77
77
|
model={currentItemPostContainer}
|
|
78
|
+
trackingParams={config.trackingParams}
|
|
78
79
|
locale={config.settings.locale}
|
|
79
80
|
on={{
|
|
80
81
|
productClick: (id) => config.callbacks?.productClick?.(id, currentItemPostContainer.id),
|
package/dist/core/enums.d.ts
CHANGED
|
@@ -33,7 +33,11 @@ export declare enum ProfileType {
|
|
|
33
33
|
Organization = "ORGANIZATION"
|
|
34
34
|
}
|
|
35
35
|
export declare enum PostType {
|
|
36
|
-
|
|
36
|
+
Article = "ARTICLE",
|
|
37
|
+
Media = "MEDIA",
|
|
38
|
+
Moment = "MOMENT",
|
|
39
|
+
ShortVideo = "SHORT_VIDEO",
|
|
40
|
+
Video = "VIDEO"
|
|
37
41
|
}
|
|
38
42
|
export declare enum Status {
|
|
39
43
|
Published = "PUBLISHED"
|
package/dist/core/enums.js
CHANGED
|
@@ -41,7 +41,11 @@ export var ProfileType;
|
|
|
41
41
|
})(ProfileType || (ProfileType = {}));
|
|
42
42
|
export var PostType;
|
|
43
43
|
(function (PostType) {
|
|
44
|
+
PostType["Article"] = "ARTICLE";
|
|
45
|
+
PostType["Media"] = "MEDIA";
|
|
46
|
+
PostType["Moment"] = "MOMENT";
|
|
44
47
|
PostType["ShortVideo"] = "SHORT_VIDEO";
|
|
48
|
+
PostType["Video"] = "VIDEO";
|
|
45
49
|
})(PostType || (PostType = {}));
|
|
46
50
|
export var Status;
|
|
47
51
|
(function (Status) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { enrichAdLinkWithTracking, enrichProductLinkWithTracking } from './service';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TrackingParams } from './types';
|
|
2
|
+
export declare const enrichProductLinkWithTracking: (data: {
|
|
3
|
+
link: string | URL;
|
|
4
|
+
productId: string;
|
|
5
|
+
trackingParams: TrackingParams | false | null | undefined;
|
|
6
|
+
}) => URL;
|
|
7
|
+
export declare const enrichAdLinkWithTracking: (data: {
|
|
8
|
+
link: string | URL;
|
|
9
|
+
adId: string;
|
|
10
|
+
trackingParams: TrackingParams | false | null | undefined;
|
|
11
|
+
}) => URL;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const enrichProductLinkWithTracking = (data) => {
|
|
2
|
+
const { link, productId, trackingParams } = data;
|
|
3
|
+
const url = link instanceof URL ? link : new URL(link);
|
|
4
|
+
if (trackingParams === false) {
|
|
5
|
+
return url;
|
|
6
|
+
}
|
|
7
|
+
url.searchParams.set('utm_source', 'streams');
|
|
8
|
+
url.searchParams.set('streams_product_id', productId);
|
|
9
|
+
return addTrackingParamsToUrl(url, trackingParams);
|
|
10
|
+
};
|
|
11
|
+
export const enrichAdLinkWithTracking = (data) => {
|
|
12
|
+
const { link, adId, trackingParams } = data;
|
|
13
|
+
const url = link instanceof URL ? link : new URL(link);
|
|
14
|
+
if (trackingParams === false) {
|
|
15
|
+
return url;
|
|
16
|
+
}
|
|
17
|
+
url.searchParams.set('utm_source', 'streams');
|
|
18
|
+
url.searchParams.set('streams_ad_id', adId);
|
|
19
|
+
return addTrackingParamsToUrl(url, trackingParams);
|
|
20
|
+
};
|
|
21
|
+
const addTrackingParamsToUrl = (url, trackingParams) => {
|
|
22
|
+
if (!trackingParams) {
|
|
23
|
+
return url;
|
|
24
|
+
}
|
|
25
|
+
if (trackingParams.campaignId) {
|
|
26
|
+
url.searchParams.set('utm_id', trackingParams.campaignId);
|
|
27
|
+
}
|
|
28
|
+
if (trackingParams.shortVideoId) {
|
|
29
|
+
url.searchParams.set('streams_short_video_id', trackingParams.shortVideoId);
|
|
30
|
+
}
|
|
31
|
+
if (trackingParams.streamId) {
|
|
32
|
+
url.searchParams.set('streams_stream_id', trackingParams.streamId);
|
|
33
|
+
}
|
|
34
|
+
return url;
|
|
35
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IPostAnalyticsHandler } from '../../posts/posts-player/types';
|
|
2
2
|
import type { IStreamAnalyticsHandler } from '../../streams/stream-player/types';
|
|
3
|
-
export declare class InternalMediaCenterAnalyticsHandler implements
|
|
3
|
+
export declare class InternalMediaCenterAnalyticsHandler implements IPostAnalyticsHandler, IStreamAnalyticsHandler {
|
|
4
4
|
constructor(graphqlOrigin: string | undefined);
|
|
5
5
|
setOrganizationId: (organizationId: string) => void;
|
|
6
|
+
trackPostOpened: (postId: string, ownerId: string) => void;
|
|
6
7
|
trackStreamView: (streamId: string) => void;
|
|
7
8
|
trackStreamPageView: (pageId: string, streamId: string) => void;
|
|
8
9
|
trackStreamEngagementTime: (streamId: string, engagementTime: number) => void;
|
|
@@ -7,6 +7,7 @@ export class InternalMediaCenterAnalyticsHandler {
|
|
|
7
7
|
AppEventsTracker.setProfileId(getOrCreateProfileId());
|
|
8
8
|
}
|
|
9
9
|
setOrganizationId = (organizationId) => AppEventsTracker.setOrganizationId(organizationId);
|
|
10
|
+
trackPostOpened = (postId, ownerId) => AppEventsTracker.trackPostOpened(postId, ownerId);
|
|
10
11
|
trackStreamView = (streamId) => AppEventsTracker.trackStreamView(streamId);
|
|
11
12
|
trackStreamPageView = (pageId, streamId) => AppEventsTracker.trackStreamPageView(pageId, streamId);
|
|
12
13
|
trackStreamEngagementTime = (streamId, engagementTime) => AppEventsTracker.trackStreamEngagementTime(streamId, engagementTime);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { IMediaCenterConfig } from './types';
|
|
2
2
|
export declare class InternalMediaCenterConfig implements IMediaCenterConfig {
|
|
3
3
|
private readonly mediaPageId;
|
|
4
|
-
|
|
4
|
+
postsPlayer: IMediaCenterConfig['postsPlayer'];
|
|
5
5
|
streamPlayer: IMediaCenterConfig['streamPlayer'];
|
|
6
6
|
handlers: IMediaCenterConfig['handlers'];
|
|
7
7
|
private graphql;
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Status, StreamStatus } from '../../core/enums';
|
|
2
2
|
import { createLocalGQLClient } from '../../core/graphql';
|
|
3
3
|
import { MockCategoryFollowingProvider } from '../categories-following/mock-categories-following-handler.svelte';
|
|
4
|
+
import { mapToPostPlayerModel } from '../../posts/posts-player/mapper';
|
|
4
5
|
import { MockPostSocialInteractionsHandler } from '../../posts/social-interactions/mock-post-social-interactions-handler.svelte';
|
|
5
|
-
import { mapToShortVideoPlayerModel } from '../../short-videos/short-videos-player/mapper';
|
|
6
6
|
import { InternalStreamPlayerDataProvider } from '../../streams/stream-player/internal-stream-player-data-provider';
|
|
7
7
|
import { InternalMediaCenterAnalyticsHandler } from './internal-media-center-analytics-handler';
|
|
8
|
-
import { GetMediaPageConfigDocument,
|
|
8
|
+
import { GetMediaPageConfigDocument, GetPostsDocument, GetStreamsDocument } from './operations.generated';
|
|
9
9
|
export class InternalMediaCenterConfig {
|
|
10
10
|
mediaPageId;
|
|
11
|
-
|
|
11
|
+
postsPlayer;
|
|
12
12
|
streamPlayer;
|
|
13
13
|
handlers;
|
|
14
14
|
graphql;
|
|
15
15
|
constructor(mediaPageId, graphqlOrigin, testingStuff) {
|
|
16
16
|
this.mediaPageId = mediaPageId;
|
|
17
17
|
this.graphql = createLocalGQLClient(graphqlOrigin);
|
|
18
|
-
this.
|
|
19
|
-
|
|
18
|
+
this.postsPlayer = {
|
|
19
|
+
getPostsCursor: async ({ filter, limit, continuationToken }) => {
|
|
20
20
|
const payload = await this.graphql
|
|
21
|
-
.query(
|
|
21
|
+
.query(GetPostsDocument, {
|
|
22
22
|
input: {
|
|
23
23
|
filter: {
|
|
24
24
|
mediaPageId: this.mediaPageId,
|
|
25
|
-
types:
|
|
25
|
+
types: filter.types,
|
|
26
26
|
statuses: [Status.Published],
|
|
27
27
|
categoryId: filter.categoryId,
|
|
28
28
|
excludeIds: filter.excludeIds
|
|
@@ -32,10 +32,10 @@ export class InternalMediaCenterConfig {
|
|
|
32
32
|
}
|
|
33
33
|
})
|
|
34
34
|
.toPromise();
|
|
35
|
-
const posts = payload.data?.
|
|
35
|
+
const posts = payload.data?.posts?.items || [];
|
|
36
36
|
return {
|
|
37
|
-
items: posts.map(
|
|
38
|
-
continuationToken: payload.data?.
|
|
37
|
+
items: posts.map(mapToPostPlayerModel),
|
|
38
|
+
continuationToken: payload.data?.posts?.continuationToken || null
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
};
|
|
@@ -23,12 +23,12 @@ export type GetMediaPageConfigQuery = {
|
|
|
23
23
|
} | null;
|
|
24
24
|
} | null;
|
|
25
25
|
};
|
|
26
|
-
export type
|
|
26
|
+
export type GetPostsQueryVariables = SchemaTypes.Exact<{
|
|
27
27
|
input: SchemaTypes.EmbedPostsInput;
|
|
28
28
|
image_scale?: SchemaTypes.InputMaybe<SchemaTypes.ImageScale>;
|
|
29
29
|
}>;
|
|
30
|
-
export type
|
|
31
|
-
|
|
30
|
+
export type GetPostsQuery = {
|
|
31
|
+
posts: {
|
|
32
32
|
continuationToken: string | null;
|
|
33
33
|
items: Array<{
|
|
34
34
|
id: string;
|
|
@@ -126,5 +126,5 @@ export type GetStreamsQuery = {
|
|
|
126
126
|
};
|
|
127
127
|
};
|
|
128
128
|
export declare const GetMediaPageConfigDocument: DocumentNode<GetMediaPageConfigQuery, GetMediaPageConfigQueryVariables>;
|
|
129
|
-
export declare const
|
|
129
|
+
export declare const GetPostsDocument: DocumentNode<GetPostsQuery, GetPostsQueryVariables>;
|
|
130
130
|
export declare const GetStreamsDocument: DocumentNode<GetStreamsQuery, GetStreamsQueryVariables>;
|
|
@@ -84,13 +84,13 @@ export const GetMediaPageConfigDocument = {
|
|
|
84
84
|
}
|
|
85
85
|
]
|
|
86
86
|
};
|
|
87
|
-
export const
|
|
87
|
+
export const GetPostsDocument = {
|
|
88
88
|
kind: 'Document',
|
|
89
89
|
definitions: [
|
|
90
90
|
{
|
|
91
91
|
kind: 'OperationDefinition',
|
|
92
92
|
operation: 'query',
|
|
93
|
-
name: { kind: 'Name', value: '
|
|
93
|
+
name: { kind: 'Name', value: 'GetPosts' },
|
|
94
94
|
variableDefinitions: [
|
|
95
95
|
{
|
|
96
96
|
kind: 'VariableDefinition',
|
|
@@ -109,7 +109,7 @@ export const GetShortVideosDocument = {
|
|
|
109
109
|
selections: [
|
|
110
110
|
{
|
|
111
111
|
kind: 'Field',
|
|
112
|
-
alias: { kind: 'Name', value: '
|
|
112
|
+
alias: { kind: 'Name', value: 'posts' },
|
|
113
113
|
name: { kind: 'Name', value: 'embedPosts' },
|
|
114
114
|
arguments: [{ kind: 'Argument', name: { kind: 'Name', value: 'input' }, value: { kind: 'Variable', name: { kind: 'Name', value: 'input' } } }],
|
|
115
115
|
selectionSet: {
|
|
@@ -118,10 +118,7 @@ export const GetShortVideosDocument = {
|
|
|
118
118
|
{
|
|
119
119
|
kind: 'Field',
|
|
120
120
|
name: { kind: 'Name', value: 'items' },
|
|
121
|
-
selectionSet: {
|
|
122
|
-
kind: 'SelectionSet',
|
|
123
|
-
selections: [{ kind: 'FragmentSpread', name: { kind: 'Name', value: 'ShortVideosPlayerPayloadFragment' } }]
|
|
124
|
-
}
|
|
121
|
+
selectionSet: { kind: 'SelectionSet', selections: [{ kind: 'FragmentSpread', name: { kind: 'Name', value: 'PostsPlayerPayloadFragment' } }] }
|
|
125
122
|
},
|
|
126
123
|
{ kind: 'Field', name: { kind: 'Name', value: 'continuationToken' } }
|
|
127
124
|
]
|
|
@@ -334,7 +331,7 @@ export const GetShortVideosDocument = {
|
|
|
334
331
|
},
|
|
335
332
|
{
|
|
336
333
|
kind: 'FragmentDefinition',
|
|
337
|
-
name: { kind: 'Name', value: '
|
|
334
|
+
name: { kind: 'Name', value: 'PostsPlayerPayloadFragment' },
|
|
338
335
|
typeCondition: { kind: 'NamedType', name: { kind: 'Name', value: 'Post' } },
|
|
339
336
|
selectionSet: {
|
|
340
337
|
kind: 'SelectionSet',
|
|
@@ -20,10 +20,10 @@ query GetMediaPageConfig($mediaPageId: String!) {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
# noinspection GraphQLSchemaValidation
|
|
23
|
-
query
|
|
24
|
-
|
|
23
|
+
query GetPosts($input: EmbedPostsInput!, $image_scale: ImageScale = ORIGINAL_ENCODED) {
|
|
24
|
+
posts: embedPosts(input: $input) {
|
|
25
25
|
items {
|
|
26
|
-
...
|
|
26
|
+
...PostsPlayerPayloadFragment
|
|
27
27
|
}
|
|
28
28
|
continuationToken
|
|
29
29
|
}
|
|
@@ -1,24 +1,26 @@
|
|
|
1
|
+
import { PostType } from '../../core/enums';
|
|
1
2
|
import type { IContentCategoryFollowingHandler } from '../categories-following';
|
|
3
|
+
import type { IPostAnalyticsHandler, PostPlayerModel } from '../../posts/posts-player/types';
|
|
2
4
|
import type { IPostSocialInteractionsHandler } from '../../posts/social-interactions';
|
|
3
|
-
import type { IShortVideoAnalyticsHandler, ShortVideoPlayerModel } from '../../short-videos/short-videos-player/types';
|
|
4
5
|
import type { IStreamPlayerDataProvider, IStreamAnalyticsHandler } from '../../streams/stream-player/types';
|
|
5
6
|
export interface IMediaCenterConfig {
|
|
6
7
|
getConfig: () => Promise<MediaCenterConfigModel | null>;
|
|
7
8
|
handlers?: {
|
|
8
|
-
analyticsHandler?:
|
|
9
|
+
analyticsHandler?: IPostAnalyticsHandler & IStreamAnalyticsHandler;
|
|
9
10
|
socialInteractionsHandler?: IPostSocialInteractionsHandler;
|
|
10
11
|
categoriesFollowingHandler?: IContentCategoryFollowingHandler;
|
|
11
12
|
};
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
postsPlayer: {
|
|
14
|
+
getPostsCursor: (input: {
|
|
14
15
|
filter: {
|
|
16
|
+
types: PostType[];
|
|
15
17
|
categoryId?: string;
|
|
16
18
|
excludeIds?: string[];
|
|
17
19
|
};
|
|
18
20
|
limit: number;
|
|
19
21
|
continuationToken?: string | null;
|
|
20
22
|
}) => Promise<{
|
|
21
|
-
items:
|
|
23
|
+
items: PostPlayerModel[];
|
|
22
24
|
continuationToken: string | null;
|
|
23
25
|
}>;
|
|
24
26
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import { PostType } from '../../core/enums';
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
};
|
|
10
10
|
import { horizontalWheelScroll } from '../../core/actions';
|
|
11
11
|
import { Utils } from '../../core/utils';
|
|
12
|
-
import { default as
|
|
12
|
+
import { default as PostsPlayerView } from '../../posts/posts-player/posts-player-view.svelte';
|
|
13
13
|
import { default as StreamPlayerView } from '../../streams/stream-player/stream-player-view.svelte';
|
|
14
14
|
import { Icon } from '../../ui/icon';
|
|
15
15
|
import { Loading } from '../../ui/loading';
|
|
@@ -20,12 +20,14 @@ import { default as DiscoverPanel } from './discover-panel.svelte';
|
|
|
20
20
|
import { MediaCenterHandler } from './media-center-handler.svelte';
|
|
21
21
|
import { MediaCenterLocalization } from './media-center-localization';
|
|
22
22
|
import { default as MobileControlsPanel } from './mobile-controls-panel.svelte';
|
|
23
|
-
import {
|
|
23
|
+
import { makePostPlayerItemsProvider } from './post-player-provider-generator';
|
|
24
24
|
import { StreamsInCategoryPanelHandler } from './streams-in-category-panel-handler.svelte';
|
|
25
25
|
import { default as StreamsInCategoryPanel } from './streams-in-category-panel.svelte';
|
|
26
26
|
import IconLineHorizontal3 from '@fluentui/svg-icons/icons/line_horizontal_3_20_regular.svg?raw';
|
|
27
27
|
import IconScreenSearch from '@fluentui/svg-icons/icons/screen_search_20_regular.svg?raw';
|
|
28
|
+
import { tick } from 'svelte';
|
|
28
29
|
import { fade } from 'svelte/transition';
|
|
30
|
+
const SCROLL_MASK_OFFSET = 32;
|
|
29
31
|
let { config, playerProps, locale = 'en' } = $props();
|
|
30
32
|
const localization = $derived(new MediaCenterLocalization(locale));
|
|
31
33
|
const commonPlayerSettings = {
|
|
@@ -42,23 +44,24 @@ let isMobileView = $state(false);
|
|
|
42
44
|
const overlayActivated = $derived(discoverHandler.activated || streamsInCategoryHandler.activated);
|
|
43
45
|
let mobileControlsPanelActive = $state(false);
|
|
44
46
|
let extraMobileControlsPanelActions = $state.raw([]);
|
|
47
|
+
let scrollAreaRef = $state(null);
|
|
45
48
|
const selectCategory = (categoryId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
|
-
var _a, _b;
|
|
49
|
+
var _a, _b, _c;
|
|
47
50
|
const selectedCategoryData = handler.getCategoryData(categoryId);
|
|
48
51
|
if (!config || !selectedCategoryData) {
|
|
49
52
|
return;
|
|
50
53
|
}
|
|
51
54
|
hideMobileControlsPanel();
|
|
52
55
|
switch (mediaCenterMode) {
|
|
53
|
-
case '
|
|
56
|
+
case 'posts':
|
|
54
57
|
if (handler.selectedCategoryId === categoryId) {
|
|
55
58
|
discoverHandler.deactivate();
|
|
56
59
|
return;
|
|
57
60
|
}
|
|
58
61
|
handler.selectedCategoryId = categoryId;
|
|
59
62
|
computedPlayerProps = {
|
|
60
|
-
mode: '
|
|
61
|
-
props: Object.assign({ dataProvider:
|
|
63
|
+
mode: 'posts',
|
|
64
|
+
props: Object.assign({ dataProvider: makePostPlayerItemsProvider({ config, categoryId }), socialInteractionsHandler: (_a = config.handlers) === null || _a === void 0 ? void 0 : _a.socialInteractionsHandler, analyticsHandler: (_b = config.handlers) === null || _b === void 0 ? void 0 : _b.analyticsHandler }, commonPlayerSettings)
|
|
62
65
|
};
|
|
63
66
|
discoverHandler.deactivate();
|
|
64
67
|
break;
|
|
@@ -76,16 +79,62 @@ const selectCategory = (categoryId) => __awaiter(void 0, void 0, void 0, functio
|
|
|
76
79
|
default:
|
|
77
80
|
Utils.assertUnreachable(mediaCenterMode);
|
|
78
81
|
}
|
|
82
|
+
// Scroll to selected category if it's hidden
|
|
83
|
+
yield scrollToSelectedCategory((_c = selectedCategoryData.parentId) !== null && _c !== void 0 ? _c : selectedCategoryData.id);
|
|
84
|
+
});
|
|
85
|
+
/**
|
|
86
|
+
* Scrolls the scroll area to make the selected category button visible
|
|
87
|
+
* @param categoryId - ID of the selected category
|
|
88
|
+
*/
|
|
89
|
+
const scrollToSelectedCategory = (categoryId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
+
if (!scrollAreaRef) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Wait for DOM to update with the new active state
|
|
94
|
+
yield tick();
|
|
95
|
+
// Find the selected category button element
|
|
96
|
+
const selectedButton = scrollAreaRef.querySelector(`[id="${categoryId}"]`);
|
|
97
|
+
if (!selectedButton) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// Get scroll area and button dimensions
|
|
101
|
+
const scrollAreaRect = scrollAreaRef.getBoundingClientRect();
|
|
102
|
+
const buttonRect = selectedButton.getBoundingClientRect();
|
|
103
|
+
// Calculate button position relative to scroll area
|
|
104
|
+
const buttonLeftRelative = buttonRect.left - scrollAreaRect.left + scrollAreaRef.scrollLeft;
|
|
105
|
+
const buttonRightRelative = buttonLeftRelative + buttonRect.width;
|
|
106
|
+
// Calculate visible area boundaries (accounting for mask gradients)
|
|
107
|
+
const hasLeftMask = scrollAreaRef.scrollLeft > 0;
|
|
108
|
+
const hasRightMask = scrollAreaRef.scrollLeft < scrollAreaRef.scrollWidth - scrollAreaRect.width - 1;
|
|
109
|
+
const visibleLeft = scrollAreaRef.scrollLeft + (hasLeftMask ? SCROLL_MASK_OFFSET : 0);
|
|
110
|
+
const visibleRight = scrollAreaRef.scrollLeft + scrollAreaRect.width - (hasRightMask ? SCROLL_MASK_OFFSET : 0);
|
|
111
|
+
// Check if button is hidden or partially hidden
|
|
112
|
+
const isHiddenLeft = buttonLeftRelative < visibleLeft;
|
|
113
|
+
const isHiddenRight = buttonRightRelative > visibleRight;
|
|
114
|
+
if (isHiddenLeft) {
|
|
115
|
+
const targetScroll = buttonLeftRelative - SCROLL_MASK_OFFSET;
|
|
116
|
+
scrollAreaRef.scrollTo({
|
|
117
|
+
left: targetScroll,
|
|
118
|
+
behavior: 'smooth'
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else if (isHiddenRight) {
|
|
122
|
+
const targetScroll = buttonRightRelative - scrollAreaRect.width + SCROLL_MASK_OFFSET;
|
|
123
|
+
scrollAreaRef.scrollTo({
|
|
124
|
+
left: targetScroll,
|
|
125
|
+
behavior: 'smooth'
|
|
126
|
+
});
|
|
127
|
+
}
|
|
79
128
|
});
|
|
80
129
|
const activateSelectedShortVideoPlayer = (shortVideo) => {
|
|
81
130
|
var _a, _b;
|
|
82
131
|
if (!config) {
|
|
83
132
|
return;
|
|
84
133
|
}
|
|
85
|
-
mediaCenterMode = '
|
|
134
|
+
mediaCenterMode = 'posts';
|
|
86
135
|
computedPlayerProps = {
|
|
87
|
-
mode: '
|
|
88
|
-
props: Object.assign({ dataProvider:
|
|
136
|
+
mode: 'posts',
|
|
137
|
+
props: Object.assign({ dataProvider: makePostPlayerItemsProvider({ config, prefetchedItems: [shortVideo] }), socialInteractionsHandler: (_a = config.handlers) === null || _a === void 0 ? void 0 : _a.socialInteractionsHandler, analyticsHandler: (_b = config.handlers) === null || _b === void 0 ? void 0 : _b.analyticsHandler }, commonPlayerSettings)
|
|
89
138
|
};
|
|
90
139
|
handler.selectedCategoryId = null;
|
|
91
140
|
discoverHandler.deactivate();
|
|
@@ -134,6 +183,8 @@ const updateScrollShadows = (scrollArea) => {
|
|
|
134
183
|
scrollArea.classList.toggle('has-both-masks', scrollHasRight && scrollHasLeft);
|
|
135
184
|
};
|
|
136
185
|
const onScrollMounted = (node) => {
|
|
186
|
+
scrollAreaRef = node;
|
|
187
|
+
scrollAreaRef.style.setProperty('--scroll-area--mask-offset', `${SCROLL_MASK_OFFSET}px`);
|
|
137
188
|
const scrollResizeObserver = new ResizeObserver(() => {
|
|
138
189
|
updateScrollShadows(node);
|
|
139
190
|
});
|
|
@@ -178,7 +229,7 @@ const onWidthAnchorMounted = (node) => {
|
|
|
178
229
|
class="media-center-controls-panel__button"
|
|
179
230
|
class:media-center-controls-panel__button--active={discoverHandler.activated}
|
|
180
231
|
onclick={toggleDiscover}>
|
|
181
|
-
<span class="media-center-controls-panel__button-icon">
|
|
232
|
+
<span class="media-center-controls-panel__button-icon" class:media-center-controls-panel__button-icon--active={discoverHandler.activated}>
|
|
182
233
|
<Icon src={IconScreenSearch} />
|
|
183
234
|
</span>
|
|
184
235
|
<span class="media-center-controls-panel__button-value">
|
|
@@ -189,6 +240,7 @@ const onWidthAnchorMounted = (node) => {
|
|
|
189
240
|
{#each handler.categories as category (category.id)}
|
|
190
241
|
<button
|
|
191
242
|
type="button"
|
|
243
|
+
id={category.id}
|
|
192
244
|
class="media-center-controls-panel__button"
|
|
193
245
|
class:media-center-controls-panel__button--active={!discoverHandler.activated && handler.controlsPanelSelectedCategory?.id === category.id}
|
|
194
246
|
data-child-name={(!discoverHandler.activated &&
|
|
@@ -210,8 +262,8 @@ const onWidthAnchorMounted = (node) => {
|
|
|
210
262
|
</div>
|
|
211
263
|
{/if}
|
|
212
264
|
{/snippet}
|
|
213
|
-
{#if computedPlayerProps.mode === '
|
|
214
|
-
<
|
|
265
|
+
{#if computedPlayerProps.mode === 'posts'}
|
|
266
|
+
<PostsPlayerView
|
|
215
267
|
{...computedPlayerProps.props}
|
|
216
268
|
mediaCenterData={{
|
|
217
269
|
controlsPanel: handler.categories.length ? controlsPanel : undefined,
|
|
@@ -304,15 +356,17 @@ const onWidthAnchorMounted = (node) => {
|
|
|
304
356
|
scrollbar-width: none;
|
|
305
357
|
padding: 0.5rem 0.625rem;
|
|
306
358
|
padding-left: 0;
|
|
359
|
+
--_scroll-area--mask-offset--left: var(--scroll-area--mask-offset);
|
|
360
|
+
--_scroll-area--mask-offset--right: calc(100% - var(--scroll-area--mask-offset));
|
|
307
361
|
}
|
|
308
362
|
:global(.media-center-controls-panel__scroll-area.has-left-mask) {
|
|
309
|
-
mask-image: linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgb(0, 0, 0)
|
|
363
|
+
mask-image: linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgb(0, 0, 0) var(--_scroll-area--mask-offset--left), rgb(0, 0, 0) 100%);
|
|
310
364
|
}
|
|
311
365
|
:global(.media-center-controls-panel__scroll-area.has-right-mask) {
|
|
312
|
-
mask-image: linear-gradient(to right, rgb(0, 0, 0) 0, rgb(0, 0, 0)
|
|
366
|
+
mask-image: linear-gradient(to right, rgb(0, 0, 0) 0, rgb(0, 0, 0) var(--_scroll-area--mask-offset--right), rgba(0, 0, 0, 0) 100%);
|
|
313
367
|
}
|
|
314
368
|
:global(.media-center-controls-panel__scroll-area.has-both-masks) {
|
|
315
|
-
mask-image: linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgb(0, 0, 0)
|
|
369
|
+
mask-image: linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgb(0, 0, 0) var(--_scroll-area--mask-offset--left), rgb(0, 0, 0) var(--_scroll-area--mask-offset--right), rgba(0, 0, 0, 0) 100%);
|
|
316
370
|
}
|
|
317
371
|
.media-center-controls-panel__button {
|
|
318
372
|
position: relative;
|
|
@@ -340,7 +394,6 @@ const onWidthAnchorMounted = (node) => {
|
|
|
340
394
|
.media-center-controls-panel__button--active {
|
|
341
395
|
background-color: rgba(255, 255, 255, 0.9);
|
|
342
396
|
color: #000000;
|
|
343
|
-
--icon--color: #000000;
|
|
344
397
|
}
|
|
345
398
|
.media-center-controls-panel__button:hover:not(.media-center-controls-panel__button--active) {
|
|
346
399
|
background-color: rgba(0, 0, 0, 0.9);
|
|
@@ -364,8 +417,12 @@ const onWidthAnchorMounted = (node) => {
|
|
|
364
417
|
pointer-events: none;
|
|
365
418
|
}
|
|
366
419
|
.media-center-controls-panel__button-icon {
|
|
367
|
-
--icon--color: #ffffff;
|
|
368
420
|
--icon--size: 1.0625rem;
|
|
421
|
+
--icon--color: #ffffff;
|
|
422
|
+
line-height: 0;
|
|
423
|
+
}
|
|
424
|
+
.media-center-controls-panel__button-icon--active {
|
|
425
|
+
--icon--color: #000000;
|
|
369
426
|
}
|
|
370
427
|
.media-center-controls-panel__button-value {
|
|
371
428
|
font-size: 0.875rem;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { Locale } from '../../core/locale';
|
|
2
2
|
import type { IMediaCenterConfig } from '../config/types';
|
|
3
|
-
import type {
|
|
3
|
+
import type { PostPlayerProps } from '../../posts/posts-player/types';
|
|
4
4
|
import type { StreamPlayerProps } from '../../streams/stream-player/types';
|
|
5
5
|
type PlayerProps = {
|
|
6
|
-
mode: '
|
|
7
|
-
props:
|
|
6
|
+
mode: 'posts';
|
|
7
|
+
props: PostPlayerProps;
|
|
8
8
|
} | {
|
|
9
9
|
mode: 'stream';
|
|
10
10
|
props: StreamPlayerProps;
|