@vouchfor/embeds 0.0.0-experiment.899f364 → 0.0.0-experiment.8a05fac

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vouchfor/embeds",
3
- "version": "0.0.0-experiment.899f364",
3
+ "version": "0.0.0-experiment.8a05fac",
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.899f364",
39
+ "@vouchfor/media-player": "0.0.0-experiment.8a05fac",
40
40
  "uuid": "^9.0.1"
41
41
  },
42
42
  "peerDependencies": {
@@ -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,8 @@ import type { ReactiveController, ReactiveControllerHost } from 'lit';
6
7
 
7
8
  import { getEnvUrls } from '~/utils/env';
8
9
 
9
- const STREAMED_THROTTLE = 10000;
10
+ // In seconds due to checking against node.currentTime
11
+ const STREAMED_THROTTLE = 10;
10
12
 
11
13
  type EmbedHost = ReactiveControllerHost & Embed;
12
14
 
@@ -37,7 +39,7 @@ class TrackingController implements ReactiveController {
37
39
  private _hasLoaded: BooleanMap = {};
38
40
  private _answersViewed: BooleanMap = {};
39
41
  private _streamedTime: TimeMap = {};
40
- private _streamedPrevTimestamp: TimeMap = {};
42
+ private _streamLatestTime: TimeMap = {};
41
43
 
42
44
  constructor(host: EmbedHost) {
43
45
  this.host = host;
@@ -132,22 +134,24 @@ class TrackingController implements ReactiveController {
132
134
  const { publicApiUrl } = getEnvUrls(this.host.env);
133
135
  const { client, tab, request, visitor } = this._getUids();
134
136
 
135
- if (this.host.enableTracking) {
136
- navigator.sendBeacon(
137
- `${publicApiUrl}/api/events`,
138
- JSON.stringify({
139
- event,
140
- payload,
141
- context: {
142
- 'x-uid-client': client,
143
- 'x-uid-tab': tab,
144
- 'x-uid-request': request,
145
- 'x-uid-visitor': visitor,
146
- 'x-reporting-metadata': this._getReportingMetadata()
147
- }
148
- })
149
- );
137
+ if (this.host.disableTracking) {
138
+ return;
150
139
  }
140
+
141
+ navigator.sendBeacon(
142
+ `${publicApiUrl}/api/events`,
143
+ JSON.stringify({
144
+ event,
145
+ payload,
146
+ context: {
147
+ 'x-uid-client': client,
148
+ 'x-uid-tab': tab,
149
+ 'x-uid-request': request,
150
+ 'x-uid-visitor': visitor,
151
+ 'x-reporting-metadata': this._getReportingMetadata()
152
+ }
153
+ })
154
+ );
151
155
  };
152
156
 
153
157
  private _handleVouchLoaded = ({ detail: vouchId }: CustomEvent<string>) => {
@@ -181,31 +185,33 @@ class TrackingController implements ReactiveController {
181
185
  }
182
186
  };
183
187
 
184
- private _handleVideoPlay = ({ detail: { id, node } }: CustomEvent<VideoEventDetail>) => {
188
+ private _handleVideoPlay = ({ detail: { id, key, node } }: CustomEvent<VideoEventDetail>) => {
185
189
  const vouchId = this._findVouchId();
186
190
 
187
191
  if (!vouchId) {
188
192
  return;
189
193
  }
194
+
190
195
  // Only increment play count once per session
191
- if (!this._answersViewed[id]) {
196
+ if (!this._answersViewed[key]) {
192
197
  this._sendTrackingEvent('VOUCH_RESPONSE_VIEWED', {
193
198
  vouchId,
194
199
  answerId: id
195
200
  });
196
- this._answersViewed[id] = true;
201
+ this._answersViewed[key] = true;
197
202
  }
198
- this._streamedTime[id] = node.currentTime;
199
- this._streamedPrevTimestamp[id] = Date.now();
203
+
204
+ this._streamedTime[key] = node.currentTime;
205
+ this._streamLatestTime[key] = node.currentTime;
200
206
  };
201
207
 
202
- private _handleVideoTimeUpdate = ({ detail: { id, node } }: CustomEvent<VideoEventDetail>) => {
208
+ private _handleVideoTimeUpdate = ({ detail: { id, key, node } }: CustomEvent<VideoEventDetail>) => {
203
209
  const vouchId = this._findVouchId();
204
210
 
205
211
  if (!vouchId) {
206
212
  return;
207
213
  }
208
- const currentTimestamp = Date.now();
214
+
209
215
  if (
210
216
  node.currentTime &&
211
217
  !node.paused &&
@@ -213,20 +219,23 @@ class TrackingController implements ReactiveController {
213
219
  // Only fire the video seeked event when this video is the active one
214
220
  id === this.host.scene?.video?.id &&
215
221
  // Throttle the frequency that we send streamed events while playing
216
- currentTimestamp - this._streamedPrevTimestamp[id] > STREAMED_THROTTLE
222
+ node.currentTime - this._streamedTime[key] > STREAMED_THROTTLE
217
223
  ) {
218
224
  this._sendTrackingEvent('VIDEO_STREAMED', {
219
225
  vouchId,
220
226
  answerId: id,
221
- streamStart: this._streamedTime[id],
227
+ streamStart: this._streamedTime[key],
222
228
  streamEnd: node.currentTime
223
229
  });
224
- this._streamedTime[id] = node.currentTime;
225
- this._streamedPrevTimestamp[id] = currentTimestamp;
230
+ this._streamedTime[key] = node.currentTime;
231
+ }
232
+
233
+ if (!this.host.paused) {
234
+ this._streamLatestTime[key] = node.currentTime;
226
235
  }
227
236
  };
228
237
 
229
- private _handleVideoPause = ({ detail: { id, node } }: CustomEvent<VideoEventDetail>) => {
238
+ private _handleVideoPause = ({ detail: { id, key } }: CustomEvent<VideoEventDetail>) => {
230
239
  const vouchId = this._findVouchId();
231
240
 
232
241
  if (!vouchId) {
@@ -234,19 +243,20 @@ class TrackingController implements ReactiveController {
234
243
  }
235
244
 
236
245
  // Don't send a tracking event if the video pauses when seeking backwards
237
- if (node.currentTime > this._streamedTime[id]) {
246
+ if (this._streamLatestTime[key] > this._streamedTime[key] + 0.5) {
238
247
  // Send a video streamed event any time the video pauses then reset the streamed state
239
248
  // We do this to capture the last bit of time that the video was played between the previous
240
249
  // stream event and the video being paused manually or stopping because it ended
241
250
  this._sendTrackingEvent('VIDEO_STREAMED', {
242
251
  vouchId,
243
252
  answerId: id,
244
- streamStart: this._streamedTime[id],
245
- streamEnd: node.currentTime
253
+ streamStart: this._streamedTime[key],
254
+ streamEnd: this._streamLatestTime[key]
246
255
  });
247
256
  }
248
- delete this._streamedTime[id];
249
- delete this._streamedPrevTimestamp[id];
257
+
258
+ delete this._streamedTime[key];
259
+ delete this._streamLatestTime[key];
250
260
  };
251
261
 
252
262
  hostConnected() {
@@ -17,7 +17,7 @@ import '@vouchfor/media-player';
17
17
  type EmbedProps = Pick<MediaPlayerProps, 'data' | 'aspectRatio' | 'preload' | 'autoplay' | 'controls'> & {
18
18
  env: Environment;
19
19
  apiKey: string;
20
- enableTracking?: boolean;
20
+ disableTracking?: boolean;
21
21
  trackingSource?: string;
22
22
  vouchId?: string;
23
23
  templateId?: string;
@@ -33,7 +33,7 @@ class Embed extends LitElement {
33
33
 
34
34
  @property({ type: String }) env: EmbedProps['env'] = 'prod';
35
35
  @property({ type: String }) apiKey: EmbedProps['apiKey'] = '';
36
- @property({ type: Boolean }) enableTracking: EmbedProps['enableTracking'] = true;
36
+ @property({ type: Boolean }) disableTracking: EmbedProps['disableTracking'] = false;
37
37
  @property({ type: String }) trackingSource: EmbedProps['trackingSource'] = 'embed';
38
38
 
39
39
  @property({ type: Array }) controls: EmbedProps['controls'];
@@ -59,6 +59,7 @@ class Embed extends LitElement {
59
59
  'waiting',
60
60
 
61
61
  'video:loadeddata',
62
+ 'video:seeking',
62
63
  'video:seeked',
63
64
  'video:play',
64
65
  'video:playing',