From 56327fa90906008e820a454dea367effabf311d5 Mon Sep 17 00:00:00 2001 From: Alex Kaminskii Date: Tue, 22 Nov 2022 17:07:14 +0100 Subject: [PATCH] refactor(player): decouple live state from MessageManager --- frontend/app/player/_web/Lists.ts | 2 +- frontend/app/player/_web/MessageManager.ts | 47 +++++++--------------- frontend/app/player/_web/WebPlayer.ts | 21 ++++++++-- 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/frontend/app/player/_web/Lists.ts b/frontend/app/player/_web/Lists.ts index 4eb5de6db..fdf560c93 100644 --- a/frontend/app/player/_web/Lists.ts +++ b/frontend/app/player/_web/Lists.ts @@ -29,7 +29,7 @@ type MarkedListsObject = { } type ListsObject = SimpleListsObject & MarkedListsObject -type InitialLists = { +export type InitialLists = { [key in typeof LIST_NAMES[number]]: any[] } diff --git a/frontend/app/player/_web/MessageManager.ts b/frontend/app/player/_web/MessageManager.ts index 9af0a4b0a..8eeb74f19 100644 --- a/frontend/app/player/_web/MessageManager.ts +++ b/frontend/app/player/_web/MessageManager.ts @@ -27,6 +27,7 @@ import { decryptSessionBytes } from './network/crypto'; import { INITIAL_STATE as SCREEN_INITIAL_STATE, State as SuperState } from './Screen/Screen'; import Lists, { INITIAL_STATE as LISTS_INITIAL_STATE } from './Lists'; +import type { InitialLists } from './Lists' import type { PerformanceChartPoint } from './managers/PerformanceTrackManager'; import type { SkipInterval } from './managers/ActivityManager'; @@ -45,7 +46,6 @@ export interface State extends SuperState { error: boolean, devtoolsLoading: boolean, - liveTimeTravel: boolean, messagesLoading: boolean, cssLoading: boolean, @@ -82,7 +82,6 @@ export default class MessageManager extends Screen { error: false, devtoolsLoading: false, - liveTimeTravel: false, messagesLoading: false, cssLoading: false, get ready() { @@ -118,39 +117,25 @@ export default class MessageManager extends Screen { constructor( private readonly session: any /*Session*/, private readonly state: Store, - config: any, - live: boolean, + initialLists?: Partial ) { super(); this.pagesManager = new PagesManager(this, this.session.isMobile) - this.mouseMoveManager = new MouseMoveManager(this); + this.mouseMoveManager = new MouseMoveManager(this) - this.sessionStart = this.session.startedAt; + this.sessionStart = this.session.startedAt - if (live) { - this.lists = new Lists() - } else { - this.activityManager = new ActivityManager(this.session.duration.milliseconds); - /* == REFACTOR_ME == */ - const eventList = session.events.toJSON(); - // TODO: fix types for events, remove immutable js - eventList.forEach((e: Record) => { - if (e.type === EVENT_TYPES.LOCATION) { //TODO type system - this.locationEventManager.append(e); - } - }) + this.lists = new Lists(initialLists) + initialLists && initialLists.event.forEach((e: Record) => { // TODO: to one of "Moveable" module + if (e.type === EVENT_TYPES.LOCATION) { + this.locationEventManager.append(e); + } + }) - this.lists = new Lists({ - event: eventList, - stack: session.stackEvents.toJSON(), - resource: session.resources.toJSON(), - exceptions: session.errors, - }) + this.activityManager = new ActivityManager(this.session.duration.milliseconds) // only if not-live - /* === */ - this.loadMessages(); - } + this.loadMessages() } private parseAndDistributeMessages(fileReader: MFileReader, onMessage?: (msg: Message) => void) { @@ -264,15 +249,11 @@ export default class MessageManager extends Screen { } } - reloadWithUnprocessedFile() { + reloadWithUnprocessedFile(onSuccess: ()=>void) { const onData = (byteArray: Uint8Array) => { const onMessage = (msg: Message) => { this.lastMessageInFileTime = msg.time } this.parseAndDistributeMessages(new MFileReader(byteArray, this.sessionStart), onMessage) } - const updateState = () => - this.state.update({ - liveTimeTravel: true, - }); // assist will pause and skip messages to prevent timestamp related errors this.reloadMessageManagers() @@ -283,7 +264,7 @@ export default class MessageManager extends Screen { return requestEFSDom(this.session.sessionId) .then(onData) - .then(updateState) + .then(onSuccess) .then(this.onFileReadSuccess) .catch(this.onFileReadFailed) .finally(this.onFileReadFinally) diff --git a/frontend/app/player/_web/WebPlayer.ts b/frontend/app/player/_web/WebPlayer.ts index a2da13d4c..572c9e5b4 100644 --- a/frontend/app/player/_web/WebPlayer.ts +++ b/frontend/app/player/_web/WebPlayer.ts @@ -20,6 +20,7 @@ export default class WebPlayer extends Player { ...ASSIST_INITIAL_STATE, inspectorMode: false, + liveTimeTravel: false, } private readonly screen: Screen @@ -29,9 +30,17 @@ export default class WebPlayer extends Player { assistManager: AssistManager // public so far private targetMarker: TargetMarker - constructor(private wpState: Store, session, config: RTCIceServer[], live: boolean) { + constructor(private wpState: Store, session, config: RTCIceServer[], live: boolean) { + + let initialLists = live ? { + event: session.events.toJSON(), + stack: session.stackEvents.toJSON(), + resource: session.resources.toJSON(), + exceptions: session.errors, + } : {} + // TODO: separate screen from manager - const screen = new MessageManager(session, wpState, config, live) + const screen = new MessageManager(session, wpState, initialLists) super(wpState, screen) this.screen = screen this.messageManager = screen @@ -39,7 +48,7 @@ export default class WebPlayer extends Player { // TODO: separate LiveWebPlayer this.assistManager = new AssistManager(session, this.messageManager, config, wpState) - this.targetMarker = new TargetMarker(this.screen) + this.targetMarker = new TargetMarker(this.screen, wpState) this.inspectorController = new InspectorController(screen) @@ -106,7 +115,11 @@ export default class WebPlayer extends Player { // TODO async toggleTimetravel() { if (!this.wpState.get().liveTimeTravel) { - return await this.messageManager.reloadWithUnprocessedFile() + return await this.messageManager.reloadWithUnprocessedFile(() => + this.wpState.update({ + liveTimeTravel: true, + }) + ) } }