diff options
-rw-r--r-- | src/client/util/ReplayMovements.ts | 204 | ||||
-rw-r--r-- | src/client/util/TrackMovements.ts (renamed from src/client/util/RecordingApi.ts) | 236 | ||||
-rw-r--r-- | src/client/views/Main.tsx | 6 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 16 | ||||
-rw-r--r-- | src/client/views/nodes/RecordingBox/RecordingBox.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/RecordingBox/RecordingView.tsx | 10 | ||||
-rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 8 |
7 files changed, 236 insertions, 246 deletions
diff --git a/src/client/util/ReplayMovements.ts b/src/client/util/ReplayMovements.ts new file mode 100644 index 000000000..e46810b52 --- /dev/null +++ b/src/client/util/ReplayMovements.ts @@ -0,0 +1,204 @@ +import { CollectionFreeFormView } from "../views/collections/collectionFreeForm"; +import { IReactionDisposer, observable, observe, reaction } from "mobx"; +import { Doc } from "../../fields/Doc"; +import { VideoBox } from "../views/nodes/VideoBox"; +import { DocumentManager } from "./DocumentManager"; +import { CollectionDockingView } from "../views/collections/CollectionDockingView"; +import { DocServer } from "../DocServer"; +import { Movement, Presentation } from "./TrackMovements"; + +export class ReplayMovements { + private timers: NodeJS.Timeout[] | null; + private videoBoxDisposeFunc: IReactionDisposer | null; + private videoBox: VideoBox | null; + private isPlaying: boolean; + + + // create static instance and getter for global use + @observable static _instance: ReplayMovements; + static get Instance(): ReplayMovements { return ReplayMovements._instance } + constructor() { + // init the global instance + ReplayMovements._instance = this; + + // instance vars for replaying + this.timers = null; + this.videoBoxDisposeFunc = null; + this.videoBox = null; + this.isPlaying = false; + } + + // pausing movements will dispose all timers that are planned to replay the movements + // play movemvents will recreate them when the user resumes the presentation + pauseMovements = (): undefined | Error => { + if (!this.isPlaying) { + console.warn('[recordingApi.ts] pauseMovements(): already on paused'); + return; + } + + this.isPlaying = false + // TODO: set userdoc presentMode to browsing + this.timers?.map(timer => clearTimeout(timer)) + } + + setVideoBox = async (videoBox: VideoBox) => { + console.log('setVideoBox', videoBox); + if (videoBox !== null) { console.warn('setVideoBox on already videoBox'); } + if (this.videoBoxDisposeFunc !== null) { console.warn('setVideoBox on already videoBox dispose func'); this.videoBoxDisposeFunc(); } + + + const { presentation } = videoBox; + if (presentation == null) { console.warn('setVideoBox on null videoBox presentation'); return; } + + let docIdtoDoc: Map<string, Doc> = new Map(); + try { + docIdtoDoc = await this.loadPresentation(presentation); + } catch { + console.error('[recordingApi.ts] setVideoBox(): error loading presentation - no replay movements'); + throw 'error loading docs from server'; + } + + + this.videoBoxDisposeFunc = + reaction(() => ({ playing: videoBox._playing, timeViewed: videoBox.player?.currentTime || 0 }), + ({ playing, timeViewed }) => + playing ? this.playMovements(presentation, docIdtoDoc, timeViewed) : this.pauseMovements() + ); + this.videoBox = videoBox; + } + + removeVideoBox = () => { + if (this.videoBoxDisposeFunc == null) { console.warn('removeVideoBox on null videoBox'); return; } + this.videoBoxDisposeFunc(); + + this.videoBox = null; + this.videoBoxDisposeFunc = null; + } + + // should be called from interacting with the screen + pauseFromInteraction = () => { + Doc.UserDoc().presentationMode = 'none'; + this.videoBox?.Pause(); + + this.pauseMovements(); + } + + loadPresentation = async (presentation: Presentation) => { + const { movements } = presentation; + if (movements === null) { + throw '[recordingApi.ts] followMovements() failed: no presentation data'; + } + + // generate a set of all unique docIds + const docIds = new Set<string>(); + for (const {docId} of movements) { + if (!docIds.has(docId)) docIds.add(docId); + } + + const docIdtoDoc = new Map<string, Doc>(); + + let refFields = await DocServer.GetRefFields([...docIds.keys()]); + for (const docId in refFields) { + if (!refFields[docId]) { + throw `one field was undefined`; + } + docIdtoDoc.set(docId, refFields[docId] as Doc); + } + console.log('loadPresentation refFields', refFields, docIdtoDoc); + + return docIdtoDoc; + } + + // returns undefined if the docView isn't open on the screen + getCollectionFFView = (docId: string) => { + const isInView = DocumentManager.Instance.getDocumentViewById(docId); + if (isInView) { return isInView.ComponentView as CollectionFreeFormView; } + } + + // will open the doc in a tab then return the CollectionFFView that holds it + openTab = (docId: string, docIdtoDoc: Map<string, Doc>) => { + const doc = docIdtoDoc.get(docId); + if (doc == undefined) { + console.error(`docIdtoDoc did not contain docId ${docId}`) + return undefined; + } + CollectionDockingView.AddSplit(doc, 'right'); + const docView = DocumentManager.Instance.getDocumentViewById(docId); + return docView?.ComponentView as CollectionFreeFormView; + } + + // helper to replay a movement + zoomAndPan = (movement: Movement, document: CollectionFreeFormView) => { + const { panX, panY, scale } = movement; + scale !== 0 && document.zoomSmoothlyAboutPt([panX, panY], scale, 0); + document.Document._panX = panX; + document.Document._panY = panY; + } + + getFirstMovements = (movements: Movement[], timeViewed: number): Map<string, Movement> => { + if (movements === null) return new Map(); + // generate a set of all unique docIds + const docIdtoFirstMove = new Map(); + for (const move of movements) { + const { docId } = move; + if (!docIdtoFirstMove.has(docId)) docIdtoFirstMove.set(docId, move); + } + return docIdtoFirstMove; + } + + endPlayingPresentation = () => { + this.isPlaying = false; + } + + public playMovements = (presentation: Presentation, docIdtoDoc: Map<string, Doc>, timeViewed: number = 0) => { + console.log('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') + } + if (this.isPlaying) return; + + this.isPlaying = true; + Doc.UserDoc().presentationMode = 'watching'; + + // only get the movements that are remaining in the video time left + const filteredMovements = presentation.movements.filter(movement => movement.time > timeViewed * 1000) + + const handleFirstMovements = () => { + // if the first movement is a closed tab, open it + const firstMovement = filteredMovements[0]; + const isClosed = this.getCollectionFFView(firstMovement.docId) === undefined; + if (isClosed) this.openTab(firstMovement.docId, docIdtoDoc); + + // for the open tabs, set it to the first move + const docIdtoFirstMove = this.getFirstMovements(filteredMovements, timeViewed); + for (const [docId, firstMove] of docIdtoFirstMove) { + const colFFView = this.getCollectionFFView(docId); + if (colFFView) this.zoomAndPan(firstMove, colFFView); + } + } + handleFirstMovements(); + + + // make timers that will execute each movement at the correct replay time + this.timers = filteredMovements.map(movement => { + const timeDiff = movement.time - timeViewed * 1000 + + return setTimeout(() => { + const collectionFFView = this.getCollectionFFView(movement.docId); + if (collectionFFView) { + this.zoomAndPan(movement, collectionFFView); + } else { + // tab wasn't open - open it and play the movement + const openedColFFView = this.openTab(movement.docId, docIdtoDoc); + openedColFFView && this.zoomAndPan(movement, openedColFFView); + } + + // if last movement, presentation is done -> cleanup :) + if (movement === filteredMovements[filteredMovements.length - 1]) { + this.endPlayingPresentation(); + } + }, timeDiff); + }); + } +} diff --git a/src/client/util/RecordingApi.ts b/src/client/util/TrackMovements.ts index 87cb85497..342bb440e 100644 --- a/src/client/util/RecordingApi.ts +++ b/src/client/util/TrackMovements.ts @@ -1,20 +1,10 @@ -import { CollectionFreeFormView } from "../views/collections/collectionFreeForm"; import { IReactionDisposer, observable, observe, reaction } from "mobx"; import { NumCast } from "../../fields/Types"; import { Doc, DocListCast } from "../../fields/Doc"; -import { VideoBox } from "../views/nodes/VideoBox"; -import { isArray } from "lodash"; -import { SelectionManager } from "./SelectionManager"; -import { DocumentDecorations } from "../views/DocumentDecorations"; -import { DocumentManager } from "./DocumentManager"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; import { Id } from "../../fields/FieldSymbols"; -import { returnAll } from "../../Utils"; -import { ContextExclusionPlugin } from "webpack"; -import { DocServer } from "../DocServer"; -import { DocumentView } from "../views/nodes/DocumentView"; -type Movement = { +export type Movement = { time: number, panX: number, panY: number, @@ -22,14 +12,13 @@ type Movement = { docId: string, } - export type Presentation = { movements: Movement[] | null, totalTime: number, meta: Object | Object[], } -export class RecordingApi { +export class TrackMovements { private static get NULL_PRESENTATION(): Presentation { return { movements: null, meta: {}, totalTime: -1, } @@ -45,24 +34,20 @@ export class RecordingApi { // create static instance and getter for global use - @observable static _instance: RecordingApi; - public static get Instance(): RecordingApi { return RecordingApi._instance } - public constructor() { + @observable static _instance: TrackMovements; + static get Instance(): TrackMovements { return TrackMovements._instance } + constructor() { // init the global instance - RecordingApi._instance = this; + TrackMovements._instance = this; // init the instance variables - this.currentPresentation = RecordingApi.NULL_PRESENTATION + this.currentPresentation = TrackMovements.NULL_PRESENTATION this.tracking = false; this.absoluteStart = -1; // used for tracking movements in the view frame this.recordingFFViews = null; this.tabChangeDisposeFunc = null; - - // for now, set playFFView - // this.playFFView = null; - this.timers = null; } // little helper :) @@ -78,7 +63,7 @@ export class RecordingApi { const disposeFunc = reaction( () => ({ x: NumCast(doc.panX, -1), y: NumCast(doc.panY, -1), scale: NumCast(doc.viewScale, 0)}), - (res) => (res.x !== -1 && res.y !== -1 && this.tracking) && this.trackMovements(res.x, res.y, key, res.scale), + (res) => (res.x !== -1 && res.y !== -1 && this.tracking) && this.trackMovement(res.x, res.y, key, res.scale), ); this.recordingFFViews?.set(key, disposeFunc); } @@ -126,7 +111,7 @@ export class RecordingApi { } } - public initTabTracker = () => { + private initTabTracker = () => { if (this.recordingFFViews === null) { this.recordingFFViews = new Map(); } @@ -145,7 +130,7 @@ export class RecordingApi { }); } - public start = (meta?: Object) => { + start = (meta?: Object) => { this.initTabTracker(); // update the presentation mode @@ -165,7 +150,7 @@ export class RecordingApi { } /* stops the video and returns the presentatation; if no presentation, returns undefined */ - public yieldPresentation(clearData: boolean = true): Presentation | null { + yieldPresentation(clearData: boolean = true): Presentation | null { // if no presentation or done tracking, return null if (this.nullPresentation || !this.tracking) return null; @@ -182,14 +167,14 @@ export class RecordingApi { return cpy; } - public finish = (): void => { + finish = (): void => { // make is tracking false this.tracking = false // reset the RecordingApi instance this.clear(); } - public clear = (): void => { + private clear = (): void => { // clear the disposeFunc if we are done (not tracking) if (!this.tracking) { this.removeAllRecordingFFViews(); @@ -202,12 +187,12 @@ export class RecordingApi { } // clear presenation data - this.currentPresentation = RecordingApi.NULL_PRESENTATION + this.currentPresentation = TrackMovements.NULL_PRESENTATION // clear absoluteStart this.absoluteStart = -1 } - private removeAllRecordingFFViews = () => { + removeAllRecordingFFViews = () => { if (this.recordingFFViews === null) { console.warn('removeAllFFViews on null RecordingApi'); return; } for (const [id, disposeFunc] of this.recordingFFViews) { @@ -217,7 +202,7 @@ export class RecordingApi { } } - private trackMovements = (panX: number, panY: number, docId: string, scale: number = 0) => { + private trackMovement = (panX: number, panY: number, docId: string, scale: number = 0) => { // ensure we are recording to track if (!this.tracking) { console.error('[recordingApi.ts] trackMovements(): tracking is false') @@ -240,195 +225,6 @@ export class RecordingApi { this.currentPresentation.movements && this.currentPresentation.movements.push(movement) } - // TODO: extract this into different class with pause and resume recording - // TODO: store the FFview with the movements - private timers: NodeJS.Timeout[] | null; - - // pausing movements will dispose all timers that are planned to replay the movements - // play movemvents will recreate them when the user resumes the presentation - public pauseMovements = (): undefined | Error => { - - if (!this._isPlaying) { console.warn('[recordingApi.ts] pauseMovements(): already on paused'); return;} - this._isPlaying = false - // TODO: set userdoc presentMode to browsing - this.timers?.map(timer => clearTimeout(timer)) - - // this.videoBox = null; - } - - private videoBoxDisposeFunc: IReactionDisposer | null = null; - private videoBox: VideoBox | null = null; - - setVideoBox = async (videoBox: VideoBox) => { - console.log('setVideoBox', videoBox); - if (videoBox !== null) { console.warn('setVideoBox on already videoBox'); } - if (this.videoBoxDisposeFunc !== null) { console.warn('setVideoBox on already videoBox dispose func'); this.videoBoxDisposeFunc(); } - - - const { presentation } = videoBox; - if (presentation == null) { console.warn('setVideoBox on null videoBox presentation'); return; } - - let docIdtoDoc: Map<string, Doc> = new Map(); - try { - docIdtoDoc = await this.loadPresentation(presentation); - } catch { - console.error('[recordingApi.ts] setVideoBox(): error loading presentation - no replay movements'); - throw 'error loading docs from server'; - } - - - this.videoBoxDisposeFunc = - reaction(() => ({ playing: videoBox._playing, timeViewed: videoBox.player?.currentTime || 0 }), - ({ playing, timeViewed }) => - playing ? this.playMovements(presentation, docIdtoDoc, timeViewed) : this.pauseMovements() - ); - this.videoBox = videoBox; - } - - removeVideoBox = () => { - if (this.videoBoxDisposeFunc == null) { console.warn('removeVideoBox on null videoBox'); return; } - this.videoBoxDisposeFunc(); - - this.videoBox = null; - this.videoBoxDisposeFunc = null; - } - - - // by calling pause on the VideoBox, the pauseMovements will be called - public pauseFromInteraction = () => { - Doc.UserDoc().presentationMode = 'none'; - this.videoBox?.Pause(); - - this.pauseMovements(); - // return this.videoBox == null - } - - - - public _isPlaying = false; - - loadPresentation = async (presentation: Presentation) => { - const { movements } = presentation; - if (movements === null) { - throw '[recordingApi.ts] followMovements() failed: no presentation data'; - } - - // generate a set of all unique docIds - const docIds = new Set<string>(); - for (const {docId} of movements) { - if (!docIds.has(docId)) docIds.add(docId); - } - - const docIdtoDoc = new Map<string, Doc>(); - - let refFields = await DocServer.GetRefFields([...docIds.keys()]); - for (const docId in refFields) { - if (!refFields[docId]) { - throw `one field was undefined`; - } - docIdtoDoc.set(docId, refFields[docId] as Doc); - } - console.log('loadPresentation refFields', refFields, docIdtoDoc); - - return docIdtoDoc; - } - - // returns undefined if the docView isn't open on the screen - getCollectionFFView = (docId: string) => { - const isInView = DocumentManager.Instance.getDocumentViewById(docId); - if (isInView) { return isInView.ComponentView as CollectionFreeFormView; } - } - - // will open the doc in a tab then return the CollectionFFView that holds it - openTab = (docId: string, docIdtoDoc: Map<string, Doc>) => { - const doc = docIdtoDoc.get(docId); - if (doc == undefined) { - console.error(`docIdtoDoc did not contain docId ${docId}`) - return undefined; - } - CollectionDockingView.AddSplit(doc, 'right'); - const docView = DocumentManager.Instance.getDocumentViewById(docId); - return docView?.ComponentView as CollectionFreeFormView; - } - - // helper to replay a movement - private preScale = -1; - zoomAndPan = (movement: Movement, document: CollectionFreeFormView) => { - const { panX, panY, scale } = movement; - (scale !== 0 && this.preScale !== scale) && document.zoomSmoothlyAboutPt([panX, panY], scale, 0); - document.Document._panX = panX; - document.Document._panY = panY; - - this.preScale = scale; - } - - getFirstMovements = (movements: Movement[], timeViewed: number): Map<string, Movement> => { - if (movements === null) return new Map(); - // generate a set of all unique docIds - const docIdtoFirstMove = new Map(); - for (const move of movements) { - const { docId } = move; - if (!docIdtoFirstMove.has(docId)) docIdtoFirstMove.set(docId, move); - } - return docIdtoFirstMove; - } - - endPlayingPresentation = () => { - this.preScale = -1; - RecordingApi.Instance._isPlaying = false; - } - - public playMovements = (presentation: Presentation, docIdtoDoc: Map<string, Doc>, timeViewed: number = 0) => { - console.log('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') - } - if (this._isPlaying) return; - - this._isPlaying = true; - Doc.UserDoc().presentationMode = 'watching'; - - // only get the movements that are remaining in the video time left - const filteredMovements = presentation.movements.filter(movement => movement.time > timeViewed * 1000) - - const handleFirstMovements = () => { - // if the first movement is a closed tab, open it - const firstMovement = filteredMovements[0]; - const isClosed = this.getCollectionFFView(firstMovement.docId) === undefined; - if (isClosed) this.openTab(firstMovement.docId, docIdtoDoc); - - // for the open tabs, set it to the first move - const docIdtoFirstMove = this.getFirstMovements(filteredMovements, timeViewed); - for (const [docId, firstMove] of docIdtoFirstMove) { - const colFFView = this.getCollectionFFView(docId); - if (colFFView) this.zoomAndPan(firstMove, colFFView); - } - } - handleFirstMovements(); - - - // make timers that will execute each movement at the correct replay time - this.timers = filteredMovements.map(movement => { - const timeDiff = movement.time - timeViewed * 1000 - - return setTimeout(() => { - const collectionFFView = this.getCollectionFFView(movement.docId); - if (collectionFFView) { - this.zoomAndPan(movement, collectionFFView); - } else { - // tab wasn't open - open it and play the movement - const openedColFFView = this.openTab(movement.docId, docIdtoDoc); - openedColFFView && this.zoomAndPan(movement, openedColFFView); - } - - // if last movement, presentation is done -> cleanup :) - if (movement === filteredMovements[filteredMovements.length - 1]) { - this.endPlayingPresentation(); - } - }, timeDiff); - }); - } // method that concatenates an array of presentatations into one public concatPresentations = (presentations: Presentation[]): Presentation => { diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 517fe097c..c1b67ba19 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -8,7 +8,8 @@ import { AssignAllExtensions } from "../../extensions/General/Extensions"; import { Docs } from "../documents/Documents"; import { CurrentUserUtils } from "../util/CurrentUserUtils"; import { LinkManager } from "../util/LinkManager"; -import { RecordingApi } from "../util/RecordingApi"; +import { ReplayMovements } from '../util/ReplayMovements'; +import { TrackMovements } from "../util/TrackMovements"; import { CollectionView } from "./collections/CollectionView"; import { MainView } from "./MainView"; @@ -37,6 +38,7 @@ AssignAllExtensions(); const expires = "expires=" + d.toUTCString(); document.cookie = `loadtime=${loading};${expires};path=/`; new LinkManager(); - new RecordingApi; + new TrackMovements(); + new ReplayMovements(); ReactDOM.render(<MainView />, document.getElementById('root')); })();
\ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 7db3b1482..a661cebb8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -58,7 +58,7 @@ import React = require("react"); import { FieldView, FieldViewProps } from "../../nodes/FieldView"; import { InkTranscription } from "../../InkTranscription"; import e = require("connect-flash"); -import { RecordingApi } from "../../../util/RecordingApi"; +import { ReplayMovements } from "../../../util/ReplayMovements"; export const panZoomSchema = createSchema({ _panX: "number", @@ -1005,20 +1005,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection @action setPan(panX: number, panY: number, panTime: number = 0, clamp: boolean = false) { - // set the current respective FFview to the tab being panned. - // if (Doc.UserDoc()?.presentationMode === 'recording') { - // // RecordingApi.Instance.setRecordingFFView(this); - // console.log('setRecordingFFView', this); - // } - // TODO: make this based off the specific recording FFView - // (Doc.UserDoc()?.presentationMode === 'none' || Doc.UserDoc()?.presentationMode === 'watching') && RecordingApi.Instance.setPlayFFView(this); - // if (Doc.UserDoc()?.presentationMode === 'watching') { - // RecordingApi.Instance.pauseVideoAndMovements(); - // Doc.UserDoc().presentationMode = 'none'; - // // RecordingApi.Instance.pauseMovements() - // } // this is the easiest way to do this -> will talk with Bob about using mobx to do this to remove this line of code. - if (Doc.UserDoc()?.presentationMode === 'watching') RecordingApi.Instance.pauseFromInteraction(); + if (Doc.UserDoc()?.presentationMode === 'watching') ReplayMovements.Instance.pauseFromInteraction(); if (!this.isAnnotationOverlay && clamp) { // this section wraps the pan position, horizontally and/or vertically whenever the content is panned out of the viewing bounds diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index a28677525..0ff7c4292 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -8,7 +8,7 @@ import { FieldView } from "../FieldView"; import { VideoBox } from "../VideoBox"; import { RecordingView } from './RecordingView'; import { DocumentType } from "../../../documents/DocumentTypes"; -import { Presentation } from "../../../util/RecordingApi"; +import { Presentation } from "../../../util/TrackMovements"; import { Doc } from "../../../../fields/Doc"; import { Id } from "../../../../fields/FieldSymbols"; diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx index ec9838bdd..83ed6914e 100644 --- a/src/client/views/nodes/RecordingBox/RecordingView.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx @@ -8,7 +8,7 @@ import { IconContext } from "react-icons"; import { Networking } from '../../../Network'; import { Upload } from '../../../../server/SharedMediaTypes'; import { returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils'; -import { Presentation, RecordingApi } from '../../../util/RecordingApi'; +import { Presentation, TrackMovements } from '../../../util/TrackMovements'; export interface MediaSegment { videoChunks: any[], @@ -64,7 +64,7 @@ export function RecordingView(props: IRecordingViewProps) { useEffect(() => { if (finished) { // make the total presentation that'll match the concatted video - let concatPres = trackScreen && RecordingApi.Instance.concatPresentations(videos.map(v => v.presentation as Presentation)); + let concatPres = trackScreen && TrackMovements.Instance.concatPresentations(videos.map(v => v.presentation as Presentation)); // this async function uses the server to create the concatted video and then sets the result to it's accessPaths (async () => { @@ -135,7 +135,7 @@ export function RecordingView(props: IRecordingViewProps) { videoRecorder.current.onstart = (event: any) => { setRecording(true); // start the recording api when the video recorder starts - trackScreen && RecordingApi.Instance.start(); + trackScreen && TrackMovements.Instance.start(); }; videoRecorder.current.onstop = () => { @@ -149,7 +149,7 @@ export function RecordingView(props: IRecordingViewProps) { }; // depending on if a presenation exists, add it to the video - const presentation = RecordingApi.Instance.yieldPresentation(); + const presentation = TrackMovements.Instance.yieldPresentation(); setVideos(videos => [...videos, (presentation != null && trackScreen) ? { ...nextVideo, presentation } : nextVideo]); } @@ -174,7 +174,7 @@ export function RecordingView(props: IRecordingViewProps) { stream instanceof MediaStream && stream.getTracks().forEach(track => track.stop()); // finish/clear the recoringApi - RecordingApi.Instance.finish(); + TrackMovements.Instance.finish(); // this will call upon progessbar to update videos to be in the correct order setFinished(true); diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 34df03954..5a221fea4 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -28,9 +28,9 @@ import { AnchorMenu } from "../pdf/AnchorMenu"; import { StyleProp } from "../StyleProvider"; import { FieldView, FieldViewProps } from './FieldView'; import "./VideoBox.scss"; -import { Presentation, RecordingApi } from "../../util/RecordingApi"; -import { List } from "../../../fields/List"; +import { Presentation } from "../../util/TrackMovements"; import { RecordingBox } from "./RecordingBox"; +import { ReplayMovements } from "../../util/ReplayMovements"; const path = require('path'); @@ -148,7 +148,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp // if presentation data exists, pass it to the recordingPi if (this.presentation != null) { - RecordingApi.Instance.setVideoBox(this); + ReplayMovements.Instance.setVideoBox(this); } } @@ -159,7 +159,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp // dispose the recordingApi's observer if (this.presentation != null) { - RecordingApi.Instance.removeVideoBox(); + ReplayMovements.Instance.removeVideoBox(); } } |