From 364b62fda03b62fabd3eb06378e905f813db7835 Mon Sep 17 00:00:00 2001 From: nick-delirium Date: Wed, 17 May 2023 17:39:39 +0200 Subject: [PATCH] cherry-pick 383b5dd6405d8f47b9d794c123390e91b4154663 conflicts --- frontend/app/player/web/Screen/Screen.ts | 24 ++++++++++++++++ .../app/player/web/Screen/screen.module.css | 5 ++++ frontend/app/player/web/WebPlayer.ts | 28 ++++++++++++++----- .../app/player/web/managers/DOM/DOMManager.ts | 4 +++ .../web/managers/DOM/SelectionManager.ts | 23 ++++++--------- .../app/player/web/managers/PagesManager.ts | 1 + 6 files changed, 63 insertions(+), 22 deletions(-) diff --git a/frontend/app/player/web/Screen/Screen.ts b/frontend/app/player/web/Screen/Screen.ts index 185b7c769..52d309873 100644 --- a/frontend/app/player/web/Screen/Screen.ts +++ b/frontend/app/player/web/Screen/Screen.ts @@ -58,6 +58,7 @@ function isIframe(el: Element): el is HTMLIFrameElement { export default class Screen { readonly overlay: HTMLDivElement readonly cursor: Cursor + private selectionTargets: { start?: HTMLDivElement, end?: HTMLDivElement } = { start: undefined, end: undefined } private readonly iframe: HTMLIFrameElement; private readonly screen: HTMLDivElement; @@ -253,4 +254,27 @@ export default class Screen { setOnUpdate(cb: any) { this.onUpdateHook = cb } + + public createSelection(start: HTMLDivElement, end: HTMLDivElement) { + this.selectionTargets = { start, end } + + this.overlay.appendChild(start); + this.overlay.appendChild(end); + + setTimeout(() => { + start.className = styles.highlightoff + end.className = styles.highlightoff + }, 750) + } + + public clearSelection() { + if (this.selectionTargets.start && this.selectionTargets.end) { + this.overlay.removeChild(this.selectionTargets.start); + this.overlay.removeChild(this.selectionTargets.end); + this.selectionTargets.start.remove() + this.selectionTargets.end.remove() + this.selectionTargets = { start: undefined, end: undefined } + } + + } } diff --git a/frontend/app/player/web/Screen/screen.module.css b/frontend/app/player/web/Screen/screen.module.css index f9a2d2d8a..b69579935 100644 --- a/frontend/app/player/web/Screen/screen.module.css +++ b/frontend/app/player/web/Screen/screen.module.css @@ -20,3 +20,8 @@ bottom: 0; z-index: 10; } + +.highlightoff { + opacity: 0; + transition: all 0.25s cubic-bezier(0, 0, 0.4, 1.0); +} \ No newline at end of file diff --git a/frontend/app/player/web/WebPlayer.ts b/frontend/app/player/web/WebPlayer.ts index 89b246311..d939b625d 100644 --- a/frontend/app/player/web/WebPlayer.ts +++ b/frontend/app/player/web/WebPlayer.ts @@ -1,22 +1,21 @@ -import { Log, LogLevel } from './types/log' +import { Log, LogLevel, SessionFilesInfo } from 'App/player' import type { Store } from 'App/player' import Player from '../player/Player' import MessageManager from './MessageManager' +import MessageLoader from './MessageLoader' import InspectorController from './addons/InspectorController' import TargetMarker from './addons/TargetMarker' import Screen, { ScaleMode } from './Screen/Screen' import { Message } from "Player/web/messages"; - -// export type State = typeof WebPlayer.INITIAL_STATE - export default class WebPlayer extends Player { static readonly INITIAL_STATE = { ...Player.INITIAL_STATE, ...TargetMarker.INITIAL_STATE, ...MessageManager.INITIAL_STATE, + ...MessageLoader.INITIAL_STATE, inspectorMode: false, } @@ -24,10 +23,17 @@ export default class WebPlayer extends Player { private readonly inspectorController: InspectorController protected screen: Screen protected readonly messageManager: MessageManager + protected readonly messageLoader: MessageLoader private targetMarker: TargetMarker - constructor(protected wpState: Store, session: any, live: boolean, isClickMap = false) { + constructor( + protected wpState: Store, + session: SessionFilesInfo, + live: boolean, + isClickMap = false, + public readonly uiErrorHandler?: { error: (msg: string) => void } + ) { let initialLists = live ? {} : { event: session.events || [], stack: session.stackEvents || [], @@ -42,12 +48,19 @@ export default class WebPlayer extends Player { } const screen = new Screen(session.isMobile, isClickMap ? ScaleMode.AdjustParentHeight : ScaleMode.Embed) - const messageManager = new MessageManager(session, wpState, screen, initialLists) + const messageManager = new MessageManager(session, wpState, screen, initialLists, uiErrorHandler) + const messageLoader = new MessageLoader( + session, + wpState, + messageManager, + isClickMap + ) super(wpState, messageManager) this.screen = screen this.messageManager = messageManager + this.messageLoader = messageLoader if (!live) { // hack. TODO: split OfflinePlayer class - void messageManager.loadMessages(isClickMap) + void messageLoader.loadFiles() } this.targetMarker = new TargetMarker(this.screen, wpState) @@ -154,6 +167,7 @@ export default class WebPlayer extends Player { this.screen.clean() // @ts-ignore this.screen = undefined; + this.messageLoader.clean() window.removeEventListener('resize', this.scale) } } diff --git a/frontend/app/player/web/managers/DOM/DOMManager.ts b/frontend/app/player/web/managers/DOM/DOMManager.ts index 85d21e85d..2b98a8cfe 100644 --- a/frontend/app/player/web/managers/DOM/DOMManager.ts +++ b/frontend/app/player/web/managers/DOM/DOMManager.ts @@ -61,6 +61,10 @@ export default class DOMManager extends ListWalker { this.stringDict = stringDict } + public clearSelectionManager() { + this.selectionManager.clearSelection() + } + append(m: Message): void { if (m.tp === MType.SetNodeScroll) { let scrollManager = this.nodeScrollManagers.get(m.id) diff --git a/frontend/app/player/web/managers/DOM/SelectionManager.ts b/frontend/app/player/web/managers/DOM/SelectionManager.ts index 6e1ef8ff2..8f44d7362 100644 --- a/frontend/app/player/web/managers/DOM/SelectionManager.ts +++ b/frontend/app/player/web/managers/DOM/SelectionManager.ts @@ -6,19 +6,15 @@ import Screen from 'Player/web/Screen/Screen'; export default class SelectionManager extends ListWalker { constructor(private readonly vElements: Map, private readonly screen: Screen) { super(); - this.screen.cursor.setOnClickHook(this.clearSelection) } private selected: [{ id: number, node: Element } | null, { id: number, node: Element } | null] = [null, null]; - private markers: Element[] = [] public clearSelection = () => { - this.selected[0] && this.screen.overlay.removeChild(this.selected[0].node) && this.selected[0].node.remove(); - this.selected[1] && this.screen.overlay.removeChild(this.selected[1].node) && this.selected[1].node.remove(); - this.markers.forEach(marker => marker.remove()) + if (this.selected[0] === null && this.selected[1] === null) return; + this.screen.clearSelection() this.selected = [null, null]; - this.markers = []; } move(t: number) { @@ -26,6 +22,7 @@ export default class SelectionManager extends ListWalker { if (!msg) { return; } + // in theory: empty selection or selection removed if (msg.selectionStart <= 0) { this.clearSelection() @@ -49,26 +46,22 @@ export default class SelectionManager extends ListWalker { Object.assign(endPointer.style, { top: endCoords.top + 'px', - left: (endCoords.left + (endCoords.width / 2) + 3) + 'px', - width: (endCoords.width / 2) + 'px', + right: (endCoords.right) + 'px', + width: (endCoords.width) + 'px', height: endCoords.height + 'px', - borderRight: '2px solid blue', position: 'absolute', boxShadow: '1px 4px 1px -2px blue', }); Object.assign(startPointer.style, { top: startCoords.top + 'px', - left: (startCoords.left - 3) + 'px', - width: (startCoords.width / 2 ) + 'px', + left: (startCoords.left) + 'px', + width: (startCoords.width) + 'px', height: startCoords.height + 'px', - borderLeft: '2px solid blue', position: 'absolute', boxShadow: '1px 4px 1px -2px blue', }); - this.markers.push(startPointer, endPointer); - this.screen.overlay.appendChild(startPointer); - this.screen.overlay.appendChild(endPointer); + this.screen.createSelection(startPointer, endPointer); this.selected = [{ id: msg.selectionStart, node: startPointer }, { id: msg.selectionEnd, node: endPointer }]; } diff --git a/frontend/app/player/web/managers/PagesManager.ts b/frontend/app/player/web/managers/PagesManager.ts index 4ab78a0ac..d6c0f0467 100644 --- a/frontend/app/player/web/managers/PagesManager.ts +++ b/frontend/app/player/web/managers/PagesManager.ts @@ -59,6 +59,7 @@ export default class PagesManager extends ListWalker { moveReady(t: number): Promise { const requiredPage = this.moveGetLast(t) if (requiredPage != null) { + this.currentPage?.clearSelectionManager() this.currentPage = requiredPage this.currentPage.reset() // Otherwise it won't apply create_document }