Ignore firstFullSnapshot once only after initial 'poster' build (#608)
* Encountered a bug where firstFullSnapshot was played twice because timer was immediately started and reached the snapshot before the setTimeout returned * Ignoring a FullSnapshot needs to be a one-time only thing, as otherwise we'll ignore it after scrubbing (restarting play head at a particular time). This is a problem if mutations have altered the player state, and we try to replay those mutations, so we e.g. try to remove an element that has already been removed because we haven't reset the FullSnapshot state * Some `npm run typings` related fixups
This commit is contained in:
@@ -89,8 +89,8 @@ export class Replayer {
|
||||
private imageMap: Map<eventWithTime, HTMLImageElement> = new Map();
|
||||
|
||||
private mirror: Mirror = createMirror();
|
||||
/** The first time the player is playing. */
|
||||
private firstPlayedEvent: eventWithTime | null = null;
|
||||
|
||||
private firstFullSnapshot: eventWithTime | true | null = null;
|
||||
|
||||
private newDocumentQueue: addedNodeMutation[] = [];
|
||||
|
||||
@@ -145,7 +145,7 @@ export class Replayer {
|
||||
}
|
||||
});
|
||||
this.emitter.on(ReplayerEvents.PlayBack, () => {
|
||||
this.firstPlayedEvent = null;
|
||||
this.firstFullSnapshot = null;
|
||||
this.mirror.reset();
|
||||
});
|
||||
|
||||
@@ -207,10 +207,11 @@ export class Replayer {
|
||||
if (firstFullsnapshot) {
|
||||
setTimeout(() => {
|
||||
// when something has been played, there is no need to rebuild poster
|
||||
if (this.firstPlayedEvent) {
|
||||
if (this.firstFullSnapshot) {
|
||||
// true if any other fullSnapshot has been executed by Timer already
|
||||
return;
|
||||
}
|
||||
this.firstPlayedEvent = firstFullsnapshot;
|
||||
this.firstFullSnapshot = firstFullsnapshot;
|
||||
this.rebuildFullSnapshot(
|
||||
firstFullsnapshot as fullSnapshotEvent & { timestamp: number },
|
||||
);
|
||||
@@ -429,9 +430,15 @@ export class Replayer {
|
||||
break;
|
||||
case EventType.FullSnapshot:
|
||||
castFn = () => {
|
||||
// Don't build a full snapshot during the first play through since we've already built it when the player was mounted.
|
||||
if (this.firstPlayedEvent && this.firstPlayedEvent === event) {
|
||||
return;
|
||||
if (this.firstFullSnapshot) {
|
||||
if (this.firstFullSnapshot === event) {
|
||||
// we've already built this exact FullSnapshot when the player was mounted, and haven't built any other FullSnapshot since
|
||||
this.firstFullSnapshot = true; // forget as we might need to re-execute this FullSnapshot later e.g. to rebuild after scrubbing
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Timer (requestAnimationFrame) can be faster than setTimeout(..., 1)
|
||||
this.firstFullSnapshot = true;
|
||||
}
|
||||
this.rebuildFullSnapshot(event, isSync);
|
||||
this.iframe.contentWindow!.scrollTo(event.data.initialOffset);
|
||||
|
||||
2
typings/replay/index.d.ts
vendored
2
typings/replay/index.d.ts
vendored
@@ -20,7 +20,7 @@ export declare class Replayer {
|
||||
private elementStateMap;
|
||||
private imageMap;
|
||||
private mirror;
|
||||
private firstPlayedEvent;
|
||||
private firstFullSnapshot;
|
||||
private newDocumentQueue;
|
||||
constructor(events: Array<eventWithTime | string>, config?: Partial<playerConfig>);
|
||||
on(event: string, handler: Handler): this;
|
||||
|
||||
Reference in New Issue
Block a user