125 lines
No EOL
3.1 KiB
TypeScript
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 });
|
|
}
|
|
}
|
|
} |