aboutsummaryrefslogtreecommitdiff
path: root/src/client/apis/recording/RecordingApi.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/apis/recording/RecordingApi.ts')
-rw-r--r--src/client/apis/recording/RecordingApi.ts153
1 files changed, 153 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..64243e443
--- /dev/null
+++ b/src/client/apis/recording/RecordingApi.ts
@@ -0,0 +1,153 @@
+import { CollectionFreeFormView } from "../../views/collections/collectionFreeForm";
+import React, { useState } from "react";
+
+export namespace RecordingApi {
+
+ type Movement = {
+ time: number,
+ panX: number,
+ panY: number,
+ }
+
+ export type Presentation = {
+ movements: Array<Movement>
+ meta: Object,
+ startDate: Date | null,
+ }
+
+ const NULL_PRESENTATION = {
+ movements: [],
+ meta: {},
+ startDate: null,
+ }
+
+ const [currentPresentation, setCurrentPresenation] = useState<Presentation>(NULL_PRESENTATION)
+ const [isRecording, setIsRecording] = useState(false)
+ const [absoluteStart, setAbsoluteStart] = useState<number>(-1)
+
+ export const initAndStart = (meta?: Object): Error | undefined => {
+ // check if already init a presentation
+ if (currentPresentation.startDate !== null) {
+ 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
+ setAbsoluteStart(startDate.getTime())
+
+ // TODO: (2) assign meta content
+
+ // (3) assign init values to currentPresenation
+ setCurrentPresenation({ ...currentPresentation, startDate })
+
+ // (4) set isRecording true to allow trackMovements
+ setIsRecording(true)
+ }
+
+ export const clear = (): Error | undefined => {
+ // TODO: maybe archive the data?
+ if (isRecording) {
+ console.error('[recordingApi.ts] clear() failed: currently recording presentation. call pause() or finish() first')
+ return new Error('[recordingApi.ts] clear()')
+ }
+ // clear presenation data
+ setCurrentPresenation(NULL_PRESENTATION)
+
+ // set isRecording false
+ setIsRecording(false)
+
+ // default absoluteStart
+ setAbsoluteStart(-1)
+ }
+
+ export const pause = (): Error | undefined => {
+ if (currentPresentation.startDate === null) {
+ console.error('[recordingApi.ts] pause() failed: no presentation started. try calling init() first')
+ return new Error('[recordingApi.ts] pause()')
+ }
+ // don't allow track movments
+ setIsRecording(false)
+
+ // set relativeStart to the pausedTimestamp
+ const timestamp = new Date().getTime()
+ setAbsoluteStart(timestamp)
+ }
+
+ export const resume = () => {
+ if (currentPresentation.startDate === null) {
+ console.error('[recordingApi.ts] resume() failed: no presentation started. try calling init() first')
+ return new Error('[recordingApi.ts] resume()')
+ }
+
+ const timestamp = new Date().getTime()
+ const startTimestamp = currentPresentation.startDate?.getTime()
+ if (!startTimestamp) {
+ console.error('[recordingApi.ts] resume() failed: no presentation data. try calling init() first')
+ return new Error('[recordingApi.ts] pause()')
+ }
+
+ setAbsoluteStart(prevTime => {
+ // const relativeUnpause = timestamp - absoluteStart
+ // const timePaused = relativeUnpause - prevTime
+ // return timePaused + absoluteStart
+ const absoluteTimePaused = timestamp - prevTime
+ return absoluteTimePaused
+ })
+ }
+
+ export const finish = (): Error | Presentation => {
+ if (currentPresentation.movements === null) {
+ console.error('[recordingApi.ts] finish() failed: no presentation data. try calling init() first')
+ return new Error('[recordingApi.ts] finish()')
+ }
+
+ // make copy and clear this class's data
+ // const returnCopy = { ...currentPresentation }
+ // clear()
+
+ // // return the copy
+ // return returnCopy
+
+ return currentPresentation
+ }
+
+ export const trackMovements = (panX: number, panY: number): Error | undefined => {
+ // ensure we are recording
+ if (!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 - absoluteStart
+
+ // make new movement struct
+ const movement: Movement = { time: relativeTime, panX, panY }
+
+ // add that movement struct to the current presentation data
+ setCurrentPresenation(prevPres => {
+ const movements = [...prevPres.movements, movement]
+ return {...prevPres, movements}
+ })
+ }
+
+ // TOOD: need to pause all intervals if possible lol
+ // TODO: extract this into different class with pause and resume recording
+ export const 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