cherry-pick 383b5dd6405d8f47b9d794c123390e91b4154663 conflicts
This commit is contained in:
parent
c4e427efa2
commit
364b62fda0
6 changed files with 63 additions and 22 deletions
|
|
@ -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 }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,3 +20,8 @@
|
|||
bottom: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.highlightoff {
|
||||
opacity: 0;
|
||||
transition: all 0.25s cubic-bezier(0, 0, 0.4, 1.0);
|
||||
}
|
||||
|
|
@ -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<typeof WebPlayer.INITIAL_STATE>, session: any, live: boolean, isClickMap = false) {
|
||||
constructor(
|
||||
protected wpState: Store<typeof WebPlayer.INITIAL_STATE>,
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
this.stringDict = stringDict
|
||||
}
|
||||
|
||||
public clearSelectionManager() {
|
||||
this.selectionManager.clearSelection()
|
||||
}
|
||||
|
||||
append(m: Message): void {
|
||||
if (m.tp === MType.SetNodeScroll) {
|
||||
let scrollManager = this.nodeScrollManagers.get(m.id)
|
||||
|
|
|
|||
|
|
@ -6,19 +6,15 @@ import Screen from 'Player/web/Screen/Screen';
|
|||
export default class SelectionManager extends ListWalker<SelectionChange> {
|
||||
constructor(private readonly vElements: Map<number, VElement>, 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<SelectionChange> {
|
|||
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<SelectionChange> {
|
|||
|
||||
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 }];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ export default class PagesManager extends ListWalker<DOMManager> {
|
|||
moveReady(t: number): Promise<void> {
|
||||
const requiredPage = this.moveGetLast(t)
|
||||
if (requiredPage != null) {
|
||||
this.currentPage?.clearSelectionManager()
|
||||
this.currentPage = requiredPage
|
||||
this.currentPage.reset() // Otherwise it won't apply create_document
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue