aboutsummaryrefslogtreecommitdiff
path: root/src/client/apis/recording/recordingApi.ts
diff options
context:
space:
mode:
authorMichael Foiani <sotech117@michaels-mbp-3.devices.brown.edu>2022-04-28 16:33:43 -0400
committerMichael Foiani <sotech117@michaels-mbp-3.devices.brown.edu>2022-04-28 16:33:43 -0400
commitc21c424267711f9534944b749e9e4703dd3c4bd6 (patch)
tree334dcdb1e4cc0865a04e74de77083ae81992948c /src/client/apis/recording/recordingApi.ts
parentc1aead50030121554bf95ad392c80e042ec9c4d6 (diff)
Refactored recordingApi.ts into a class
Diffstat (limited to 'src/client/apis/recording/recordingApi.ts')
-rw-r--r--src/client/apis/recording/recordingApi.ts149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/client/apis/recording/recordingApi.ts b/src/client/apis/recording/recordingApi.ts
new file mode 100644
index 000000000..bdeeb79ea
--- /dev/null
+++ b/src/client/apis/recording/recordingApi.ts
@@ -0,0 +1,149 @@
+import { CollectionFreeFormView } from "../../views/collections/collectionFreeForm";
+import React, { useState } from "react";
+import { observable } from "mobx";
+
+type Movement = {
+ time: number,
+ panX: number,
+ panY: number,
+}
+
+type Presentation = {
+ movements: Array<Movement>
+ meta: Object,
+ startDate: Date | null,
+}
+
+export class RecordingApi {
+
+ private static NULL_PRESENTATION: Presentation = {
+ movements: [],
+ meta: {},
+ startDate: null,
+ }
+
+ // instance variables
+ private currentPresentation: Presentation;
+ private isRecording: boolean;
+ private absoluteStart: number;
+
+
+ constructor() {
+ this.currentPresentation = RecordingApi.NULL_PRESENTATION
+ this.isRecording = false;
+ this.absoluteStart = -1;
+ }
+
+ // little helper :)
+ private get isInitPresenation(): boolean {
+ return this.currentPresentation.startDate === null
+ }
+
+ public start = (view: CollectionFreeFormView, meta?: Object): Error | undefined => {
+ // check if already init a presentation
+ if (!this.isInitPresenation) {
+ console.error('[recordingApi.ts] start() failed: current presentation data exists. please call clear() first.')
+ return new Error('[recordingApi.ts] start()')
+ }
+
+ // (1a) get start date for presenation
+ const startDate = new Date()
+ // (1b) set start timestamp to absolute timestamp
+ this.absoluteStart = startDate.getTime()
+
+ // (2) assign meta content if it exists
+ this.currentPresentation.meta = meta || {}
+
+ // (3) assign start date to currentPresenation
+ this.currentPresentation.startDate = startDate
+
+ // (4) set isRecording true to allow trackMovements
+ this.isRecording = true
+ }
+
+ public clear = (): Error | undefined => {
+ // TODO: maybe archive the data?
+ if (this.isRecording) {
+ console.error('[recordingApi.ts] clear() failed: currently recording presentation. call pause() or finish() first')
+ return new Error('[recordingApi.ts] clear()')
+ }
+
+ // clear presenation data
+ this.currentPresentation = RecordingApi.NULL_PRESENTATION
+ // clear isRecording
+ this.isRecording = false
+ // clear absoluteStart
+ this.absoluteStart = -1
+ }
+
+ public pause = (): Error | undefined => {
+ if (this.currentPresentation.startDate === null) {
+ console.error('[recordingApi.ts] pause() failed: no presentation started. try calling init() first')
+ return new Error('[recordingApi.ts] pause(): no presenation')
+ }
+ // don't allow track movments
+ this.isRecording = false
+
+ // set relativeStart to the pausedTimestamp
+ const timestamp = new Date().getTime()
+ this.absoluteStart = timestamp
+ }
+
+ public resume = () => {
+ const timestamp = new Date().getTime()
+ const startTimestamp = this.currentPresentation.startDate?.getTime()
+ if (!startTimestamp) {
+ console.error('[recordingApi.ts] resume() failed: no presentation data. try calling start() first')
+ return new Error('[recordingApi.ts] pause()')
+ }
+
+ // update absoluteStart to bridge the paused time
+ const absoluteTimePaused = timestamp - this.absoluteStart
+ this.absoluteStart = absoluteTimePaused
+ }
+
+ public finish = (): Error | Presentation => {
+ if (this.isInitPresenation) {
+ console.error('[recordingApi.ts] finish() failed: no presentation data. try calling start() first')
+ return new Error('[recordingApi.ts] finish()')
+ }
+
+ // return a copy of the the presentation data
+ return { ...this.currentPresentation }
+ }
+
+ public trackMovements = (panX: number, panY: number): Error | undefined => {
+ // ensure we are recording
+ if (!this.isRecording) {
+ console.error('[recordingApi.ts] pause() failed: recording is paused()')
+ return new Error('[recordingApi.ts] pause()')
+ }
+
+ // get the relative time
+ const timestamp = new Date().getTime()
+ const relativeTime = timestamp - this.absoluteStart
+
+ // make new movement struct
+ const movement: Movement = { time: relativeTime, panX, panY }
+
+ // add that movement to the current presentation data's movement array
+ this.currentPresentation.movements.push(movement)
+ }
+
+ // TOOD: need to pause all intervals if possible lol
+ // TODO: extract this into different class with pause and resume recording
+ public followMovements = (presentation: Presentation, docView: CollectionFreeFormView): void => {
+ const document = docView.Document
+
+ const { movements } = presentation
+ movements.forEach(movement => {
+ const { panX, panY, time } = movement
+ // set the pan to what was stored
+ setTimeout(() => {
+ document._panX = panX;
+ document._panY = panY;
+ }, time)
+ })
+ }
+
+} \ No newline at end of file