openreplay/frontend/app/player/MessageDistributor/StatedScreen/StatedScreen.ts
2021-08-05 21:36:28 +05:30

125 lines
No EOL
3.1 KiB
TypeScript

import Screen, { INITIAL_STATE as SUPER_INITIAL_STATE, State as SuperState } from './Screen/Screen';
import { update, getState } from '../../store';
//export interface targetPosition
interface BoundingRect {
top: number,
left: number,
width: number,
height: number,
}
export interface MarkedTarget {
boundingRect: BoundingRect,
el: Element,
selector: string,
count: number,
index: number,
active?: boolean,
percent: number
}
export interface State extends SuperState {
messagesLoading: boolean,
cssLoading: boolean,
disconnected: boolean,
userPageLoading: boolean,
markedTargets: MarkedTarget[] | null,
activeTargetIndex: number
}
export const INITIAL_STATE: State = {
...SUPER_INITIAL_STATE,
messagesLoading: false,
cssLoading: false,
disconnected: false,
userPageLoading: false,
markedTargets: null,
activeTargetIndex: 0
};
export default class StatedScreen extends Screen {
constructor() { super(); }
setMessagesLoading(messagesLoading: boolean) {
this.display(!messagesLoading);
update({ messagesLoading });
}
setCSSLoading(cssLoading: boolean) {
this.displayFrame(!cssLoading);
update({ cssLoading });
}
setDisconnected(disconnected: boolean) {
if (!getState().live) return; //?
this.display(!disconnected);
update({ disconnected });
}
setUserPageLoading(userPageLoading: boolean) {
this.display(!userPageLoading);
update({ userPageLoading });
}
setSize({ height, width }: { height: number, width: number }) {
update({ width, height });
this.scale();
const { markedTargets } = getState();
if (markedTargets) {
update({
markedTargets: markedTargets.map(mt => ({
...mt,
boundingRect: this.calculateRelativeBoundingRect(mt.el),
})),
});
}
}
private calculateRelativeBoundingRect(el: Element): BoundingRect {
if (!this.parentElement) return {top:0, left:0, width:0,height:0} //TODO
const { top, left, width, height } = el.getBoundingClientRect();
const s = this.getScale();
const scrinRect = this.screen.getBoundingClientRect();
const parentRect = this.parentElement.getBoundingClientRect();
return {
top: top*s + scrinRect.top - parentRect.top,
left: left*s + scrinRect.left - parentRect.left,
width: width*s,
height: height*s,
}
}
setActiveTarget(index) {
update({ activeTargetIndex: index });
}
setMarkedTargets(selections: { selector: string, count: number }[] | null) {
if (selections) {
const targets: MarkedTarget[] = [];
let index = 0;
selections.forEach((s) => {
const el = this.getElementBySelector(s.selector);
if (!el) return;
targets.push({
...s,
el,
index: index++,
percent: 0,
boundingRect: this.calculateRelativeBoundingRect(el),
})
});
const totalCount = targets.reduce((a, b) => {
return a + b.count
}, 0);
update({ markedTargets: targets.map(i => ({...i, percent: Math.round((i.count * 100) / totalCount) })) });
} else {
update({ markedTargets: null });
}
}
}