diff options
author | Michael Foiani <sotech117@michaels-mbp-3.devices.brown.edu> | 2022-05-04 03:30:07 -0400 |
---|---|---|
committer | Michael Foiani <sotech117@michaels-mbp-3.devices.brown.edu> | 2022-05-04 03:30:07 -0400 |
commit | a2173243c7a447527e2e86ec0a00998ed8b9cc40 (patch) | |
tree | 8bb3801f2298e0083d8eda69e0d5491617afe71c | |
parent | 4dc4b0939d4e4afbc9f6db999ff80d434ef4ccc6 (diff) |
Get play and pause to work. There is a bug with getting double called that was causing choppiness.
-rw-r--r-- | src/client/util/RecordingApi.ts | 207 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 10 |
3 files changed, 148 insertions, 71 deletions
diff --git a/src/client/util/RecordingApi.ts b/src/client/util/RecordingApi.ts index b53cba79d..dfe8e98ca 100644 --- a/src/client/util/RecordingApi.ts +++ b/src/client/util/RecordingApi.ts @@ -183,11 +183,10 @@ export class RecordingApi { // TODO: extract this into different class with pause and resume recording private playFFView: CollectionFreeFormView | null; - private timers: Timer[] | null; + private timers: NodeJS.Timeout[] | null; - // public followMovements = (presentation: Presentation): undefined | Error => { - // console.log(presentation) - // if (presentation.startDate === null || this.playFFView === null) { + // public loadPresentation = (presentation: Presentation): undefined | Error => { + // if (presentation.startTime === null || this.playFFView === null) { // return new Error('[recordingApi.ts] followMovements() failed: no presentation data or no view') // } @@ -195,48 +194,85 @@ export class RecordingApi { // const { movements } = presentation // this.timers = movements.map(movement => { // const { panX, panY, time } = movement - // return new Timer(() => { + + // const t = new Timer(() => { // document._panX = panX; // document._panY = panY; // // TODO: consider cleaning this array to null or some state - // }, time) + // }, time - presentation.startTime) + // t.pause() + // return t // }) + // console.log(this.timers) // } public setPlayFFView = (view: CollectionFreeFormView): void => { this.playFFView = view } + // public pauseMovements = (): undefined | Error => { + // console.log('[recordingApi.ts] pauseMovements()') + // if (this.playFFView === null) { + // return new Error('[recordingApi.ts] pauseMovements() failed: no view') + // } + // // TODO: set userdoc presentMode to browsing + // this.timers?.forEach(timer => timer.pause()) + // } + public pauseMovements = (): undefined | Error => { if (this.playFFView === null) { return new Error('[recordingApi.ts] pauseMovements() failed: no view') } - // TODO: set userdoc presentMode to browsing - this.timers?.forEach(timer => timer.pause()) - } - public resumeMovements = (): undefined | Error => { - if (this.playFFView === null) { - return new Error('[recordingApi.ts] resumeMovements() failed: no view') + if (!this._isPlaying) { + return new Error('[recordingApi.ts] pauseMovements() failed: not playing') } - this.timers?.forEach(timer => timer.resume()) + // TODO: set userdoc presentMode to browsing + //console.log('cleared timers', this.timers) + console.log(this.timers?.map(timer => clearTimeout(timer))) + console.log('[recordingApi.ts] pauseMovements()') + + this._isPlaying = false } - public followMovements = (presentation: Presentation): undefined | Error => { + // public resumeMovements = (): undefined | Error => { + // if (this.playFFView === null) { + // return new Error('[recordingApi.ts] resumeMovements() failed: no view') + // } + // console.log('resume') + // this.timers?.forEach(timer => timer.resume()) + // } + + private _isPlaying = false; + + public playMovements = (presentation: Presentation, timeViewed: number = 0): undefined | Error => { if (presentation.startTime === null || this.playFFView === null) { return new Error('[recordingApi.ts] followMovements() failed: no presentation data or no view') } + if (this._isPlaying) { + return new Error('[recordingApi.ts] playMovements() failed: already playing') + } + this._isPlaying = true; + + console.log(timeViewed) + const document = this.playFFView.Document const { movements } = presentation - movements.forEach(movement => { + this.timers = movements.reduce((arr: NodeJS.Timeout[], movement) => { const { panX, panY, time } = movement + const absoluteTime = time - presentation.startTime - timeViewed*1000 + if (absoluteTime < 0) return arr; + // set the pan to what was stored - setTimeout(() => { + arr.push(setTimeout(() => { document._panX = panX; document._panY = panY; - }, time - presentation.startTime) - }) + }, absoluteTime)) + return arr; + }, []) + + console.log(this.timers.length) } // Unfinished code for tracing multiple free form views // export let pres: Map<CollectionFreeFormView, IReactionDisposer> = new Map() @@ -258,58 +294,95 @@ export class RecordingApi { /** Represents the `setTimeout` with an ability to perform pause/resume actions * citation: https://stackoverflow.com/questions/3969475/javascript-pause-settimeout */ -export class Timer { - private _start: Date; - private _remaining: number; - private _durationTimeoutId?: NodeJS.Timeout; - private _callback: (...args: any[]) => void; - private _done = false; - get done () { - return this._done; +class Timer { + private timerId: NodeJS.Timeout | null; + private callback: (...args: any[]) => void + private start: number + private remaining: number; + + constructor(callback: (...args: any[]) => void, delay: number) { + this.callback = callback; + this.remaining = delay; + + this.start = Date.now(); + this.timerId = setTimeout(this.callback, this.remaining); } - public constructor(callback: (...args: any[]) => void, ms = 0) { - this._callback = () => { - callback(); - this._done = true; - }; - this._remaining = ms; - this.resume(); - } - - /** pauses the timer */ - public pause(): Timer { - if (this._durationTimeoutId && !this._done) { - this._clearTimeoutRef(); - this._remaining -= new Date().getTime() - this._start.getTime(); - } - return this; - } + public pause = () => { + console.log('[timer.ts] pause()') + this.timerId !== null && clearTimeout(this.timerId); + this.timerId = null; + this.remaining -= (Date.now() - this.start); + }; - /** resumes the timer */ - public resume(): Timer { - if (!this._durationTimeoutId && !this._done) { - this._start = new Date; - this._durationTimeoutId = setTimeout(this._callback, this._remaining); + public resume = () => { + if (this.timerId) { + return; } - return this; - } - /** - * clears the timeout and marks it as done. - * - * After called, the timeout will not resume - */ - public clearTimeout() { - this._clearTimeoutRef(); - this._done = true; - } + this.start = Date.now(); + this.timerId = setTimeout(this.callback, this.remaining); + }; - private _clearTimeoutRef() { - if (this._durationTimeoutId) { - clearTimeout(this._durationTimeoutId); - this._durationTimeoutId = undefined; - } - } - -}
\ No newline at end of file + public clear = () => { + console.log('[timer.ts] clear()') + this.timerId !== null && clearTimeout(this.timerId); + // this.timerId = null; + // this.remaining -= (Date.now() - this.start); + }; +} +// class Timer { +// private _start: Date; +// private _remaining: number; +// private _durationTimeoutId?: NodeJS.Timeout; +// private _callback: (...args: any[]) => void; +// private _done = false; +// get done () { +// return this._done; +// } + +// public constructor(callback: (...args: any[]) => void, ms = 0) { +// this._callback = () => { +// callback(); +// this._done = true; +// }; +// this._remaining = ms; +// this.resume(); +// } + +// /** pauses the timer */ +// public pause(): Timer { +// if (this._durationTimeoutId && !this._done) { +// this._clearTimeoutRef(); +// this._remaining -= new Date().getTime() - this._start.getTime(); +// } +// return this; +// } + +// /** resumes the timer */ +// public resume(): Timer { +// if (!this._durationTimeoutId && !this._done) { +// this._start = new Date; +// this._durationTimeoutId = setTimeout(this._callback, this._remaining); +// } +// return this; +// } + +// /** +// * clears the timeout and marks it as done. +// * +// * After called, the timeout will not resume +// */ +// public clearTimeout() { +// this._clearTimeoutRef(); +// this._done = true; +// } + +// private _clearTimeoutRef() { +// if (this._durationTimeoutId) { +// clearTimeout(this._durationTimeoutId); +// this._durationTimeoutId = undefined; +// } +// } + +// }
\ 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 8bcf6f46f..214d4bbdc 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -966,7 +966,7 @@ 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. - RecordingApi.Instance.setRecordingFFView(this); + Doc.UserDoc()?.presentationMode === 'recording' && RecordingApi.Instance.setRecordingFFView(this); // TODO: make this based off the specific recording FFView Doc.UserDoc()?.presentationMode !== 'recording' && RecordingApi.Instance.setPlayFFView(this); diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 7364a64d9..15a198a00 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -156,11 +156,10 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp @action public Play = (update: boolean = true) => { // if presentation isn't null, call followmovements on the recording api if (this.presentation) { - const err = RecordingApi.Instance.followMovements(this.presentation); - if (err) console.log(err); + const err = RecordingApi.Instance.playMovements(this.presentation, this.player?.currentTime || 0); + err && console.log(err) } - this._playing = true; const eleTime = this.player?.currentTime || 0; if (this.timeline) { @@ -198,6 +197,11 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp // pauses video @action public Pause = (update: boolean = true) => { + if (this.presentation) { + const err = RecordingApi.Instance.pauseMovements(); + err && console.log(err); + } + this._playing = false; this.removeCurrentlyPlaying(); try { |