@streamscloud/embeddable 11.0.0 → 12.1.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.
Files changed (174) hide show
  1. package/dist/ads/ad-card/cmp.ad-card.svelte +4 -4
  2. package/dist/ads/ad-card/cmp.ad-card.svelte.d.ts +2 -0
  3. package/dist/content-player/cmp.content-player.svelte +63 -128
  4. package/dist/content-player/content-player-config.svelte.d.ts +3 -10
  5. package/dist/content-player/content-player-config.svelte.js +3 -21
  6. package/dist/content-player/content-player-settings.d.ts +7 -21
  7. package/dist/content-player/content-player-settings.js +0 -4
  8. package/dist/content-player/controls-and-attachments.svelte +39 -5
  9. package/dist/content-player/overview-panel.svelte +14 -6
  10. package/dist/content-player/overview-panel.svelte.d.ts +5 -1
  11. package/dist/content-player/ui-manager.svelte.d.ts +0 -2
  12. package/dist/content-player/ui-manager.svelte.js +0 -2
  13. package/dist/media-center/config/internal-media-center-config.d.ts +7 -3
  14. package/dist/media-center/config/internal-media-center-config.js +28 -24
  15. package/dist/media-center/config/operations.generated.d.ts +36 -23
  16. package/dist/media-center/config/operations.generated.js +53 -33
  17. package/dist/media-center/config/operations.graphql +34 -21
  18. package/dist/media-center/config/types.d.ts +13 -2
  19. package/dist/media-center/media-center/cmp.media-center.svelte +195 -149
  20. package/dist/media-center/media-center/cmp.media-center.svelte.d.ts +2 -19
  21. package/dist/media-center/media-center/discover/data-loading.d.ts +8 -0
  22. package/dist/media-center/media-center/discover/data-loading.js +35 -0
  23. package/dist/media-center/media-center/discover/discover-header-localization.d.ts +6 -0
  24. package/dist/media-center/media-center/discover/discover-header-localization.js +15 -0
  25. package/dist/media-center/media-center/discover/discover-header.svelte +214 -0
  26. package/dist/media-center/media-center/discover/discover-header.svelte.d.ts +9 -0
  27. package/dist/media-center/media-center/discover/discover-view-handler.svelte.d.ts +28 -0
  28. package/dist/media-center/media-center/discover/discover-view-handler.svelte.js +101 -0
  29. package/dist/media-center/media-center/discover/discover-view-localization.d.ts +6 -0
  30. package/dist/media-center/media-center/discover/discover-view-localization.js +15 -0
  31. package/dist/media-center/media-center/discover/discover-view.svelte +238 -0
  32. package/dist/media-center/media-center/discover/{discover-panel.svelte.d.ts → discover-view.svelte.d.ts} +4 -4
  33. package/dist/media-center/media-center/discover/index.d.ts +2 -2
  34. package/dist/media-center/media-center/discover/index.js +2 -2
  35. package/dist/media-center/media-center/discover/types.svelte.d.ts +20 -0
  36. package/dist/media-center/media-center/discover/types.svelte.js +20 -0
  37. package/dist/media-center/media-center/feed/feed-handler.svelte.d.ts +50 -0
  38. package/dist/media-center/media-center/feed/feed-handler.svelte.js +84 -0
  39. package/dist/media-center/media-center/feed/feed-providers-generator.d.ts +11 -0
  40. package/dist/media-center/media-center/feed/feed-providers-generator.js +79 -0
  41. package/dist/media-center/media-center/feed/index.d.ts +1 -0
  42. package/dist/media-center/media-center/feed/index.js +1 -0
  43. package/dist/media-center/media-center/feed/types.d.ts +12 -0
  44. package/dist/media-center/media-center/handlers/categories-handler.svelte.d.ts +29 -10
  45. package/dist/media-center/media-center/handlers/categories-handler.svelte.js +25 -7
  46. package/dist/media-center/media-center/handlers/index.d.ts +2 -1
  47. package/dist/media-center/media-center/handlers/index.js +1 -1
  48. package/dist/media-center/media-center/handlers/media-center-settings-handler.svelte.d.ts +19 -0
  49. package/dist/media-center/media-center/handlers/media-center-settings-handler.svelte.js +26 -0
  50. package/dist/media-center/media-center/header-footer/media-center-footer.svelte +4 -8
  51. package/dist/media-center/media-center/header-footer/media-center-header-localization.d.ts +1 -0
  52. package/dist/media-center/media-center/header-footer/media-center-header-localization.js +6 -0
  53. package/dist/media-center/media-center/header-footer/media-center-header-mobile.svelte +25 -36
  54. package/dist/media-center/media-center/header-footer/media-center-header-mobile.svelte.d.ts +2 -1
  55. package/dist/media-center/media-center/header-footer/media-center-header.svelte +14 -11
  56. package/dist/media-center/media-center/header-footer/media-center-header.svelte.d.ts +1 -2
  57. package/dist/media-center/media-center/media-center-context.svelte.d.ts +31 -13
  58. package/dist/media-center/media-center/media-center-context.svelte.js +71 -35
  59. package/dist/media-center/media-center/menu/menu-localization.d.ts +2 -11
  60. package/dist/media-center/media-center/menu/menu-localization.js +6 -45
  61. package/dist/media-center/media-center/menu/menu.svelte +94 -93
  62. package/dist/media-center/media-center/menu/menu.svelte.d.ts +1 -1
  63. package/dist/media-center/media-center/menu/popular-streams-panel-handler.svelte.d.ts +1 -1
  64. package/dist/media-center/media-center/menu/popular-streams-panel-handler.svelte.js +0 -3
  65. package/dist/media-center/media-center/moments/cmp.moments-circle.svelte +41 -0
  66. package/dist/media-center/media-center/moments/cmp.moments-circle.svelte.d.ts +7 -0
  67. package/dist/media-center/media-center/moments/index.d.ts +1 -0
  68. package/dist/media-center/media-center/moments/index.js +1 -0
  69. package/dist/media-center/media-center/streams-in-category/streams-in-category-panel-handler.svelte.d.ts +1 -1
  70. package/dist/media-center/media-center/streams-in-category/streams-in-category-panel-handler.svelte.js +1 -1
  71. package/dist/media-center/media-center/types.d.ts +44 -1
  72. package/dist/media-page/index.d.ts +121 -0
  73. package/dist/media-page/index.js +43 -0
  74. package/dist/posts/attachments/cmp.attachments.svelte +1 -0
  75. package/dist/posts/controls/cmp.controls.svelte +50 -13
  76. package/dist/posts/data-loaders/operations.generated.d.ts +4 -0
  77. package/dist/posts/data-loaders/operations.generated.js +6 -2
  78. package/dist/posts/model/types.d.ts +2 -0
  79. package/dist/posts/post-viewer/cmp.post-viewer.svelte +26 -18
  80. package/dist/posts/post-viewer/mapper.js +2 -0
  81. package/dist/posts/post-viewer/operations.generated.d.ts +2 -0
  82. package/dist/posts/post-viewer/operations.generated.js +3 -1
  83. package/dist/posts/post-viewer/operations.graphql +2 -0
  84. package/dist/posts/post-viewer/post-texts.svelte +3 -3
  85. package/dist/posts/posts-player/cmp.posts-player.svelte +20 -6
  86. package/dist/posts/posts-player/cmp.posts-player.svelte.d.ts +18 -2
  87. package/dist/posts/posts-player/index.d.ts +18 -3
  88. package/dist/posts/posts-player/index.js +42 -89
  89. package/dist/posts/posts-player/posts-player-proxy.svelte +19 -0
  90. package/dist/posts/posts-player/posts-player-proxy.svelte.d.ts +22 -0
  91. package/dist/posts/posts-player/posts-player-view.svelte +20 -34
  92. package/dist/posts/posts-player/posts-player-view.svelte.d.ts +2 -6
  93. package/dist/posts/posts-player/types.d.ts +19 -6
  94. package/dist/products/product-card/cmp.product-card.svelte +5 -5
  95. package/dist/products/product-card/cmp.product-card.svelte.d.ts +1 -1
  96. package/dist/short-videos/short-video-card/cmp.short-video-card.svelte +160 -19
  97. package/dist/short-videos/short-video-card/cmp.short-video-card.svelte.d.ts +2 -1
  98. package/dist/short-videos/short-video-card/localization.d.ts +5 -0
  99. package/dist/short-videos/short-video-card/localization.js +13 -0
  100. package/dist/short-videos/short-video-card/types.d.ts +4 -0
  101. package/dist/short-videos/short-videos-player/index.js +26 -33
  102. package/dist/streams/layout/element-views/cmp.stream-element.svelte +2 -2
  103. package/dist/streams/layout/element-views/cmp.text-ref-stream-element.svelte +7 -3
  104. package/dist/streams/layout/element-views/cmp.text-ref-stream-element.svelte.d.ts +2 -0
  105. package/dist/streams/layout/element-views/cmp.text-stream-element.svelte +7 -3
  106. package/dist/streams/layout/element-views/cmp.text-stream-element.svelte.d.ts +2 -0
  107. package/dist/streams/layout/element-views/price-element-view.svelte +2 -2
  108. package/dist/streams/layout/element-views/price-stream-element-localization.d.ts +1 -1
  109. package/dist/streams/layout/element-views/price-stream-element-localization.js +2 -2
  110. package/dist/streams/layout/models/mapper.js +2 -0
  111. package/dist/streams/streams-player/index.d.ts +21 -2
  112. package/dist/streams/streams-player/index.js +49 -24
  113. package/dist/streams/streams-player/stream-overview.svelte +1 -1
  114. package/dist/streams/streams-player/streams-player-buffer.svelte.d.ts +1 -3
  115. package/dist/streams/streams-player/streams-player-buffer.svelte.js +2 -2
  116. package/dist/streams/streams-player/streams-player-view.svelte +25 -21
  117. package/dist/streams/streams-player/streams-player-view.svelte.d.ts +1 -5
  118. package/dist/streams/streams-player/types.d.ts +18 -4
  119. package/dist/ui/line-clamp/cmp.line-clamp-auto.svelte +119 -0
  120. package/dist/ui/line-clamp/cmp.line-clamp-auto.svelte.d.ts +10 -0
  121. package/dist/ui/line-clamp/cmp.line-clamp.svelte +44 -72
  122. package/dist/ui/line-clamp/cmp.line-clamp.svelte.d.ts +3 -4
  123. package/dist/ui/line-clamp/index.d.ts +1 -0
  124. package/dist/ui/line-clamp/index.js +1 -0
  125. package/dist/ui/player/button/cmp.mobile-player-buttons-group.svelte +44 -0
  126. package/dist/ui/player/button/cmp.mobile-player-buttons-group.svelte.d.ts +7 -0
  127. package/dist/ui/player/button/cmp.player-button.svelte +0 -1
  128. package/dist/ui/player/button/cmp.player-buttons-group.svelte +15 -11
  129. package/dist/ui/player/button/cmp.player-buttons-group.svelte.d.ts +1 -1
  130. package/dist/ui/player/button/index.d.ts +1 -0
  131. package/dist/ui/player/button/index.js +1 -0
  132. package/dist/ui/player/button/types.d.ts +0 -2
  133. package/dist/ui/player/close-orchestrator/close-orchestrator.svelte.d.ts +18 -0
  134. package/dist/ui/player/close-orchestrator/close-orchestrator.svelte.js +58 -0
  135. package/dist/ui/player/close-orchestrator/index.d.ts +2 -0
  136. package/dist/ui/player/close-orchestrator/index.js +1 -0
  137. package/dist/ui/player/close-orchestrator/types.d.ts +9 -0
  138. package/dist/ui/player/close-orchestrator/types.js +1 -0
  139. package/dist/ui/player/colors/index.d.ts +1 -0
  140. package/dist/ui/player/colors/index.js +1 -0
  141. package/dist/ui/player/colors/player-colors.d.ts +11 -0
  142. package/dist/ui/player/colors/player-colors.js +1 -0
  143. package/dist/ui/player/providers/chunks-player-buffer/player-chunks-manager.svelte.d.ts +2 -6
  144. package/dist/ui/player/providers/chunks-player-buffer/player-chunks-manager.svelte.js +11 -11
  145. package/dist/ui/player/providers/default-chunks-player-buffer.svelte.d.ts +2 -3
  146. package/dist/ui/player/providers/default-chunks-player-buffer.svelte.js +5 -5
  147. package/dist/ui/player/providers/default-feed-player-buffer.svelte.d.ts +3 -4
  148. package/dist/ui/player/providers/default-feed-player-buffer.svelte.js +16 -9
  149. package/dist/ui/player/providers/service.d.ts +2 -0
  150. package/dist/ui/player/providers/service.js +13 -0
  151. package/dist/ui/player/providers/types.d.ts +1 -0
  152. package/dist/ui/with-background/cmp.with-background.svelte +86 -0
  153. package/dist/ui/with-background/cmp.with-background.svelte.d.ts +10 -0
  154. package/dist/ui/with-background/index.d.ts +1 -0
  155. package/dist/ui/with-background/index.js +1 -0
  156. package/package.json +5 -1
  157. package/dist/content-player/fade-mixins.scss +0 -12
  158. package/dist/content-player/header.svelte +0 -15
  159. package/dist/content-player/header.svelte.d.ts +0 -28
  160. package/dist/media-center/media-center/discover/discover-panel-handler.svelte.d.ts +0 -31
  161. package/dist/media-center/media-center/discover/discover-panel-handler.svelte.js +0 -94
  162. package/dist/media-center/media-center/discover/discover-panel-localization.d.ts +0 -19
  163. package/dist/media-center/media-center/discover/discover-panel-localization.js +0 -78
  164. package/dist/media-center/media-center/discover/discover-panel.svelte +0 -142
  165. package/dist/media-center/media-center/handlers/feed-handler.svelte.d.ts +0 -6
  166. package/dist/media-center/media-center/handlers/feed-handler.svelte.js +0 -12
  167. package/dist/media-center/media-center/providers/index.d.ts +0 -2
  168. package/dist/media-center/media-center/providers/index.js +0 -2
  169. package/dist/media-center/media-center/providers/post-player-provider-generator.d.ts +0 -8
  170. package/dist/media-center/media-center/providers/post-player-provider-generator.js +0 -32
  171. package/dist/media-center/media-center/providers/streams-player-provider-generator.d.ts +0 -8
  172. package/dist/media-center/media-center/providers/streams-player-provider-generator.js +0 -36
  173. package/dist/media-center/model/types.d.ts +0 -17
  174. /package/dist/media-center/{model → media-center/feed}/types.js +0 -0
@@ -1,7 +1,9 @@
1
- import type { IContentPlayerSettingsInitializer } from '../../content-player/content-player-settings';
1
+ import type { Locale } from '../../core/locale';
2
2
  import type { IPostModel } from '..';
3
3
  import type { IPostSocialInteractionsHandler } from '../social-interactions';
4
- import type { IPlayerDataProvider } from '../../ui/player/providers';
4
+ import type { ICloseOrchestrator } from '../../ui/player/close-orchestrator';
5
+ import type { PlayerColors } from '../../ui/player/colors';
6
+ import type { IPlayerBuffer, IPlayerDataProvider } from '../../ui/player/providers';
5
7
  export interface IPostAnalyticsHandler {
6
8
  setOrganizationId: (organizationId: string) => void;
7
9
  trackPostOpened: (postId: string, ownerId: string) => void;
@@ -14,14 +16,25 @@ export interface IPostAnalyticsHandler {
14
16
  export type PostPlayerModel = IPostModel & {
15
17
  analyticsOrganizationId: string | null;
16
18
  };
17
- export type PostPlayerProps = {
18
- dataProvider: IPlayerDataProvider<PostPlayerModel>;
19
+ export type PostsPlayerProps = {
20
+ dataProvider: {
21
+ type: 'buffer';
22
+ buffer: IPlayerBuffer<PostPlayerModel>;
23
+ } | {
24
+ type: 'provider';
25
+ provider: IPlayerDataProvider<PostPlayerModel>;
26
+ };
19
27
  socialInteractionsHandler?: IPostSocialInteractionsHandler;
20
28
  analyticsHandler?: IPostAnalyticsHandler;
21
29
  playerSettings?: PostPlayerSettings;
30
+ closeOrchestrator: ICloseOrchestrator;
22
31
  on?: {
23
- playerClosed?: () => void;
24
32
  postActivated?: (id: string) => void;
33
+ backgroundImageLoaded?: (imageUrl: string | null) => void;
25
34
  };
26
35
  };
27
- export type PostPlayerSettings = IContentPlayerSettingsInitializer;
36
+ export type PostPlayerSettings = {
37
+ locale?: Locale;
38
+ showStreamsCloudWatermark?: boolean;
39
+ playerColors?: PlayerColors;
40
+ };
@@ -4,7 +4,7 @@ import { Image } from '../../ui/image';
4
4
  import { LineClamp } from '../../ui/line-clamp';
5
5
  import { ProportionalContainer } from '../../ui/proportional-container';
6
6
  import { ProductCardLocalization } from './product-card-localization';
7
- let { product, colors, includeBeforeNowPrefix, trackingParams, inert = false, locale = 'en', on } = $props();
7
+ let { product, colors, includeBeforeNowPrefix, trackingParams, inert = false, locale, on } = $props();
8
8
  const localization = $derived(new ProductCardLocalization(locale));
9
9
  const shortDescriptionPresented = $derived(product.shortDescription && product.shortDescription.length > 0);
10
10
  const trackImpression = (node) => {
@@ -58,13 +58,13 @@ const styles = $derived.by(() => {
58
58
  </ProportionalContainer>
59
59
 
60
60
  <div class="product-card__info">
61
- <LineClamp maxLines={1}>
61
+ <LineClamp maxLines={1} locale={locale}>
62
62
  <div class="product-card__brand">{product.brandName}</div>
63
63
  </LineClamp>
64
- <LineClamp value={product.shortDescription} maxLines={shortDescriptionPresented ? 1 : 2}>
64
+ <LineClamp maxLines={shortDescriptionPresented ? 1 : 2} locale={locale}>
65
65
  <div class="product-card__title" class:two-lines={!shortDescriptionPresented}>{product.title}</div>
66
66
  </LineClamp>
67
- <LineClamp value={product.shortDescription} maxLines={2}>
67
+ <LineClamp maxLines={2} locale={locale}>
68
68
  <div class="product-card__description" class:two-lines={shortDescriptionPresented}>{product.shortDescription}</div>
69
69
  </LineClamp>
70
70
  <div class="product-price">
@@ -110,7 +110,7 @@ const styles = $derived.by(() => {
110
110
  --product-price-color: var(--_product-card--price-color);
111
111
  --product-price--sale--color: var(--_product-card--sale-price-color);
112
112
  --image--border-radius: 0.25rem;
113
- --image--object-fit: contain;
113
+ --image--object-fit: cover;
114
114
  --image--width: auto;
115
115
  --image--height: auto;
116
116
  width: 100%;
@@ -8,7 +8,7 @@ type Props = {
8
8
  price?: string | null;
9
9
  salePrice?: string | null;
10
10
  };
11
- locale?: Locale;
11
+ locale: Locale;
12
12
  includeBeforeNowPrefix?: boolean;
13
13
  inert?: boolean;
14
14
  trackingParams: TrackingParams;
@@ -1,27 +1,112 @@
1
- <script lang="ts">import { Icon } from '../../ui/icon';
1
+ <script lang="ts">import { toPriceRepresentation } from '../../products/price-helper';
2
+ import { Icon } from '../../ui/icon';
2
3
  import { ImageRounded } from '../../ui/image';
3
4
  import { LineClamp } from '../../ui/line-clamp';
4
5
  import { ProportionalContainer } from '../../ui/proportional-container';
6
+ import { TimeAgo } from '../../ui/time-ago';
7
+ import { ShortVideoCardLocalization } from './localization';
5
8
  import IconPhone from '@fluentui/svg-icons/icons/phone_20_regular.svg?raw';
6
- let { shortVideo, aspectRatio = 9 / 16, on } = $props();
9
+ import IconShoppingBag from '@fluentui/svg-icons/icons/shopping_bag_20_regular.svg?raw';
10
+ const ADJUST_TEXT_SIZE = false;
11
+ let { shortVideo, locale, on } = $props();
12
+ const localization = new ShortVideoCardLocalization(locale);
13
+ const adjustTextSize = (node) => {
14
+ if (!ADJUST_TEXT_SIZE) {
15
+ return;
16
+ }
17
+ const isOverflown = ({ clientHeight, scrollHeight }) => scrollHeight > clientHeight;
18
+ const resizeObserver = new ResizeObserver(() => {
19
+ node.style.fontSize = '';
20
+ const { fontSize } = window.getComputedStyle(node);
21
+ const originalFontSize = parseFloat(fontSize);
22
+ const maxSize = originalFontSize * 2;
23
+ let i = originalFontSize;
24
+ let overflow = false;
25
+ while (!overflow && i < maxSize) {
26
+ node.style.fontSize = `${i}px`;
27
+ overflow = isOverflown(node);
28
+ if (!overflow) {
29
+ i += 1;
30
+ }
31
+ }
32
+ node.style.fontSize = `${i - 1}px`;
33
+ });
34
+ resizeObserver.observe(node);
35
+ return {
36
+ destroy() {
37
+ resizeObserver.disconnect();
38
+ }
39
+ };
40
+ };
7
41
  </script>
8
42
 
9
43
  <div class="short-video-card">
10
44
  <div class="short-video-card__media">
11
- <ProportionalContainer ratio={aspectRatio}>
45
+ <ProportionalContainer ratio={2 / 3}>
12
46
  <ImageRounded src={shortVideo.cover} alt="" noBorders={true} />
13
47
  </ProportionalContainer>
14
48
 
15
49
  <div class="short-video-card__media-icons">
16
- <Icon src={IconPhone}></Icon>
50
+ <Icon src={shortVideo.products.length ? IconShoppingBag : IconPhone}></Icon>
17
51
  </div>
18
52
  </div>
19
53
 
20
- {#if shortVideo.text}
21
- <div class="short-video-card__text">
22
- <LineClamp value={shortVideo.text} maxLines={2} enableShowMore={false} />
54
+ <div class="short-video-card__info">
55
+ <div class="short-video-card__meta">
56
+ <span><TimeAgo date={shortVideo.displayDate} locale={locale} /></span>
57
+ {#if shortVideo.viewsCount}
58
+ <span>&middot;</span>
59
+ <span>{localization.viewsLabel(shortVideo.viewsCount)}</span>
60
+ {/if}
23
61
  </div>
24
- {/if}
62
+
63
+ <div class="short-video-card__text" use:adjustTextSize>
64
+ {#if shortVideo.text}
65
+ {shortVideo.text}
66
+ {/if}
67
+ </div>
68
+
69
+ <div class="short-video-card__products">
70
+ {#snippet productView(product: IPostProductCardModel)}
71
+ <div class="product-card">
72
+ <ProportionalContainer ratio={4 / 5}>
73
+ <ImageRounded src={product.image} alt={product.title} noBorders={true} />
74
+ </ProportionalContainer>
75
+
76
+ <div class="product-card__info">
77
+ <div class="product-card__title">
78
+ <LineClamp maxLines={1} enableShowMore={false} locale={locale}>{product.title}</LineClamp>
79
+ </div>
80
+ <div class="product-card__price">
81
+ <LineClamp maxLines={1} locale={locale}>
82
+ <span>
83
+ {toPriceRepresentation({
84
+ amount: product.salePrice || product.price,
85
+ currency: product.currency,
86
+ options: { currencyMode: 'none' }
87
+ })}
88
+ </span>
89
+ {#if product.salePrice}
90
+ &nbsp;
91
+ <span
92
+ >{toPriceRepresentation({
93
+ amount: product.price,
94
+ currency: product.currency,
95
+ options: { currencyMode: 'none' }
96
+ })}
97
+ </span>
98
+ {/if}
99
+ </LineClamp>
100
+ </div>
101
+ </div>
102
+ </div>
103
+ {/snippet}
104
+
105
+ {#each shortVideo.products as product (product.id)}
106
+ {@render productView(product)}
107
+ {/each}
108
+ </div>
109
+ </div>
25
110
 
26
111
  {#if on?.click}
27
112
  <button type="button" onclick={on.click} class="short-video-card__link" aria-label="none">&nbsp;</button>
@@ -44,13 +129,12 @@ let { shortVideo, aspectRatio = 9 / 16, on } = $props();
44
129
  overflow: hidden;
45
130
  container-type: inline-size;
46
131
  width: 100%;
47
- border-radius: 0.375rem;
48
132
  }
49
133
  .short-video-card__media {
50
134
  display: flex;
51
135
  align-items: center;
52
136
  justify-content: center;
53
- --image--rounded--outer--border-radius: 1%;
137
+ --image--rounded--outer--border-radius: 0.5rem;
54
138
  }
55
139
  .short-video-card__media-icons {
56
140
  position: absolute;
@@ -63,17 +147,45 @@ let { shortVideo, aspectRatio = 9 / 16, on } = $props();
63
147
  --icon--color: #ffffff;
64
148
  --icon--filter: drop-shadow(1px 1px 0 rgba(0, 0, 0, 0.2));
65
149
  }
150
+ .short-video-card__info {
151
+ margin-top: clamp(0.4375rem, 3.6cqi, 0.625rem);
152
+ display: flex;
153
+ flex-direction: column;
154
+ gap: clamp(0.4375rem, 3.6cqi, 0.625rem);
155
+ }
156
+ .short-video-card__meta {
157
+ font-size: clamp(0.625rem, 4.3cqi, 0.75rem);
158
+ font-weight: 500;
159
+ color: #999999;
160
+ display: flex;
161
+ align-items: center;
162
+ gap: 0.25rem;
163
+ }
66
164
  .short-video-card__text {
67
- position: absolute;
68
- bottom: 0;
69
- left: 0;
70
- right: 0;
71
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.9) 30%, rgba(0, 0, 0, 0.01) 100%);
72
165
  color: #ffffff;
73
- font-size: 0.75rem;
74
- font-weight: 400;
75
- padding: 0.75rem 0.75rem;
76
- padding-top: 2.5rem;
166
+ --min-font: 0.75rem;
167
+ --max-font: 0.9375rem;
168
+ --line-height: 1.2;
169
+ font-size: clamp(var(--min-font), 5.4cqi, var(--max-font));
170
+ line-height: var(--line-height);
171
+ font-weight: 500;
172
+ height: clamp(var(--min-font) * var(--line-height) * 2 - 1px, 5.4cqi * var(--line-height) * 2 - 1px, var(--max-font) * var(--line-height) * 2 - 1px);
173
+ white-space: pre-line;
174
+ word-break: break-word;
175
+ display: -webkit-box;
176
+ overflow: hidden;
177
+ -webkit-box-orient: vertical;
178
+ line-clamp: 2;
179
+ -webkit-line-clamp: 2;
180
+ text-overflow: ellipsis;
181
+ }
182
+ .short-video-card__products {
183
+ display: grid;
184
+ grid-template-columns: repeat(3, minmax(0, 1fr));
185
+ gap: clamp(0.625rem, 5cqi, 0.875rem);
186
+ }
187
+ .short-video-card__products > :nth-child(n+4) {
188
+ display: none;
77
189
  }
78
190
  .short-video-card__link {
79
191
  position: absolute;
@@ -81,4 +193,33 @@ let { shortVideo, aspectRatio = 9 / 16, on } = $props();
81
193
  left: 0;
82
194
  width: 100%;
83
195
  height: 100%;
196
+ }
197
+
198
+ .product-card {
199
+ --image--rounded--outer--border-radius: 0.375rem;
200
+ container-type: inline-size;
201
+ }
202
+ .product-card__info {
203
+ display: flex;
204
+ flex-direction: column;
205
+ color: #ffffff;
206
+ font-size: clamp(0.5rem, 2.9cqi, 0.5rem);
207
+ line-height: clamp(0.75rem, 4.3cqi, 0.75rem);
208
+ font-weight: 500;
209
+ /* Set 'container-type: inline-size;' to reference container*/
210
+ }
211
+ @container (width < 60px) {
212
+ .product-card__info {
213
+ display: none;
214
+ }
215
+ }
216
+ .product-card__title {
217
+ font-weight: 500;
218
+ }
219
+ .product-card__price {
220
+ font-weight: 600;
221
+ }
222
+ .product-card__price span:nth-child(2) {
223
+ color: #999999;
224
+ text-decoration: line-through;
84
225
  }</style>
@@ -1,7 +1,8 @@
1
+ import type { Locale } from '../../core/locale';
1
2
  import type { ShortVideoCardModel } from './types';
2
3
  type Props = {
3
4
  shortVideo: ShortVideoCardModel;
4
- aspectRatio?: number;
5
+ locale: Locale;
5
6
  on?: {
6
7
  click?: () => void;
7
8
  };
@@ -0,0 +1,5 @@
1
+ import { type Locale } from '../../core/locale';
2
+ export declare class ShortVideoCardLocalization {
3
+ viewsLabel: (count: number) => string;
4
+ constructor(locale: Locale);
5
+ }
@@ -0,0 +1,13 @@
1
+ import {} from '../../core/locale';
2
+ export class ShortVideoCardLocalization {
3
+ viewsLabel;
4
+ constructor(locale) {
5
+ this.viewsLabel = loc.viewsLabel[locale];
6
+ }
7
+ }
8
+ const loc = {
9
+ viewsLabel: {
10
+ en: (count) => `${count} view${count !== 1 ? 's' : ''}`,
11
+ no: (count) => `${count} visning${count !== 1 ? 'er' : ''}`
12
+ }
13
+ };
@@ -1,5 +1,9 @@
1
+ import type { IPostProductCardModel } from '../../posts/model';
1
2
  export type ShortVideoCardModel = {
2
3
  id: string;
3
4
  text: string | null;
4
5
  cover: string;
6
+ displayDate: string;
7
+ viewsCount: number;
8
+ products: IPostProductCardModel[];
5
9
  };
@@ -1,10 +1,8 @@
1
1
  import { InternalMediaCenterConfig } from '../../media-center/config/internal-media-center-config';
2
2
  import {} from '../../media-center/config/types';
3
- import { MediaCenter } from '../../media-center/media-center';
4
3
  import { InternalPostAnalyticsHandler } from '../../posts/handlers';
4
+ import { openPostsPlayer } from '../../posts/posts-player';
5
5
  import { InternalShortVideoPlayerItemsProvider } from '../data-providers';
6
- import { ModalShadowHost } from '../../ui/shadow-dom';
7
- import { mount, unmount } from 'svelte';
8
6
  /**
9
7
  * Opens the short videos player modal.
10
8
  *
@@ -71,35 +69,30 @@ import { mount, unmount } from 'svelte';
71
69
  export async function openShortVideosPlayer(init) {
72
70
  const { ids, graphqlOrigin, initialId, initiator, playerSettings, on } = init;
73
71
  const dataProvider = new InternalShortVideoPlayerItemsProvider({ ids, graphqlOrigin, initialId, initiator });
74
- const mediaCenterConfig = init.mediaPageId ? new InternalMediaCenterConfig(init.mediaPageId, graphqlOrigin) : undefined;
72
+ const mediaCenterConfig = init.mediaPageId ? new InternalMediaCenterConfig({ mediaPageId: init.mediaPageId, graphqlOrigin, initiator }) : undefined;
75
73
  const analyticsHandler = new InternalPostAnalyticsHandler(graphqlOrigin);
76
- const shadowHost = new ModalShadowHost();
77
- const mounted = mount(MediaCenter, {
78
- target: shadowHost.shadowRoot,
79
- props: {
80
- config: mediaCenterConfig || null,
81
- playerProps: {
82
- mode: 'posts',
83
- props: {
84
- dataProvider,
85
- analyticsHandler,
86
- playerSettings: {
87
- hideCloseButton: playerSettings?.hideCloseButton,
88
- locale: playerSettings?.locale,
89
- showStreamsCloudWatermark: true
90
- },
91
- on: {
92
- playerClosed: async () => {
93
- await unmount(mounted);
94
- shadowHost.remove();
95
- if (on?.playerClosed) {
96
- on.playerClosed();
97
- }
98
- }
99
- }
100
- }
101
- }
102
- }
103
- });
104
- shadowHost.attachToBody();
74
+ if (mediaCenterConfig) {
75
+ openPostsPlayer({
76
+ postsProvider: dataProvider,
77
+ mediaCenterConfig,
78
+ playerSettings: {
79
+ hideCloseButton: playerSettings?.hideCloseButton,
80
+ locale: playerSettings?.locale,
81
+ showStreamsCloudWatermark: true
82
+ },
83
+ on
84
+ });
85
+ }
86
+ else {
87
+ openPostsPlayer({
88
+ postsProvider: dataProvider,
89
+ analyticsHandler,
90
+ playerSettings: {
91
+ hideCloseButton: playerSettings?.hideCloseButton,
92
+ locale: playerSettings?.locale,
93
+ showStreamsCloudWatermark: true
94
+ },
95
+ on
96
+ });
97
+ }
105
98
  }
@@ -70,9 +70,9 @@ const productModel = $derived.by(() => {
70
70
  {:else if model.type === StreamElementType.Stock}
71
71
  <StockStreamElementView model={model} locale={locale} />
72
72
  {:else if model.type === StreamElementType.Text}
73
- <TextStreamElementView model={model} />
73
+ <TextStreamElementView model={model} locale={locale} />
74
74
  {:else if model.type === StreamElementType.TextRef && data}
75
- <TextRefStreamElementView model={model} data={data} />
75
+ <TextRefStreamElementView model={model} data={data} locale={locale} />
76
76
  {:else if model.type === StreamElementType.WebView}
77
77
  <WebViewStreamElementView model={model} />
78
78
  {/if}
@@ -1,7 +1,7 @@
1
- <script lang="ts">import { LineClamp } from '../../../ui/line-clamp';
1
+ <script lang="ts">import { LineClamp, LineClampAuto } from '../../../ui/line-clamp';
2
2
  import { getStringValueByKey } from './data-by-key-accessor';
3
3
  import { generateTextStyles } from '../styles-transformer';
4
- let { model, data } = $props();
4
+ let { model, data, locale } = $props();
5
5
  const value = $derived.by(() => {
6
6
  const values = [];
7
7
  const value = getStringValueByKey(data, model.key);
@@ -19,5 +19,9 @@ const value = $derived.by(() => {
19
19
  </script>
20
20
 
21
21
  <div class="text-ref-stream-element" style={generateTextStyles(model.styles)}>
22
- <LineClamp value={value} maxLines={model.styles?.maxLines || 'auto'} />
22
+ {#if model.styles?.maxLines}
23
+ <LineClamp maxLines={model.styles?.maxLines} locale={locale}>{value}</LineClamp>
24
+ {:else}
25
+ <LineClampAuto locale={locale}>{value}</LineClampAuto>
26
+ {/if}
23
27
  </div>
@@ -1,8 +1,10 @@
1
+ import type { Locale } from '../../../core/locale';
1
2
  import type { TextRefStreamElementModel } from '../elements';
2
3
  import type { StreamSlotDataRef } from '../slot-data-ref';
3
4
  type Props = {
4
5
  model: TextRefStreamElementModel;
5
6
  data: StreamSlotDataRef;
7
+ locale: Locale;
6
8
  };
7
9
  declare const Cmp: import("svelte").Component<Props, {}, "">;
8
10
  type Cmp = ReturnType<typeof Cmp>;
@@ -1,11 +1,15 @@
1
- <script lang="ts">import { LineClamp } from '../../../ui/line-clamp';
1
+ <script lang="ts">import { LineClamp, LineClampAuto } from '../../../ui/line-clamp';
2
2
  import { generateTextStyles } from '../styles-transformer';
3
- let { model, placeholder } = $props();
3
+ let { model, locale, placeholder } = $props();
4
4
  </script>
5
5
 
6
6
  <div class="text-stream-element" style={generateTextStyles(model.styles)}>
7
7
  {#if model.value}
8
- <LineClamp value={model.value} maxLines={model.styles?.maxLines || 'auto'} />
8
+ {#if model.styles?.maxLines}
9
+ <LineClamp maxLines={model.styles?.maxLines} locale={locale}>{model.value}</LineClamp>
10
+ {:else}
11
+ <LineClampAuto locale={locale}>{model.value}</LineClampAuto>
12
+ {/if}
9
13
  {:else if placeholder}
10
14
  {@render placeholder()}
11
15
  {/if}
@@ -1,8 +1,10 @@
1
+ import type { Locale } from '../../../core/locale';
1
2
  import type { TextStreamElementModel } from '../elements';
2
3
  import type { Snippet } from 'svelte';
3
4
  type Props = {
4
5
  model: TextStreamElementModel;
5
6
  placeholder?: Snippet;
7
+ locale: Locale;
6
8
  };
7
9
  declare const Cmp: import("svelte").Component<Props, {}, "">;
8
10
  type Cmp = ReturnType<typeof Cmp>;
@@ -138,12 +138,12 @@ $effect(() => {
138
138
  {/if}
139
139
  {#if model.textAfter}
140
140
  <div class="price-stream-element__text-after" style={textAfterCustomStyles}>
141
- <LineClamp value={model.textAfter} maxLines={1} />
141
+ <LineClamp maxLines={1} locale={localization.locale}>{model.textAfter}</LineClamp>
142
142
  </div>
143
143
  {/if}
144
144
  </div>
145
145
  {#if model.stock}
146
- <StockElementView model={model.stock} heightOverrideDdu={stockElementHeight} locale={localization.stockLocalization} />
146
+ <StockElementView model={model.stock} heightOverrideDdu={stockElementHeight} locale={localization.locale} />
147
147
  {/if}
148
148
  </div>
149
149
 
@@ -2,6 +2,6 @@ import { type Locale } from '../../../core/locale';
2
2
  export declare class PriceStreamElementLocalization {
3
3
  saveValue: (value: string | number) => string;
4
4
  beforeValue: (value: string) => string;
5
- stockLocalization: Locale;
5
+ locale: Locale;
6
6
  constructor(locale: Locale);
7
7
  }
@@ -2,11 +2,11 @@ import {} from '../../../core/locale';
2
2
  export class PriceStreamElementLocalization {
3
3
  saveValue;
4
4
  beforeValue;
5
- stockLocalization;
5
+ locale;
6
6
  constructor(locale) {
7
7
  this.saveValue = loc.saveValue[locale];
8
8
  this.beforeValue = loc.beforeValue[locale];
9
- this.stockLocalization = locale;
9
+ this.locale = locale;
10
10
  }
11
11
  }
12
12
  const loc = {
@@ -13,6 +13,8 @@ export const mapToPostModel = (model) => {
13
13
  kicker: null,
14
14
  title: null,
15
15
  text: model.text,
16
+ viewsCount: model.header?.postViewsCount ?? 0,
17
+ displayDate: model.header?.postDisplayDate ?? '',
16
18
  heading: model.header && {
17
19
  image: model.header.sourceImage,
18
20
  name: model.header.sourceName,
@@ -1,7 +1,8 @@
1
+ import type { Locale } from '../../core/locale';
1
2
  import { type IMediaCenterConfig } from '../../media-center/config/types';
2
3
  import type { IPostSocialInteractionsHandler } from '../../posts/social-interactions';
3
4
  import type { StreamPageViewerModel } from '../stream-page-viewer/types';
4
- import type { IStreamAnalyticsHandler, IStreamsPlayerDataProvider, StreamAmplificationParameters, StreamPlayerModel, StreamsPlayerSettings } from './types';
5
+ import type { IStreamAnalyticsHandler, IStreamsPlayerDataProvider, StreamAmplificationParameters, StreamPlayerModel } from './types';
5
6
  export { type StreamPlayerModel, type StreamPageViewerModel };
6
7
  export { mapToStreamPlayerModel } from '../data-loaders/mapper';
7
8
  export type { IStreamsPlayerDataProvider, IStreamAnalyticsHandler, IMediaCenterConfig };
@@ -110,7 +111,19 @@ export type { IStreamsPlayerDataProvider, IStreamAnalyticsHandler, IMediaCenterC
110
111
  */
111
112
  export declare function openStreamsPlayer(init: {
112
113
  dataProvider: IStreamsPlayerDataProvider;
113
- mediaCenterConfig?: IMediaCenterConfig;
114
+ mediaCenterConfig: IMediaCenterConfig;
115
+ amplificationParameters?: StreamAmplificationParameters;
116
+ playerSettings?: StreamsPlayerSettings;
117
+ on?: {
118
+ streamActivated?: (data: {
119
+ title: string;
120
+ image: string | null;
121
+ }) => void;
122
+ playerClosed?: () => void;
123
+ };
124
+ }): void;
125
+ export declare function openStreamsPlayer(init: {
126
+ dataProvider: IStreamsPlayerDataProvider;
114
127
  postSocialInteractionsHandler?: IPostSocialInteractionsHandler;
115
128
  analyticsHandler?: IStreamAnalyticsHandler;
116
129
  amplificationParameters?: StreamAmplificationParameters;
@@ -139,3 +152,9 @@ export declare function openStreamsPlayer(init: {
139
152
  playerClosed?: () => void;
140
153
  };
141
154
  }): void;
155
+ export type StreamsPlayerSettings = {
156
+ disableBackground?: boolean;
157
+ locale?: Locale;
158
+ showStreamsCloudWatermark?: boolean;
159
+ hideCloseButton?: boolean;
160
+ };