aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/apis/recording/recordingApi.tsx151
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx3
2 files changed, 153 insertions, 1 deletions
diff --git a/src/client/apis/recording/recordingApi.tsx b/src/client/apis/recording/recordingApi.tsx
new file mode 100644
index 000000000..55714f03b
--- /dev/null
+++ b/src/client/apis/recording/recordingApi.tsx
@@ -0,0 +1,151 @@
+import { CollectionFreeFormView } from "../../views/collections/collectionFreeForm";
+import React, { useState } from "react";
+
+export function RecordingApi() {
+
+ type Movement = {
+ time: number,
+ panX: number,
+ panY: number,
+ }
+
+ 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)
+
+ const initAndStart = (view: CollectionFreeFormView, 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)
+ }
+
+ 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)
+
+ // clear isRecording
+ setIsRecording(false)
+
+ // clear absoluteStart
+ setAbsoluteStart(-1)
+ }
+
+ 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(): no presenation')
+ }
+ // don't allow track movments
+ setIsRecording(false)
+
+ // set relativeStart to the pausedTimestamp
+ const timestamp = new Date().getTime()
+ setAbsoluteStart(timestamp)
+ }
+
+ 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
+ })
+ }
+
+ 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
+ }
+
+ 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
+ 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
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 75855f5d9..1db90a65a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -118,7 +118,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@observable _keyframeEditing = false;
@observable ChildDrag: DocumentView | undefined; // child document view being dragged. needed to update drop areas of groups when a group item is dragged.
- @observable storedMovements: object[] = []; // stores the movement if in presenting mode
+ @observable storedMovements: object[] = []; // stores the movement if in recoding mode
@computed get views() { return this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z).map(ele => ele.ele); }
@computed get backgroundEvents() { return this.props.layerProvider?.(this.layoutDoc) === false && SnappingManager.GetIsDragging(); }
@@ -959,6 +959,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
}
+
followMovements = (): void => {
// need the first for subtraction
let first = null;