openreplay/frontend/app/player/web/managers/PagesManager.ts
Andrey Babushkin fd5c0c9747
Add lokalisation (#3092)
* applied eslint

* add locales and lint the project

* removed error boundary

* updated locales

* fix min files

* fix locales
2025-03-06 17:43:15 +01:00

124 lines
3.4 KiB
TypeScript

import logger from 'App/logger';
import ListWalker from '../../common/ListWalker';
import { Message, MType } from '../messages';
import type Screen from '../Screen/Screen';
import DOMManager from './DOM/DOMManager';
export default class PagesManager extends ListWalker<DOMManager> {
private currentPage: DOMManager | null = null;
/**
* String Dictionary in tracker may be desync with CreateDocument (why???)
* e.g. some StringDictionary and other messages before any 'CreateDocument' one
* TODO: understand why and fix
*/
private stringDicts: Record<number, string>[] = [{}];
private globalDictionary: Map<string, string> = new Map();
constructor(
private screen: Screen,
private isMobile: boolean,
private setCssLoading: (flag: boolean) => void,
) {
super();
}
/*
Assumed that messages added in a correct time sequence.
*/
falseOrder = false;
appendMessage(m: Message): void {
if ([MType.StringDict, MType.StringDictGlobal].includes(m.tp)) {
this.globalDictionary.set(m.key, m.value);
return;
}
if (m.tp === MType.StringDictDeprecated) {
let currentDict = this.stringDicts[0];
if (currentDict[m.key] !== undefined && currentDict[m.key] !== m.value) {
this.falseOrder = true;
this.stringDicts.unshift({});
currentDict = this.stringDicts[0];
}
currentDict[m.key] = m.value;
return;
}
if (m.tp === MType.CreateDocument) {
if (!this.falseOrder) {
this.stringDicts.unshift({});
}
super.append(
new DOMManager({
screen: this.screen,
isMobile: this.isMobile,
// TODO: this is a deprecated code on life support, remove it after 09.2025
stringDict: this.stringDicts[0],
time: m.time,
setCssLoading: this.setCssLoading,
globalDict: {
get: (key: string) => this.globalDictionary.get(key),
all: () => Object.fromEntries(this.globalDictionary),
},
}),
);
this.falseOrder = false;
}
if (this.last === null) {
logger.warn('DOMMessage before any document created, skipping:', m);
return;
}
this.last.append(m);
}
sortPages(comparator: (a: Message, b: Message) => number) {
this.forEach((page) => page.sort(comparator));
}
public getNode(id: number) {
return this.currentPage?.getNode(id);
}
spriteMapEl: SVGElement | null = null;
injectSpriteMap = (spriteEl: SVGElement) => {
this.spriteMapEl = spriteEl;
this.refreshSprites();
};
refreshSprites = () => {
const int = setInterval(() => {
const potential = this.screen.document?.body.querySelector(
'#OPENREPLAY_SPRITES_MAP',
);
if (potential) {
potential.innerHTML = this.spriteMapEl!.innerHTML;
clearInterval(int);
}
}, 250);
};
moveReady(t: number): Promise<void> {
const requiredPage = this.moveGetLast(t);
let changed = false;
if (requiredPage != null) {
this.currentPage?.clearSelectionManager();
this.currentPage = requiredPage;
this.currentPage.reset(); // Otherwise it won't apply create_document
changed = true;
}
if (this.currentPage != null) {
return this.currentPage.moveReady(t).then(() => {
if (changed && this.spriteMapEl) {
setTimeout(() => {
this.refreshSprites();
}, 0);
}
});
}
return Promise.resolve();
}
}