@streamscloud/embeddable 2.2.0 → 2.2.2
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/core/analytics.profile-id.d.ts +5 -0
- package/dist/core/analytics.profile-id.js +17 -0
- package/dist/core/document.event-handlers.d.ts +1 -0
- package/dist/core/document.event-handlers.js +5 -0
- package/dist/core/graphql.d.ts +2 -1
- package/dist/core/graphql.js +4 -1
- package/dist/short-videos/short-videos-player/cmp.short-videos-player.svelte +9 -5
- package/dist/short-videos/short-videos-player/index.js +8 -4
- package/dist/short-videos/short-videos-player/types.d.ts +2 -2
- package/dist/streams/stream-player/cmp.stream-player.svelte +12 -4
- package/dist/streams/stream-player/cmp.stream-player.svelte.d.ts +1 -2
- package/dist/streams/stream-player/index.d.ts +1 -1
- package/dist/streams/stream-player/index.js +9 -25
- package/dist/ui/icon/cmp.icon.svelte +13 -26
- package/dist/ui/shadow-dom/shadow-host.d.ts +1 -5
- package/dist/ui/shadow-dom/shadow-host.js +1 -14
- package/package.json +3 -5
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Key used for storing the profile ID in local storage
|
|
3
|
+
*/
|
|
4
|
+
const PROFILE_ID_STORAGE_KEY = 'streamscloud_profile_id';
|
|
5
|
+
/**
|
|
6
|
+
* Retrieves the profile ID from localStorage or generates a new one if it doesn't exist
|
|
7
|
+
* @returns The profile ID to use for analytics tracking
|
|
8
|
+
*/
|
|
9
|
+
export const getOrCreateProfileId = () => {
|
|
10
|
+
const storedProfileId = localStorage.getItem(PROFILE_ID_STORAGE_KEY);
|
|
11
|
+
if (!storedProfileId) {
|
|
12
|
+
const newProfileId = crypto.randomUUID();
|
|
13
|
+
localStorage.setItem(PROFILE_ID_STORAGE_KEY, newProfileId);
|
|
14
|
+
return newProfileId;
|
|
15
|
+
}
|
|
16
|
+
return storedProfileId;
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const handleEsc: (event: KeyboardEvent, callback: () => void) => void;
|
package/dist/core/graphql.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export declare const createLocalGQLClient: (graphqlUrl
|
|
1
|
+
export declare const createLocalGQLClient: (graphqlUrl?: string, customFetch?: typeof fetch) => import("@urql/core").Client;
|
|
2
|
+
export declare const resolveGraphQLUrl: (url?: string) => string;
|
package/dist/core/graphql.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createClient, fetchExchange } from '@urql/core';
|
|
2
2
|
export const createLocalGQLClient = (graphqlUrl, customFetch) => createClient({
|
|
3
|
-
url: graphqlUrl,
|
|
3
|
+
url: resolveGraphQLUrl(graphqlUrl),
|
|
4
4
|
requestPolicy: 'network-only',
|
|
5
5
|
fetchOptions: {
|
|
6
6
|
credentials: 'include'
|
|
@@ -8,3 +8,6 @@ export const createLocalGQLClient = (graphqlUrl, customFetch) => createClient({
|
|
|
8
8
|
fetch: customFetch || fetch,
|
|
9
9
|
exchanges: [fetchExchange]
|
|
10
10
|
});
|
|
11
|
+
export const resolveGraphQLUrl = (url) => {
|
|
12
|
+
return url || 'https://api.streamscloud.com/graphql';
|
|
13
|
+
};
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
import { handleEsc } from '../../core/document.event-handlers';
|
|
10
11
|
import { createLocalGQLClient } from '../../core/graphql';
|
|
11
12
|
import { mapShortVideoViewerModel, ShortVideoViewer } from '../short-video-viewer';
|
|
12
13
|
import { GetShortVideosDocument } from './operations.generated';
|
|
@@ -16,7 +17,7 @@ import { SpotlightLayout } from '../../ui/spotlight-layout';
|
|
|
16
17
|
import { default as Controls } from './controls.svelte';
|
|
17
18
|
import { ShortVideosPlayerLocalization } from './short-videos-player-localization.svelte';
|
|
18
19
|
import { ShortVideosPlayerUiManager } from './ui-manager.svelte';
|
|
19
|
-
import {
|
|
20
|
+
import { onMount, untrack } from 'svelte';
|
|
20
21
|
let { input, localization: localizationInit, on } = $props();
|
|
21
22
|
const localization = $derived(new ShortVideosPlayerLocalization(localizationInit));
|
|
22
23
|
let buffer = $state(input.type === 'provider' ? new PlayerBuffer(input.provider) : null);
|
|
@@ -69,17 +70,20 @@ const uiManager = new ShortVideosPlayerUiManager();
|
|
|
69
70
|
onMount(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
70
71
|
uiManager.detailsCollapsed = window && window.innerWidth < window.innerHeight;
|
|
71
72
|
}));
|
|
72
|
-
onDestroy(() => {
|
|
73
|
-
// end tracking the short video
|
|
74
|
-
});
|
|
75
73
|
const handleDimensionsChanged = (dimensions) => {
|
|
76
74
|
uiManager.updateDimensions({
|
|
77
75
|
mainViewColumnWidth: dimensions.mainSceneWidth,
|
|
78
76
|
viewTotalWidth: dimensions.totalWidth
|
|
79
77
|
});
|
|
80
78
|
};
|
|
79
|
+
const onPlayerClose = () => {
|
|
80
|
+
var _a;
|
|
81
|
+
(_a = on === null || on === void 0 ? void 0 : on.closePlayer) === null || _a === void 0 ? void 0 : _a.call(on);
|
|
82
|
+
};
|
|
81
83
|
</script>
|
|
82
84
|
|
|
85
|
+
<svelte:document onkeydown={(e) => handleEsc(e, onPlayerClose)} />
|
|
86
|
+
|
|
83
87
|
<div class="short-videos-player-container">
|
|
84
88
|
<div class="short-videos-player" style={uiManager.globalCssVariables}>
|
|
85
89
|
{#if buffer}
|
|
@@ -92,7 +96,7 @@ const handleDimensionsChanged = (dimensions) => {
|
|
|
92
96
|
</PlayerSlider>
|
|
93
97
|
</div>
|
|
94
98
|
</SpotlightLayout>
|
|
95
|
-
<Controls buffer={buffer} uiManager={uiManager} localization={localization} on={{ closePlayer: () =>
|
|
99
|
+
<Controls buffer={buffer} uiManager={uiManager} localization={localization} on={{ closePlayer: () => onPlayerClose() }} />
|
|
96
100
|
{:else}
|
|
97
101
|
<Loading positionFixedCenter={true} timeout={1000} />
|
|
98
102
|
{/if}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isIdsInit, isShortVideosProviderInit } from './types';
|
|
2
2
|
import { ShadowHost } from '../../ui/shadow-dom';
|
|
3
|
-
import { mount } from 'svelte';
|
|
3
|
+
import { mount, unmount } from 'svelte';
|
|
4
4
|
import { default as ShortVideosPlayer } from './cmp.short-videos-player.svelte';
|
|
5
5
|
/**
|
|
6
6
|
* Opens the short videos player modal with the specified provider or by fetching videos by IDs.
|
|
@@ -88,14 +88,18 @@ export const openShortVideosPlayer = async (init) => {
|
|
|
88
88
|
if (!input) {
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
|
-
const shadowHost = new ShadowHost(
|
|
92
|
-
mount(ShortVideosPlayer, {
|
|
91
|
+
const shadowHost = new ShadowHost();
|
|
92
|
+
const mounted = mount(ShortVideosPlayer, {
|
|
93
93
|
target: shadowHost.shadowRoot,
|
|
94
94
|
props: {
|
|
95
95
|
input,
|
|
96
96
|
localization: init.localization,
|
|
97
97
|
on: {
|
|
98
|
-
closePlayer: () => {
|
|
98
|
+
closePlayer: async () => {
|
|
99
|
+
if (init.on?.playerClosed) {
|
|
100
|
+
init.on.playerClosed();
|
|
101
|
+
}
|
|
102
|
+
await unmount(mounted);
|
|
99
103
|
shadowHost.remove();
|
|
100
104
|
}
|
|
101
105
|
}
|
|
@@ -10,7 +10,7 @@ export type IdsPlayerInput = {
|
|
|
10
10
|
type: 'ids';
|
|
11
11
|
ids: string[];
|
|
12
12
|
initialId?: string;
|
|
13
|
-
graphqlUrl
|
|
13
|
+
graphqlUrl?: string;
|
|
14
14
|
};
|
|
15
15
|
export type OpenShortVideosPlayerInit = ProviderInit | IdsInit;
|
|
16
16
|
type ProviderInit = {
|
|
@@ -22,7 +22,7 @@ type ProviderInit = {
|
|
|
22
22
|
};
|
|
23
23
|
type IdsInit = {
|
|
24
24
|
ids: string[];
|
|
25
|
-
graphqlUrl
|
|
25
|
+
graphqlUrl?: string;
|
|
26
26
|
initialId?: string;
|
|
27
27
|
localization?: IShortVideosPlayerLocalization;
|
|
28
28
|
on?: {
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
import { getOrCreateProfileId } from '../../core/analytics.profile-id';
|
|
11
|
+
import { handleEsc } from '../../core/document.event-handlers';
|
|
12
|
+
import { createLocalGQLClient, resolveGraphQLUrl } from '../../core/graphql';
|
|
10
13
|
import { toastrWarning } from '../../core/toastr';
|
|
11
14
|
import { ShortVideoViewer } from '../../short-videos/short-video-viewer';
|
|
12
15
|
import { mapToShortVideoViewerModel } from '../layout/models';
|
|
@@ -23,7 +26,7 @@ import { StreamPlayerLocalization } from './stream-player-localization.svelte';
|
|
|
23
26
|
import { StreamPlayerUiManager } from './ui-manager.svelte';
|
|
24
27
|
import { onMount } from 'svelte';
|
|
25
28
|
import { AppEventsTracker } from '@streamscloud/streams-analytics-collector';
|
|
26
|
-
let { streamId,
|
|
29
|
+
let { streamId, graphqlUrl, localization: localizationInit, on } = $props();
|
|
27
30
|
const localization = $derived(new StreamPlayerLocalization(localizationInit));
|
|
28
31
|
let model = $state(null);
|
|
29
32
|
let buffer = $state.raw(null);
|
|
@@ -51,12 +54,15 @@ onMount(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
51
54
|
var _a, _b, _c, _d;
|
|
52
55
|
uiManager.overviewCollapsed = window && window.innerWidth < window.innerHeight;
|
|
53
56
|
try {
|
|
57
|
+
const graphql = createLocalGQLClient(graphqlUrl);
|
|
54
58
|
const streamPayload = yield graphql.query(GetStreamDocument, { id: streamId }).toPromise();
|
|
55
59
|
if (!((_a = streamPayload.data) === null || _a === void 0 ? void 0 : _a.stream)) {
|
|
56
60
|
toastrWarning(localization.streamNotFound);
|
|
57
61
|
(_b = on === null || on === void 0 ? void 0 : on.closePlayer) === null || _b === void 0 ? void 0 : _b.call(on);
|
|
58
62
|
return;
|
|
59
63
|
}
|
|
64
|
+
AppEventsTracker.setEndpoint(resolveGraphQLUrl(graphqlUrl));
|
|
65
|
+
AppEventsTracker.setProfileId(getOrCreateProfileId());
|
|
60
66
|
(_c = on === null || on === void 0 ? void 0 : on.streamActivated) === null || _c === void 0 ? void 0 : _c.call(on, {
|
|
61
67
|
ownerId: streamPayload.data.stream.ownerProfile.id,
|
|
62
68
|
title: streamPayload.data.stream.title,
|
|
@@ -146,6 +152,8 @@ const onProgress = (pageId, videoId, progress) => {
|
|
|
146
152
|
};
|
|
147
153
|
</script>
|
|
148
154
|
|
|
155
|
+
<svelte:document onkeydown={(e) => handleEsc(e, onPlayerClose)} />
|
|
156
|
+
|
|
149
157
|
<div class="stream-player-container">
|
|
150
158
|
{#if loading}
|
|
151
159
|
<Loading positionAbsoluteCenter={true} timeout={600} />
|
|
@@ -165,8 +173,8 @@ const onProgress = (pageId, videoId, progress) => {
|
|
|
165
173
|
<StreamPageViewer
|
|
166
174
|
page={item}
|
|
167
175
|
on={{
|
|
168
|
-
progress: (videoId:
|
|
169
|
-
productClick: (productId:
|
|
176
|
+
progress: (videoId: String, progress: Number) => onProgress(item.id, videoId, progress),
|
|
177
|
+
productClick: (productId: String) => onProductCardClick(productId)
|
|
170
178
|
}} />
|
|
171
179
|
{:else if item.type === 'short-video'}
|
|
172
180
|
<ShortVideoViewer
|
|
@@ -196,7 +204,7 @@ const onProgress = (pageId, videoId, progress) => {
|
|
|
196
204
|
localization={localization}
|
|
197
205
|
on={{
|
|
198
206
|
closePlayer: () => onPlayerClose(),
|
|
199
|
-
productClick: (productId:
|
|
207
|
+
productClick: (productId: String) => onProductCardClick(productId)
|
|
200
208
|
}} />
|
|
201
209
|
{/if}
|
|
202
210
|
</div>
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { type IStreamPlayerLocalization } from './stream-player-localization.svelte';
|
|
2
|
-
import type { Client } from '@urql/core';
|
|
3
2
|
type Props = {
|
|
4
3
|
streamId: string;
|
|
5
4
|
localization?: IStreamPlayerLocalization;
|
|
6
|
-
|
|
5
|
+
graphqlUrl?: string;
|
|
7
6
|
on?: {
|
|
8
7
|
closePlayer?: () => void;
|
|
9
8
|
streamActivated?: (data: {
|
|
@@ -1,25 +1,7 @@
|
|
|
1
|
-
import { createLocalGQLClient } from '../../core/graphql';
|
|
2
1
|
import { ShadowHost } from '../../ui/shadow-dom';
|
|
3
2
|
import { default as StreamPlayer } from './cmp.stream-player.svelte';
|
|
4
3
|
import { AppEventsTracker } from '@streamscloud/streams-analytics-collector';
|
|
5
|
-
import { mount } from 'svelte';
|
|
6
|
-
/**
|
|
7
|
-
* Key used for storing the profile ID in local storage
|
|
8
|
-
*/
|
|
9
|
-
const PROFILE_ID_STORAGE_KEY = 'streamscloud_profile_id';
|
|
10
|
-
/**
|
|
11
|
-
* Retrieves the profile ID from localStorage or generates a new one if it doesn't exist
|
|
12
|
-
* @returns The profile ID to use for analytics tracking
|
|
13
|
-
*/
|
|
14
|
-
function getOrCreateProfileId() {
|
|
15
|
-
const storedProfileId = localStorage.getItem(PROFILE_ID_STORAGE_KEY);
|
|
16
|
-
if (!storedProfileId) {
|
|
17
|
-
const newProfileId = crypto.randomUUID();
|
|
18
|
-
localStorage.setItem(PROFILE_ID_STORAGE_KEY, newProfileId);
|
|
19
|
-
return newProfileId;
|
|
20
|
-
}
|
|
21
|
-
return storedProfileId;
|
|
22
|
-
}
|
|
4
|
+
import { mount, unmount } from 'svelte';
|
|
23
5
|
/**
|
|
24
6
|
* Opens the stream player modal with the specified stream details.
|
|
25
7
|
*
|
|
@@ -45,14 +27,12 @@ function getOrCreateProfileId() {
|
|
|
45
27
|
*/
|
|
46
28
|
export const openStreamPlayer = (init) => {
|
|
47
29
|
const { streamId, graphqlUrl, localization } = init;
|
|
48
|
-
const shadowHost = new ShadowHost(
|
|
49
|
-
|
|
50
|
-
AppEventsTracker.setProfileId(getOrCreateProfileId());
|
|
51
|
-
mount(StreamPlayer, {
|
|
30
|
+
const shadowHost = new ShadowHost();
|
|
31
|
+
const mounted = mount(StreamPlayer, {
|
|
52
32
|
target: shadowHost.shadowRoot,
|
|
53
33
|
props: {
|
|
54
34
|
streamId,
|
|
55
|
-
|
|
35
|
+
graphqlUrl,
|
|
56
36
|
localization,
|
|
57
37
|
on: {
|
|
58
38
|
streamActivated: (data) => {
|
|
@@ -61,7 +41,11 @@ export const openStreamPlayer = (init) => {
|
|
|
61
41
|
init.on.streamActivated({ title: data.title, image: data.image });
|
|
62
42
|
}
|
|
63
43
|
},
|
|
64
|
-
closePlayer: () => {
|
|
44
|
+
closePlayer: async () => {
|
|
45
|
+
if (init.on?.playerClosed) {
|
|
46
|
+
init.on.playerClosed();
|
|
47
|
+
}
|
|
48
|
+
await unmount(mounted);
|
|
65
49
|
shadowHost.remove();
|
|
66
50
|
}
|
|
67
51
|
}
|
|
@@ -1,34 +1,20 @@
|
|
|
1
1
|
<script lang="ts">import { IconColor } from './types';
|
|
2
|
-
import { inlineSvg } from '@svelte-put/inline-svg';
|
|
3
2
|
let { src, color = null } = $props();
|
|
4
|
-
let svgRef;
|
|
5
|
-
$effect(() => {
|
|
6
|
-
if (svgRef && src) {
|
|
7
|
-
inlineSvg(svgRef, src);
|
|
8
|
-
}
|
|
9
|
-
});
|
|
10
|
-
const fillSvg = (node) => {
|
|
11
|
-
svgRef = node;
|
|
12
|
-
return inlineSvg(node, src);
|
|
13
|
-
};
|
|
14
3
|
</script>
|
|
15
4
|
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
{#if src.startsWith('<svg')}
|
|
5
|
+
{#if src.startsWith('<svg')}
|
|
6
|
+
<div
|
|
7
|
+
class="icon"
|
|
8
|
+
class:icon--white={color === IconColor.White}
|
|
9
|
+
class:icon--text={color === IconColor.Text}
|
|
10
|
+
class:icon--gray={color === IconColor.Gray}
|
|
11
|
+
class:icon--green={color === IconColor.Green}
|
|
12
|
+
class:icon--red={color === IconColor.Red}
|
|
13
|
+
class:icon--orange={color === IconColor.Orange}
|
|
14
|
+
class:icon--blue={color === IconColor.Blue}>
|
|
27
15
|
{@html src}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
{/if}
|
|
31
|
-
</div>
|
|
16
|
+
</div>
|
|
17
|
+
{/if}
|
|
32
18
|
|
|
33
19
|
<style>@keyframes fadeIn {
|
|
34
20
|
0% {
|
|
@@ -45,6 +31,7 @@ const fillSvg = (node) => {
|
|
|
45
31
|
--_icon--color: var(--icon--color);
|
|
46
32
|
--_icon--size: var(--icon--size, 1.25em);
|
|
47
33
|
--_icon--stroke-width: var(--icon--stroke-width, 0);
|
|
34
|
+
display: contents;
|
|
48
35
|
}
|
|
49
36
|
.icon--white {
|
|
50
37
|
--_icon--color: #ffffff;
|
|
@@ -3,11 +3,7 @@ import reset from './_reset.scss?raw';
|
|
|
3
3
|
export class ShadowHost {
|
|
4
4
|
shadowRoot;
|
|
5
5
|
host;
|
|
6
|
-
|
|
7
|
-
constructor(init) {
|
|
8
|
-
this.callbacks = {
|
|
9
|
-
onClosed: init.onClosed
|
|
10
|
-
};
|
|
6
|
+
constructor() {
|
|
11
7
|
const host = document.createElement('div');
|
|
12
8
|
host.style.all = 'unset';
|
|
13
9
|
host.style.position = 'fixed';
|
|
@@ -19,7 +15,6 @@ export class ShadowHost {
|
|
|
19
15
|
host.style.margin = '0';
|
|
20
16
|
host.style.boxSizing = 'border-box';
|
|
21
17
|
host.style.textAlign = 'initial';
|
|
22
|
-
document.addEventListener('keydown', this.handleEsc);
|
|
23
18
|
this.host = host;
|
|
24
19
|
this.shadowRoot = host.attachShadow({ mode: 'open' });
|
|
25
20
|
const styleElement = document.createElement('style');
|
|
@@ -33,13 +28,5 @@ export class ShadowHost {
|
|
|
33
28
|
remove() {
|
|
34
29
|
this.host.remove();
|
|
35
30
|
document.getElementsByTagName('html')[0].style.overflow = '';
|
|
36
|
-
document.removeEventListener('keydown', this.handleEsc);
|
|
37
|
-
this.callbacks.onClosed();
|
|
38
31
|
}
|
|
39
|
-
handleEsc = (event) => {
|
|
40
|
-
if (event.key === 'Escape' || event.key === 'Esc') {
|
|
41
|
-
// Remove the modal from the DOM, for example:
|
|
42
|
-
this.remove();
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
32
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamscloud/embeddable",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"author": "StreamsCloud",
|
|
5
5
|
"repository": "https://github.com/StreamsCloud/streamscloud-frontend-packages.git",
|
|
6
6
|
"type": "module",
|
|
@@ -92,11 +92,10 @@
|
|
|
92
92
|
},
|
|
93
93
|
"peerDependencies": {
|
|
94
94
|
"@fluentui/svg-icons": "^1.1.292",
|
|
95
|
-
"@
|
|
95
|
+
"@streamscloud/streams-analytics-collector": "latest",
|
|
96
96
|
"@urql/core": "^5.1.1",
|
|
97
97
|
"mobile-detect": "^1.4.5",
|
|
98
|
-
"svelte": "^5.25.3"
|
|
99
|
-
"@streamscloud/streams-analytics-collector": "latest"
|
|
98
|
+
"svelte": "^5.25.3"
|
|
100
99
|
},
|
|
101
100
|
"devDependencies": {
|
|
102
101
|
"@eslint/compat": "^1.2.9",
|
|
@@ -111,7 +110,6 @@
|
|
|
111
110
|
"@graphql-codegen/typescript": "^4.1.6",
|
|
112
111
|
"@graphql-codegen/typescript-operations": "^4.6.1",
|
|
113
112
|
"@graphql-typed-document-node/core": "^3.2.0",
|
|
114
|
-
"@svelte-put/inline-svg": "^4.0.1",
|
|
115
113
|
"@sveltejs/package": "^2.3.11",
|
|
116
114
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
|
117
115
|
"@tsconfig/svelte": "^5.0.4",
|