@streamscloud/embeddable 7.5.2 → 8.0.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/content-player/cmp.content-player.svelte +69 -34
- package/dist/content-player/content-player-config.svelte.d.ts +8 -17
- package/dist/content-player/content-player-config.svelte.js +16 -15
- package/dist/content-player/content-player-settings.d.ts +14 -0
- package/dist/content-player/content-player-settings.js +14 -0
- package/dist/content-player/controls-and-attachments.svelte +9 -4
- package/dist/content-player/header.svelte +1 -1
- package/dist/content-player/index.d.ts +1 -1
- package/dist/core/analytics.profile-id.js +27 -1
- package/dist/core/utils/html-helper.d.ts +1 -0
- package/dist/core/utils/html-helper.js +3 -0
- package/dist/media-center/media-center/cmp.media-center.svelte +32 -24
- package/dist/media-center/media-center/discover-panel.svelte +1 -1
- package/dist/posts/attachments/cmp.attachments.svelte +7 -6
- package/dist/posts/attachments/cmp.attachments.svelte.d.ts +2 -2
- package/dist/posts/controls/cmp.controls.svelte +2 -2
- package/dist/posts/controls/cmp.controls.svelte.d.ts +2 -2
- package/dist/posts/index.d.ts +1 -0
- package/dist/posts/model/index.d.ts +3 -1
- package/dist/posts/model/index.js +2 -1
- package/dist/posts/model/post-media-model.svelte.d.ts +20 -0
- package/dist/posts/model/post-media-model.svelte.js +16 -0
- package/dist/posts/model/post-model.d.ts +25 -0
- package/dist/posts/model/post-model.js +28 -0
- package/dist/posts/model/types.d.ts +53 -9
- package/dist/posts/model/types.js +1 -1
- package/dist/posts/model/utils.d.ts +4 -0
- package/dist/posts/model/utils.js +7 -0
- package/dist/posts/post-viewer/attachments-horizontal.svelte +7 -2
- package/dist/posts/post-viewer/attachments-horizontal.svelte.d.ts +2 -2
- package/dist/posts/post-viewer/cmp.post-viewer.svelte +27 -50
- package/dist/posts/post-viewer/cmp.post-viewer.svelte.d.ts +2 -2
- package/dist/posts/post-viewer/heading.svelte +2 -1
- package/dist/posts/post-viewer/heading.svelte.d.ts +2 -2
- package/dist/posts/post-viewer/index.d.ts +1 -3
- package/dist/posts/post-viewer/index.js +1 -2
- package/dist/posts/post-viewer/mapper.d.ts +2 -2
- package/dist/posts/post-viewer/mapper.js +23 -27
- package/dist/posts/post-viewer/media/post-media.svelte +64 -0
- package/dist/posts/post-viewer/{post-media.svelte.d.ts → media/post-media.svelte.d.ts} +4 -6
- package/dist/posts/post-viewer/post-texts.svelte +101 -0
- package/dist/posts/post-viewer/post-texts.svelte.d.ts +11 -0
- package/dist/posts/post-viewer/post-viewer-localization.d.ts +1 -0
- package/dist/posts/post-viewer/post-viewer-localization.js +4 -1
- package/dist/posts/posts-player/index.d.ts +2 -3
- package/dist/posts/posts-player/index.js +0 -1
- package/dist/posts/posts-player/posts-player-view.svelte +3 -2
- package/dist/posts/posts-player/types.d.ts +5 -4
- package/dist/short-videos/short-videos-player/index.d.ts +3 -4
- package/dist/short-videos/short-videos-player/index.js +0 -1
- package/dist/short-videos/short-videos-player/mapper.js +2 -2
- package/dist/short-videos/short-videos-player/short-videos-player-view.svelte +3 -2
- package/dist/short-videos/short-videos-player/types.d.ts +5 -4
- package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte +4 -3
- package/dist/streams/layout/models/index.d.ts +1 -1
- package/dist/streams/layout/models/index.js +1 -1
- package/dist/streams/layout/models/mapper.d.ts +2 -2
- package/dist/streams/layout/models/mapper.js +10 -9
- package/dist/streams/stream-player/index.d.ts +3 -4
- package/dist/streams/stream-player/stream-player-view.svelte +4 -3
- package/dist/streams/stream-player/types.d.ts +3 -2
- package/dist/ui/line-clamp/cmp.line-clamp.svelte +1 -0
- package/dist/ui/player-slider/cmp.player-slider.svelte +44 -7
- package/dist/ui/player-slider/cmp.player-slider.svelte.d.ts +2 -2
- package/dist/ui/player-slider/player-buffer.svelte.d.ts +4 -3
- package/dist/ui/player-slider/player-buffer.svelte.js +9 -3
- package/dist/ui/player-slider/types.d.ts +5 -2
- package/dist/ui/slider/cmp.slider.svelte +398 -0
- package/dist/ui/slider/cmp.slider.svelte.d.ts +31 -0
- package/dist/ui/slider/index.d.ts +2 -0
- package/dist/ui/slider/index.js +2 -0
- package/dist/ui/slider/slider-localization.d.ts +5 -0
- package/dist/ui/slider/slider-localization.js +13 -0
- package/dist/ui/slider/types.d.ts +11 -0
- package/dist/ui/slider/types.js +8 -0
- package/package.json +2 -2
- package/dist/posts/post-viewer/media/media-slider.svelte +0 -10
- package/dist/posts/post-viewer/media/media-slider.svelte.d.ts +0 -27
- package/dist/posts/post-viewer/post-media.svelte +0 -26
- package/dist/posts/post-viewer/types.d.ts +0 -60
- package/dist/posts/post-viewer/types.js +0 -1
- package/dist/posts/post-viewer/utils.d.ts +0 -2
- package/dist/posts/post-viewer/utils.js +0 -13
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export class PostViewerMediaModel {
|
|
2
|
+
currentItem = $derived.by(() => {
|
|
3
|
+
const item = this.items[this.currentIndex];
|
|
4
|
+
return item ? item : { isImage: true, url: '' };
|
|
5
|
+
});
|
|
6
|
+
currentIndex = $state(0);
|
|
7
|
+
isGallery = $derived.by(() => this.items.length > 1);
|
|
8
|
+
items;
|
|
9
|
+
mediaFit;
|
|
10
|
+
constructor(init) {
|
|
11
|
+
const { media, mediaFit, mediaIndex } = init;
|
|
12
|
+
this.items = media;
|
|
13
|
+
this.mediaFit = mediaFit;
|
|
14
|
+
this.currentIndex = mediaIndex || 0;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PostViewerMediaModel } from './post-media-model.svelte';
|
|
2
|
+
import type { IPostModel, IPostAdCardModel, IPostHeadingModel, IPostProductCardModel } from './types';
|
|
3
|
+
export declare class PostModel {
|
|
4
|
+
id: string;
|
|
5
|
+
media: PostViewerMediaModel;
|
|
6
|
+
texts: {
|
|
7
|
+
kicker: string | null;
|
|
8
|
+
title: string | null;
|
|
9
|
+
text: string | null;
|
|
10
|
+
readMoreUrl: string | null;
|
|
11
|
+
};
|
|
12
|
+
heading: PostHeadingModel | null;
|
|
13
|
+
enableSocialInteractions: boolean;
|
|
14
|
+
attachments: false | {
|
|
15
|
+
products: PostProductCardModel[];
|
|
16
|
+
ads: PostAdCardModel[];
|
|
17
|
+
};
|
|
18
|
+
constructor(init: IPostModel & {
|
|
19
|
+
mediaIndex?: number;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
type PostHeadingModel = IPostHeadingModel;
|
|
23
|
+
type PostAdCardModel = IPostAdCardModel;
|
|
24
|
+
type PostProductCardModel = IPostProductCardModel;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { PostViewerMediaModel } from './post-media-model.svelte';
|
|
2
|
+
export class PostModel {
|
|
3
|
+
id;
|
|
4
|
+
media;
|
|
5
|
+
texts;
|
|
6
|
+
heading;
|
|
7
|
+
enableSocialInteractions;
|
|
8
|
+
attachments;
|
|
9
|
+
constructor(init) {
|
|
10
|
+
this.id = init.id;
|
|
11
|
+
this.media = new PostViewerMediaModel({ media: init.media, mediaFit: init.mediaFit, mediaIndex: init.mediaIndex });
|
|
12
|
+
this.texts = {
|
|
13
|
+
kicker: init.kicker,
|
|
14
|
+
title: init.title,
|
|
15
|
+
text: init.text,
|
|
16
|
+
readMoreUrl: init.readMoreUrl ?? null
|
|
17
|
+
};
|
|
18
|
+
this.heading = init.heading;
|
|
19
|
+
this.enableSocialInteractions = init.enableSocialInteractions;
|
|
20
|
+
this.attachments =
|
|
21
|
+
init.products.length || init.ads.length
|
|
22
|
+
? {
|
|
23
|
+
products: init.products,
|
|
24
|
+
ads: init.ads
|
|
25
|
+
}
|
|
26
|
+
: false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -1,13 +1,57 @@
|
|
|
1
|
-
import type
|
|
2
|
-
|
|
3
|
-
export type PostContainer = PostAttachmentsContainer & {
|
|
1
|
+
import { AdType, type Currency } from '../../core/enums';
|
|
2
|
+
export type IPostModel = {
|
|
4
3
|
id: string;
|
|
4
|
+
media: IPostMediaItemModel[];
|
|
5
|
+
mediaFit: PostModelMediaFit;
|
|
6
|
+
kicker: string | null;
|
|
7
|
+
title: string | null;
|
|
8
|
+
text: string | null;
|
|
9
|
+
readMoreUrl?: string;
|
|
10
|
+
heading: IPostHeadingModel | null;
|
|
5
11
|
enableSocialInteractions: boolean;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
products: IPostProductCardModel[];
|
|
13
|
+
ads: IPostAdCardModel[];
|
|
14
|
+
};
|
|
15
|
+
export type IPostMediaItemModel = {
|
|
16
|
+
isImage: true;
|
|
17
|
+
url: string;
|
|
18
|
+
} | {
|
|
19
|
+
isImage: false;
|
|
20
|
+
url: string;
|
|
21
|
+
thumbnailUrl: string;
|
|
9
22
|
};
|
|
10
|
-
export type
|
|
11
|
-
|
|
12
|
-
|
|
23
|
+
export type IPostHeadingModel = {
|
|
24
|
+
image: string | null;
|
|
25
|
+
name: string;
|
|
26
|
+
displayDate: string;
|
|
27
|
+
viewsCount: number;
|
|
28
|
+
};
|
|
29
|
+
export type PostModelMediaFit = 'cover' | 'contain';
|
|
30
|
+
export type IPostProductCardModel = {
|
|
31
|
+
id: string;
|
|
32
|
+
title: string;
|
|
33
|
+
shortDescription: string | null;
|
|
34
|
+
link: string | null;
|
|
35
|
+
image: string | null;
|
|
36
|
+
brandName: string | null;
|
|
37
|
+
price: number;
|
|
38
|
+
currency: Currency;
|
|
39
|
+
salePrice: number | null;
|
|
40
|
+
};
|
|
41
|
+
export type IPostAdCardModel = {
|
|
42
|
+
id: string;
|
|
43
|
+
type: AdType;
|
|
44
|
+
image: string | null;
|
|
45
|
+
title: string;
|
|
46
|
+
description: string | null;
|
|
47
|
+
price: number | null;
|
|
48
|
+
priceInfoLabel: string | null;
|
|
49
|
+
currency: Currency | null;
|
|
50
|
+
ctaButton: {
|
|
51
|
+
background: string;
|
|
52
|
+
textColor: string;
|
|
53
|
+
text: string;
|
|
54
|
+
url: string;
|
|
55
|
+
border: string;
|
|
56
|
+
} | null;
|
|
13
57
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import { AdType } from '../../core/enums';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">import { horizontalWheelScroll, swallowTouch } from '../../core/actions';
|
|
2
2
|
import { Currency } from '../../core/enums';
|
|
3
|
+
import { PostModel } from '../model';
|
|
3
4
|
import { toPriceRepresentation } from '../../products/price-helper';
|
|
4
5
|
import { Icon, IconColor } from '../../ui/icon';
|
|
5
6
|
import { ImageRounded } from '../../ui/image';
|
|
@@ -7,7 +8,10 @@ import { PostViewerUiManager } from './ui-manager.svelte';
|
|
|
7
8
|
import IconTargetArrow from '@fluentui/svg-icons/icons/target_arrow_20_regular.svg?raw';
|
|
8
9
|
let { model, uiManager, on } = $props();
|
|
9
10
|
const attachmentsToShow = $derived.by(() => {
|
|
10
|
-
|
|
11
|
+
if (!model.attachments) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
const products = model.attachments.products
|
|
11
15
|
.filter((p) => !!p.image)
|
|
12
16
|
.map((p) => ({
|
|
13
17
|
isAd: false,
|
|
@@ -22,7 +26,7 @@ const attachmentsToShow = $derived.by(() => {
|
|
|
22
26
|
title: p.title,
|
|
23
27
|
description: p.shortDescription
|
|
24
28
|
}));
|
|
25
|
-
const ads = model.ads
|
|
29
|
+
const ads = model.attachments.ads
|
|
26
30
|
.filter((a) => !!a.image)
|
|
27
31
|
.map((a) => {
|
|
28
32
|
var _a;
|
|
@@ -154,6 +158,7 @@ const variables = $derived.by(() => {
|
|
|
154
158
|
}
|
|
155
159
|
}
|
|
156
160
|
.attachments-horizontal {
|
|
161
|
+
pointer-events: auto;
|
|
157
162
|
display: flex;
|
|
158
163
|
gap: 0.5rem;
|
|
159
164
|
flex-wrap: nowrap;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { PostModel } from '../model';
|
|
2
2
|
import { PostViewerUiManager } from './ui-manager.svelte';
|
|
3
3
|
type Props = {
|
|
4
|
-
model:
|
|
4
|
+
model: PostModel;
|
|
5
5
|
uiManager: PostViewerUiManager;
|
|
6
6
|
on?: {
|
|
7
7
|
productClick?: (productId: string) => void;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script lang="ts">import { PostControls } from '../controls';
|
|
2
|
-
import {
|
|
2
|
+
import { PostModel } from '../model';
|
|
3
3
|
import { default as AttachmentsHorizontal } from './attachments-horizontal.svelte';
|
|
4
4
|
import { default as Heading } from './heading.svelte';
|
|
5
|
-
import { default as PostMedia } from './post-media.svelte';
|
|
5
|
+
import { default as PostMedia } from './media/post-media.svelte';
|
|
6
|
+
import { default as Texts } from './post-texts.svelte';
|
|
6
7
|
import { PostViewerLocalization } from './post-viewer-localization';
|
|
7
8
|
import { PostViewerUiManager } from './ui-manager.svelte';
|
|
8
9
|
let { model, socialInteractionsHandler, enableAttachments = true, enableControls = true, autoplay = 'on-appearance', locale = 'en', on } = $props();
|
|
@@ -35,40 +36,33 @@ const trackControlsPanelSize = (node) => {
|
|
|
35
36
|
}
|
|
36
37
|
};
|
|
37
38
|
};
|
|
38
|
-
const handleMediaContentChanged = (data) => {
|
|
39
|
-
console.warn('gallery:', data.galleryMode, 'seekBar:', data.videoSeekBar);
|
|
40
|
-
};
|
|
41
39
|
const variables = $derived.by(() => {
|
|
42
|
-
const values = [
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
const values = [];
|
|
41
|
+
if (model.media.isGallery) {
|
|
42
|
+
values.push(`--_post-viewer--information--padding-bottom: 45px`);
|
|
43
|
+
}
|
|
45
44
|
return values.join(';');
|
|
46
45
|
});
|
|
47
46
|
</script>
|
|
48
47
|
|
|
49
48
|
<div class="post-viewer" style={variables} use:viewerMounted>
|
|
50
|
-
<PostMedia id={model.id} media={model.media} autoplay={autoplay} on={{
|
|
49
|
+
<PostMedia id={model.id} media={model.media} locale={locale} autoplay={autoplay} on={{ videoProgress: on?.progress }} />
|
|
51
50
|
<div class="post-viewer__information">
|
|
52
51
|
{#if model.heading}
|
|
53
52
|
<Heading model={model.heading} uiManager={uiManager} localization={localization} />
|
|
54
53
|
{/if}
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
on
|
|
66
|
-
|
|
67
|
-
productImpression: on?.productImpression,
|
|
68
|
-
adClick: on?.adClick,
|
|
69
|
-
adImpression: on?.adImpression
|
|
70
|
-
}} />
|
|
71
|
-
</div>
|
|
54
|
+
<Texts model={model.texts} uiManager={uiManager} localization={localization} />
|
|
55
|
+
|
|
56
|
+
{#if uiManager.showAttachments && model.attachments}
|
|
57
|
+
<AttachmentsHorizontal
|
|
58
|
+
model={model}
|
|
59
|
+
uiManager={uiManager}
|
|
60
|
+
on={{
|
|
61
|
+
productClick: on?.productClick,
|
|
62
|
+
productImpression: on?.productImpression,
|
|
63
|
+
adClick: on?.adClick,
|
|
64
|
+
adImpression: on?.adImpression
|
|
65
|
+
}} />
|
|
72
66
|
{/if}
|
|
73
67
|
</div>
|
|
74
68
|
|
|
@@ -94,7 +88,6 @@ const variables = $derived.by(() => {
|
|
|
94
88
|
}
|
|
95
89
|
}
|
|
96
90
|
.post-viewer {
|
|
97
|
-
--video--media-fit: cover;
|
|
98
91
|
width: 100%;
|
|
99
92
|
min-width: 100%;
|
|
100
93
|
max-width: 100%;
|
|
@@ -116,7 +109,6 @@ const variables = $derived.by(() => {
|
|
|
116
109
|
position: absolute;
|
|
117
110
|
left: auto;
|
|
118
111
|
right: 0;
|
|
119
|
-
top: 5rem;
|
|
120
112
|
bottom: 6.25rem;
|
|
121
113
|
gap: 2.5rem;
|
|
122
114
|
display: flex;
|
|
@@ -126,38 +118,23 @@ const variables = $derived.by(() => {
|
|
|
126
118
|
padding: 0 0.625rem;
|
|
127
119
|
}
|
|
128
120
|
.post-viewer__information {
|
|
121
|
+
pointer-events: none;
|
|
129
122
|
position: absolute;
|
|
130
123
|
bottom: 0;
|
|
131
124
|
left: 0;
|
|
132
125
|
right: 0;
|
|
133
126
|
padding: 1.875rem 0;
|
|
127
|
+
padding-bottom: var(--_post-viewer--information--padding-bottom, 1.875rem);
|
|
128
|
+
display: flex;
|
|
129
|
+
flex-direction: column;
|
|
130
|
+
gap: 1.25rem;
|
|
134
131
|
background: linear-gradient(0deg, #000 0%, rgba(0, 0, 0, 0) 100%);
|
|
135
132
|
/* Set 'container-type: inline-size;' to reference container*/
|
|
136
133
|
}
|
|
137
134
|
@container (width < 576px) {
|
|
138
135
|
.post-viewer__information {
|
|
139
136
|
padding-block: 1.25rem;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
.post-viewer__text {
|
|
143
|
-
color: #ffffff;
|
|
144
|
-
font-size: 1.125rem;
|
|
145
|
-
font-weight: 400;
|
|
146
|
-
text-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);
|
|
147
|
-
padding: var(--_post-viewer--information--text--padding);
|
|
148
|
-
/* Set 'container-type: inline-size;' to reference container*/
|
|
149
|
-
}
|
|
150
|
-
@container (width < 576px) {
|
|
151
|
-
.post-viewer__text {
|
|
152
|
-
font-size: 0.9375rem;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
.post-viewer__attachments {
|
|
156
|
-
margin-top: 1.25rem;
|
|
157
|
-
/* Set 'container-type: inline-size;' to reference container*/
|
|
158
|
-
}
|
|
159
|
-
@container (width < 576px) {
|
|
160
|
-
.post-viewer__attachments {
|
|
161
|
-
margin-top: 0.625rem;
|
|
137
|
+
padding-bottom: var(--_post-viewer--information--padding-bottom, 1.25rem);
|
|
138
|
+
gap: 0.625rem;
|
|
162
139
|
}
|
|
163
140
|
}</style>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Locale } from '../../core/locale';
|
|
2
|
+
import { PostModel } from '../model';
|
|
2
3
|
import type { IPostSocialInteractionsHandler } from '../social-interactions';
|
|
3
|
-
import type { PostViewerModel } from './types';
|
|
4
4
|
type Props = {
|
|
5
|
-
model:
|
|
5
|
+
model: PostModel;
|
|
6
6
|
socialInteractionsHandler?: IPostSocialInteractionsHandler;
|
|
7
7
|
enableAttachments?: boolean;
|
|
8
8
|
enableControls?: boolean;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
<script lang="ts">import {
|
|
1
|
+
<script lang="ts">import { PostModel } from '../model';
|
|
2
|
+
import { PostViewerUiManager } from './ui-manager.svelte';
|
|
2
3
|
import { ImageRound } from '../../ui/image';
|
|
3
4
|
import { TimeAgo } from '../../ui/time-ago';
|
|
4
5
|
import { PostViewerLocalization } from './post-viewer-localization';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { PostModel } from '../model';
|
|
1
2
|
import { PostViewerUiManager } from './ui-manager.svelte';
|
|
2
3
|
import { PostViewerLocalization } from './post-viewer-localization';
|
|
3
|
-
import type { PostViewerHeadingModel } from './types';
|
|
4
4
|
type Props = {
|
|
5
|
-
model:
|
|
5
|
+
model: NonNullable<PostModel['heading']>;
|
|
6
6
|
uiManager: PostViewerUiManager;
|
|
7
7
|
localization: PostViewerLocalization;
|
|
8
8
|
};
|
|
@@ -1,4 +1,2 @@
|
|
|
1
1
|
export { default as PostViewer } from './cmp.post-viewer.svelte';
|
|
2
|
-
export
|
|
3
|
-
export { mapToPostViewerModel } from './mapper';
|
|
4
|
-
export { getPostCoverImage } from './utils';
|
|
2
|
+
export { mapToPostModel } from './mapper';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
+
import type { IPostModel } from '../model';
|
|
1
2
|
import type { PostViewerPayloadFragment } from './operations.generated';
|
|
2
|
-
|
|
3
|
-
export declare const mapToPostViewerModel: (payload: PostViewerPayloadFragment) => PostViewerModel;
|
|
3
|
+
export declare const mapToPostModel: (payload: PostViewerPayloadFragment) => IPostModel;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { MediaType } from '../../core/enums';
|
|
2
2
|
import { getMediaItemImageUrl } from '../../core/media';
|
|
3
3
|
import { shouldUseSalePrice } from '../../products/price-helper';
|
|
4
|
-
export const
|
|
4
|
+
export const mapToPostModel = (payload) => {
|
|
5
5
|
return {
|
|
6
6
|
id: payload.id,
|
|
7
7
|
media: mapToPostViewerMediaModel(payload.postData),
|
|
8
|
+
mediaFit: mediaFitFromPostType(payload.postData),
|
|
9
|
+
kicker: extractPostKicker(payload.postData),
|
|
10
|
+
title: extractPostTitle(payload.postData),
|
|
8
11
|
text: extractPostText(payload.postData),
|
|
9
12
|
enableSocialInteractions: payload.enableSocialInteractions,
|
|
10
13
|
heading: null,
|
|
@@ -19,35 +22,28 @@ export const mapToPostViewerModel = (payload) => {
|
|
|
19
22
|
// )
|
|
20
23
|
};
|
|
21
24
|
};
|
|
22
|
-
const
|
|
23
|
-
return payload.
|
|
25
|
+
const mediaFitFromPostType = (payload) => {
|
|
26
|
+
return payload.shortVideoData || payload.momentData ? 'cover' : 'contain';
|
|
27
|
+
};
|
|
28
|
+
const extractPostKicker = (payload) => {
|
|
29
|
+
return payload.articleData?.kicker ?? null;
|
|
24
30
|
};
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
case MediaType.Video:
|
|
31
|
-
case MediaType.ShortVideo:
|
|
32
|
-
return { type: 'video', url: mediaBlob.url, thumbnailUrl: mediaBlob.thumbnailUrl, isMutable: true };
|
|
33
|
-
default:
|
|
34
|
-
return emptyMedia;
|
|
35
|
-
}
|
|
31
|
+
const extractPostTitle = (payload) => {
|
|
32
|
+
return payload.articleData?.title ?? payload.videoData?.title ?? null;
|
|
33
|
+
};
|
|
34
|
+
const extractPostText = (payload) => {
|
|
35
|
+
return payload.mediaData?.text ?? payload.momentData?.text ?? payload.shortVideoData?.text ?? payload.videoData?.text ?? null;
|
|
36
36
|
};
|
|
37
37
|
const mapToPostViewerMediaModel = (payload) => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
isMutable: items.some((x) => x.isMutable)
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
return toSingleMediaItem(mediaBlob);
|
|
38
|
+
return payload.media.map((i) => {
|
|
39
|
+
return i.type === MediaType.Image
|
|
40
|
+
? { isImage: true, url: i.url }
|
|
41
|
+
: {
|
|
42
|
+
isImage: false,
|
|
43
|
+
url: i.url,
|
|
44
|
+
thumbnailUrl: i.thumbnailUrl
|
|
45
|
+
};
|
|
46
|
+
});
|
|
51
47
|
};
|
|
52
48
|
const mapToPostViewerAdCardModel = (payload) => {
|
|
53
49
|
return {
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script lang="ts">import { Image } from '../../../ui/image';
|
|
2
|
+
import { Slider } from '../../../ui/slider';
|
|
3
|
+
import { Video } from '../../../ui/video';
|
|
4
|
+
let { id, media, locale, autoplay = 'on-appearance', on } = $props();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
{#snippet mediaItem(item: IPostMediaItemModel)}
|
|
8
|
+
{#if item.isImage}
|
|
9
|
+
<Image src={item.url} />
|
|
10
|
+
{:else}
|
|
11
|
+
<Video
|
|
12
|
+
src={item.url}
|
|
13
|
+
poster={item.thumbnailUrl}
|
|
14
|
+
controls={false}
|
|
15
|
+
autoplay={autoplay}
|
|
16
|
+
loop={true}
|
|
17
|
+
id={id}
|
|
18
|
+
hideSpeaker={true}
|
|
19
|
+
on={{
|
|
20
|
+
progress: on?.videoProgress
|
|
21
|
+
}} />
|
|
22
|
+
{/if}
|
|
23
|
+
{/snippet}
|
|
24
|
+
|
|
25
|
+
<div class="post-media" class:post-media--fit={media.mediaFit === 'contain'} class:post-media--fill={media.mediaFit === 'cover'}>
|
|
26
|
+
{#if media.items.length === 1}
|
|
27
|
+
{@render mediaItem(media.items[0])}
|
|
28
|
+
{:else if media.items.length > 1}
|
|
29
|
+
<Slider items={media.items} initialIndex={media.currentIndex} locale={locale} on={{ indexChanged: (index) => (media.currentIndex = index) }}>
|
|
30
|
+
{#snippet children(item)}
|
|
31
|
+
{@render mediaItem(item)}
|
|
32
|
+
{/snippet}
|
|
33
|
+
</Slider>
|
|
34
|
+
{/if}
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<style>@keyframes fadeIn {
|
|
38
|
+
0% {
|
|
39
|
+
opacity: 1;
|
|
40
|
+
}
|
|
41
|
+
50% {
|
|
42
|
+
opacity: 0.4;
|
|
43
|
+
}
|
|
44
|
+
100% {
|
|
45
|
+
opacity: 1;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
.post-media {
|
|
49
|
+
width: 100%;
|
|
50
|
+
min-width: 100%;
|
|
51
|
+
max-width: 100%;
|
|
52
|
+
height: 100%;
|
|
53
|
+
min-height: 100%;
|
|
54
|
+
max-height: 100%;
|
|
55
|
+
background-color: rgba(0, 0, 0, 0.6);
|
|
56
|
+
}
|
|
57
|
+
.post-media--fit {
|
|
58
|
+
--video--media-fit: contain;
|
|
59
|
+
--image--object-fit: contain;
|
|
60
|
+
}
|
|
61
|
+
.post-media--fill {
|
|
62
|
+
--video--media-fit: cover;
|
|
63
|
+
--image--object-fit: cover;
|
|
64
|
+
}</style>
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Locale } from '../../../core/locale';
|
|
2
|
+
import type { PostViewerMediaModel } from '../../model/post-media-model.svelte';
|
|
2
3
|
type Props = {
|
|
3
4
|
id: string;
|
|
4
5
|
media: PostViewerMediaModel;
|
|
6
|
+
locale: Locale;
|
|
5
7
|
autoplay?: true | false | 'on-appearance';
|
|
6
8
|
on: {
|
|
7
|
-
|
|
8
|
-
videoSeekBar: boolean;
|
|
9
|
-
galleryMode: boolean;
|
|
10
|
-
}) => void;
|
|
11
|
-
progress?: (progress: number) => void;
|
|
9
|
+
videoProgress?: (progress: number) => void;
|
|
12
10
|
};
|
|
13
11
|
};
|
|
14
12
|
declare const PostMedia: import("svelte").Component<Props, {}, "">;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<script lang="ts">import { LineClamp } from '../../ui/line-clamp';
|
|
2
|
+
import { PostViewerLocalization } from './post-viewer-localization';
|
|
3
|
+
import { PostViewerUiManager } from './ui-manager.svelte';
|
|
4
|
+
let { model, uiManager, localization } = $props();
|
|
5
|
+
const variables = $derived.by(() => {
|
|
6
|
+
const values = [
|
|
7
|
+
`--_post-viewer-texts--padding: 0 ${uiManager.controlsPanelWidth ? uiManager.controlsPanelWidth : uiManager.infoPaddingInline}px 0 ${uiManager.infoPaddingInline}px`
|
|
8
|
+
];
|
|
9
|
+
return values.join(';');
|
|
10
|
+
});
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<div class="post-viewer-texts" style={variables}>
|
|
14
|
+
{#if model.kicker}
|
|
15
|
+
<div class="post-viewer-texts__kicker">
|
|
16
|
+
<LineClamp value={model.kicker} maxLines={1} enableShowMore={false} />
|
|
17
|
+
</div>
|
|
18
|
+
{/if}
|
|
19
|
+
{#if model.title}
|
|
20
|
+
<div class="post-viewer-texts__title">
|
|
21
|
+
<LineClamp value={model.title} maxLines={2} enableShowMore={false} />
|
|
22
|
+
</div>
|
|
23
|
+
{/if}
|
|
24
|
+
{#if model.text}
|
|
25
|
+
<div class="post-viewer-texts__text">
|
|
26
|
+
<LineClamp value={model.text} maxLines={2} enableShowMore={true} />
|
|
27
|
+
</div>
|
|
28
|
+
{/if}
|
|
29
|
+
{#if model.readMoreUrl}
|
|
30
|
+
<a class="post-viewer-texts__read-more" href={model.readMoreUrl} target="_blank" rel="noopener noreferrer">
|
|
31
|
+
{localization.readMore}
|
|
32
|
+
</a>
|
|
33
|
+
{/if}
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<style>@keyframes fadeIn {
|
|
37
|
+
0% {
|
|
38
|
+
opacity: 1;
|
|
39
|
+
}
|
|
40
|
+
50% {
|
|
41
|
+
opacity: 0.4;
|
|
42
|
+
}
|
|
43
|
+
100% {
|
|
44
|
+
opacity: 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
.post-viewer-texts {
|
|
48
|
+
color: #ffffff;
|
|
49
|
+
text-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);
|
|
50
|
+
padding: var(--_post-viewer-texts--padding);
|
|
51
|
+
display: flex;
|
|
52
|
+
flex-direction: column;
|
|
53
|
+
gap: 0.625rem;
|
|
54
|
+
/* Set 'container-type: inline-size;' to reference container*/
|
|
55
|
+
}
|
|
56
|
+
@container (width < 576px) {
|
|
57
|
+
.post-viewer-texts {
|
|
58
|
+
gap: 0.375rem;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
.post-viewer-texts__kicker {
|
|
62
|
+
font-size: 1rem;
|
|
63
|
+
font-weight: 400;
|
|
64
|
+
/* Set 'container-type: inline-size;' to reference container*/
|
|
65
|
+
}
|
|
66
|
+
@container (width < 576px) {
|
|
67
|
+
.post-viewer-texts__kicker {
|
|
68
|
+
font-size: 0.875rem;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
.post-viewer-texts__title {
|
|
72
|
+
font-size: 1.25rem;
|
|
73
|
+
font-weight: 500;
|
|
74
|
+
/* Set 'container-type: inline-size;' to reference container*/
|
|
75
|
+
}
|
|
76
|
+
@container (width < 576px) {
|
|
77
|
+
.post-viewer-texts__title {
|
|
78
|
+
font-size: 1rem;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
.post-viewer-texts__text {
|
|
82
|
+
font-size: 1.125rem;
|
|
83
|
+
font-weight: 400;
|
|
84
|
+
/* Set 'container-type: inline-size;' to reference container*/
|
|
85
|
+
}
|
|
86
|
+
@container (width < 576px) {
|
|
87
|
+
.post-viewer-texts__text {
|
|
88
|
+
font-size: 0.9375rem;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
.post-viewer-texts__read-more {
|
|
92
|
+
pointer-events: auto;
|
|
93
|
+
font-size: 1rem;
|
|
94
|
+
font-weight: 400;
|
|
95
|
+
/* Set 'container-type: inline-size;' to reference container*/
|
|
96
|
+
}
|
|
97
|
+
@container (width < 576px) {
|
|
98
|
+
.post-viewer-texts__read-more {
|
|
99
|
+
font-size: 0.875rem;
|
|
100
|
+
}
|
|
101
|
+
}</style>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PostModel } from '../model/post-model';
|
|
2
|
+
import { PostViewerLocalization } from './post-viewer-localization';
|
|
3
|
+
import { PostViewerUiManager } from './ui-manager.svelte';
|
|
4
|
+
type Props = {
|
|
5
|
+
model: PostModel['texts'];
|
|
6
|
+
uiManager: PostViewerUiManager;
|
|
7
|
+
localization: PostViewerLocalization;
|
|
8
|
+
};
|
|
9
|
+
declare const PostTexts: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type PostTexts = ReturnType<typeof PostTexts>;
|
|
11
|
+
export default PostTexts;
|