From ba6acb803c929299c579fa68c4addd4dacbd5c1f Mon Sep 17 00:00:00 2001 From: Zane Mayberry Date: Mon, 28 Mar 2022 09:13:34 -0700 Subject: [PATCH] [HIG-2114] add replace events function for use by chunking --- src/replay/index.ts | 12 +++++++++++ src/replay/machine.ts | 40 +++++++++++++++++++++++++++++++++++++ src/replay/timer.ts | 5 +++++ typings/replay/index.d.ts | 1 + typings/replay/machine.d.ts | 5 +++++ 5 files changed, 63 insertions(+) diff --git a/src/replay/index.ts b/src/replay/index.ts index a4056edd..3247a046 100644 --- a/src/replay/index.ts +++ b/src/replay/index.ts @@ -505,6 +505,18 @@ export class Replayer { ); } + public replaceEvents(events: eventWithTime[]) { + for (const event of events) { + if (indicatesTouchDevice(event)) { + this.mouse.classList.add('touch-device'); + break; + } + } + Promise.resolve().then(() => + this.service.send({ type: 'REPLACE_EVENTS', payload: { events } }), + ); + } + public enableInteract() { this.iframe.setAttribute('scrolling', 'auto'); this.iframe.style.pointerEvents = 'auto'; diff --git a/src/replay/machine.ts b/src/replay/machine.ts index 8c5ca33f..f9188774 100644 --- a/src/replay/machine.ts +++ b/src/replay/machine.ts @@ -38,6 +38,12 @@ export type PlayerEvent = event: eventWithTime; }; } + | { + type: 'REPLACE_EVENTS'; + payload: { + events: eventWithTime[]; + }; + } | { type: 'END'; }; @@ -107,6 +113,10 @@ export function createPlayerService( target: 'playing', actions: ['addEvent'], }, + REPLACE_EVENTS: { + target: 'playing', + actions: ['replaceEvents'], + }, }, }, paused: { @@ -127,6 +137,10 @@ export function createPlayerService( target: 'paused', actions: ['addEvent'], }, + REPLACE_EVENTS: { + target: 'paused', + actions: ['replaceEvents'], + }, }, }, live: { @@ -234,6 +248,32 @@ export function createPlayerService( return Date.now(); }, }), + replaceEvents: assign((ctx, machineEvent) => { + const { events: curEvents, timer, baselineTime } = ctx; + if (machineEvent.type === 'REPLACE_EVENTS') { + const { events: newEvents } = machineEvent.payload; + curEvents.length = 0; + const actions: actionWithDelay[] = []; + for (const event of newEvents) { + addDelay(event, baselineTime); + curEvents.push(event); + if (event.timestamp >= baselineTime) { + const castFn = getCastFn(event, false); + actions.push({ + doAction: () => { + castFn(); + }, + delay: event.delay!, + }); + } + } + + if (timer.isActive()) { + timer.replaceActions(actions); + } + } + return { ...ctx, events: curEvents }; + }), addEvent: assign((ctx, machineEvent) => { const { baselineTime, timer, events } = ctx; if (machineEvent.type === 'ADD_EVENT') { diff --git a/src/replay/timer.ts b/src/replay/timer.ts index c64d2c77..c817be37 100644 --- a/src/replay/timer.ts +++ b/src/replay/timer.ts @@ -33,6 +33,11 @@ export class Timer { this.actions = this.actions.concat(actions); } + public replaceActions(actions: actionWithDelay[]) { + this.actions.length = 0; + this.actions.splice(0, 0, ...actions) + } + public start() { this.timeOffset = 0; let lastTimestamp = performance.now(); diff --git a/typings/replay/index.d.ts b/typings/replay/index.d.ts index c8e84bf7..b9a463aa 100644 --- a/typings/replay/index.d.ts +++ b/typings/replay/index.d.ts @@ -37,6 +37,7 @@ export declare class Replayer { resume(timeOffset?: number): void; startLive(baselineTime?: number): void; addEvent(rawEvent: eventWithTime | string): void; + replaceEvents(events: eventWithTime[]): void; enableInteract(): void; disableInteract(): void; private setupDom; diff --git a/typings/replay/machine.d.ts b/typings/replay/machine.d.ts index 3d82c1ec..413e8149 100644 --- a/typings/replay/machine.d.ts +++ b/typings/replay/machine.d.ts @@ -30,6 +30,11 @@ export declare type PlayerEvent = { payload: { event: eventWithTime; }; +} | { + type: 'REPLACE_EVENTS'; + payload: { + event: eventWithTime[]; + }; } | { type: 'END'; };