diff options
author | Michael Foiani <sotech117@michaels-mbp-5.devices.brown.edu> | 2022-06-14 15:57:54 -0400 |
---|---|---|
committer | Michael Foiani <sotech117@michaels-mbp-5.devices.brown.edu> | 2022-06-14 15:57:54 -0400 |
commit | f02aaa806d0dac2cd0d243b68e1942550122d266 (patch) | |
tree | d23ed43ee96015e1f8ecbf75a1f5fe747e2349b6 /src | |
parent | 7c9001006c1c7ffc10ab0bf0fe5a8b4af85f987f (diff) |
added code that correctly and effeicintly adds and removes reactions onto any tab the user observes
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/RecordingApi.ts | 100 |
1 files changed, 68 insertions, 32 deletions
diff --git a/src/client/util/RecordingApi.ts b/src/client/util/RecordingApi.ts index a8740a5bd..2b8d11818 100644 --- a/src/client/util/RecordingApi.ts +++ b/src/client/util/RecordingApi.ts @@ -1,13 +1,15 @@ import { CollectionFreeFormView } from "../views/collections/collectionFreeForm"; -import { IReactionDisposer, observable, reaction } from "mobx"; +import { IReactionDisposer, observable, observe, reaction } from "mobx"; import { NumCast } from "../../fields/Types"; -import { Doc } from "../../fields/Doc"; +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"; type Movement = { time: number, @@ -35,7 +37,8 @@ export class RecordingApi { private tracking: boolean; private absoluteStart: number; // instance variable for holding the FFViews and their disposers - private recordingFFViews: Map<String, IReactionDisposer> | null; + private recordingFFViews: Map<string, IReactionDisposer> | null; + private tabChangeDisposeFunc: IReactionDisposer | null; // create static instance and getter for global use @@ -52,6 +55,7 @@ export class RecordingApi { // used for tracking movements in the view frame this.recordingFFViews = null; + this.tabChangeDisposeFunc = null; // for now, set playFFView this.playFFView = null; @@ -63,30 +67,73 @@ export class RecordingApi { return this.currentPresentation.movements === null } - private addRecordingFFView(doc: Doc, docId: String): void { + private addRecordingFFView(doc: Doc, key: string = doc[Id]): void { + console.info('adding dispose func : docId', key, 'doc', doc); + + if (this.recordingFFViews === null) { console.warn('addFFView on null RecordingApi'); return; } + if (this.recordingFFViews.has(key)) { console.warn('addFFView : key already in map'); return; } + 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, docId, res.scale), + (res) => (res.x !== -1 && res.y !== -1 && this.tracking) && this.trackMovements(res.x, res.y, key, res.scale), ); - - console.log('adding dispose func : docId', docId, 'doc', doc); - this.recordingFFViews?.set(docId, disposeFunc); + this.recordingFFViews?.set(key, disposeFunc); } - public start = (meta?: Object) => { - // init the dispose funcs - this.recordingFFViews = new Map(); - // look over all open tabs and only track free form docs - for (const { contentItem, DashDoc } of CollectionDockingView.Instance.tabMap) { - if ('viewType' in DashDoc && DashDoc.viewType === 'freeform') { - const docId = contentItem.config.props.documentId; - // remove the proxy on the DashDoc by using the spread operator - this.addRecordingFFView(DashDoc, docId); + private removeRecordingFFView = (key: string) => { + console.info('removing dispose func : docId', key); + if (this.recordingFFViews === null) { console.warn('removeFFView on null RecordingApi'); return; } + this.recordingFFViews.get(key)?.(); + this.recordingFFViews.delete(key); + } + + // in the case where only one tab was changed (updates not across dashboards), set only one to true + private updateRecordingFFViewsFromTabs = (docList: Doc[], onlyOne = false) => { + if (this.recordingFFViews === null) return; + + // so that the size comparisons are correct, we must filter to only the FFViews + const isFFView = (doc: Doc) => doc && 'viewType' in doc && doc.viewType === 'freeform'; + const tabbedFFViews = new Set<String>(); + for (const DashDoc of docList) { + if (isFFView(DashDoc)) tabbedFFViews.add(DashDoc[Id]); + } + + + // new tab was added - need to add it + if (tabbedFFViews.size > this.recordingFFViews.size) { + for (const DashDoc of docList) { + if (!this.recordingFFViews.has(DashDoc[Id])) { + isFFView(DashDoc) && this.addRecordingFFView(DashDoc); + + // only one max change, so return + if (onlyOne) return; + } } } + // tab was removed - need to remove it from recordingFFViews + else if (tabbedFFViews.size < this.recordingFFViews.size) { + for (const [key] of this.recordingFFViews) { + if (!tabbedFFViews.has(key)) { + this.removeRecordingFFView(key); + if (onlyOne) return; + } + } + } + } - console.log(this.recordingFFViews); + public start = (meta?: Object) => { + // init the dispose funcs on the page + this.recordingFFViews = new Map(); + const docList = DocListCast(CollectionDockingView.Instance.props.Document.data); + this.updateRecordingFFViewsFromTabs(docList); + // create a reaction to monitor changes in tabs + this.tabChangeDisposeFunc = + reaction(() => CollectionDockingView.Instance.props.Document.data, + (change) => { + // TODO: consider changing between dashboards + this.updateRecordingFFViewsFromTabs(DocListCast(change), true); + }); // update the presentation mode Doc.UserDoc().presentationMode = 'recording'; @@ -118,6 +165,7 @@ export class RecordingApi { // reset the current presentation clearData && this.clear(); + console.log('yieldPresentation', cpy); return cpy; } @@ -132,6 +180,7 @@ export class RecordingApi { // clear the disposeFunc if we are done (not tracking) if (!this.tracking) { this.removeAllRecordingFFViews(); + this.tabChangeDisposeFunc?.(); // update the presentation mode now that we are done tracking Doc.UserDoc().presentationMode = 'none'; } @@ -144,7 +193,7 @@ export class RecordingApi { } private removeAllRecordingFFViews = () => { - if (this.recordingFFViews === null) { console.warn('removeFFView on null RecordingApi'); return; } + if (this.recordingFFViews === null) { console.warn('removeAllFFViews on null RecordingApi'); return; } for (const [id, disposeFunc] of this.recordingFFViews) { disposeFunc(); @@ -282,17 +331,4 @@ export class RecordingApi { // return the combined presentation with the updated total summed time return { movements: combinedMovements, totalTime: sumTime, meta: combinedMetas }; } - - // public AddRecordingFFView(ffView: Doc): void { - // pres.set(ffView, - // reaction(() => ({ x: ffView.panX, y: ffView.panY }), - // (pt) => RecordingApi.trackMovements(ffView, pt.x, pt.y))) - // ) - // } - - // public RemoveRecordingFFView(ffView: CollectionFreeFormView): void { - // const disposer = pres.get(ffView); - // disposer?.(); - // pres.delete(ffView) - // } } |