Merge branch 'small-player-refactoring' into dev
This commit is contained in:
commit
1f80cb4e64
16 changed files with 303 additions and 293 deletions
23
frontend/app/player/MessageDistributor/Lists.ts
Normal file
23
frontend/app/player/MessageDistributor/Lists.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import type { Message } from './messages'
|
||||
import ListWalker from './managers/ListWalker';
|
||||
|
||||
export const LIST_NAMES = ["redux", "mobx", "vuex", "ngrx", "graphql", "exceptions", "profiles", "longtasks"] as const;
|
||||
|
||||
export const INITIAL_STATE = {}
|
||||
LIST_NAMES.forEach(name => {
|
||||
INITIAL_STATE[`${name}ListNow`] = []
|
||||
INITIAL_STATE[`${name}List`] = []
|
||||
})
|
||||
|
||||
|
||||
type ListsObject = {
|
||||
[key in typeof LIST_NAMES[number]]: ListWalker<any>
|
||||
}
|
||||
|
||||
export function initLists(): ListsObject {
|
||||
const lists: Partial<ListsObject> = {};
|
||||
for (var i = 0; i < LIST_NAMES.length; i++) {
|
||||
lists[LIST_NAMES[i]] = new ListWalker();
|
||||
}
|
||||
return lists as ListsObject;
|
||||
}
|
||||
|
|
@ -4,8 +4,6 @@ import logger from 'App/logger';
|
|||
import Resource, { TYPES } from 'Types/session/resource'; // MBTODO: player types?
|
||||
import { TYPES as EVENT_TYPES } from 'Types/session/event';
|
||||
import Log from 'Types/session/log';
|
||||
import Profile from 'Types/session/profile';
|
||||
import ReduxAction from 'Types/session/reduxAction';
|
||||
|
||||
import { update } from '../store';
|
||||
import {
|
||||
|
|
@ -18,7 +16,7 @@ import StatedScreen from './StatedScreen/StatedScreen';
|
|||
|
||||
import ListWalker from './managers/ListWalker';
|
||||
import PagesManager from './managers/PagesManager';
|
||||
import MouseManager from './managers/MouseManager';
|
||||
import MouseMoveManager from './managers/MouseMoveManager';
|
||||
|
||||
import PerformanceTrackManager from './managers/PerformanceTrackManager';
|
||||
import WindowNodeCounter from './managers/WindowNodeCounter';
|
||||
|
|
@ -30,16 +28,11 @@ import loadFiles from './network/loadFiles';
|
|||
|
||||
import { INITIAL_STATE as SUPER_INITIAL_STATE, State as SuperState } from './StatedScreen/StatedScreen';
|
||||
import { INITIAL_STATE as ASSIST_INITIAL_STATE, State as AssistState } from './managers/AssistManager';
|
||||
import { INITIAL_STATE as LISTS_INITIAL_STATE , LIST_NAMES, initLists } from './Lists';
|
||||
|
||||
import type { PerformanceChartPoint } from './managers/PerformanceTrackManager';
|
||||
import type { SkipInterval } from './managers/ActivityManager';
|
||||
|
||||
const LIST_NAMES = ["redux", "mobx", "vuex", "ngrx", "graphql", "exceptions", "profiles", "longtasks"] as const;
|
||||
const LISTS_INITIAL_STATE = {};
|
||||
LIST_NAMES.forEach(name => {
|
||||
LISTS_INITIAL_STATE[`${name}ListNow`] = [];
|
||||
LISTS_INITIAL_STATE[`${name}List`] = [];
|
||||
})
|
||||
|
||||
export interface State extends SuperState, AssistState {
|
||||
performanceChartData: PerformanceChartPoint[],
|
||||
|
|
@ -61,18 +54,6 @@ export const INITIAL_STATE: State = {
|
|||
skipIntervals: [],
|
||||
};
|
||||
|
||||
type ListsObject = {
|
||||
[key in typeof LIST_NAMES[number]]: ListWalker<any> //
|
||||
}
|
||||
|
||||
function initLists(): ListsObject {
|
||||
const lists: Partial<ListsObject> = {};
|
||||
for (var i = 0; i < LIST_NAMES.length; i++) {
|
||||
lists[LIST_NAMES[i]] = new ListWalker();
|
||||
}
|
||||
return lists as ListsObject;
|
||||
}
|
||||
|
||||
|
||||
import type {
|
||||
Message,
|
||||
|
|
@ -97,7 +78,7 @@ export default class MessageDistributor extends StatedScreen {
|
|||
|
||||
private readonly resizeManager: ListWalker<SetViewportSize> = new ListWalker([]);
|
||||
private readonly pagesManager: PagesManager;
|
||||
private readonly mouseManager: MouseManager;
|
||||
private readonly mouseMoveManager: MouseMoveManager;
|
||||
private readonly assistManager: AssistManager;
|
||||
|
||||
private readonly scrollManager: ListWalker<SetViewportScroll> = new ListWalker();
|
||||
|
|
@ -114,7 +95,7 @@ export default class MessageDistributor extends StatedScreen {
|
|||
constructor(private readonly session: any /*Session*/, jwt: string, config, live: boolean) {
|
||||
super();
|
||||
this.pagesManager = new PagesManager(this, this.session.isMobile)
|
||||
this.mouseManager = new MouseManager(this);
|
||||
this.mouseMoveManager = new MouseMoveManager(this);
|
||||
this.assistManager = new AssistManager(session, this, config);
|
||||
|
||||
this.sessionStart = this.session.startedAt;
|
||||
|
|
@ -136,11 +117,11 @@ export default class MessageDistributor extends StatedScreen {
|
|||
|
||||
eventList.forEach(e => {
|
||||
if (e.type === EVENT_TYPES.LOCATION) { //TODO type system
|
||||
this.locationEventManager.add(e);
|
||||
this.locationEventManager.append(e);
|
||||
}
|
||||
});
|
||||
this.session.errors.forEach(e => {
|
||||
this.lists.exceptions.add(e);
|
||||
this.lists.exceptions.append(e);
|
||||
});
|
||||
/* === */
|
||||
this.loadMessages();
|
||||
|
|
@ -226,12 +207,12 @@ export default class MessageDistributor extends StatedScreen {
|
|||
move(t: number, index?: number): void {
|
||||
const stateToUpdate: Partial<State> = {};
|
||||
/* == REFACTOR_ME == */
|
||||
const lastLoadedLocationMsg = this.loadedLocationManager.moveToLast(t, index);
|
||||
const lastLoadedLocationMsg = this.loadedLocationManager.moveGetLast(t, index);
|
||||
if (!!lastLoadedLocationMsg) {
|
||||
setListsStartTime(lastLoadedLocationMsg.time)
|
||||
this.navigationStartOffset = lastLoadedLocationMsg.navigationStart - this.sessionStart;
|
||||
}
|
||||
const llEvent = this.locationEventManager.moveToLast(t, index);
|
||||
const llEvent = this.locationEventManager.moveGetLast(t, index);
|
||||
if (!!llEvent) {
|
||||
if (llEvent.domContentLoadedTime != null) {
|
||||
stateToUpdate.domContentLoadedTime = {
|
||||
|
|
@ -250,22 +231,22 @@ export default class MessageDistributor extends StatedScreen {
|
|||
}
|
||||
}
|
||||
/* === */
|
||||
const lastLocationMsg = this.locationManager.moveToLast(t, index);
|
||||
const lastLocationMsg = this.locationManager.moveGetLast(t, index);
|
||||
if (!!lastLocationMsg) {
|
||||
stateToUpdate.location = lastLocationMsg.url;
|
||||
}
|
||||
const lastConnectionInfoMsg = this.connectionInfoManger.moveToLast(t, index);
|
||||
const lastConnectionInfoMsg = this.connectionInfoManger.moveGetLast(t, index);
|
||||
if (!!lastConnectionInfoMsg) {
|
||||
stateToUpdate.connType = lastConnectionInfoMsg.type;
|
||||
stateToUpdate.connBandwidth = lastConnectionInfoMsg.downlink;
|
||||
}
|
||||
const lastPerformanceTrackMessage = this.performanceTrackManager.moveToLast(t, index);
|
||||
const lastPerformanceTrackMessage = this.performanceTrackManager.moveGetLast(t, index);
|
||||
if (!!lastPerformanceTrackMessage) {
|
||||
stateToUpdate.performanceChartTime = lastPerformanceTrackMessage.time;
|
||||
}
|
||||
|
||||
LIST_NAMES.forEach(key => {
|
||||
const lastMsg = this.lists[key].moveToLast(t, key === 'exceptions' ? undefined : index);
|
||||
const lastMsg = this.lists[key].moveGetLast(t, key === 'exceptions' ? undefined : index);
|
||||
if (lastMsg != null) {
|
||||
stateToUpdate[`${key}ListNow`] = this.lists[key].listNow;
|
||||
}
|
||||
|
|
@ -275,19 +256,19 @@ export default class MessageDistributor extends StatedScreen {
|
|||
|
||||
/* Sequence of the managers is important here */
|
||||
// Preparing the size of "screen"
|
||||
const lastResize = this.resizeManager.moveToLast(t, index);
|
||||
const lastResize = this.resizeManager.moveGetLast(t, index);
|
||||
if (!!lastResize) {
|
||||
this.setSize(lastResize)
|
||||
}
|
||||
this.pagesManager.moveReady(t).then(() => {
|
||||
|
||||
const lastScroll = this.scrollManager.moveToLast(t, index);
|
||||
const lastScroll = this.scrollManager.moveGetLast(t, index);
|
||||
if (!!lastScroll && this.window) {
|
||||
this.window.scrollTo(lastScroll.x, lastScroll.y);
|
||||
}
|
||||
// Moving mouse and setting :hover classes on ready view
|
||||
this.mouseManager.move(t);
|
||||
const lastClick = this.clickManager.moveToLast(t);
|
||||
this.mouseMoveManager.move(t);
|
||||
const lastClick = this.clickManager.moveGetLast(t);
|
||||
if (!!lastClick && t - lastClick.time < 600) { // happend during last 600ms
|
||||
this.cursor.click();
|
||||
}
|
||||
|
|
@ -300,7 +281,7 @@ export default class MessageDistributor extends StatedScreen {
|
|||
}
|
||||
}
|
||||
|
||||
_decodeMessage(msg, keys: Array<string>) {
|
||||
private decodeMessage(msg, keys: Array<string>) {
|
||||
const decoded = {};
|
||||
try {
|
||||
keys.forEach(key => {
|
||||
|
|
@ -314,7 +295,7 @@ export default class MessageDistributor extends StatedScreen {
|
|||
}
|
||||
|
||||
/* Binded */
|
||||
distributeMessage = (msg: Message, index: number): void => {
|
||||
distributeMessage(msg: Message, index: number): void {
|
||||
if ([
|
||||
"mouse_move",
|
||||
"mouse_click",
|
||||
|
|
@ -355,74 +336,72 @@ export default class MessageDistributor extends StatedScreen {
|
|||
break;
|
||||
/* */
|
||||
case "set_page_location":
|
||||
this.locationManager.add(msg);
|
||||
this.locationManager.append(msg);
|
||||
if (msg.navigationStart > 0) {
|
||||
this.loadedLocationManager.add(msg);
|
||||
this.loadedLocationManager.append(msg);
|
||||
}
|
||||
break;
|
||||
case "set_viewport_size":
|
||||
this.resizeManager.add(msg);
|
||||
this.resizeManager.append(msg);
|
||||
break;
|
||||
case "mouse_move":
|
||||
this.mouseManager.add(msg);
|
||||
this.mouseMoveManager.append(msg);
|
||||
break;
|
||||
case "mouse_click":
|
||||
this.clickManager.add(msg);
|
||||
this.clickManager.append(msg);
|
||||
break;
|
||||
case "set_viewport_scroll":
|
||||
this.scrollManager.add(msg);
|
||||
this.scrollManager.append(msg);
|
||||
break;
|
||||
case "performance_track":
|
||||
this.performanceTrackManager.add(msg);
|
||||
this.performanceTrackManager.append(msg);
|
||||
break;
|
||||
case "set_page_visibility":
|
||||
this.performanceTrackManager.handleVisibility(msg)
|
||||
break;
|
||||
case "connection_information":
|
||||
this.connectionInfoManger.add(msg);
|
||||
this.connectionInfoManger.append(msg);
|
||||
break;
|
||||
case "o_table":
|
||||
this.decoder.set(msg.key, msg.value);
|
||||
break;
|
||||
case "redux":
|
||||
decoded = this._decodeMessage(msg, ["state", "action"]);
|
||||
decoded = this.decodeMessage(msg, ["state", "action"]);
|
||||
logger.log(decoded)
|
||||
if (decoded != null) {
|
||||
this.lists.redux.add(decoded);
|
||||
this.lists.redux.append(decoded);
|
||||
}
|
||||
break;
|
||||
case "ng_rx":
|
||||
decoded = this._decodeMessage(msg, ["state", "action"]);
|
||||
decoded = this.decodeMessage(msg, ["state", "action"]);
|
||||
logger.log(decoded)
|
||||
if (decoded != null) {
|
||||
this.lists.ngrx.add(decoded);
|
||||
this.lists.ngrx.append(decoded);
|
||||
}
|
||||
break;
|
||||
case "vuex":
|
||||
decoded = this._decodeMessage(msg, ["state", "mutation"]);
|
||||
decoded = this.decodeMessage(msg, ["state", "mutation"]);
|
||||
logger.log(decoded)
|
||||
if (decoded != null) {
|
||||
this.lists.vuex.add(decoded);
|
||||
this.lists.vuex.append(decoded);
|
||||
}
|
||||
break;
|
||||
case "mob_x":
|
||||
decoded = this._decodeMessage(msg, ["payload"]);
|
||||
decoded = this.decodeMessage(msg, ["payload"]);
|
||||
logger.log(decoded)
|
||||
|
||||
if (decoded != null) {
|
||||
this.lists.mobx.add(decoded);
|
||||
this.lists.mobx.append(decoded);
|
||||
}
|
||||
break;
|
||||
case "graph_ql":
|
||||
// @ts-ignore some hack? TODO: remove
|
||||
msg.duration = 0;
|
||||
this.lists.graphql.add(msg);
|
||||
this.lists.graphql.append(msg);
|
||||
break;
|
||||
case "profiler":
|
||||
this.lists.profiles.add(msg);
|
||||
this.lists.profiles.append(msg);
|
||||
break;
|
||||
case "long_task":
|
||||
this.lists.longtasks.add({
|
||||
this.lists.longtasks.append({
|
||||
...msg,
|
||||
time: msg.timestamp - this.sessionStart,
|
||||
});
|
||||
|
|
@ -447,7 +426,7 @@ export default class MessageDistributor extends StatedScreen {
|
|||
this.performanceTrackManager.setCurrentNodesCount(this.windowNodeCounter.count);
|
||||
break;
|
||||
}
|
||||
this.pagesManager.add(msg);
|
||||
this.pagesManager.append(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -457,7 +436,7 @@ export default class MessageDistributor extends StatedScreen {
|
|||
}
|
||||
|
||||
getFirstMessageTime(): number {
|
||||
return 0; //this.pagesManager.minTime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: clean managers?
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@ export default class ActivityManager extends ListWalker<SkipInterval> {
|
|||
|
||||
updateAcctivity(time: number) {
|
||||
if (time - this.lastActivity >= this.minInterval) {
|
||||
this.add(new SkipIntervalCls(this.lastActivity, time));
|
||||
this.append(new SkipIntervalCls(this.lastActivity, time));
|
||||
}
|
||||
this.lastActivity = time;
|
||||
}
|
||||
|
||||
end() {
|
||||
if (this.endTime - this.lastActivity >= this.minInterval) {
|
||||
this.add(new SkipIntervalCls(this.lastActivity, this.endTime));
|
||||
this.append(new SkipIntervalCls(this.lastActivity, this.endTime));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,12 +40,12 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
if (!this.nodeScrollManagers[ m.id ]) {
|
||||
this.nodeScrollManagers[ m.id ] = new ListWalker();
|
||||
}
|
||||
this.nodeScrollManagers[ m.id ].add(m);
|
||||
this.nodeScrollManagers[ m.id ].append(m);
|
||||
return;
|
||||
//case "css_insert_rule": // || //set_css_data ???
|
||||
//case "css_delete_rule":
|
||||
// (m.tp === "set_node_attribute" && this.isLink[ m.id ] && m.key === "href")) {
|
||||
// this.stylesManager.add(m);
|
||||
// this.stylesManager.append(m);
|
||||
// return;
|
||||
default:
|
||||
if (m.tp === "create_element_node") {
|
||||
|
|
@ -62,7 +62,7 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
logger.log("Ignorring message: ", m)
|
||||
return; // Ignoring...
|
||||
}
|
||||
super.add(m);
|
||||
super.append(m);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -299,7 +299,7 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
moveReady(t: number): Promise<void> {
|
||||
this.moveApply(t, this.applyMessage); // This function autoresets pointer if necessary (better name?)
|
||||
this.nodeScrollManagers.forEach(manager => {
|
||||
const msg = manager.moveToLast(t); // TODO: reset (?)
|
||||
const msg = manager.moveGetLast(t); // TODO: reset (?)
|
||||
|
||||
if (!!msg && !!this.nl[msg.id]) {
|
||||
const node = this.nl[msg.id] as HTMLElement;
|
||||
|
|
|
|||
|
|
@ -1,26 +1,19 @@
|
|||
import type { Timed } from '../messages/timed';
|
||||
|
||||
export default class ListWalker<T extends Timed> {
|
||||
// Optimisation: #prop compiles to method that costs mor than strict property call.
|
||||
_p = 0;
|
||||
_list: Array<T>;
|
||||
constructor(list: Array<T> = []) {
|
||||
this._list = list;
|
||||
}
|
||||
|
||||
add(m: T): void {
|
||||
return this.append(m);
|
||||
}
|
||||
private p = 0
|
||||
constructor(private _list: Array<T> = []) {}
|
||||
|
||||
append(m: T): void {
|
||||
if (this.length > 0 && this.last && m.time < this.last.time) {
|
||||
console.error("Trying to append message with the less time then the list tail: ", m);
|
||||
console.error("Trying to append message with the less time then the list tail: ", m)
|
||||
return
|
||||
}
|
||||
this._list.push(m);
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this._p = 0;
|
||||
this.p = 0
|
||||
}
|
||||
|
||||
sort(comparator): void {
|
||||
|
|
@ -32,14 +25,6 @@ export default class ListWalker<T extends Timed> {
|
|||
this._list.forEach(f);
|
||||
}
|
||||
|
||||
// set pointer(p: number): void {
|
||||
// if (p >= this.length || p < 0) {
|
||||
// // console.error("Trying to set wrong pointer")
|
||||
// return;
|
||||
// }
|
||||
// this._p = p;
|
||||
// }
|
||||
|
||||
get last(): T | null {
|
||||
if (this._list.length === 0) {
|
||||
return null;
|
||||
|
|
@ -48,17 +33,17 @@ export default class ListWalker<T extends Timed> {
|
|||
}
|
||||
|
||||
get current(): T | null {
|
||||
if (this._p === 0) {
|
||||
if (this.p === 0) {
|
||||
return null;
|
||||
}
|
||||
return this._list[ this._p - 1 ];
|
||||
return this._list[ this.p - 1 ];
|
||||
}
|
||||
|
||||
get timeNow(): number {
|
||||
if (this._p === 0) {
|
||||
if (this.p === 0) {
|
||||
return 0;
|
||||
}
|
||||
return this._list[ this._p - 1 ].time;
|
||||
return this._list[ this.p - 1 ].time;
|
||||
}
|
||||
|
||||
get length(): number {
|
||||
|
|
@ -79,7 +64,7 @@ export default class ListWalker<T extends Timed> {
|
|||
}
|
||||
|
||||
get listNow(): Array<T> {
|
||||
return this._list.slice(0, this._p);
|
||||
return this._list.slice(0, this.p);
|
||||
}
|
||||
|
||||
get list(): Array<T> {
|
||||
|
|
@ -91,15 +76,15 @@ export default class ListWalker<T extends Timed> {
|
|||
}
|
||||
|
||||
get countNow(): number {
|
||||
return this._p;
|
||||
return this.p;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns last message with the time <= t.
|
||||
Assumed that the current message is already handled so
|
||||
if pointer doesn't cahnge <undefined> is returned.
|
||||
if pointer doesn't cahnge <null> is returned.
|
||||
*/
|
||||
moveToLast(t: number, index?: number): T | null {
|
||||
moveGetLast(t: number, index?: number): T | null {
|
||||
let key: string = "time"; //TODO
|
||||
let val = t;
|
||||
if (index) {
|
||||
|
|
@ -108,42 +93,29 @@ export default class ListWalker<T extends Timed> {
|
|||
}
|
||||
|
||||
let changed = false;
|
||||
while (this._p < this.length && this._list[this._p][key] <= val) {
|
||||
this._p++;
|
||||
while (this.p < this.length && this._list[this.p][key] <= val) {
|
||||
this.p++;
|
||||
changed = true;
|
||||
}
|
||||
while (this._p > 0 && this._list[ this._p - 1 ][key] > val) {
|
||||
this._p--;
|
||||
while (this.p > 0 && this._list[ this.p - 1 ][key] > val) {
|
||||
this.p--;
|
||||
changed = true;
|
||||
}
|
||||
return changed ? this._list[ this._p - 1 ] : null;
|
||||
return changed ? this._list[ this.p - 1 ] : null;
|
||||
}
|
||||
|
||||
// moveToLastByIndex(i: number): ?T {
|
||||
// let changed = false;
|
||||
// while (!!this._list[this._p] && this._list[this._p]._index <= i) {
|
||||
// this._p++;
|
||||
// changed = true;
|
||||
// }
|
||||
// while (this._p > 0 && this._list[ this._p - 1 ]._index > i) {
|
||||
// this._p--;
|
||||
// changed = true;
|
||||
// }
|
||||
// return changed ? this._list[ this._p - 1 ] : undefined;
|
||||
// }
|
||||
|
||||
moveApply(t: number, fn: (T) => void): void {
|
||||
moveApply(t: number, fn: (T) => void, fnBack?: (T) => void): void {
|
||||
// Applying only in increment order for now
|
||||
if (t < this.timeNow) {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
while (!!this._list[this._p] && this._list[this._p].time <= t) {
|
||||
fn(this._list[ this._p++ ]);
|
||||
while (!!this._list[this.p] && this._list[this.p].time <= t) {
|
||||
fn(this._list[ this.p++ ]);
|
||||
}
|
||||
while (fnBack && this.p > 0 && this._list[ this.p - 1 ].time > t) {
|
||||
fnBack(this._list[ --this.p ]);
|
||||
}
|
||||
//while (this._p > 0 && this._list[ this._p - 1 ].time > t) {
|
||||
// fnBack(this._list[ --this._p ]);
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
// import type { MobX } from '../messages';
|
||||
// import type { Timed } from '../Timed';
|
||||
|
||||
// import ListWalker from './ListWalker';
|
||||
|
||||
// type MobXTimed = MobX & Timed;
|
||||
|
||||
// export default class MobXStateManager extends ListWalker<MobXTimed> {
|
||||
// moveToLast(t: number) {
|
||||
// super.moveApply(t, )
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
|
|
@ -6,10 +6,10 @@ import ListWalker from './ListWalker';
|
|||
const HOVER_CLASS = "-openreplay-hover";
|
||||
const HOVER_CLASS_DEPR = "-asayer-hover";
|
||||
|
||||
export default class MouseManager extends ListWalker<MouseMove> {
|
||||
export default class MouseMoveManager extends ListWalker<MouseMove> {
|
||||
private hoverElements: Array<Element> = [];
|
||||
|
||||
constructor(private screen: StatedScreen) {super();}
|
||||
constructor(private screen: StatedScreen) {super()}
|
||||
|
||||
private updateHover(): void {
|
||||
// @ts-ignore TODO
|
||||
|
|
@ -32,7 +32,7 @@ export default class MouseManager extends ListWalker<MouseMove> {
|
|||
}
|
||||
|
||||
move(t: number) {
|
||||
const lastMouseMove = this.moveToLast(t);
|
||||
const lastMouseMove = this.moveGetLast(t);
|
||||
if (!!lastMouseMove){
|
||||
this.screen.cursor.move(lastMouseMove);
|
||||
//window.getComputedStyle(this.screen.getCursorTarget()).cursor === 'pointer' // might nfluence performance though
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
//@flow
|
||||
import type StatedScreen from '../StatedScreen';
|
||||
import type { Message } from '../messages';
|
||||
import type { Timed } from '../Timed';
|
||||
|
||||
import ListWalker from './ListWalker';
|
||||
import DOMManager from './DOMManager';
|
||||
|
||||
type TimedMessage = Timed & Message;
|
||||
|
||||
export default class PagesManager extends ListWalker<TimedMessage> {
|
||||
#currentPage: DOMManager;
|
||||
|
||||
#isMobile: boolean;
|
||||
#screen: StatedScreen;
|
||||
|
||||
constructor(screen: StatedScreen, isMobile: boolean): void {
|
||||
super();
|
||||
this.#screen = screen;
|
||||
this.#isMobile = isMobile;
|
||||
}
|
||||
|
||||
/*
|
||||
Assumed that messages added in a correct time sequence.
|
||||
*/
|
||||
add(m: TimedMessage): void {
|
||||
if (m.tp === "create_document") {
|
||||
super.add(new DOMManager(this.#screen, this.#isMobile, m.time))
|
||||
}
|
||||
if (this.last === null) {
|
||||
// Log wrong
|
||||
return;
|
||||
}
|
||||
this.last.add(m);
|
||||
}
|
||||
|
||||
sort(comparator) {
|
||||
this.forEach(page => page.sort(comparator))
|
||||
}
|
||||
|
||||
moveReady(t: number): Promise<void> {
|
||||
const requiredPage = this.moveToLast(t);
|
||||
if (!!requiredPage) {
|
||||
this.#currentPage = requiredPage;
|
||||
this.#currentPage.reset(); // Otherwise it won't apply create_document
|
||||
}
|
||||
if (!!this.#currentPage) {
|
||||
return this.#currentPage.moveReady(t);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import type StatedScreen from '../StatedScreen';
|
||||
import type { Message } from '../messages';
|
||||
|
||||
import ListWalker from './ListWalker';
|
||||
import DOMManager from './DOMManager';
|
||||
|
||||
|
||||
export default class PagesManager extends ListWalker<DOMManager> {
|
||||
private currentPage: DOMManager | null = null
|
||||
|
||||
private isMobile: boolean;
|
||||
private screen: StatedScreen;
|
||||
|
||||
constructor(screen: StatedScreen, isMobile: boolean) {
|
||||
super()
|
||||
this.screen = screen
|
||||
this.isMobile = isMobile
|
||||
}
|
||||
|
||||
/*
|
||||
Assumed that messages added in a correct time sequence.
|
||||
*/
|
||||
add(m: Message): void {
|
||||
if (m.tp === "create_document") {
|
||||
super.append(new DOMManager(this.screen, this.isMobile, m.time))
|
||||
}
|
||||
if (this.last === null) {
|
||||
// Log wrong
|
||||
return;
|
||||
}
|
||||
this.last.append(m)
|
||||
}
|
||||
|
||||
sort(comparator) {
|
||||
this.forEach(page => page.sort(comparator))
|
||||
}
|
||||
|
||||
moveReady(t: number): Promise<void> {
|
||||
const requiredPage = this.moveGetLast(t)
|
||||
if (requiredPage != null) {
|
||||
this.currentPage = requiredPage
|
||||
this.currentPage.reset() // Otherwise it won't apply create_document
|
||||
}
|
||||
if (this.currentPage != null) {
|
||||
return this.currentPage.moveReady(t)
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ export default class PerformanceTrackManager extends ListWalker<PerformanceTrack
|
|||
time: msg.time,
|
||||
nodesCount: this.prevNodesCount,
|
||||
});
|
||||
super.add(msg);
|
||||
super.append(msg);
|
||||
}
|
||||
|
||||
setCurrentNodesCount(count: number) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
import { applyChange, revertChange } from 'deep-diff';
|
||||
import ListWalker from './ListWalker';
|
||||
import type { Redux } from '../messages';
|
||||
|
||||
export default class ReduxStateManager extends ListWalker<Redux> {
|
||||
private state: Object = {}
|
||||
private finalStates: Object[] = []
|
||||
|
||||
moveWasUpdated(time, index) {
|
||||
super.moveApply(
|
||||
time,
|
||||
this.onIncrement,
|
||||
this.onDecrement,
|
||||
)
|
||||
}
|
||||
|
||||
onIncrement = (item) => {
|
||||
this.processRedux(item, true);
|
||||
}
|
||||
|
||||
onDecrement = (item) => {
|
||||
this.processRedux(item, false);
|
||||
}
|
||||
|
||||
private processRedux(action, forward) {
|
||||
if (forward) {
|
||||
if (!!action.state) {
|
||||
this.finalStates.push(this.state);
|
||||
this.state = JSON.parse(JSON.stringify(action.state)); // Deep clone :(
|
||||
} else {
|
||||
action.diff.forEach(d => {
|
||||
try {
|
||||
applyChange(this.state, d);
|
||||
} catch (e) {
|
||||
//console.warn("Deepdiff error")
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!!action.state) {
|
||||
this.state = this.finalStates.pop();
|
||||
} else {
|
||||
action.diff.forEach(d => {
|
||||
try {
|
||||
revertChange(this.state, 1, d); // bad lib :( TODO: write our own diff
|
||||
} catch (e) {
|
||||
//console.warn("Deepdiff error")
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
// @flow
|
||||
|
||||
class NodeCounter {
|
||||
_id: number;
|
||||
_parent: NodeCount | null = null;
|
||||
_count: number = 0;
|
||||
_children: Array<NodeCounter> = [];
|
||||
|
||||
|
||||
bubbleCount(count: number) {
|
||||
this._count += count;
|
||||
if (this._parent != null) {
|
||||
this._parent.bubbleCount(count);
|
||||
}
|
||||
}
|
||||
|
||||
newChild(): NodeCounter {
|
||||
const child = new NodeCounter();
|
||||
this._children.push(child);
|
||||
child._parent = this;
|
||||
this.bubbleCount(1);
|
||||
return child
|
||||
}
|
||||
|
||||
removeChild(child: NodeCounter) {
|
||||
this._children = this._children.filter(c => c != child);
|
||||
this.bubbleCount(-(child._count + 1));
|
||||
}
|
||||
|
||||
removeNode() {
|
||||
this._parent.removeChild(this);
|
||||
this._parent = null;
|
||||
}
|
||||
|
||||
moveNode(newParent: NodeCounter) {
|
||||
this.removeNode();
|
||||
newParent._children.push(this);
|
||||
this._parent = newParent;
|
||||
newParent.bubbleCount(this._count + 1);
|
||||
}
|
||||
|
||||
get count() {
|
||||
return this._count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default class WindowNodeCounter {
|
||||
_root: NodeCounter = new NodeCounter();
|
||||
_nodes: Array<NodeCounter> = [ this._root ];
|
||||
|
||||
|
||||
reset() {
|
||||
this._root = new NodeCounter();
|
||||
this._nodes = [ this._root ];
|
||||
}
|
||||
|
||||
addNode(id: number, parentID: number) {
|
||||
if (!this._nodes[ parentID ]) {
|
||||
//TODO: iframe case
|
||||
//console.error(`Wrong! Node with id ${ parentID } (parentId) not found.`);
|
||||
return;
|
||||
}
|
||||
if (!!this._nodes[ id ]) {
|
||||
//console.error(`Wrong! Node with id ${ id } already exists.`);
|
||||
return;
|
||||
}
|
||||
this._nodes[id] = this._nodes[ parentID ].newChild();
|
||||
}
|
||||
|
||||
removeNode(id: number) {
|
||||
if (!this._nodes[ id ]) {
|
||||
// Might be text node
|
||||
//console.error(`Wrong! Node with id ${ id } not found.`);
|
||||
return;
|
||||
}
|
||||
this._nodes[ id ].removeNode();
|
||||
}
|
||||
|
||||
moveNode(id: number, parentId: number) {
|
||||
if (!this._nodes[ id ]) {
|
||||
console.error(`Wrong! Node with id ${ id } not found.`);
|
||||
return;
|
||||
}
|
||||
if (!this._nodes[ parentId ]) {
|
||||
console.error(`Wrong! Node with id ${ parentId } (parentId) not found.`);
|
||||
return;
|
||||
}
|
||||
this._nodes[ id ].moveNode(this._nodes[ parentId ]);
|
||||
}
|
||||
|
||||
get count() {
|
||||
return this._root.count;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
|
||||
class NodeCounter {
|
||||
private parent: NodeCounter | null = null
|
||||
private _count: number = 0
|
||||
private children: Array<NodeCounter> = []
|
||||
|
||||
|
||||
bubbleCount(count: number) {
|
||||
this._count += count
|
||||
if (this.parent != null) {
|
||||
this.parent.bubbleCount(count)
|
||||
}
|
||||
}
|
||||
|
||||
newChild(): NodeCounter {
|
||||
const child = new NodeCounter()
|
||||
this.children.push(child)
|
||||
child.parent = this
|
||||
this.bubbleCount(1)
|
||||
return child
|
||||
}
|
||||
|
||||
removeChild(child: NodeCounter) {
|
||||
this.children = this.children.filter(c => c != child)
|
||||
this.bubbleCount(-(child._count + 1))
|
||||
}
|
||||
|
||||
removeNode() {
|
||||
if (this.parent) {
|
||||
this.parent.removeChild(this)
|
||||
}
|
||||
this.parent = null
|
||||
}
|
||||
|
||||
moveNode(newParent: NodeCounter) {
|
||||
this.removeNode()
|
||||
newParent.children.push(this)
|
||||
this.parent = newParent
|
||||
newParent.bubbleCount(this._count + 1)
|
||||
}
|
||||
|
||||
get count() {
|
||||
return this._count
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default class WindowNodeCounter {
|
||||
private root: NodeCounter = new NodeCounter()
|
||||
private nodes: Array<NodeCounter> = [ this.root ]
|
||||
|
||||
|
||||
reset() {
|
||||
this.root = new NodeCounter()
|
||||
this.nodes = [ this.root ]
|
||||
}
|
||||
|
||||
addNode(id: number, parentID: number) {
|
||||
if (!this.nodes[ parentID ]) {
|
||||
//TODO: iframe case
|
||||
//console.error(`Wrong! Node with id ${ parentID } (parentId) not found.`);
|
||||
return
|
||||
}
|
||||
if (!!this.nodes[ id ]) {
|
||||
//console.error(`Wrong! Node with id ${ id } already exists.`);
|
||||
return
|
||||
}
|
||||
this.nodes[id] = this.nodes[ parentID ].newChild()
|
||||
}
|
||||
|
||||
removeNode(id: number) {
|
||||
if (!this.nodes[ id ]) {
|
||||
// Might be text node
|
||||
//console.error(`Wrong! Node with id ${ id } not found.`);
|
||||
return
|
||||
}
|
||||
this.nodes[ id ].removeNode()
|
||||
}
|
||||
|
||||
moveNode(id: number, parentId: number) {
|
||||
if (!this.nodes[ id ]) {
|
||||
console.error(`Wrong! Node with id ${ id } not found.`)
|
||||
return
|
||||
}
|
||||
if (!this.nodes[ parentId ]) {
|
||||
console.error(`Wrong! Node with id ${ parentId } (parentId) not found.`)
|
||||
return
|
||||
}
|
||||
this.nodes[ id ].moveNode(this.nodes[ parentId ])
|
||||
}
|
||||
|
||||
get count() {
|
||||
return this.root.count
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -80,7 +80,7 @@ export default class ImagePlayer {
|
|||
logger.error(e);
|
||||
}
|
||||
});
|
||||
Object.values(this.lists).forEach(list => list.moveToLast(0)); // In case of negative values
|
||||
Object.values(this.lists).forEach(list => list.moveGetLast(0)); // In case of negative values
|
||||
})
|
||||
|
||||
if (session.socket == null || typeof session.socket.jwt !== "string" || typeof session.socket.url !== "string") {
|
||||
|
|
@ -190,8 +190,8 @@ export default class ImagePlayer {
|
|||
_setTime(ts) {
|
||||
ts = Math.max(Math.min(ts, this.state.endTime), 0);
|
||||
this.state.setTime(ts);
|
||||
Object.values(this.lists).forEach(list => list.moveToLast(ts));
|
||||
const screen = this._screens.moveToLast(ts);
|
||||
Object.values(this.lists).forEach(list => list.moveGetLast(ts));
|
||||
const screen = this._screens.moveGetLast(ts);
|
||||
if (screen != null) {
|
||||
const { dataURL, width, height } = screen;
|
||||
this.state.setSize(width, height);
|
||||
|
|
@ -199,7 +199,7 @@ export default class ImagePlayer {
|
|||
//this._screen.style.backgroundImage = `url(${screen.dataURL})`;
|
||||
screen.loadImage.then(() => this._screen.style.backgroundImage = `url(${screen.dataURL})`);
|
||||
}
|
||||
const lastClick = this._clicks.moveToLast(ts);
|
||||
const lastClick = this._clicks.moveGetLast(ts);
|
||||
if (lastClick != null && lastClick.time > ts - 600) {
|
||||
this._animateClick(lastClick);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ export default class PerformanceList {
|
|||
return this._list.count;
|
||||
}
|
||||
|
||||
moveToLast(t) {
|
||||
this._list.moveToLast(t);
|
||||
moveGetLast(t) {
|
||||
this._list.moveGetLast(t);
|
||||
}
|
||||
|
||||
append(m) {
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ export default class ScreenList {
|
|||
this._walker._list.splice(p, 0, m);
|
||||
}
|
||||
|
||||
moveToLast(time) {
|
||||
return this._walker.moveToLast(time);
|
||||
moveGetLast(time) {
|
||||
return this._walker.moveGetLast(time);
|
||||
}
|
||||
|
||||
insertScreen(time, width, height, arrayBuffer): void {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue