@streamscloud/embeddable 7.0.1 → 7.0.2-1759150121372
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 +13 -12
- package/dist/ads/ad-card/cmp.ad-card.svelte.d.ts +2 -2
- package/dist/content-player/cmp.content-player.svelte +224 -0
- package/dist/content-player/cmp.content-player.svelte.d.ts +33 -0
- package/dist/content-player/content-player-config.svelte.d.ts +49 -0
- package/dist/content-player/content-player-config.svelte.js +43 -0
- package/dist/content-player/controls-and-attachments.svelte +275 -0
- package/dist/content-player/controls-and-attachments.svelte.d.ts +28 -0
- package/dist/content-player/fade-mixins.scss +12 -0
- package/dist/content-player/index.d.ts +2 -0
- package/dist/content-player/index.js +2 -0
- package/dist/content-player/overview-panel.svelte +85 -0
- package/dist/content-player/overview-panel.svelte.d.ts +10 -0
- package/dist/{streams/stream-player → content-player}/ui-manager.svelte.d.ts +10 -9
- package/dist/content-player/ui-manager.svelte.js +68 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/media-center/config/internal-media-center-config.js +2 -1
- package/dist/media-center/config/types.d.ts +1 -1
- package/dist/media-center/media-center/cmp.media-center.svelte +13 -9
- package/dist/media-center/media-center/overview.svelte +3 -2
- package/dist/media-center/media-center/short-video-resources-generator.d.ts +1 -1
- package/dist/media-center/model/types.d.ts +12 -0
- package/dist/posts/attachments/cmp.attachments.svelte +50 -0
- package/dist/{short-videos/short-video-viewer → posts/attachments}/cmp.attachments.svelte.d.ts +3 -3
- package/dist/posts/attachments/index.d.ts +1 -0
- package/dist/posts/attachments/index.js +1 -0
- package/dist/{short-videos/short-video-viewer/cmp.short-video-controls.svelte → posts/controls/cmp.controls.svelte} +21 -26
- package/dist/posts/controls/cmp.controls.svelte.d.ts +12 -0
- package/dist/posts/controls/index.d.ts +1 -0
- package/dist/posts/controls/index.js +1 -0
- package/dist/posts/index.d.ts +1 -0
- package/dist/posts/index.js +2 -0
- package/dist/posts/model/index.d.ts +1 -0
- package/dist/posts/model/index.js +1 -0
- package/dist/posts/model/types.d.ts +13 -0
- package/dist/posts/model/types.js +1 -0
- package/dist/{short-videos/short-video-viewer/cmp.attachments-horizontal.svelte → posts/post-viewer/attachments-horizontal.svelte} +2 -3
- package/dist/posts/post-viewer/attachments-horizontal.svelte.d.ts +13 -0
- package/dist/posts/post-viewer/cmp.post-viewer.svelte +120 -0
- package/dist/{short-videos/short-video-viewer/cmp.short-video-viewer.svelte.d.ts → posts/post-viewer/cmp.post-viewer.svelte.d.ts} +3 -2
- package/dist/posts/post-viewer/heading.svelte +76 -0
- package/dist/posts/post-viewer/heading.svelte.d.ts +9 -0
- package/dist/posts/post-viewer/index.d.ts +4 -0
- package/dist/posts/post-viewer/index.js +3 -0
- package/dist/posts/post-viewer/mapper.d.ts +3 -0
- package/dist/{short-videos/short-video-viewer → posts/post-viewer}/mapper.js +33 -17
- package/dist/{short-videos/short-video-viewer → posts/post-viewer}/operations.generated.d.ts +2 -2
- package/dist/{short-videos/short-video-viewer → posts/post-viewer}/operations.generated.js +2 -2
- package/dist/{short-videos/short-video-viewer → posts/post-viewer}/operations.graphql +1 -1
- package/dist/posts/post-viewer/post-media.svelte +20 -0
- package/dist/posts/post-viewer/post-media.svelte.d.ts +12 -0
- package/dist/{short-videos/short-video-viewer/short-video-viewer-localization.d.ts → posts/post-viewer/post-viewer-localization.d.ts} +2 -3
- package/dist/{short-videos/short-video-viewer/short-video-viewer-localization.js → posts/post-viewer/post-viewer-localization.js} +3 -5
- package/dist/{short-videos/short-video-viewer → posts/post-viewer}/types.d.ts +24 -25
- package/dist/{short-videos/short-video-viewer → posts/post-viewer}/ui-manager.svelte.d.ts +5 -3
- package/dist/{short-videos/short-video-viewer → posts/post-viewer}/ui-manager.svelte.js +11 -4
- package/dist/posts/post-viewer/utils.d.ts +2 -0
- package/dist/posts/post-viewer/utils.js +13 -0
- package/dist/posts/social-interactions/index.d.ts +1 -0
- package/dist/posts/social-interactions/index.js +1 -0
- package/dist/posts/social-interactions/types.d.ts +9 -0
- package/dist/posts/social-interactions/types.js +1 -0
- package/dist/products/product-card/cmp.product-card.svelte +27 -8
- package/dist/products/product-card/cmp.product-card.svelte.d.ts +2 -1
- package/dist/short-videos/short-videos-player/cmp.short-videos-player.svelte +11 -17
- package/dist/short-videos/short-videos-player/cmp.short-videos-player.svelte.d.ts +1 -5
- package/dist/short-videos/short-videos-player/index.d.ts +20 -5
- package/dist/short-videos/short-videos-player/internal-short-video-analytics-handler.d.ts +1 -1
- package/dist/short-videos/short-videos-player/internal-short-video-analytics-handler.js +1 -1
- package/dist/short-videos/short-videos-player/internal-short-video-player-provider.d.ts +1 -1
- package/dist/short-videos/short-videos-player/mapper.js +2 -2
- package/dist/short-videos/short-videos-player/short-videos-player-view.svelte +50 -216
- package/dist/short-videos/short-videos-player/short-videos-player-view.svelte.d.ts +2 -9
- package/dist/short-videos/short-videos-player/types.d.ts +6 -7
- package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte +3 -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 +6 -6
- package/dist/streams/stream-player/index.d.ts +25 -4
- package/dist/streams/stream-player/internal-stream-analytics-handler.d.ts +2 -0
- package/dist/streams/stream-player/internal-stream-analytics-handler.js +2 -0
- package/dist/streams/stream-player/stream-overview.svelte +47 -122
- package/dist/streams/stream-player/stream-overview.svelte.d.ts +1 -4
- package/dist/streams/stream-player/stream-player-buffer.svelte.d.ts +1 -1
- package/dist/streams/stream-player/stream-player-localization.d.ts +1 -5
- package/dist/streams/stream-player/stream-player-localization.js +2 -10
- package/dist/streams/stream-player/stream-player-view.svelte +229 -0
- package/dist/streams/stream-player/stream-player-view.svelte.d.ts +8 -0
- package/dist/streams/stream-player/types.d.ts +4 -4
- package/dist/ui/{player → player-slider}/cmp.player-slider.svelte.d.ts +2 -10
- package/dist/ui/{player → player-slider}/types.d.ts +9 -0
- package/dist/ui/player-slider/types.js +1 -0
- package/package.json +5 -1
- package/dist/short-videos/short-video-viewer/cmp.attachments-horizontal.svelte.d.ts +0 -13
- package/dist/short-videos/short-video-viewer/cmp.attachments.svelte +0 -52
- package/dist/short-videos/short-video-viewer/cmp.short-video-controls.svelte.d.ts +0 -19
- package/dist/short-videos/short-video-viewer/cmp.short-video-heading.svelte +0 -89
- package/dist/short-videos/short-video-viewer/cmp.short-video-heading.svelte.d.ts +0 -9
- package/dist/short-videos/short-video-viewer/cmp.short-video-product-card.svelte +0 -26
- package/dist/short-videos/short-video-viewer/cmp.short-video-product-card.svelte.d.ts +0 -16
- package/dist/short-videos/short-video-viewer/cmp.short-video-viewer.svelte +0 -146
- package/dist/short-videos/short-video-viewer/index.d.ts +0 -5
- package/dist/short-videos/short-video-viewer/index.js +0 -4
- package/dist/short-videos/short-video-viewer/mapper.d.ts +0 -3
- package/dist/short-videos/short-video-viewer/short-video-attachments-localization.d.ts +0 -5
- package/dist/short-videos/short-video-viewer/short-video-attachments-localization.js +0 -7
- package/dist/short-videos/short-videos-player/controls.svelte +0 -261
- package/dist/short-videos/short-videos-player/controls.svelte.d.ts +0 -22
- package/dist/short-videos/short-videos-player/fade-mixins.scss +0 -12
- package/dist/short-videos/short-videos-player/short-videos-player-localization.d.ts +0 -7
- package/dist/short-videos/short-videos-player/short-videos-player-localization.js +0 -11
- package/dist/short-videos/short-videos-player/ui-manager.svelte.d.ts +0 -24
- package/dist/short-videos/short-videos-player/ui-manager.svelte.js +0 -47
- package/dist/streams/cmp.stream-product-card.svelte +0 -25
- package/dist/streams/cmp.stream-product-card.svelte.d.ts +0 -16
- package/dist/streams/stream-player/controls.svelte +0 -301
- package/dist/streams/stream-player/controls.svelte.d.ts +0 -20
- package/dist/streams/stream-player/fade-mixins.scss +0 -12
- package/dist/streams/stream-player/stream-player.svelte +0 -393
- package/dist/streams/stream-player/stream-player.svelte.d.ts +0 -16
- package/dist/streams/stream-player/ui-manager.svelte.js +0 -63
- /package/dist/{streams/stream-player → content-player}/button-mixins.scss +0 -0
- /package/dist/{ui/player → media-center/model}/types.js +0 -0
- /package/dist/{short-videos/short-video-viewer → posts/post-viewer}/types.js +0 -0
- /package/dist/ui/{player → player-slider}/cmp.player-slider.svelte +0 -0
- /package/dist/ui/{player → player-slider}/index.d.ts +0 -0
- /package/dist/ui/{player → player-slider}/index.js +0 -0
- /package/dist/ui/{player → player-slider}/player-buffer.svelte.d.ts +0 -0
- /package/dist/ui/{player → player-slider}/player-buffer.svelte.js +0 -0
- /package/dist/ui/{player → player-slider}/prevent-slider-scroll.d.ts +0 -0
- /package/dist/ui/{player → player-slider}/prevent-slider-scroll.js +0 -0
- /package/dist/ui/{player → player-slider}/wheel-gestures-adapter.d.ts +0 -0
- /package/dist/ui/{player → player-slider}/wheel-gestures-adapter.js +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<script lang="ts">import { PostControls } from '../controls';
|
|
2
|
+
import { LineClamp } from '../../ui/line-clamp';
|
|
3
|
+
import { default as AttachmentsHorizontal } from './attachments-horizontal.svelte';
|
|
4
|
+
import { default as Heading } from './heading.svelte';
|
|
5
|
+
import { default as PostMedia } from './post-media.svelte';
|
|
6
|
+
import { PostViewerLocalization } from './post-viewer-localization';
|
|
7
|
+
import { PostViewerUiManager } from './ui-manager.svelte';
|
|
8
|
+
let { model, socialInteractionsHandler, showAttachments = true, showControls = true, autoplay = 'on-appearance', locale = 'en', on } = $props();
|
|
9
|
+
const localization = $derived(new PostViewerLocalization(locale));
|
|
10
|
+
const uiManager = new PostViewerUiManager();
|
|
11
|
+
$effect(() => {
|
|
12
|
+
uiManager.setCanShowAttachments(showAttachments);
|
|
13
|
+
uiManager.setCanShowControls(showControls);
|
|
14
|
+
});
|
|
15
|
+
const trackControlsPanelSize = (node) => {
|
|
16
|
+
const resizeObserver = new ResizeObserver(([entry]) => {
|
|
17
|
+
const width = entry.contentRect.width;
|
|
18
|
+
uiManager.setControlsPanelWidth(width);
|
|
19
|
+
});
|
|
20
|
+
resizeObserver.observe(node);
|
|
21
|
+
return {
|
|
22
|
+
destroy() {
|
|
23
|
+
resizeObserver.unobserve(node);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<div class="post-viewer" style={uiManager.globalCssVariables}>
|
|
30
|
+
<PostMedia id={model.id} media={model.media} autoplay={autoplay} on={{ progress: on?.progress }} />
|
|
31
|
+
<div class="post-viewer__information">
|
|
32
|
+
{#if model.heading}
|
|
33
|
+
<Heading model={model.heading} localization={localization} />
|
|
34
|
+
{/if}
|
|
35
|
+
<div class="post-viewer__text">
|
|
36
|
+
{#if model.text}
|
|
37
|
+
<LineClamp value={model.text} maxLines={2} enableShowMore={true} />
|
|
38
|
+
{/if}
|
|
39
|
+
</div>
|
|
40
|
+
{#if uiManager.showAttachments && (model.ads.length || model.products.length)}
|
|
41
|
+
<div class="post-viewer__attachments">
|
|
42
|
+
<AttachmentsHorizontal
|
|
43
|
+
model={model}
|
|
44
|
+
on={{
|
|
45
|
+
productClick: on?.productClick,
|
|
46
|
+
productImpression: on?.productImpression,
|
|
47
|
+
adClick: on?.adClick,
|
|
48
|
+
adImpression: on?.adImpression
|
|
49
|
+
}} />
|
|
50
|
+
</div>
|
|
51
|
+
{/if}
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div class="post-viewer__controls-panel" use:trackControlsPanelSize>
|
|
55
|
+
{#if uiManager.showControls}
|
|
56
|
+
<PostControls model={model} socialInteractionsHandler={socialInteractionsHandler} on={{ attachmentsClicked: uiManager.toggleEnableAttachments }} />
|
|
57
|
+
{/if}
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<style>@keyframes fadeIn {
|
|
62
|
+
0% {
|
|
63
|
+
opacity: 1;
|
|
64
|
+
}
|
|
65
|
+
50% {
|
|
66
|
+
opacity: 0.4;
|
|
67
|
+
}
|
|
68
|
+
100% {
|
|
69
|
+
opacity: 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
.post-viewer {
|
|
73
|
+
--video--media-fit: cover;
|
|
74
|
+
width: 100%;
|
|
75
|
+
min-width: 100%;
|
|
76
|
+
max-width: 100%;
|
|
77
|
+
height: 100%;
|
|
78
|
+
min-height: 100%;
|
|
79
|
+
max-height: 100%;
|
|
80
|
+
border-radius: 0.375rem;
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
position: relative;
|
|
83
|
+
/* Set 'container-type: inline-size;' to reference container*/
|
|
84
|
+
}
|
|
85
|
+
@container (width < 576px) {
|
|
86
|
+
.post-viewer {
|
|
87
|
+
border-radius: 0;
|
|
88
|
+
position: relative;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
.post-viewer__controls-panel {
|
|
92
|
+
position: absolute;
|
|
93
|
+
left: auto;
|
|
94
|
+
right: 0.625rem;
|
|
95
|
+
top: 5rem;
|
|
96
|
+
bottom: 6.25rem;
|
|
97
|
+
gap: 2.5rem;
|
|
98
|
+
display: flex;
|
|
99
|
+
flex-direction: column;
|
|
100
|
+
justify-content: flex-end;
|
|
101
|
+
align-items: flex-end;
|
|
102
|
+
}
|
|
103
|
+
.post-viewer__information {
|
|
104
|
+
position: absolute;
|
|
105
|
+
bottom: 0;
|
|
106
|
+
left: 0;
|
|
107
|
+
right: 0;
|
|
108
|
+
padding: 1.875rem 0;
|
|
109
|
+
background: linear-gradient(0deg, #000 0%, rgba(0, 0, 0, 0) 100%);
|
|
110
|
+
}
|
|
111
|
+
.post-viewer__text {
|
|
112
|
+
color: #ffffff;
|
|
113
|
+
font-size: 1.125rem;
|
|
114
|
+
font-weight: 400;
|
|
115
|
+
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);
|
|
116
|
+
padding: var(--post-viewer--information--text--padding);
|
|
117
|
+
}
|
|
118
|
+
.post-viewer__attachments {
|
|
119
|
+
margin-top: 1.25rem;
|
|
120
|
+
}</style>
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Locale } from '../../core/locale';
|
|
2
|
-
import type { IPostSocialInteractionsHandler
|
|
2
|
+
import type { IPostSocialInteractionsHandler } from '../social-interactions';
|
|
3
|
+
import type { PostViewerModel } from './types';
|
|
3
4
|
type Props = {
|
|
4
|
-
model:
|
|
5
|
+
model: PostViewerModel;
|
|
5
6
|
socialInteractionsHandler?: IPostSocialInteractionsHandler;
|
|
6
7
|
showAttachments?: boolean;
|
|
7
8
|
showControls?: boolean;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script lang="ts">import { ImageRound } from '../../ui/image';
|
|
2
|
+
import { TimeAgo } from '../../ui/time-ago';
|
|
3
|
+
import { PostViewerLocalization } from './post-viewer-localization';
|
|
4
|
+
let { model, localization } = $props();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<div class="post-viewer-heading">
|
|
8
|
+
<div class="post-viewer-heading__source-image">
|
|
9
|
+
<ImageRound src={model.image} alt={`${model.name} profilbilde`} noBorders={true} />
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div class="post-viewer-heading__info">
|
|
13
|
+
<div class="post-viewer-heading__source-name">{model.name}</div>
|
|
14
|
+
<p class="post-viewer-heading__metadata">
|
|
15
|
+
<TimeAgo date={model.displayDate} locale={localization.locale} />
|
|
16
|
+
{#if Number.isInteger(model.viewsCount) && model.viewsCount}
|
|
17
|
+
<span>·</span>
|
|
18
|
+
{localization.viewsCount(model.viewsCount)}
|
|
19
|
+
{/if}
|
|
20
|
+
</p>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<style>@keyframes fadeIn {
|
|
25
|
+
0% {
|
|
26
|
+
opacity: 1;
|
|
27
|
+
}
|
|
28
|
+
50% {
|
|
29
|
+
opacity: 0.4;
|
|
30
|
+
}
|
|
31
|
+
100% {
|
|
32
|
+
opacity: 1;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
.post-viewer-heading {
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
padding: var(--post-viewer--heading--padding);
|
|
39
|
+
min-width: 0;
|
|
40
|
+
}
|
|
41
|
+
.post-viewer-heading__source-image {
|
|
42
|
+
width: 2rem;
|
|
43
|
+
min-width: 2rem;
|
|
44
|
+
max-width: 2rem;
|
|
45
|
+
height: 2rem;
|
|
46
|
+
min-height: 2rem;
|
|
47
|
+
max-height: 2rem;
|
|
48
|
+
margin-right: 0.625rem;
|
|
49
|
+
--image--rounded--outer--border-radius: 0.5rem;
|
|
50
|
+
--image--rounded--inner--border-width: 0;
|
|
51
|
+
--rounded-img-background: none;
|
|
52
|
+
}
|
|
53
|
+
.post-viewer-heading__info {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
min-width: 0;
|
|
57
|
+
}
|
|
58
|
+
.post-viewer-heading__source-name {
|
|
59
|
+
font-size: 0.75rem;
|
|
60
|
+
line-height: 0.9375rem;
|
|
61
|
+
font-weight: 500;
|
|
62
|
+
color: #ffffff;
|
|
63
|
+
text-shadow: 1px 1px hsl(0, 0%, 10%);
|
|
64
|
+
text-overflow: ellipsis;
|
|
65
|
+
width: 100%;
|
|
66
|
+
white-space: nowrap;
|
|
67
|
+
overflow: hidden;
|
|
68
|
+
}
|
|
69
|
+
.post-viewer-heading__metadata {
|
|
70
|
+
margin: 0;
|
|
71
|
+
font-size: 0.625rem;
|
|
72
|
+
line-height: 0.75rem;
|
|
73
|
+
font-weight: 400;
|
|
74
|
+
color: #ffffff;
|
|
75
|
+
text-shadow: 1px 1px hsl(0, 0%, 10%);
|
|
76
|
+
}</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PostViewerLocalization } from './post-viewer-localization';
|
|
2
|
+
import type { PostViewerHeadingModel } from './types';
|
|
3
|
+
type Props = {
|
|
4
|
+
model: PostViewerHeadingModel;
|
|
5
|
+
localization: PostViewerLocalization;
|
|
6
|
+
};
|
|
7
|
+
declare const Heading: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type Heading = ReturnType<typeof Heading>;
|
|
9
|
+
export default Heading;
|
|
@@ -1,26 +1,15 @@
|
|
|
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
|
|
5
|
-
const mediaBlob = payload.postData.media[0];
|
|
6
|
-
if (!mediaBlob) {
|
|
7
|
-
console.warn(`Short video '${payload.id}' media is missing. Unexpected behavior.`);
|
|
8
|
-
}
|
|
4
|
+
export const mapToPostViewerModel = (payload) => {
|
|
9
5
|
return {
|
|
10
6
|
id: payload.id,
|
|
11
|
-
media:
|
|
12
|
-
? { isImage: true, url: mediaBlob.url }
|
|
13
|
-
: {
|
|
14
|
-
isImage: false,
|
|
15
|
-
url: mediaBlob.url,
|
|
16
|
-
thumbnailUrl: mediaBlob.thumbnailUrl
|
|
17
|
-
},
|
|
7
|
+
media: mapToPostViewerMediaModel(payload.postData),
|
|
18
8
|
text: payload.postData.shortVideoData.text,
|
|
19
9
|
enableSocialInteractions: payload.enableSocialInteractions,
|
|
20
10
|
heading: null,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
products: payload.allProducts.map((x) => mapToShortVideoProductCard(x))
|
|
11
|
+
ads: payload.ad ? [mapToPostViewerAdCardModel(payload.ad)] : [],
|
|
12
|
+
products: payload.allProducts.map((x) => mapToPostViewerProductCard(x))
|
|
24
13
|
// uncomment if you want to test many products behavior
|
|
25
14
|
// .flatMap((x) =>
|
|
26
15
|
// Array.from({ length: 20 }, (_, i) => ({
|
|
@@ -30,7 +19,34 @@ export const mapToShortVideoViewerModel = (payload) => {
|
|
|
30
19
|
// )
|
|
31
20
|
};
|
|
32
21
|
};
|
|
33
|
-
const
|
|
22
|
+
const emptyMedia = { type: 'image', url: '', isMutable: false };
|
|
23
|
+
const toSingleMediaItem = (mediaBlob) => {
|
|
24
|
+
switch (mediaBlob.type) {
|
|
25
|
+
case MediaType.Image:
|
|
26
|
+
return { type: 'image', url: mediaBlob.url, isMutable: false };
|
|
27
|
+
case MediaType.Video:
|
|
28
|
+
case MediaType.ShortVideo:
|
|
29
|
+
return { type: 'video', url: mediaBlob.url, thumbnailUrl: mediaBlob.thumbnailUrl, isMutable: true };
|
|
30
|
+
default:
|
|
31
|
+
return emptyMedia;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const mapToPostViewerMediaModel = (payload) => {
|
|
35
|
+
const mediaBlob = payload.media[0];
|
|
36
|
+
if (!payload.media.length) {
|
|
37
|
+
return emptyMedia;
|
|
38
|
+
}
|
|
39
|
+
if (payload.media.length > 1) {
|
|
40
|
+
const items = payload.media.map(toSingleMediaItem);
|
|
41
|
+
return {
|
|
42
|
+
type: 'gallery',
|
|
43
|
+
items,
|
|
44
|
+
isMutable: items.some((x) => x.isMutable)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return toSingleMediaItem(mediaBlob);
|
|
48
|
+
};
|
|
49
|
+
const mapToPostViewerAdCardModel = (payload) => {
|
|
34
50
|
return {
|
|
35
51
|
id: payload.id,
|
|
36
52
|
type: payload.type,
|
|
@@ -43,7 +59,7 @@ const mapToShortVideoAdCardModel = (payload) => {
|
|
|
43
59
|
ctaButton: payload.ctaButton
|
|
44
60
|
};
|
|
45
61
|
};
|
|
46
|
-
const
|
|
62
|
+
const mapToPostViewerProductCard = (payload, referenceDate) => {
|
|
47
63
|
const effectiveSalePrice = payload.priceAndAvailability.productSalePrices?.find((x) => shouldUseSalePrice({
|
|
48
64
|
price: payload.priceAndAvailability.price,
|
|
49
65
|
salePrice: x.salePrice,
|
package/dist/{short-videos/short-video-viewer → posts/post-viewer}/operations.generated.d.ts
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as SchemaTypes from '../../../gql/types';
|
|
2
2
|
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
|
3
|
-
export type
|
|
3
|
+
export type PostViewerPayloadFragment = {
|
|
4
4
|
id: string;
|
|
5
5
|
enableSocialInteractions: boolean;
|
|
6
6
|
allProducts: Array<{
|
|
@@ -58,4 +58,4 @@ export type ShortVideoViewerPayloadFragment = {
|
|
|
58
58
|
} | null;
|
|
59
59
|
};
|
|
60
60
|
};
|
|
61
|
-
export declare const
|
|
61
|
+
export declare const PostViewerPayloadFragmentDoc: DocumentNode<PostViewerPayloadFragment, unknown>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const PostViewerPayloadFragmentDoc = {
|
|
2
2
|
kind: 'Document',
|
|
3
3
|
definitions: [
|
|
4
4
|
{
|
|
5
5
|
kind: 'FragmentDefinition',
|
|
6
|
-
name: { kind: 'Name', value: '
|
|
6
|
+
name: { kind: 'Name', value: 'PostViewerPayloadFragment' },
|
|
7
7
|
typeCondition: { kind: 'NamedType', name: { kind: 'Name', value: 'Post' } },
|
|
8
8
|
selectionSet: {
|
|
9
9
|
kind: 'SelectionSet',
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">import { Image } from '../../ui/image';
|
|
2
|
+
import { Video } from '../../ui/video';
|
|
3
|
+
let { id, media, autoplay = 'on-appearance', on } = $props();
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
{#if media.type === 'video'}
|
|
7
|
+
<Video
|
|
8
|
+
src={media.url}
|
|
9
|
+
poster={media.thumbnailUrl}
|
|
10
|
+
controls={false}
|
|
11
|
+
autoplay={autoplay}
|
|
12
|
+
loop={true}
|
|
13
|
+
id={id}
|
|
14
|
+
hideSpeaker={true}
|
|
15
|
+
on={{
|
|
16
|
+
progress: on?.progress
|
|
17
|
+
}} />
|
|
18
|
+
{:else if media.type === 'image'}
|
|
19
|
+
<Image src={media.url} />
|
|
20
|
+
{/if}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PostViewerMediaModel } from './types';
|
|
2
|
+
type Props = {
|
|
3
|
+
id: string;
|
|
4
|
+
media: PostViewerMediaModel;
|
|
5
|
+
autoplay?: true | false | 'on-appearance';
|
|
6
|
+
on?: {
|
|
7
|
+
progress?: (progress: number) => void;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
declare const PostMedia: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type PostMedia = ReturnType<typeof PostMedia>;
|
|
12
|
+
export default PostMedia;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type Locale } from '../../core/locale';
|
|
2
|
-
export declare class
|
|
2
|
+
export declare class PostViewerLocalization {
|
|
3
3
|
viewsCount: (count: number) => string;
|
|
4
|
-
|
|
5
|
-
productLocale: Locale;
|
|
4
|
+
locale: Locale;
|
|
6
5
|
constructor(locale: Locale);
|
|
7
6
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import {} from '../../core/locale';
|
|
2
|
-
export class
|
|
2
|
+
export class PostViewerLocalization {
|
|
3
3
|
viewsCount;
|
|
4
|
-
|
|
5
|
-
productLocale;
|
|
4
|
+
locale;
|
|
6
5
|
constructor(locale) {
|
|
7
6
|
this.viewsCount = loc.viewsCount[locale];
|
|
8
|
-
this.
|
|
9
|
-
this.productLocale = locale;
|
|
7
|
+
this.locale = locale;
|
|
10
8
|
}
|
|
11
9
|
}
|
|
12
10
|
const loc = {
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
import { AdType, type Currency } from '../../core/enums';
|
|
2
|
-
export type
|
|
2
|
+
export type PostViewerModel = {
|
|
3
3
|
id: string;
|
|
4
|
-
media:
|
|
5
|
-
isImage: true;
|
|
6
|
-
url: string;
|
|
7
|
-
} | {
|
|
8
|
-
isImage: false;
|
|
9
|
-
url: string;
|
|
10
|
-
thumbnailUrl: string;
|
|
11
|
-
};
|
|
4
|
+
media: PostViewerMediaModel;
|
|
12
5
|
text: string | null;
|
|
13
|
-
heading:
|
|
6
|
+
heading: PostViewerHeadingModel | null;
|
|
14
7
|
enableSocialInteractions: boolean;
|
|
15
|
-
products:
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
products: PostViewerProductCardModel[];
|
|
9
|
+
ads: PostViewerAdCardModel[];
|
|
10
|
+
};
|
|
11
|
+
export type PostViewerMediaModel = PostViewerImageMediaModel | PostViewerVideoMediaModel | {
|
|
12
|
+
type: 'gallery';
|
|
13
|
+
items: Array<PostViewerImageMediaModel | PostViewerVideoMediaModel>;
|
|
14
|
+
isMutable: boolean;
|
|
15
|
+
};
|
|
16
|
+
export type PostViewerImageMediaModel = {
|
|
17
|
+
type: 'image';
|
|
18
|
+
url: string;
|
|
19
|
+
isMutable: false;
|
|
20
|
+
};
|
|
21
|
+
export type PostViewerVideoMediaModel = {
|
|
22
|
+
type: 'video';
|
|
23
|
+
url: string;
|
|
24
|
+
thumbnailUrl: string;
|
|
25
|
+
isMutable: true;
|
|
18
26
|
};
|
|
19
|
-
export type
|
|
27
|
+
export type PostViewerHeadingModel = {
|
|
20
28
|
image: string | null;
|
|
21
29
|
name: string;
|
|
22
30
|
displayDate: string;
|
|
23
31
|
viewsCount: number;
|
|
24
32
|
};
|
|
25
|
-
export
|
|
26
|
-
getIsLiked: (shortVideoId: string) => PromiseLike<{
|
|
27
|
-
readonly isLiked: boolean;
|
|
28
|
-
}>;
|
|
29
|
-
toggleLike: (shortVideoId: string) => PromiseLike<void>;
|
|
30
|
-
share: (shortVideoId: string) => PromiseLike<void>;
|
|
31
|
-
}
|
|
32
|
-
type PromiseLike<T> = T | Promise<T>;
|
|
33
|
-
export type ShortVideoProductCardModel = {
|
|
33
|
+
export type PostViewerProductCardModel = {
|
|
34
34
|
id: string;
|
|
35
35
|
title: string;
|
|
36
36
|
shortDescription: string | null;
|
|
@@ -41,7 +41,7 @@ export type ShortVideoProductCardModel = {
|
|
|
41
41
|
currency: Currency;
|
|
42
42
|
salePrice: number | null;
|
|
43
43
|
};
|
|
44
|
-
export type
|
|
44
|
+
export type PostViewerAdCardModel = {
|
|
45
45
|
id: string;
|
|
46
46
|
type: AdType;
|
|
47
47
|
image: string | null;
|
|
@@ -58,4 +58,3 @@ export type ShortVideoAdCardModel = {
|
|
|
58
58
|
border: string;
|
|
59
59
|
} | null;
|
|
60
60
|
};
|
|
61
|
-
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare class
|
|
1
|
+
export declare class PostViewerUiManager {
|
|
2
2
|
readonly globalCssVariables: string;
|
|
3
3
|
readonly showAttachments: boolean;
|
|
4
4
|
readonly showControls: boolean;
|
|
@@ -6,8 +6,10 @@ export declare class ShortVideoViewerUiManager {
|
|
|
6
6
|
private canShowControls;
|
|
7
7
|
private canShowAttachments;
|
|
8
8
|
private enableAttachments;
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
private infoPaddingLeft;
|
|
10
|
+
private infoPaddingRight;
|
|
11
|
+
setCanShowAttachments: (value: boolean) => void;
|
|
12
|
+
setCanShowControls: (value: boolean) => void;
|
|
11
13
|
toggleEnableAttachments: () => void;
|
|
12
14
|
setControlsPanelWidth(value: number): void;
|
|
13
15
|
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
const INFO_PADDING_HORIZONTAL = 20;
|
|
2
|
+
export class PostViewerUiManager {
|
|
2
3
|
globalCssVariables = $derived.by(() => {
|
|
3
|
-
const values = [
|
|
4
|
+
const values = [
|
|
5
|
+
`--post-viewer--heading--padding: 0 ${this.infoPaddingRight}px 14px ${this.infoPaddingLeft}px`,
|
|
6
|
+
`--post-viewer--information--text--padding: 0 ${this.infoPaddingRight}px 0 ${this.infoPaddingLeft}px`,
|
|
7
|
+
`--post-viewer--attachments-horizontal--padding-horizontal: ${INFO_PADDING_HORIZONTAL}px`
|
|
8
|
+
];
|
|
4
9
|
return values.join(';');
|
|
5
10
|
});
|
|
6
11
|
showAttachments = $derived.by(() => {
|
|
@@ -16,10 +21,12 @@ export class ShortVideoViewerUiManager {
|
|
|
16
21
|
canShowAttachments = $state(false);
|
|
17
22
|
// managed internally by component
|
|
18
23
|
enableAttachments = $state(true);
|
|
19
|
-
|
|
24
|
+
infoPaddingLeft = $derived(INFO_PADDING_HORIZONTAL);
|
|
25
|
+
infoPaddingRight = $derived(INFO_PADDING_HORIZONTAL + this.controlsPanelWidth ? this.controlsPanelWidth + 10 : 0);
|
|
26
|
+
setCanShowAttachments = (value) => {
|
|
20
27
|
this.canShowAttachments = value;
|
|
21
28
|
};
|
|
22
|
-
|
|
29
|
+
setCanShowControls = (value) => {
|
|
23
30
|
this.canShowControls = value;
|
|
24
31
|
};
|
|
25
32
|
toggleEnableAttachments = () => {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Utils } from '../../core/utils';
|
|
2
|
+
export const getPostCoverImage = (post) => {
|
|
3
|
+
switch (post.media.type) {
|
|
4
|
+
case 'image':
|
|
5
|
+
return post.media.url;
|
|
6
|
+
case 'video':
|
|
7
|
+
return post.media.thumbnailUrl;
|
|
8
|
+
case 'gallery':
|
|
9
|
+
return post.media.items[0].type === 'image' ? post.media.items[0].url : post.media.items[0].thumbnailUrl;
|
|
10
|
+
default:
|
|
11
|
+
Utils.assertUnreachable(post.media);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { IPostSocialInteractionsHandler } from './types';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface IPostSocialInteractionsHandler {
|
|
2
|
+
getIsLiked: (shortVideoId: string) => PromiseLike<{
|
|
3
|
+
readonly isLiked: boolean;
|
|
4
|
+
}>;
|
|
5
|
+
toggleLike: (shortVideoId: string) => PromiseLike<void>;
|
|
6
|
+
share: (shortVideoId: string) => PromiseLike<void>;
|
|
7
|
+
}
|
|
8
|
+
type PromiseLike<T> = T | Promise<T>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -5,12 +5,31 @@ import { ProportionalContainer } from '../../ui/proportional-container';
|
|
|
5
5
|
import { ProductCardLocalization } from './product-card-localization';
|
|
6
6
|
let { product, includeBeforeNowPrefix, inert = false, locale = 'en', on } = $props();
|
|
7
7
|
const localization = $derived(new ProductCardLocalization(locale));
|
|
8
|
-
const
|
|
8
|
+
const shortDescriptionPresented = $derived(product.shortDescription && product.shortDescription.length > 0);
|
|
9
|
+
const trackImpression = (node) => {
|
|
10
|
+
if (on === null || on === void 0 ? void 0 : on.impression) {
|
|
11
|
+
const observer = new IntersectionObserver((entries) => {
|
|
12
|
+
entries.forEach((entry) => {
|
|
13
|
+
var _a;
|
|
14
|
+
if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
|
|
15
|
+
(_a = on.impression) === null || _a === void 0 ? void 0 : _a.call(on, product.id);
|
|
16
|
+
observer.unobserve(entry.target);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}, { threshold: 0.5 });
|
|
20
|
+
observer.observe(node);
|
|
21
|
+
return {
|
|
22
|
+
destroy() {
|
|
23
|
+
observer.disconnect();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
};
|
|
9
28
|
const onProductClicked = (event) => {
|
|
10
29
|
event.preventDefault();
|
|
11
30
|
event.stopPropagation();
|
|
12
|
-
if (on === null || on === void 0 ? void 0 : on.
|
|
13
|
-
on.
|
|
31
|
+
if (on === null || on === void 0 ? void 0 : on.click) {
|
|
32
|
+
on.click(product.id);
|
|
14
33
|
}
|
|
15
34
|
if (!product.link) {
|
|
16
35
|
return;
|
|
@@ -19,7 +38,7 @@ const onProductClicked = (event) => {
|
|
|
19
38
|
};
|
|
20
39
|
</script>
|
|
21
40
|
|
|
22
|
-
<div class="product-card" inert={inert}>
|
|
41
|
+
<div class="product-card" inert={inert} use:trackImpression>
|
|
23
42
|
<ProportionalContainer ratio={1}>
|
|
24
43
|
<Image src={product.image} />
|
|
25
44
|
</ProportionalContainer>
|
|
@@ -28,11 +47,11 @@ const onProductClicked = (event) => {
|
|
|
28
47
|
<LineClamp maxLines={1}>
|
|
29
48
|
<div class="product-card__brand">{product.brandName}</div>
|
|
30
49
|
</LineClamp>
|
|
31
|
-
<LineClamp value={product.shortDescription} maxLines={
|
|
32
|
-
<div class="product-card__title" class:two-lines={!
|
|
50
|
+
<LineClamp value={product.shortDescription} maxLines={shortDescriptionPresented ? 1 : 2}>
|
|
51
|
+
<div class="product-card__title" class:two-lines={!shortDescriptionPresented}>{product.title}</div>
|
|
33
52
|
</LineClamp>
|
|
34
53
|
<LineClamp value={product.shortDescription} maxLines={2}>
|
|
35
|
-
<div class="product-card__description" class:two-lines={
|
|
54
|
+
<div class="product-card__description" class:two-lines={shortDescriptionPresented}>{product.shortDescription}</div>
|
|
36
55
|
</LineClamp>
|
|
37
56
|
<div class="product-price">
|
|
38
57
|
<div class="product-price__before-price">
|
|
@@ -49,7 +68,7 @@ const onProductClicked = (event) => {
|
|
|
49
68
|
</div>
|
|
50
69
|
</div>
|
|
51
70
|
|
|
52
|
-
{#if product.link || on?.
|
|
71
|
+
{#if product.link || on?.click}
|
|
53
72
|
<a href={product.link} onclick={onProductClicked} target="_blank" rel="noopener noreferrer" class="product-card__link" aria-label="none"> </a>
|
|
54
73
|
{/if}
|
|
55
74
|
</div>
|
|
@@ -6,7 +6,8 @@ type Props = {
|
|
|
6
6
|
includeBeforeNowPrefix?: boolean;
|
|
7
7
|
inert?: boolean;
|
|
8
8
|
on?: {
|
|
9
|
-
|
|
9
|
+
click?: (id: string) => void;
|
|
10
|
+
impression?: (id: string) => void;
|
|
10
11
|
};
|
|
11
12
|
};
|
|
12
13
|
declare const Cmp: import("svelte").Component<Props, {}, "">;
|