refactoring(player): separating Screen and MessageManager; renamings

This commit is contained in:
Alex Kaminskii 2022-11-22 18:59:55 +01:00
parent af6fd085e2
commit daf35a2dfa
52 changed files with 91 additions and 134 deletions

View file

@ -1,9 +1,9 @@
import WebPlayer from './_web/WebPlayer';
import WebPlayer from './web/WebPlayer';
import reduxStore, {update, cleanStore} from './_store';
import type { State as MMState } from './_web/MessageManager'
import type { State as MMState } from './web/MessageManager'
import type { State as PState } from './player/Player'
import type { Store } from './player/types'
import type { Store } from './common/types'
const myStore: Store<PState & MMState> = {

View file

@ -1,15 +1,11 @@
import { applyChange, revertChange } from 'deep-diff';
import { INITIAL_STATE as MM_INITIAL_STATE } from '../_web/MessageManager'
import Player from '../player/Player'
import WebPlayer from '../web/WebPlayer'
const UPDATE = 'player/UPDATE';
const CLEAN = 'player/CLEAN';
const REDUX = 'player/REDUX';
const resetState = {
...MM_INITIAL_STATE,
...Player.INITIAL_STATE,
...WebPlayer.INITIAL_STATE,
initialized: false,
};

View file

@ -1,4 +1,4 @@
// export * from './connector';
// export * from './store';
// export * from './selectors';
// export { default } from './store';
export * from './connector';
export * from './store';
export * from './selectors';
export { default } from './store';

View file

@ -1,4 +1,4 @@
import type { Timed } from '../_web/messages/timed';
import type { Timed } from './types';
export default class ListWalker<T extends Timed> {
private p = 0

View file

@ -1,4 +1,4 @@
import type { Timed } from '../_web/messages/timed';
import type { Timed } from './types';
import ListWalker from './ListWalker'

View file

@ -1,5 +1,4 @@
import { Store } from '../player/types'
import { Store } from './types'
// (not a type)
export default class SimpleSore<G, S=G> implements Store<G, S> {

View file

@ -1,3 +1,6 @@
export interface Timed {
time: number
}
export interface Moveable {
move(time: number): void
@ -18,4 +21,3 @@ export interface Store<G extends Object, S extends Object = G> {
update(state: Partial<S>): void
}

View file

@ -1,7 +1,7 @@
import SimpleStore from './_common/SimpleStore'
import type { Store } from './player/types'
import SimpleStore from './common/SimpleStore'
import type { Store } from './common/types'
import WebPlayer from './_web/WebPlayer'
import WebPlayer from './web/WebPlayer'
type WebState = typeof WebPlayer.INITIAL_STATE //?
type WebPlayerStore = Store<WebState>

View file

@ -1,9 +1,9 @@
export * from './_web/assist/AssistManager';
export * from './_web/assist/LocalStream';
export * from './_web/WebPlayer';
export * from './web/assist/AssistManager';
export * from './web/assist/LocalStream';
export * from './web/WebPlayer';
export * from './create';
export type { MarkedTarget } from './_web/TargetMarker'
export type { MarkedTarget } from './web/TargetMarker'
//export * from './_store';
//export * from './_singletone';
export * from './_store';
export * from './_singletone';

View file

@ -1,4 +1,4 @@
import type { Store, Moveable, Interval } from './types';
import type { Store, Moveable, Interval } from '../common/types';
import * as localStorage from './localStorage';
const fps = 60

View file

@ -1,6 +1,6 @@
import * as typedLocalStorage from './localStorage';
import type { Moveable, Cleanable, Store } from './types';
import type { Moveable, Cleanable, Store } from '../common/types';
import Animator from './Animator';
import type { GetState as AnimatorGetState, SetState as AnimatorSetState } from './Animator';
@ -57,8 +57,6 @@ export default class Player extends Animator {
}
}
/* === TODO: incapsulate in LSCache === */
toggleAutoplay() {
@ -67,14 +65,14 @@ export default class Player extends Animator {
this.pState.update({ autoplay })
}
// Shouldn't it be in the react part as a fully (with localStorage-cache react hook)?
//TODO: move to react part (with localStorage-cache react hook)?
toggleEvents() {
const showEvents = !this.pState.get().showEvents
localStorage.setItem(SHOW_EVENTS_STORAGE_KEY, `${showEvents}`);
this.pState.update({ showEvents })
}
// move to React part?
// TODO: move to React part
toggleSkipToIssue() {
const skipToIssue = !this.pState.get().skipToIssue
localStorage.setItem(SKIP_TO_ISSUE_STORAGE_KEY, `${skipToIssue}`);
@ -107,15 +105,6 @@ export default class Player extends Animator {
}
/* === === */
// TODO: move theese to React hooks
// injectNotes(notes: Note[]) {
// update({ notes })
// }
// filterOutNote(noteId: number) {
// const { notes } = getState()
// update({ notes: notes.filter((note: Note) => note.noteId !== noteId) })
// }
clean() {
this.pause()

View file

@ -1,5 +1,5 @@
import ListWalker from '../_common/ListWalker';
import ListWalkerWithMarks from '../_common/ListWalkerWithMarks';
import ListWalker from '../common/ListWalker';
import ListWalkerWithMarks from '../common/ListWalkerWithMarks';
import type { Message } from './messages'

View file

@ -8,10 +8,8 @@ import Log from 'Types/session/log';
import { toast } from 'react-toastify';
import type { Store } from '../player/types';
import ListWalker from '../_common/ListWalker';
import Screen from './Screen/Screen';
import type { Store } from '../common/types';
import ListWalker from '../common/ListWalker';
import PagesManager from './managers/PagesManager';
import MouseMoveManager from './managers/MouseMoveManager';
@ -24,15 +22,19 @@ import MFileReader from './messages/MFileReader';
import { loadFiles, requestEFSDom, requestEFSDevtools } from './network/loadFiles';
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 Screen, {
INITIAL_STATE as SCREEN_INITIAL_STATE,
State as ScreenState,
} from './Screen/Screen';
import type { InitialLists } from './Lists'
import type { PerformanceChartPoint } from './managers/PerformanceTrackManager';
import type { SkipInterval } from './managers/ActivityManager';
export interface State extends SuperState {
export interface State extends ScreenState {
performanceChartData: PerformanceChartPoint[],
skipIntervals: SkipInterval[],
connType?: string,
@ -73,7 +75,7 @@ const visualChanges = [
"set_viewport_scroll",
]
export default class MessageManager extends Screen {
export default class MessageManager {
static INITIAL_STATE: State = {
...SCREEN_INITIAL_STATE,
...LISTS_INITIAL_STATE,
@ -116,12 +118,12 @@ export default class MessageManager extends Screen {
constructor(
private readonly session: any /*Session*/,
private readonly state: Store<State>,
private readonly state: Store<State>,
private readonly screen: Screen,
initialLists?: Partial<InitialLists>
) {
super();
this.pagesManager = new PagesManager(this, this.session.isMobile)
this.mouseMoveManager = new MouseMoveManager(this)
this.pagesManager = new PagesManager(screen, this.session.isMobile, this)
this.mouseMoveManager = new MouseMoveManager(screen)
this.sessionStart = this.session.startedAt
@ -281,8 +283,8 @@ export default class MessageManager extends Screen {
this.performanceTrackManager = new PerformanceTrackManager()
this.windowNodeCounter = new WindowNodeCounter();
this.pagesManager = new PagesManager(this, this.session.isMobile)
this.mouseMoveManager = new MouseMoveManager(this);
this.pagesManager = new PagesManager(this.screen, this.session.isMobile, this)
this.mouseMoveManager = new MouseMoveManager(this.screen);
this.activityManager = new ActivityManager(this.session.duration.milliseconds);
}
@ -339,14 +341,14 @@ export default class MessageManager extends Screen {
this.pagesManager.moveReady(t).then(() => {
const lastScroll = this.scrollManager.moveGetLast(t, index);
if (!!lastScroll && this.window) {
this.window.scrollTo(lastScroll.x, lastScroll.y);
if (!!lastScroll && this.screen.window) {
this.screen.window.scrollTo(lastScroll.x, lastScroll.y);
}
// Moving mouse and setting :hover classes on ready view
this.mouseMoveManager.move(t);
const lastClick = this.clickManager.moveGetLast(t);
if (!!lastClick && t - lastClick.time < 600) { // happend during last 600ms
this.cursor.click();
this.screen.cursor.click();
}
// After all changes - redraw the marker
//this.marker.redraw();
@ -514,17 +516,17 @@ export default class MessageManager extends Screen {
}
setMessagesLoading(messagesLoading: boolean) {
this.display(!messagesLoading);
this.screen.display(!messagesLoading);
this.state.update({ messagesLoading });
}
setCSSLoading(cssLoading: boolean) {
this.displayFrame(!cssLoading);
this.screen.displayFrame(!cssLoading);
this.state.update({ cssLoading });
}
private setSize({ height, width }: { height: number, width: number }) {
this.scale({ height, width });
this.screen.scale({ height, width });
this.state.update({ width, height });
//this.updateMarketTargets()

View file

@ -1,6 +1,6 @@
import type Screen from './Screen/Screen'
import type { Point } from './Screen/types'
import type { Store } from '../player/types'
import type { Store } from '../common/types'
function getOffset(el: Element, innerWindow: Window) {

View file

@ -1,4 +1,4 @@
import type { Store } from '../player/types'
import type { Store } from '../common/types'
import Player, { State as PlayerState } from '../player/Player'
import MessageManager from './MessageManager'
@ -39,17 +39,13 @@ export default class WebPlayer extends Player {
exceptions: session.errors,
} : {}
// TODO: separate screen from manager
const screen = new MessageManager(session, wpState, initialLists)
super(wpState, screen)
const screen = new Screen()
const messageManager = new MessageManager(session, wpState, screen, initialLists)
super(wpState, messageManager)
this.screen = screen
this.messageManager = screen
// TODO: separate LiveWebPlayer
this.assistManager = new AssistManager(session, this.messageManager, config, wpState)
this.messageManager = messageManager
this.targetMarker = new TargetMarker(this.screen, wpState)
this.inspectorController = new InspectorController(screen)
@ -65,6 +61,8 @@ export default class WebPlayer extends Player {
endTime, // : 0, //TODO: through initialState
})
// TODO: separate LiveWebPlayer
this.assistManager = new AssistManager(session, this.messageManager, config, wpState)
if (live) {
this.assistManager.connect(session.agentToken)
}
@ -123,6 +121,15 @@ export default class WebPlayer extends Player {
}
}
// TODO: restore notes functionality
// injectNotes(notes: Note[]) {
// update({ notes })
// }
// filterOutNote(noteId: number) {
// const { notes } = getState()
// update({ notes: notes.filter((note: Note) => note.noteId !== noteId) })
// }
toggleUserName(name?: string) {
this.screen.cursor.showTag(name)
}

View file

@ -1,4 +1,4 @@
import ListWalker from '../../_common/ListWalker';
import ListWalker from '../../common/ListWalker';
class SkipIntervalCls {

View file

@ -1,9 +1,11 @@
import logger from 'App/logger';
import type Screen from '../../Screen/Screen';
import type MessageManager from '../../MessageManager';
import type { Message, SetNodeScroll, CreateElementNode } from '../../messages';
import ListWalker from '../../../_common/ListWalker';
import ListWalker from '../../../common/ListWalker';
import StylesManager, { rewriteNodeStyleSheet } from './StylesManager';
import FocusManager from './FocusManager';
import {
@ -51,12 +53,13 @@ export default class DOMManager extends ListWalker<Message> {
constructor(
private readonly screen: MessageManager,
private readonly screen: Screen,
private readonly isMobile: boolean,
public readonly time: number
public readonly time: number,
mm: MessageManager,
) {
super()
this.stylesManager = new StylesManager(screen)
this.stylesManager = new StylesManager(screen, mm)
}
append(m: Message): void {

View file

@ -1,7 +1,7 @@
import logger from 'App/logger';
import type { SetNodeFocus } from '../../messages';
import type { VElement } from './VirtualDOM';
import ListWalker from '../../../_common/ListWalker';
import ListWalker from '../../../common/ListWalker';
const FOCUS_CLASS = "-openreplay-focus"

View file

@ -1,11 +1,9 @@
import type MessageManager from '../../MessageManager';
import type Screen from '../../Screen/Screen';
import type MessageManager from '../../MessageManager'
import type { CssInsertRule, CssDeleteRule } from '../../messages';
type CSSRuleMessage = CssInsertRule | CssDeleteRule;
import ListWalker from '../../../_common/ListWalker';
const HOVER_CN = "-openreplay-hover";
const HOVER_SELECTOR = `.${HOVER_CN}`;
@ -21,17 +19,14 @@ export function rewriteNodeStyleSheet(doc: Document, node: HTMLLinkElement | HTM
}
}
export default class StylesManager extends ListWalker<CSSRuleMessage> {
export default class StylesManager {
private linkLoadingCount: number = 0;
private linkLoadPromises: Array<Promise<void>> = [];
private skipCSSLinks: Array<string> = []; // should be common for all pages
constructor(private readonly screen: MessageManager) {
super();
}
constructor(private readonly screen: Screen, private readonly mm: MessageManager) {}
reset():void {
super.reset();
this.linkLoadingCount = 0;
this.linkLoadPromises = [];
@ -43,7 +38,7 @@ export default class StylesManager extends ListWalker<CSSRuleMessage> {
const promise = new Promise<void>((resolve) => {
if (this.skipCSSLinks.includes(value)) resolve();
this.linkLoadingCount++;
this.screen.setCSSLoading(true);
this.mm.setCSSLoading(true);
const addSkipAndResolve = () => {
this.skipCSSLinks.push(value); // watch out
resolve()
@ -62,44 +57,13 @@ export default class StylesManager extends ListWalker<CSSRuleMessage> {
clearTimeout(timeoutId);
this.linkLoadingCount--;
if (this.linkLoadingCount === 0) {
this.screen.setCSSLoading(false);
this.mm.setCSSLoading(false);
}
});
this.linkLoadPromises.push(promise);
}
private manageRule = (msg: CSSRuleMessage):void => {
// if (msg.tp === "css_insert_rule") {
// let styleSheet = this.#screen.document.styleSheets[ msg.stylesheetID ];
// if (!styleSheet) {
// logger.log("No stylesheet with corresponding ID found: ", msg)
// styleSheet = this.#screen.document.styleSheets[0];
// if (!styleSheet) {
// return;
// }
// }
// try {
// styleSheet.insertRule(msg.rule, msg.index);
// } catch (e) {
// logger.log(e, msg)
// //const index = Math.min(msg.index, styleSheet.cssRules.length);
// styleSheet.insertRule(msg.rule, styleSheet.cssRules.length);
// //styleSheet.ownerNode.innerHTML += msg.rule;
// }
// }
// if (msg.tp === "css_delete_rule") {
// // console.warn('Warning: STYLESHEET_DELETE_RULE msg')
// const styleSheet = this.#screen.document.styleSheets[msg.stylesheetID];
// if (!styleSheet) {
// logger.log("No stylesheet with corresponding ID found: ", msg)
// return;
// }
// styleSheet.deleteRule(msg.index);
// }
}
moveReady(t: number): Promise<void> {
moveReady(t: number): Promise<void[]> {
return Promise.all(this.linkLoadPromises)
.then(() => this.moveApply(t, this.manageRule));
}
}

View file

@ -2,7 +2,7 @@ import type Screen from '../Screen/Screen'
import type { Point } from '../Screen/types'
import type { MouseMove } from '../messages'
import ListWalker from '../../_common/ListWalker'
import ListWalker from '../../common/ListWalker'
const HOVER_CLASS = "-openreplay-hover";
const HOVER_CLASS_DEPR = "-asayer-hover";

View file

@ -1,28 +1,23 @@
import type Screen from '../Screen/Screen';
import type { Message } from '../messages';
import type MessageManager from '../MessageManager';
import ListWalker from '../../_common/ListWalker';
import ListWalker from '../../common/ListWalker';
import DOMManager from './DOM/DOMManager';
export default class PagesManager extends ListWalker<DOMManager> {
private currentPage: DOMManager | null = null
private isMobile: boolean;
private screen: Screen;
constructor(screen: Screen, isMobile: boolean) {
super()
this.screen = screen
this.isMobile = isMobile
}
constructor(private screen: Screen, private isMobile: boolean, private mm: MessageManager) { super() }
/*
Assumed that messages added in a correct time sequence.
*/
appendMessage(m: Message): void {
if (m.tp === "create_document") {
super.append(new DOMManager(this.screen, this.isMobile, m.time))
super.append(new DOMManager(this.screen, this.isMobile, m.time, this.mm))
}
if (this.last === null) {
// Log wrong

View file

@ -1,6 +1,6 @@
import type { PerformanceTrack, SetPageVisibility } from '../messages';
import ListWalker from '../../_common/ListWalker';
import ListWalker from '../../common/ListWalker';
export type PerformanceChartPoint = {
time: number,