@vouchfor/embeds 0.0.0-experiment.a913709 → 0.0.0-experiment.ab40ec5
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/components/Embed/controllers/fetcher.d.ts +0 -7
- package/dist/es/components/Embed/controllers/tracking.d.ts +2 -0
- package/dist/es/components/Embed/index.d.ts +9 -6
- package/dist/es/embeds.js +898 -610
- package/dist/es/embeds.js.map +1 -1
- package/dist/es/utils/env.d.ts +5 -11
- package/dist/iife/embeds.iife.js +310 -366
- package/dist/iife/embeds.iife.js.map +1 -1
- package/package.json +6 -6
- package/src/components/Embed/Embed.stories.ts +7 -20
- package/src/components/Embed/controllers/fetcher.ts +63 -45
- package/src/components/Embed/controllers/tracking.ts +74 -29
- package/src/components/Embed/index.ts +12 -18
- package/src/utils/env.ts +18 -32
- package/dist/es/components/Embed/controllers/event-forwarder.d.ts +0 -14
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.ab40ec5",
|
4
4
|
"license": "MIT",
|
5
5
|
"author": "Aaron Williams",
|
6
6
|
"main": "dist/es/embeds.js",
|
@@ -26,7 +26,7 @@
|
|
26
26
|
"lint:staged": "lint-staged",
|
27
27
|
"prepublishOnly": "yarn build",
|
28
28
|
"size": "size-limit",
|
29
|
-
"storybook": "yarn prebuild && storybook dev -p
|
29
|
+
"storybook": "yarn prebuild && storybook dev -p 6007",
|
30
30
|
"prebuild": "yarn build:deps && yarn generate:manifest",
|
31
31
|
"test": "true"
|
32
32
|
},
|
@@ -35,12 +35,12 @@
|
|
35
35
|
"**/*.{md,json,yml}": "prettier --write"
|
36
36
|
},
|
37
37
|
"dependencies": {
|
38
|
-
"@lit/task": "1.0.0",
|
39
|
-
"@vouchfor/media-player": "0.0.0-experiment.
|
38
|
+
"@lit/task": "^1.0.0",
|
39
|
+
"@vouchfor/media-player": "0.0.0-experiment.ab40ec5",
|
40
40
|
"uuid": "^9.0.1"
|
41
41
|
},
|
42
42
|
"peerDependencies": {
|
43
|
-
"lit": "^3.0
|
43
|
+
"lit": "^3.1.0"
|
44
44
|
},
|
45
45
|
"devDependencies": {
|
46
46
|
"@esm-bundle/chai": "^4.3.4-fix.0",
|
@@ -62,7 +62,7 @@
|
|
62
62
|
"eslint": "^8.50.0",
|
63
63
|
"eslint-plugin-import": "^2.28.1",
|
64
64
|
"lint-staged": "^14.0.1",
|
65
|
-
"lit": "^
|
65
|
+
"lit": "^3.1.0",
|
66
66
|
"prettier": "^3.0.3",
|
67
67
|
"react": "^18.2.0",
|
68
68
|
"react-dom": "^18.2.0",
|
@@ -10,30 +10,18 @@ type EmbedArgs = EmbedProps & {
|
|
10
10
|
showVouch?: boolean;
|
11
11
|
};
|
12
12
|
|
13
|
-
const _Embed = ({
|
14
|
-
vouchId,
|
15
|
-
templateId,
|
16
|
-
preload,
|
17
|
-
autoplay,
|
18
|
-
env,
|
19
|
-
apiKey,
|
20
|
-
controls,
|
21
|
-
|
22
|
-
resolution,
|
23
|
-
aspectRatio
|
24
|
-
}: EmbedArgs) => {
|
13
|
+
const _Embed = ({ vouchId, templateId, preload, autoplay, env, apiKey, controls, aspectRatio }: EmbedArgs) => {
|
25
14
|
return html`
|
26
15
|
<div style="height: 100vh">
|
27
16
|
<vouch-embed
|
28
17
|
env=${ifDefined(env)}
|
29
18
|
apiKey=${ifDefined(apiKey)}
|
30
|
-
?autoplay=${autoplay}
|
31
19
|
vouchId=${ifDefined(vouchId)}
|
32
20
|
templateId=${ifDefined(templateId)}
|
33
|
-
resolution=${ifDefined(resolution)}
|
34
|
-
aspectRatio=${ifDefined(aspectRatio)}
|
35
|
-
preload=${ifDefined(preload)}
|
36
21
|
.controls=${controls}
|
22
|
+
?autoplay=${autoplay}
|
23
|
+
preload=${ifDefined(preload)}
|
24
|
+
aspectRatio=${ifDefined(aspectRatio)}
|
37
25
|
></vouch-embed>
|
38
26
|
</div>
|
39
27
|
`;
|
@@ -51,11 +39,10 @@ type Story = StoryObj<EmbedArgs>;
|
|
51
39
|
|
52
40
|
const Embed: Story = {
|
53
41
|
args: {
|
54
|
-
env: '
|
42
|
+
env: 'local',
|
55
43
|
apiKey: 'TVik9uTMgE-PD25UTHIS6gyl0hMBWC7AT4dkpdlLBT4VIfDWZJrQiCk6Ak7m1',
|
56
44
|
vouchId: '6JQEIPeStt',
|
57
|
-
templateId: '
|
58
|
-
resolution: 1080,
|
45
|
+
templateId: '357fc118-e179-4171-9446-ff2b8e9d1b29',
|
59
46
|
aspectRatio: 0,
|
60
47
|
preload: 'none',
|
61
48
|
autoplay: false
|
@@ -63,7 +50,7 @@ const Embed: Story = {
|
|
63
50
|
argTypes: {
|
64
51
|
env: {
|
65
52
|
control: 'radio',
|
66
|
-
options: ['
|
53
|
+
options: ['local', 'dev', 'staging', 'prod']
|
67
54
|
},
|
68
55
|
preload: {
|
69
56
|
control: 'radio',
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { Task } from '@lit/task';
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
2
3
|
|
3
4
|
import type { Embed, EmbedProps } from '..';
|
4
|
-
import type { TemplateInstance } from '@vouchfor/canvas-video';
|
5
5
|
import type { ReactiveControllerHost } from 'lit';
|
6
6
|
import type { Environment } from '~/utils/env';
|
7
7
|
|
@@ -21,8 +21,6 @@ class FetcherController {
|
|
21
21
|
host: EmbedHost;
|
22
22
|
|
23
23
|
private _fetching = false;
|
24
|
-
private _vouch: EmbedProps['data'] | null = null;
|
25
|
-
private _template: TemplateInstance | null = null;
|
26
24
|
|
27
25
|
set fetching(value) {
|
28
26
|
if (this._fetching !== value) {
|
@@ -34,51 +32,67 @@ class FetcherController {
|
|
34
32
|
return this._fetching;
|
35
33
|
}
|
36
34
|
|
37
|
-
|
38
|
-
if (this._vouch !== value) {
|
39
|
-
this._vouch = value;
|
40
|
-
this.host.requestUpdate();
|
41
|
-
}
|
42
|
-
}
|
43
|
-
get vouch() {
|
44
|
-
return this._vouch;
|
45
|
-
}
|
46
|
-
|
47
|
-
set template(value) {
|
48
|
-
if (this._template !== value) {
|
49
|
-
this._template = value;
|
50
|
-
this.host.requestUpdate();
|
51
|
-
}
|
52
|
-
}
|
53
|
-
get template() {
|
54
|
-
return this._template;
|
55
|
-
}
|
56
|
-
|
57
|
-
private async getVouch(env: Environment, apiKey: string, vouchId?: string) {
|
35
|
+
private getVouch = async (env: Environment, apiKey: string, vouchId: string) => {
|
58
36
|
const { embedApiUrl } = getEnvUrls(env);
|
59
37
|
|
60
|
-
|
61
|
-
|
38
|
+
const cacheCheck = uuidv4();
|
39
|
+
const res = await fetch(`${embedApiUrl}/vouches/${vouchId}`, {
|
40
|
+
method: 'GET',
|
41
|
+
headers: [
|
42
|
+
['X-Api-Key', apiKey],
|
43
|
+
['X-Cache-Check', cacheCheck]
|
44
|
+
]
|
45
|
+
});
|
46
|
+
|
47
|
+
const vouch = await res.json();
|
48
|
+
this.host.dispatchEvent(new CustomEvent('vouch:loaded', { detail: vouchId }));
|
49
|
+
|
50
|
+
// HACK: we're currently using API Gateway caching on the embed API without any invalidation logic,
|
51
|
+
// so to ensure that the cache stays up to date, whenever we detect a cache hit we trigger another
|
52
|
+
// API call with the `Cache-Control` header which will re-fill the cache
|
53
|
+
const resCacheCheck = res?.headers?.get('X-Cache-Check');
|
54
|
+
if (resCacheCheck && resCacheCheck !== cacheCheck) {
|
55
|
+
fetch(`${embedApiUrl}/vouches/${vouchId}`, {
|
62
56
|
method: 'GET',
|
63
|
-
headers: [
|
64
|
-
|
57
|
+
headers: [
|
58
|
+
['X-Api-Key', apiKey],
|
59
|
+
['Cache-Control', 'max-age=0']
|
60
|
+
]
|
61
|
+
});
|
65
62
|
}
|
66
63
|
|
67
|
-
return
|
68
|
-
}
|
64
|
+
return vouch;
|
65
|
+
};
|
69
66
|
|
70
|
-
private async
|
67
|
+
private getTemplate = async (env: Environment, apiKey: string, templateId: string) => {
|
71
68
|
const { embedApiUrl } = getEnvUrls(env);
|
72
69
|
|
73
|
-
|
74
|
-
|
70
|
+
const cacheCheck = uuidv4();
|
71
|
+
const res = await fetch(`${embedApiUrl}/templates/${templateId}`, {
|
72
|
+
method: 'GET',
|
73
|
+
headers: [
|
74
|
+
['X-Api-Key', apiKey],
|
75
|
+
['X-Cache-Check', cacheCheck]
|
76
|
+
]
|
77
|
+
});
|
78
|
+
const template = await res.json();
|
79
|
+
|
80
|
+
// HACK: we're currently using API Gateway caching on the embed API without any invalidation logic,
|
81
|
+
// so to ensure that the cache stays up to date, whenever we detect a cache hit we trigger another
|
82
|
+
// API call with the `Cache-Control` header which will re-fill the cache
|
83
|
+
const resCacheCheck = res?.headers?.get('X-Cache-Check');
|
84
|
+
if (resCacheCheck && resCacheCheck !== cacheCheck) {
|
85
|
+
fetch(`${embedApiUrl}/templates/${templateId}`, {
|
75
86
|
method: 'GET',
|
76
|
-
headers: [
|
77
|
-
|
87
|
+
headers: [
|
88
|
+
['X-Api-Key', apiKey],
|
89
|
+
['Cache-Control', 'max-age=0']
|
90
|
+
]
|
91
|
+
});
|
78
92
|
}
|
79
93
|
|
80
|
-
return
|
81
|
-
}
|
94
|
+
return template;
|
95
|
+
};
|
82
96
|
|
83
97
|
constructor(host: EmbedHost) {
|
84
98
|
this.host = host;
|
@@ -86,22 +100,26 @@ class FetcherController {
|
|
86
100
|
this.host,
|
87
101
|
async ([env, apiKey, data, vouchId, templateId]: TaskDeps) => {
|
88
102
|
try {
|
89
|
-
|
90
|
-
|
103
|
+
host.vouch = undefined;
|
104
|
+
host.template = undefined;
|
91
105
|
|
92
106
|
if (data) {
|
93
|
-
|
94
|
-
|
95
|
-
|
107
|
+
let template;
|
108
|
+
if (templateId) {
|
109
|
+
this.fetching = true;
|
110
|
+
template = await this.getTemplate(env, apiKey, templateId);
|
111
|
+
}
|
112
|
+
host.vouch = data;
|
113
|
+
host.template = template ?? data?.settings?.template?.instance;
|
96
114
|
} else if (vouchId) {
|
97
115
|
this.fetching = true;
|
98
116
|
|
99
117
|
const [vouch, template] = await Promise.all([
|
100
118
|
this.getVouch(env, apiKey, vouchId),
|
101
|
-
this.getTemplate(env, apiKey, templateId)
|
119
|
+
templateId ? this.getTemplate(env, apiKey, templateId) : null
|
102
120
|
]);
|
103
|
-
|
104
|
-
|
121
|
+
host.vouch = vouch;
|
122
|
+
host.template = template ?? vouch?.settings?.template?.instance;
|
105
123
|
}
|
106
124
|
} finally {
|
107
125
|
this.fetching = false;
|
@@ -1,3 +1,4 @@
|
|
1
|
+
/* eslint-disable max-lines */
|
1
2
|
import { v4 as uuidv4 } from 'uuid';
|
2
3
|
|
3
4
|
import type { Embed } from '..';
|
@@ -6,7 +7,7 @@ import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
6
7
|
|
7
8
|
import { getEnvUrls } from '~/utils/env';
|
8
9
|
|
9
|
-
const STREAMED_THROTTLE =
|
10
|
+
const STREAMED_THROTTLE = 10000;
|
10
11
|
|
11
12
|
type EmbedHost = ReactiveControllerHost & Embed;
|
12
13
|
|
@@ -37,6 +38,7 @@ class TrackingController implements ReactiveController {
|
|
37
38
|
private _hasLoaded: BooleanMap = {};
|
38
39
|
private _answersViewed: BooleanMap = {};
|
39
40
|
private _streamedTime: TimeMap = {};
|
41
|
+
private _streamLatestTime: TimeMap = {};
|
40
42
|
private _streamedPrevTimestamp: TimeMap = {};
|
41
43
|
|
42
44
|
constructor(host: EmbedHost) {
|
@@ -45,11 +47,11 @@ class TrackingController implements ReactiveController {
|
|
45
47
|
}
|
46
48
|
|
47
49
|
private _findVouchId() {
|
48
|
-
if (this.host.
|
49
|
-
if ('uuid' in this.host.
|
50
|
-
return this.host.
|
50
|
+
if (this.host.vouch) {
|
51
|
+
if ('uuid' in this.host.vouch) {
|
52
|
+
return this.host.vouch.uuid;
|
51
53
|
}
|
52
|
-
return this.host.
|
54
|
+
return this.host.vouch.id;
|
53
55
|
}
|
54
56
|
}
|
55
57
|
|
@@ -116,7 +118,7 @@ class TrackingController implements ReactiveController {
|
|
116
118
|
});
|
117
119
|
|
118
120
|
return {
|
119
|
-
source:
|
121
|
+
source: this.host.trackingSource,
|
120
122
|
time: new Date(),
|
121
123
|
region,
|
122
124
|
country,
|
@@ -132,7 +134,10 @@ class TrackingController implements ReactiveController {
|
|
132
134
|
const { publicApiUrl } = getEnvUrls(this.host.env);
|
133
135
|
const { client, tab, request, visitor } = this._getUids();
|
134
136
|
|
135
|
-
|
137
|
+
if (this.host.disableTracking) {
|
138
|
+
return;
|
139
|
+
}
|
140
|
+
|
136
141
|
navigator.sendBeacon(
|
137
142
|
`${publicApiUrl}/api/events`,
|
138
143
|
JSON.stringify({
|
@@ -180,63 +185,101 @@ class TrackingController implements ReactiveController {
|
|
180
185
|
}
|
181
186
|
};
|
182
187
|
|
183
|
-
private _handleVideoPlay = ({ detail: { id, node } }: CustomEvent<VideoEventDetail>) => {
|
188
|
+
private _handleVideoPlay = ({ detail: { id, key, node } }: CustomEvent<VideoEventDetail>) => {
|
184
189
|
const vouchId = this._findVouchId();
|
190
|
+
|
185
191
|
if (!vouchId) {
|
186
192
|
return;
|
187
193
|
}
|
194
|
+
|
188
195
|
// Only increment play count once per session
|
189
|
-
if (!this._answersViewed[
|
196
|
+
if (!this._answersViewed[key]) {
|
190
197
|
this._sendTrackingEvent('VOUCH_RESPONSE_VIEWED', {
|
191
198
|
vouchId,
|
192
199
|
answerId: id
|
193
200
|
});
|
194
|
-
this._answersViewed[
|
201
|
+
this._answersViewed[key] = true;
|
195
202
|
}
|
196
|
-
|
197
|
-
this.
|
203
|
+
|
204
|
+
this._streamedTime[key] = node.currentTime;
|
205
|
+
this._streamLatestTime[key] = node.currentTime;
|
206
|
+
this._streamedPrevTimestamp[key] = Date.now();
|
198
207
|
};
|
199
208
|
|
200
|
-
private
|
209
|
+
private _handleVideoSeeking = ({ detail: { id, key } }: CustomEvent<VideoEventDetail>) => {
|
201
210
|
const vouchId = this._findVouchId();
|
211
|
+
|
202
212
|
if (!vouchId) {
|
203
213
|
return;
|
204
214
|
}
|
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
|
+
};
|
229
|
+
|
230
|
+
private _handleVideoTimeUpdate = ({ detail: { id, key, node } }: CustomEvent<VideoEventDetail>) => {
|
231
|
+
const vouchId = this._findVouchId();
|
232
|
+
|
233
|
+
if (!vouchId) {
|
234
|
+
return;
|
235
|
+
}
|
236
|
+
|
205
237
|
const currentTimestamp = Date.now();
|
206
238
|
if (
|
239
|
+
node.currentTime &&
|
240
|
+
!node.paused &&
|
207
241
|
!this.host.paused &&
|
208
242
|
// Only fire the video seeked event when this video is the active one
|
209
243
|
id === this.host.scene?.video?.id &&
|
210
244
|
// Throttle the frequency that we send streamed events while playing
|
211
|
-
currentTimestamp - this._streamedPrevTimestamp[
|
245
|
+
currentTimestamp - this._streamedPrevTimestamp[key] > STREAMED_THROTTLE
|
212
246
|
) {
|
213
247
|
this._sendTrackingEvent('VIDEO_STREAMED', {
|
214
248
|
vouchId,
|
215
249
|
answerId: id,
|
216
|
-
streamStart: this._streamedTime[
|
250
|
+
streamStart: this._streamedTime[key],
|
217
251
|
streamEnd: node.currentTime
|
218
252
|
});
|
219
|
-
this._streamedTime[
|
220
|
-
this._streamedPrevTimestamp[
|
253
|
+
this._streamedTime[key] = node.currentTime;
|
254
|
+
this._streamedPrevTimestamp[key] = currentTimestamp;
|
221
255
|
}
|
256
|
+
|
257
|
+
this._streamLatestTime[key] = node.currentTime;
|
222
258
|
};
|
223
259
|
|
224
|
-
private _handleVideoPause = ({ detail: { id, node } }: CustomEvent<VideoEventDetail>) => {
|
260
|
+
private _handleVideoPause = ({ detail: { id, key, node } }: CustomEvent<VideoEventDetail>) => {
|
225
261
|
const vouchId = this._findVouchId();
|
262
|
+
|
226
263
|
if (!vouchId) {
|
227
264
|
return;
|
228
265
|
}
|
229
|
-
|
230
|
-
//
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
266
|
+
|
267
|
+
// Don't send a tracking event if the video pauses when seeking backwards
|
268
|
+
if (node.currentTime > this._streamedTime[key]) {
|
269
|
+
// Send a video streamed event any time the video pauses then reset the streamed state
|
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
|
+
});
|
278
|
+
}
|
279
|
+
|
280
|
+
delete this._streamedTime[key];
|
281
|
+
delete this._streamLatestTime[key];
|
282
|
+
delete this._streamedPrevTimestamp[key];
|
240
283
|
};
|
241
284
|
|
242
285
|
hostConnected() {
|
@@ -244,6 +287,7 @@ class TrackingController implements ReactiveController {
|
|
244
287
|
this.host.addEventListener('vouch:loaded', this._handleVouchLoaded);
|
245
288
|
this.host.mediaPlayer?.addEventListener('play', this._handlePlay);
|
246
289
|
this.host.mediaPlayer?.addEventListener('video:play', this._handleVideoPlay);
|
290
|
+
this.host.mediaPlayer?.addEventListener('video:seeking', this._handleVideoSeeking);
|
247
291
|
this.host.mediaPlayer?.addEventListener('video:pause', this._handleVideoPause);
|
248
292
|
this.host.mediaPlayer?.addEventListener('video:timeupdate', this._handleVideoTimeUpdate);
|
249
293
|
});
|
@@ -253,6 +297,7 @@ class TrackingController implements ReactiveController {
|
|
253
297
|
this.host.removeEventListener('vouch:loaded', this._handleVouchLoaded);
|
254
298
|
this.host.mediaPlayer?.removeEventListener('play', this._handlePlay);
|
255
299
|
this.host.mediaPlayer?.removeEventListener('video:play', this._handleVideoPlay);
|
300
|
+
this.host.mediaPlayer?.removeEventListener('video:seeking', this._handleVideoSeeking);
|
256
301
|
this.host.mediaPlayer?.removeEventListener('video:pause', this._handleVideoPause);
|
257
302
|
this.host.mediaPlayer?.removeEventListener('video:timeupdate', this._handleVideoTimeUpdate);
|
258
303
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { html, LitElement } from 'lit';
|
2
|
-
import { customElement, property } from 'lit/decorators.js';
|
2
|
+
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
|
|
@@ -14,12 +14,11 @@ import { TrackingController } from './controllers/tracking';
|
|
14
14
|
|
15
15
|
import '@vouchfor/media-player';
|
16
16
|
|
17
|
-
type EmbedProps = Pick<
|
18
|
-
MediaPlayerProps,
|
19
|
-
'data' | 'resolution' | 'aspectRatio' | 'preload' | 'autoplay' | 'controls'
|
20
|
-
> & {
|
17
|
+
type EmbedProps = Pick<MediaPlayerProps, 'data' | 'aspectRatio' | 'preload' | 'autoplay' | 'controls'> & {
|
21
18
|
env: Environment;
|
22
19
|
apiKey: string;
|
20
|
+
disableTracking?: boolean;
|
21
|
+
trackingSource?: string;
|
23
22
|
vouchId?: string;
|
24
23
|
templateId?: string;
|
25
24
|
};
|
@@ -34,13 +33,13 @@ class Embed extends LitElement {
|
|
34
33
|
|
35
34
|
@property({ type: String }) env: EmbedProps['env'] = 'prod';
|
36
35
|
@property({ type: String }) apiKey: EmbedProps['apiKey'] = '';
|
36
|
+
@property({ type: Boolean }) disableTracking: EmbedProps['disableTracking'] = false;
|
37
|
+
@property({ type: String }) trackingSource: EmbedProps['trackingSource'] = 'embed';
|
37
38
|
|
39
|
+
@property({ type: Array }) controls: EmbedProps['controls'];
|
38
40
|
@property({ type: String }) preload: EmbedProps['preload'] = 'auto';
|
39
41
|
@property({ type: Boolean }) autoplay: EmbedProps['autoplay'] = false;
|
40
|
-
|
41
|
-
@property({ type: Number }) resolution: EmbedProps['resolution'] = 1080;
|
42
42
|
@property({ type: Number }) aspectRatio: EmbedProps['aspectRatio'] = 0;
|
43
|
-
@property({ type: Array }) controls: EmbedProps['controls'];
|
44
43
|
|
45
44
|
private eventController = new EventForwardController(this, [
|
46
45
|
'durationchange',
|
@@ -60,6 +59,7 @@ class Embed extends LitElement {
|
|
60
59
|
'waiting',
|
61
60
|
|
62
61
|
'video:loadeddata',
|
62
|
+
'video:seeking',
|
63
63
|
'video:seeked',
|
64
64
|
'video:play',
|
65
65
|
'video:playing',
|
@@ -74,13 +74,8 @@ class Embed extends LitElement {
|
|
74
74
|
// @ts-ignore
|
75
75
|
private _trackingController = new TrackingController(this);
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
}
|
80
|
-
|
81
|
-
get template(): TemplateInstance | null {
|
82
|
-
return this._fetcherController.template;
|
83
|
-
}
|
77
|
+
@state() vouch: EmbedProps['data'];
|
78
|
+
@state() template: TemplateInstance | undefined;
|
84
79
|
|
85
80
|
get fetching() {
|
86
81
|
return this._fetcherController.fetching;
|
@@ -176,18 +171,17 @@ class Embed extends LitElement {
|
|
176
171
|
|
177
172
|
render() {
|
178
173
|
return html`
|
179
|
-
<vmp-media-player
|
174
|
+
<vmp-new-media-player
|
180
175
|
${ref(this._mediaPlayerRef)}
|
181
176
|
${this.eventController.register()}
|
182
177
|
?autoplay=${this.autoplay}
|
183
178
|
?loading=${this.fetching}
|
184
179
|
.data=${this.vouch}
|
185
180
|
.template=${this.template}
|
186
|
-
resolution=${ifDefined(this.resolution)}
|
187
181
|
aspectRatio=${ifDefined(this.aspectRatio)}
|
188
182
|
preload=${ifDefined(this.preload)}
|
189
183
|
.controls=${this.controls}
|
190
|
-
></vmp-media-player>
|
184
|
+
></vmp-new-media-player>
|
191
185
|
`;
|
192
186
|
}
|
193
187
|
}
|
package/src/utils/env.ts
CHANGED
@@ -1,15 +1,11 @@
|
|
1
|
-
type Environment = 'dev' | 'staging' | 'prod';
|
1
|
+
type Environment = 'local' | 'dev' | 'staging' | 'prod';
|
2
2
|
|
3
3
|
type GetEnvUrlsReturn = {
|
4
|
-
marketingUrl: string;
|
5
4
|
videoUrl: string;
|
6
5
|
publicApiUrl: string;
|
7
6
|
embedApiUrl: string;
|
8
|
-
publicRecorderUrl: string;
|
9
7
|
};
|
10
8
|
|
11
|
-
const marketingUrl = 'https://vouchfor.com';
|
12
|
-
|
13
9
|
const devVideoUrl = 'https://d2rxhdlm2q91uk.cloudfront.net';
|
14
10
|
const stagingVideoUrl = 'https://d1ix11aj5kfygl.cloudfront.net';
|
15
11
|
const prodVideoUrl = 'https://d157jlwnudd93d.cloudfront.net';
|
@@ -18,61 +14,51 @@ const devPublicApiUrl = 'https://bshyfw4h5a.execute-api.ap-southeast-2.amazonaws
|
|
18
14
|
const stagingPublicApiUrl = 'https://gyzw7rpbq3.execute-api.ap-southeast-2.amazonaws.com/staging';
|
19
15
|
const prodPublicApiUrl = 'https://vfcjuim1l3.execute-api.ap-southeast-2.amazonaws.com/prod';
|
20
16
|
|
21
|
-
const
|
22
|
-
const
|
23
|
-
const
|
24
|
-
|
25
|
-
const devPublicRecorderUrl = 'https://dev.vouchfor.com';
|
26
|
-
const stagingPublicRecorderUrl = 'https://staging.vouchfor.com';
|
27
|
-
const prodPublicRecorderUrl = 'https://app.vouchfor.com';
|
17
|
+
const localEmbedApiUrl = 'http://localhost:6060/v2';
|
18
|
+
const devEmbedApiUrl = 'https://embed-dev.vouchfor.com/v2';
|
19
|
+
const stagingEmbedApiUrl = 'https://embed-staging.vouchfor.com/v2';
|
20
|
+
const prodEmbedApiUrl = 'https://embed.vouchfor.com/v2';
|
28
21
|
|
29
22
|
// We are handling the case where env is an unknown string so the ts error is a lie
|
30
23
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
31
24
|
// @ts-ignore
|
32
25
|
function getEnvUrls(env: Environment): GetEnvUrlsReturn {
|
33
|
-
if (!['dev', 'staging', 'prod'].includes(env)) {
|
26
|
+
if (!['local', 'dev', 'staging', 'prod'].includes(env)) {
|
34
27
|
throw new Error(`Unknown environment: ${env}`);
|
35
28
|
}
|
36
29
|
|
30
|
+
if (env === 'local') {
|
31
|
+
return {
|
32
|
+
videoUrl: devVideoUrl,
|
33
|
+
publicApiUrl: devPublicApiUrl,
|
34
|
+
embedApiUrl: localEmbedApiUrl
|
35
|
+
};
|
36
|
+
}
|
37
|
+
|
37
38
|
if (env === 'dev') {
|
38
39
|
return {
|
39
|
-
marketingUrl,
|
40
40
|
videoUrl: devVideoUrl,
|
41
41
|
publicApiUrl: devPublicApiUrl,
|
42
|
-
embedApiUrl: devEmbedApiUrl
|
43
|
-
publicRecorderUrl: devPublicRecorderUrl
|
42
|
+
embedApiUrl: devEmbedApiUrl
|
44
43
|
};
|
45
44
|
}
|
46
45
|
|
47
46
|
if (env === 'staging') {
|
48
47
|
return {
|
49
|
-
marketingUrl,
|
50
48
|
videoUrl: stagingVideoUrl,
|
51
49
|
publicApiUrl: stagingPublicApiUrl,
|
52
|
-
embedApiUrl: stagingEmbedApiUrl
|
53
|
-
publicRecorderUrl: stagingPublicRecorderUrl
|
50
|
+
embedApiUrl: stagingEmbedApiUrl
|
54
51
|
};
|
55
52
|
}
|
56
53
|
|
57
54
|
if (env === 'prod') {
|
58
55
|
return {
|
59
|
-
marketingUrl,
|
60
56
|
videoUrl: prodVideoUrl,
|
61
57
|
publicApiUrl: prodPublicApiUrl,
|
62
|
-
embedApiUrl: prodEmbedApiUrl
|
63
|
-
publicRecorderUrl: prodPublicRecorderUrl
|
58
|
+
embedApiUrl: prodEmbedApiUrl
|
64
59
|
};
|
65
60
|
}
|
66
61
|
}
|
67
62
|
|
68
|
-
export {
|
69
|
-
marketingUrl,
|
70
|
-
devEmbedApiUrl,
|
71
|
-
stagingEmbedApiUrl,
|
72
|
-
prodEmbedApiUrl,
|
73
|
-
devPublicRecorderUrl,
|
74
|
-
stagingPublicRecorderUrl,
|
75
|
-
prodPublicRecorderUrl,
|
76
|
-
getEnvUrls
|
77
|
-
};
|
63
|
+
export { devEmbedApiUrl, stagingEmbedApiUrl, prodEmbedApiUrl, getEnvUrls };
|
78
64
|
export type { Environment };
|
@@ -1,14 +0,0 @@
|
|
1
|
-
import type { Embed } from '..';
|
2
|
-
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
3
|
-
type EmbedHost = ReactiveControllerHost & Embed;
|
4
|
-
declare class EventForwardController implements ReactiveController {
|
5
|
-
host: EmbedHost;
|
6
|
-
private _events;
|
7
|
-
private _cleanup;
|
8
|
-
private _forwardElementRef;
|
9
|
-
constructor(host: EmbedHost, events: string[]);
|
10
|
-
register(): import("lit-html/directive.js").DirectiveResult<typeof import("lit-html/directives/ref.js").RefDirective>;
|
11
|
-
hostConnected(): void;
|
12
|
-
hostDisconnected(): void;
|
13
|
-
}
|
14
|
-
export { EventForwardController };
|