diff options
Diffstat (limited to 'src/client/util/ReplayMovements.ts')
-rw-r--r-- | src/client/util/ReplayMovements.ts | 79 |
1 files changed, 45 insertions, 34 deletions
diff --git a/src/client/util/ReplayMovements.ts b/src/client/util/ReplayMovements.ts index b881f18b4..c5afe549c 100644 --- a/src/client/util/ReplayMovements.ts +++ b/src/client/util/ReplayMovements.ts @@ -1,19 +1,21 @@ import { IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { Doc, IdToDoc } from '../../fields/Doc'; -import { CollectionDockingView } from '../views/collections/CollectionDockingView'; import { CollectionFreeFormView } from '../views/collections/collectionFreeForm'; -import { OpenWhereMod } from '../views/nodes/DocumentView'; -import { VideoBox } from '../views/nodes/VideoBox'; -import { DocumentManager } from './DocumentManager'; +import { DocumentView } from '../views/nodes/DocumentView'; +import { OpenWhereMod } from '../views/nodes/OpenWhere'; +import { SnappingManager } from './SnappingManager'; import { Movement, Presentation } from './TrackMovements'; +import { ViewBoxInterface } from '../views/ViewBoxInterface'; +import { StrCast } from '../../fields/Types'; export class ReplayMovements { private timers: NodeJS.Timeout[] | null; private videoBoxDisposeFunc: IReactionDisposer | null; - private videoBox: VideoBox | null; + private videoBox: ViewBoxInterface<any> | null; private isPlaying: boolean; // create static instance and getter for global use + // eslint-disable-next-line no-use-before-define @observable static _instance: ReplayMovements; static get Instance(): ReplayMovements { return ReplayMovements._instance; @@ -28,6 +30,22 @@ export class ReplayMovements { this.videoBoxDisposeFunc = null; this.videoBox = null; this.isPlaying = false; + + reaction( + () => SnappingManager.UserPanned, + () => { + if (Doc.UserDoc()?.presentationMode === 'watching') this.pauseFromInteraction(); + } + ); + reaction( + () => DocumentView.Selected().slice(), + selviews => { + const selVideo = selviews.find(dv => dv.ComponentView?.playFrom); + if (selVideo?.ComponentView?.Play) { + this.setVideoBox(selVideo.ComponentView); + } else this.removeVideoBox(); + } + ); } // pausing movements will dispose all timers that are planned to replay the movements @@ -44,18 +62,16 @@ export class ReplayMovements { this.timers?.map(timer => clearTimeout(timer)); }; - setVideoBox = async (videoBox: VideoBox) => { - // console.info('setVideoBox', videoBox); + setVideoBox = async (videoBox: ViewBoxInterface<any>) => { if (this.videoBox !== null) { console.warn('setVideoBox on already videoBox'); } - if (this.videoBoxDisposeFunc !== null) { - console.warn('setVideoBox on already videoBox dispose func'); - this.videoBoxDisposeFunc(); - } + this.videoBoxDisposeFunc?.(); + + const data = StrCast(videoBox.dataDoc?.[videoBox.fieldKey + '_presentation']); + const presentation = data ? JSON.parse(data) : null; - const { presentation } = videoBox; - if (presentation == null) { + if (presentation === null) { console.warn('setVideoBox on null videoBox presentation'); return; } @@ -63,18 +79,14 @@ export class ReplayMovements { this.loadPresentation(presentation); this.videoBoxDisposeFunc = reaction( - () => ({ playing: videoBox._playing, timeViewed: videoBox.player?.currentTime || 0 }), + () => ({ playing: videoBox.IsPlaying?.(), timeViewed: videoBox.PlayerTime?.() || 0 }), ({ playing, timeViewed }) => (playing ? this.playMovements(presentation, timeViewed) : this.pauseMovements()) ); this.videoBox = videoBox; }; removeVideoBox = () => { - if (this.videoBoxDisposeFunc == null) { - console.warn('removeVideoBox on null videoBox'); - return; - } - this.videoBoxDisposeFunc(); + this.videoBoxDisposeFunc?.(); this.videoBox = null; this.videoBoxDisposeFunc = null; @@ -82,7 +94,7 @@ export class ReplayMovements { // should be called from interacting with the screen pauseFromInteraction = () => { - this.videoBox?.Pause(); + this.videoBox?.Pause?.(); this.pauseMovements(); }; @@ -90,7 +102,7 @@ export class ReplayMovements { loadPresentation = (presentation: Presentation) => { const { movements } = presentation; if (movements === null) { - throw '[recordingApi.ts] followMovements() failed: no presentation data'; + throw new Error('[recordingApi.ts] followMovements() failed: no presentation data'); } movements.forEach((movement, i) => { @@ -105,10 +117,8 @@ export class ReplayMovements { // returns undefined if the docView isn't open on the screen getCollectionFFView = (doc: Doc) => { - const isInView = DocumentManager.Instance.getDocumentView(doc); - if (isInView) { - return isInView.ComponentView as CollectionFreeFormView; - } + const isInView = DocumentView.getDocumentView(doc); + return isInView?.ComponentView as CollectionFreeFormView; }; // will open the doc in a tab then return the CollectionFFView that holds it @@ -118,8 +128,8 @@ export class ReplayMovements { return undefined; } // console.log('openTab', docId, doc); - CollectionDockingView.AddSplit(doc, OpenWhereMod.right); - const docView = DocumentManager.Instance.getDocumentView(doc); + DocumentView.addSplit(doc, OpenWhereMod.right); + const docView = DocumentView.getDocumentView(doc); // BUG - this returns undefined if the doc is already open return docView?.ComponentView as CollectionFreeFormView; }; @@ -136,9 +146,9 @@ export class ReplayMovements { if (movements === null) return new Map(); // generate a set of all unique docIds const docIdtoFirstMove = new Map<Doc, Movement>(); - for (const move of movements) { + movements.forEach(move => { if (!docIdtoFirstMove.has(move.doc)) docIdtoFirstMove.set(move.doc, move); - } + }); return docIdtoFirstMove; }; @@ -151,10 +161,10 @@ export class ReplayMovements { // console.info('playMovements', presentation, timeViewed, docIdtoDoc); if (presentation.movements === null || presentation.movements.length === 0) { - //|| this.playFFView === null) { - return new Error('[recordingApi.ts] followMovements() failed: no presentation data'); + // || this.playFFView === null) { + return '[recordingApi.ts] followMovements() failed: no presentation data'; } - if (this.isPlaying) return; + if (this.isPlaying) return undefined; this.isPlaying = true; Doc.UserDoc().presentationMode = 'watching'; @@ -170,10 +180,10 @@ export class ReplayMovements { // for the open tabs, set it to the first move const docIdtoFirstMove = this.getFirstMovements(filteredMovements); - for (const [doc, firstMove] of docIdtoFirstMove) { + Array.from(docIdtoFirstMove).forEach(([doc, firstMove]) => { const colFFView = this.getCollectionFFView(doc); if (colFFView) this.zoomAndPan(firstMove, colFFView); - } + }); }; handleFirstMovements(); @@ -197,5 +207,6 @@ export class ReplayMovements { } }, timeDiff); }); + return undefined; }; } |