@vouchfor/embeds 0.0.0-experiment.93ea548 → 0.0.0-experiment.9e95139
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/es/embeds.js +416 -325
- package/dist/es/embeds.js.map +1 -1
- package/dist/es/{components → src/components}/Embed/controllers/fetcher.d.ts +1 -0
- package/dist/es/{components → src/components}/Embed/controllers/tracking.d.ts +6 -3
- package/dist/es/{components → src/components}/Embed/index.d.ts +4 -1
- package/dist/iife/embeds.iife.js +305 -190
- package/dist/iife/embeds.iife.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Embed/Embed.stories.ts +14 -1
- package/src/components/Embed/controllers/fetcher.ts +29 -8
- package/src/components/Embed/controllers/tracking.ts +84 -98
- package/src/components/Embed/index.ts +9 -2
- /package/dist/es/{index.d.ts → src/index.d.ts} +0 -0
- /package/dist/es/{utils → src/utils}/env.d.ts +0 -0
- /package/dist/es/{utils → src/utils}/events.d.ts +0 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vouchfor/embeds",
|
3
|
-
"version": "0.0.0-experiment.
|
3
|
+
"version": "0.0.0-experiment.9e95139",
|
4
4
|
"license": "MIT",
|
5
5
|
"author": "Aaron Williams",
|
6
6
|
"main": "dist/es/embeds.js",
|
@@ -36,7 +36,7 @@
|
|
36
36
|
},
|
37
37
|
"dependencies": {
|
38
38
|
"@lit/task": "^1.0.0",
|
39
|
-
"@vouchfor/media-player": "0.0.0-experiment.
|
39
|
+
"@vouchfor/media-player": "0.0.0-experiment.9e95139",
|
40
40
|
"uuid": "^9.0.1"
|
41
41
|
},
|
42
42
|
"peerDependencies": {
|
@@ -10,7 +10,17 @@ type EmbedArgs = EmbedProps & {
|
|
10
10
|
showVouch?: boolean;
|
11
11
|
};
|
12
12
|
|
13
|
-
const _Embed = ({
|
13
|
+
const _Embed = ({
|
14
|
+
vouchId,
|
15
|
+
templateId,
|
16
|
+
questionIndexes,
|
17
|
+
preload,
|
18
|
+
autoplay,
|
19
|
+
env,
|
20
|
+
apiKey,
|
21
|
+
controls,
|
22
|
+
aspectRatio
|
23
|
+
}: EmbedArgs) => {
|
14
24
|
return html`
|
15
25
|
<div style="height: 100vh">
|
16
26
|
<vouch-embed
|
@@ -18,10 +28,12 @@ const _Embed = ({ vouchId, templateId, preload, autoplay, env, apiKey, controls,
|
|
18
28
|
apiKey=${ifDefined(apiKey)}
|
19
29
|
vouchId=${ifDefined(vouchId)}
|
20
30
|
templateId=${ifDefined(templateId)}
|
31
|
+
.questionIndexes=${questionIndexes}
|
21
32
|
.controls=${controls}
|
22
33
|
?autoplay=${autoplay}
|
23
34
|
preload=${ifDefined(preload)}
|
24
35
|
aspectRatio=${ifDefined(aspectRatio)}
|
36
|
+
@error=${console.log}
|
25
37
|
></vouch-embed>
|
26
38
|
</div>
|
27
39
|
`;
|
@@ -43,6 +55,7 @@ const Embed: Story = {
|
|
43
55
|
apiKey: 'TVik9uTMgE-PD25UTHIS6gyl0hMBWC7AT4dkpdlLBT4VIfDWZJrQiCk6Ak7m1',
|
44
56
|
vouchId: '6JQEIPeStt',
|
45
57
|
templateId: '357fc118-e179-4171-9446-ff2b8e9d1b29',
|
58
|
+
questionIndexes: [],
|
46
59
|
aspectRatio: 0,
|
47
60
|
preload: 'none',
|
48
61
|
autoplay: false
|
@@ -9,7 +9,7 @@ import { getEnvUrls } from '~/utils/env';
|
|
9
9
|
|
10
10
|
type EmbedHost = ReactiveControllerHost & Embed;
|
11
11
|
|
12
|
-
type
|
12
|
+
type FetchTaskDeps = [
|
13
13
|
EmbedProps['env'],
|
14
14
|
EmbedProps['apiKey'],
|
15
15
|
EmbedProps['data'],
|
@@ -17,10 +17,13 @@ type TaskDeps = [
|
|
17
17
|
EmbedProps['templateId']
|
18
18
|
];
|
19
19
|
|
20
|
+
type FilterTaskDeps = [EmbedProps['data'], EmbedProps['questionIndexes']];
|
21
|
+
|
20
22
|
class FetcherController {
|
21
23
|
host: EmbedHost;
|
22
24
|
|
23
25
|
private _fetching = false;
|
26
|
+
private _vouch: EmbedProps['data'];
|
24
27
|
|
25
28
|
set fetching(value) {
|
26
29
|
if (this._fetching !== value) {
|
@@ -45,13 +48,13 @@ class FetcherController {
|
|
45
48
|
});
|
46
49
|
|
47
50
|
const vouch = await res.json();
|
48
|
-
this.host.dispatchEvent(new CustomEvent('vouch:loaded', { detail:
|
51
|
+
this.host.dispatchEvent(new CustomEvent('vouch:loaded', { detail: vouch?.id }));
|
49
52
|
|
50
53
|
// HACK: we're currently using API Gateway caching on the embed API without any invalidation logic,
|
51
54
|
// so to ensure that the cache stays up to date, whenever we detect a cache hit we trigger another
|
52
55
|
// API call with the `Cache-Control` header which will re-fill the cache
|
53
56
|
const resCacheCheck = res?.headers?.get('X-Cache-Check');
|
54
|
-
if (resCacheCheck
|
57
|
+
if (resCacheCheck !== cacheCheck) {
|
55
58
|
fetch(`${embedApiUrl}/vouches/${vouchId}`, {
|
56
59
|
method: 'GET',
|
57
60
|
headers: [
|
@@ -81,7 +84,7 @@ class FetcherController {
|
|
81
84
|
// so to ensure that the cache stays up to date, whenever we detect a cache hit we trigger another
|
82
85
|
// API call with the `Cache-Control` header which will re-fill the cache
|
83
86
|
const resCacheCheck = res?.headers?.get('X-Cache-Check');
|
84
|
-
if (resCacheCheck
|
87
|
+
if (resCacheCheck !== cacheCheck) {
|
85
88
|
fetch(`${embedApiUrl}/templates/${templateId}`, {
|
86
89
|
method: 'GET',
|
87
90
|
headers: [
|
@@ -96,9 +99,9 @@ class FetcherController {
|
|
96
99
|
|
97
100
|
constructor(host: EmbedHost) {
|
98
101
|
this.host = host;
|
99
|
-
new Task<
|
102
|
+
new Task<FetchTaskDeps, void>(
|
100
103
|
this.host,
|
101
|
-
async ([env, apiKey, data, vouchId, templateId]:
|
104
|
+
async ([env, apiKey, data, vouchId, templateId]: FetchTaskDeps) => {
|
102
105
|
try {
|
103
106
|
host.vouch = undefined;
|
104
107
|
host.template = undefined;
|
@@ -109,7 +112,7 @@ class FetcherController {
|
|
109
112
|
this.fetching = true;
|
110
113
|
template = await this.getTemplate(env, apiKey, templateId);
|
111
114
|
}
|
112
|
-
|
115
|
+
this._vouch = data;
|
113
116
|
host.template = template ?? data?.settings?.template?.instance;
|
114
117
|
} else if (vouchId) {
|
115
118
|
this.fetching = true;
|
@@ -118,7 +121,7 @@ class FetcherController {
|
|
118
121
|
this.getVouch(env, apiKey, vouchId),
|
119
122
|
templateId ? this.getTemplate(env, apiKey, templateId) : null
|
120
123
|
]);
|
121
|
-
|
124
|
+
this._vouch = vouch;
|
122
125
|
host.template = template ?? vouch?.settings?.template?.instance;
|
123
126
|
}
|
124
127
|
} finally {
|
@@ -127,6 +130,24 @@ class FetcherController {
|
|
127
130
|
},
|
128
131
|
() => [host.env, host.apiKey, host.data, host.vouchId, host.templateId]
|
129
132
|
);
|
133
|
+
|
134
|
+
// This second task is to be able to filter the vouch without fetching it again if only the questionIndexes changed
|
135
|
+
new Task<FilterTaskDeps, void>(
|
136
|
+
this.host,
|
137
|
+
([vouch, questionIndexes]: FilterTaskDeps) => {
|
138
|
+
host.vouch = vouch
|
139
|
+
? {
|
140
|
+
...vouch,
|
141
|
+
questions: {
|
142
|
+
items: vouch?.questions.items.filter(
|
143
|
+
(_, index) => !questionIndexes?.length || questionIndexes?.includes(index + 1)
|
144
|
+
)
|
145
|
+
}
|
146
|
+
}
|
147
|
+
: undefined;
|
148
|
+
},
|
149
|
+
() => [this._vouch, host.questionIndexes]
|
150
|
+
);
|
130
151
|
}
|
131
152
|
}
|
132
153
|
|
@@ -1,19 +1,19 @@
|
|
1
|
-
/* eslint-disable max-lines */
|
2
1
|
import { v4 as uuidv4 } from 'uuid';
|
3
2
|
|
4
3
|
import type { Embed } from '..';
|
5
4
|
import type { VideoEventDetail } from '@vouchfor/media-player';
|
6
5
|
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
7
6
|
|
7
|
+
import packageJson from '../../../../package.json';
|
8
8
|
import { getEnvUrls } from '~/utils/env';
|
9
9
|
|
10
|
-
const
|
10
|
+
const MINIMUM_SEND_THRESHOLD = 1;
|
11
11
|
|
12
12
|
type EmbedHost = ReactiveControllerHost & Embed;
|
13
13
|
|
14
14
|
type TrackingEvent = 'VOUCH_LOADED' | 'VOUCH_RESPONSE_VIEWED' | 'VIDEO_PLAYED' | 'VIDEO_STREAMED';
|
15
15
|
type TrackingPayload = {
|
16
|
-
vouchId
|
16
|
+
vouchId?: string;
|
17
17
|
answerId?: string;
|
18
18
|
streamStart?: number;
|
19
19
|
streamEnd?: number;
|
@@ -37,22 +37,23 @@ class TrackingController implements ReactiveController {
|
|
37
37
|
private _hasPlayed = false;
|
38
38
|
private _hasLoaded: BooleanMap = {};
|
39
39
|
private _answersViewed: BooleanMap = {};
|
40
|
-
private
|
40
|
+
private _streamStartTime: TimeMap = {};
|
41
41
|
private _streamLatestTime: TimeMap = {};
|
42
|
-
private
|
42
|
+
private _currentlyPlayingVideo: VideoEventDetail | null = null;
|
43
43
|
|
44
44
|
constructor(host: EmbedHost) {
|
45
45
|
this.host = host;
|
46
46
|
host.addController(this);
|
47
47
|
}
|
48
48
|
|
49
|
-
private _findVouchId() {
|
49
|
+
private _findVouchId(payload?: TrackingPayload) {
|
50
|
+
if (payload && 'vouchId' in payload) {
|
51
|
+
return payload.vouchId;
|
52
|
+
}
|
50
53
|
if (this.host.vouch) {
|
51
|
-
if ('uuid' in this.host.vouch) {
|
52
|
-
return this.host.vouch.uuid;
|
53
|
-
}
|
54
54
|
return this.host.vouch.id;
|
55
55
|
}
|
56
|
+
return null;
|
56
57
|
}
|
57
58
|
|
58
59
|
private _createVisitor = (visitorId: string) => {
|
@@ -130,30 +131,56 @@ class TrackingController implements ReactiveController {
|
|
130
131
|
};
|
131
132
|
};
|
132
133
|
|
133
|
-
private _sendTrackingEvent = (event: TrackingEvent, payload
|
134
|
-
const
|
135
|
-
const { client, tab, request, visitor } = this._getUids();
|
134
|
+
private _sendTrackingEvent = (event: TrackingEvent, payload?: TrackingPayload) => {
|
135
|
+
const vouchId = this._findVouchId(payload);
|
136
136
|
|
137
|
-
if (this.host.disableTracking) {
|
137
|
+
if (!vouchId || this.host.disableTracking) {
|
138
138
|
return;
|
139
139
|
}
|
140
140
|
|
141
|
+
const { publicApiUrl } = getEnvUrls(this.host.env);
|
142
|
+
const { client, tab, request, visitor } = this._getUids();
|
143
|
+
|
141
144
|
navigator.sendBeacon(
|
142
|
-
`${publicApiUrl}/api/events`,
|
145
|
+
`${publicApiUrl}/api/v2/events`,
|
143
146
|
JSON.stringify({
|
144
147
|
event,
|
145
|
-
payload
|
148
|
+
payload: {
|
149
|
+
...payload,
|
150
|
+
vouchId
|
151
|
+
},
|
146
152
|
context: {
|
147
153
|
'x-uid-client': client,
|
148
154
|
'x-uid-tab': tab,
|
149
155
|
'x-uid-request': request,
|
150
156
|
'x-uid-visitor': visitor,
|
151
|
-
'x-reporting-metadata': this._getReportingMetadata()
|
157
|
+
'x-reporting-metadata': this._getReportingMetadata(),
|
158
|
+
'x-embeds-version': packageJson.version
|
152
159
|
}
|
153
160
|
})
|
154
161
|
);
|
155
162
|
};
|
156
163
|
|
164
|
+
private _streamEnded = () => {
|
165
|
+
if (this._currentlyPlayingVideo) {
|
166
|
+
const { id, key } = this._currentlyPlayingVideo;
|
167
|
+
// Don't send a tracking event when seeking backwards
|
168
|
+
if (this._streamLatestTime[key] > this._streamStartTime[key] + MINIMUM_SEND_THRESHOLD) {
|
169
|
+
// Send a video streamed event any time the stream ends to capture the time between starting
|
170
|
+
// the video and the video stopping for any reason (pausing, deleting the embed node or closing the browser)
|
171
|
+
this._sendTrackingEvent('VIDEO_STREAMED', {
|
172
|
+
answerId: id,
|
173
|
+
streamStart: this._streamStartTime[key],
|
174
|
+
streamEnd: this._streamLatestTime[key]
|
175
|
+
});
|
176
|
+
}
|
177
|
+
|
178
|
+
// Make sure these events are only sent once by deleting the start and latest times
|
179
|
+
delete this._streamStartTime[key];
|
180
|
+
delete this._streamLatestTime[key];
|
181
|
+
}
|
182
|
+
};
|
183
|
+
|
157
184
|
private _handleVouchLoaded = ({ detail: vouchId }: CustomEvent<string>) => {
|
158
185
|
if (!vouchId) {
|
159
186
|
return;
|
@@ -161,24 +188,15 @@ class TrackingController implements ReactiveController {
|
|
161
188
|
|
162
189
|
// Only send loaded event once per session
|
163
190
|
if (!this._hasLoaded[vouchId]) {
|
164
|
-
this._sendTrackingEvent('VOUCH_LOADED', {
|
165
|
-
vouchId
|
166
|
-
});
|
191
|
+
this._sendTrackingEvent('VOUCH_LOADED', { vouchId });
|
167
192
|
this._hasLoaded[vouchId] = true;
|
168
193
|
}
|
169
194
|
};
|
170
195
|
|
171
196
|
private _handlePlay = () => {
|
172
|
-
const vouchId = this._findVouchId();
|
173
|
-
|
174
|
-
if (!vouchId) {
|
175
|
-
return;
|
176
|
-
}
|
177
|
-
|
178
197
|
// Only send the video played event once per session
|
179
198
|
if (!this._hasPlayed) {
|
180
199
|
this._sendTrackingEvent('VIDEO_PLAYED', {
|
181
|
-
vouchId,
|
182
200
|
streamStart: this.host.currentTime
|
183
201
|
});
|
184
202
|
this._hasPlayed = true;
|
@@ -186,118 +204,86 @@ class TrackingController implements ReactiveController {
|
|
186
204
|
};
|
187
205
|
|
188
206
|
private _handleVideoPlay = ({ detail: { id, key, node } }: CustomEvent<VideoEventDetail>) => {
|
189
|
-
const vouchId = this._findVouchId();
|
190
|
-
|
191
|
-
if (!vouchId) {
|
192
|
-
return;
|
193
|
-
}
|
194
|
-
|
195
207
|
// Only increment play count once per session
|
196
208
|
if (!this._answersViewed[key]) {
|
197
209
|
this._sendTrackingEvent('VOUCH_RESPONSE_VIEWED', {
|
198
|
-
vouchId,
|
199
210
|
answerId: id
|
200
211
|
});
|
201
212
|
this._answersViewed[key] = true;
|
202
213
|
}
|
203
214
|
|
204
|
-
this.
|
205
|
-
|
206
|
-
|
207
|
-
};
|
208
|
-
|
209
|
-
private _handleVideoSeeking = ({ detail: { id, key } }: CustomEvent<VideoEventDetail>) => {
|
210
|
-
const vouchId = this._findVouchId();
|
211
|
-
|
212
|
-
if (!vouchId) {
|
213
|
-
return;
|
215
|
+
if (!this._streamStartTime[key]) {
|
216
|
+
this._streamStartTime[key] = node.currentTime;
|
217
|
+
this._streamLatestTime[key] = node.currentTime;
|
214
218
|
}
|
215
|
-
|
216
|
-
if (this._streamLatestTime[key]) {
|
217
|
-
this._sendTrackingEvent('VIDEO_STREAMED', {
|
218
|
-
vouchId,
|
219
|
-
answerId: id,
|
220
|
-
streamStart: this._streamedTime[key],
|
221
|
-
streamEnd: this._streamLatestTime[key]
|
222
|
-
});
|
223
|
-
}
|
224
|
-
|
225
|
-
delete this._streamedTime[key];
|
226
|
-
delete this._streamLatestTime[key];
|
227
|
-
delete this._streamedPrevTimestamp[key];
|
228
219
|
};
|
229
220
|
|
230
221
|
private _handleVideoTimeUpdate = ({ detail: { id, key, node } }: CustomEvent<VideoEventDetail>) => {
|
231
|
-
const vouchId = this._findVouchId();
|
232
|
-
|
233
|
-
if (!vouchId) {
|
234
|
-
return;
|
235
|
-
}
|
236
|
-
|
237
|
-
const currentTimestamp = Date.now();
|
238
222
|
if (
|
239
|
-
|
240
|
-
!node.paused &&
|
223
|
+
// We only want to count any time that the video is actually playing
|
241
224
|
!this.host.paused &&
|
242
|
-
// Only
|
243
|
-
id === this.host.scene?.video?.id
|
244
|
-
// Throttle the frequency that we send streamed events while playing
|
245
|
-
currentTimestamp - this._streamedPrevTimestamp[key] > STREAMED_THROTTLE
|
225
|
+
// Only update the latest time if this event fires for the currently active video
|
226
|
+
id === this.host.scene?.video?.id
|
246
227
|
) {
|
228
|
+
this._currentlyPlayingVideo = { id, key, node };
|
229
|
+
this._streamLatestTime[key] = node.currentTime;
|
230
|
+
}
|
231
|
+
};
|
232
|
+
|
233
|
+
private _handleVideoPause = ({ detail: { id, key } }: CustomEvent<VideoEventDetail>) => {
|
234
|
+
if (this._streamLatestTime[key] > this._streamStartTime[key] + MINIMUM_SEND_THRESHOLD) {
|
247
235
|
this._sendTrackingEvent('VIDEO_STREAMED', {
|
248
|
-
vouchId,
|
249
236
|
answerId: id,
|
250
|
-
streamStart: this.
|
251
|
-
streamEnd:
|
237
|
+
streamStart: this._streamStartTime[key],
|
238
|
+
streamEnd: this._streamLatestTime[key]
|
252
239
|
});
|
253
|
-
this._streamedTime[key] = node.currentTime;
|
254
|
-
this._streamedPrevTimestamp[key] = currentTimestamp;
|
255
240
|
}
|
256
|
-
|
257
|
-
this._streamLatestTime[key]
|
241
|
+
delete this._streamStartTime[key];
|
242
|
+
delete this._streamLatestTime[key];
|
258
243
|
};
|
259
244
|
|
260
|
-
private
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
245
|
+
private _pageUnloading = () => {
|
246
|
+
this._streamEnded();
|
247
|
+
// This will try to send the same stream event again so we delete the start and latest
|
248
|
+
// time in stream ended so that there is no times to send and the pause event does nothing
|
249
|
+
this.host.pause();
|
250
|
+
};
|
266
251
|
|
267
|
-
|
268
|
-
if (
|
269
|
-
|
270
|
-
// We do this to capture the last bit of time that the video was played between the previous
|
271
|
-
// stream event and the video being paused manually or stopping because it ended
|
272
|
-
this._sendTrackingEvent('VIDEO_STREAMED', {
|
273
|
-
vouchId,
|
274
|
-
answerId: id,
|
275
|
-
streamStart: this._streamedTime[key],
|
276
|
-
streamEnd: node.currentTime
|
277
|
-
});
|
252
|
+
private _handleVisibilityChange = () => {
|
253
|
+
if (document.visibilityState === 'hidden') {
|
254
|
+
this._pageUnloading();
|
278
255
|
}
|
256
|
+
};
|
279
257
|
|
280
|
-
|
281
|
-
|
282
|
-
delete this._streamedPrevTimestamp[key];
|
258
|
+
private _handlePageHide = () => {
|
259
|
+
this._pageUnloading();
|
283
260
|
};
|
284
261
|
|
285
262
|
hostConnected() {
|
286
263
|
requestAnimationFrame(() => {
|
264
|
+
if ('onvisibilitychange' in document) {
|
265
|
+
document.addEventListener('visibilitychange', this._handleVisibilityChange);
|
266
|
+
} else {
|
267
|
+
window.addEventListener('pagehide', this._handlePageHide);
|
268
|
+
}
|
287
269
|
this.host.addEventListener('vouch:loaded', this._handleVouchLoaded);
|
288
270
|
this.host.mediaPlayer?.addEventListener('play', this._handlePlay);
|
289
271
|
this.host.mediaPlayer?.addEventListener('video:play', this._handleVideoPlay);
|
290
|
-
this.host.mediaPlayer?.addEventListener('video:seeking', this._handleVideoSeeking);
|
291
272
|
this.host.mediaPlayer?.addEventListener('video:pause', this._handleVideoPause);
|
292
273
|
this.host.mediaPlayer?.addEventListener('video:timeupdate', this._handleVideoTimeUpdate);
|
293
274
|
});
|
294
275
|
}
|
295
276
|
|
296
277
|
hostDisconnected() {
|
278
|
+
this._streamEnded();
|
279
|
+
if ('onvisibilitychange' in document) {
|
280
|
+
document.removeEventListener('visibilitychange', this._handleVisibilityChange);
|
281
|
+
} else {
|
282
|
+
window.removeEventListener('pagehide', this._handlePageHide);
|
283
|
+
}
|
297
284
|
this.host.removeEventListener('vouch:loaded', this._handleVouchLoaded);
|
298
285
|
this.host.mediaPlayer?.removeEventListener('play', this._handlePlay);
|
299
286
|
this.host.mediaPlayer?.removeEventListener('video:play', this._handleVideoPlay);
|
300
|
-
this.host.mediaPlayer?.removeEventListener('video:seeking', this._handleVideoSeeking);
|
301
287
|
this.host.mediaPlayer?.removeEventListener('video:pause', this._handleVideoPause);
|
302
288
|
this.host.mediaPlayer?.removeEventListener('video:timeupdate', this._handleVideoTimeUpdate);
|
303
289
|
}
|
@@ -3,7 +3,7 @@ import { customElement, property, state } from 'lit/decorators.js';
|
|
3
3
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
4
4
|
import { createRef, ref } from 'lit/directives/ref.js';
|
5
5
|
|
6
|
-
import type { Scene, TemplateInstance } from '@vouchfor/canvas-video';
|
6
|
+
import type { Scene, Scenes, TemplateInstance } from '@vouchfor/canvas-video';
|
7
7
|
import type { MediaPlayer, MediaPlayerProps } from '@vouchfor/media-player';
|
8
8
|
import type { Ref } from 'lit/directives/ref.js';
|
9
9
|
import type { Environment } from '~/utils/env';
|
@@ -21,15 +21,18 @@ type EmbedProps = Pick<MediaPlayerProps, 'data' | 'aspectRatio' | 'preload' | 'a
|
|
21
21
|
trackingSource?: string;
|
22
22
|
vouchId?: string;
|
23
23
|
templateId?: string;
|
24
|
+
// Index of the questions to include starting from 1
|
25
|
+
questionIndexes?: number[];
|
24
26
|
};
|
25
27
|
|
26
28
|
@customElement('vouch-embed')
|
27
29
|
class Embed extends LitElement {
|
28
30
|
private _mediaPlayerRef: Ref<MediaPlayer> = createRef();
|
29
31
|
|
30
|
-
@property({ type: Object
|
32
|
+
@property({ type: Object }) data: EmbedProps['data'];
|
31
33
|
@property({ type: String }) vouchId: EmbedProps['vouchId'];
|
32
34
|
@property({ type: String }) templateId: EmbedProps['templateId'];
|
35
|
+
@property({ type: Array }) questionIndexes: EmbedProps['questionIndexes'];
|
33
36
|
|
34
37
|
@property({ type: String }) env: EmbedProps['env'] = 'prod';
|
35
38
|
@property({ type: String }) apiKey: EmbedProps['apiKey'] = '';
|
@@ -149,6 +152,10 @@ class Embed extends LitElement {
|
|
149
152
|
return this._mediaPlayerRef.value?.scenes ?? [];
|
150
153
|
}
|
151
154
|
|
155
|
+
get sceneConfig(): Scenes | null {
|
156
|
+
return this._mediaPlayerRef.value?.sceneConfig ?? null;
|
157
|
+
}
|
158
|
+
|
152
159
|
get videoState() {
|
153
160
|
return this._mediaPlayerRef.value?.videoState;
|
154
161
|
}
|
File without changes
|
File without changes
|
File without changes
|