From 513e9042ea815e964462e824d85fbd229381250f Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 27 Apr 2019 01:19:52 -0400
Subject: A bunch more stuff

---
 src/client/views/collections/CollectionVideoView.tsx | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

(limited to 'src/client/views/collections/CollectionVideoView.tsx')

diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index 779dc8fc3..d314e3fc0 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -1,6 +1,5 @@
 import { action, observable, trace } from "mobx";
 import { observer } from "mobx-react";
-import { KeyStore } from "../../../fields/KeyStore";
 import { ContextMenu } from "../ContextMenu";
 import { CollectionViewType, CollectionBaseView, CollectionRenderProps } from "./CollectionBaseView";
 import React = require("react");
@@ -8,6 +7,7 @@ import "./CollectionVideoView.scss";
 import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView";
 import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import { emptyFunction } from "../../../Utils";
+import { NumCast } from "../../../new_fields/Types";
 
 
 @observer
@@ -44,8 +44,9 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
         if (ele) {
             this._player = ele.getElementsByTagName("video")[0];
             console.log(this._player);
-            if (this.props.Document.GetNumber(KeyStore.CurPage, -1) >= 0) {
-                this._currentTimecode = this.props.Document.GetNumber(KeyStore.CurPage, -1);
+            const curPage = NumCast(this.props.Document.curPage, -1);
+            if (curPage >= 0) {
+                this._currentTimecode = curPage;
             }
         }
     }
@@ -69,7 +70,7 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
                 (this._player as any).AHackBecauseSomethingResetsTheVideoToZero = -1;
             } else {
                 this._currentTimecode = this._player.currentTime;
-                this.props.Document.SetNumber(KeyStore.CurPage, Math.round(this._currentTimecode));
+                this.props.Document.curPage = Math.round(this._currentTimecode);
             }
         }
     }
-- 
cgit v1.2.3-70-g09d2


From 506af03831bf3cc002f93ad8708eafb909c0a194 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 27 Apr 2019 22:27:26 -0400
Subject: Various fixes

---
 src/client/DocServer.ts                            | 24 ++++++++++++++++++----
 src/client/documents/Documents.ts                  |  2 +-
 src/client/northstar/dash-nodes/HistogramBox.tsx   |  2 +-
 src/client/views/collections/CollectionPDFView.tsx |  2 +-
 src/client/views/collections/CollectionSubView.tsx |  1 +
 .../views/collections/CollectionVideoView.tsx      |  2 +-
 src/client/views/collections/CollectionView.tsx    |  2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 +-
 src/client/views/nodes/FieldView.tsx               |  4 ++--
 src/client/views/nodes/FormattedTextBox.tsx        |  2 +-
 src/client/views/nodes/KeyValueBox.tsx             |  2 +-
 src/new_fields/util.ts                             |  5 +++--
 src/server/database.ts                             | 21 +++++++++++++------
 src/server/index.ts                                | 10 +++++----
 14 files changed, 55 insertions(+), 26 deletions(-)

(limited to 'src/client/views/collections/CollectionVideoView.tsx')

diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index c7cbfce37..07997f072 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -55,12 +55,28 @@ export namespace DocServer {
                 map[id] = cached;
             }
         }
-        const prom = Utils.EmitCallback(_socket, MessageStore.GetFields, requestedIds);
-        requestedIds.map((id, index) => _cache[id] = prom.then((fields: RefField[]) => fields[index]));
+        const prom = Utils.EmitCallback(_socket, MessageStore.GetRefFields, requestedIds).then(fields => {
+            for (const key in fields) {
+                const field = fields[key];
+                if (field) {
+                    fields[key] = SerializationHelper.Deserialize(field);
+                }
+            }
+            return fields;
+        });
+        requestedIds.forEach((id, index) => _cache[id] = prom.then((fields: RefField[]) => fields[index]));
         const fields = await prom;
-        requestedIds.map((id, index) => map[id] = fields[index]);
+        requestedIds.forEach((id, index) => {
+            const field = fields[index];
+            if (field) {
+                _cache[id] = field;
+            } else {
+                delete _cache[id];
+            }
+            map[id] = field;
+        });
         const otherFields = await Promise.all(promises);
-        waitingIds.map((id, index) => map[id] = otherFields[index]);
+        waitingIds.forEach((id, index) => map[id] = otherFields[index]);
         return map;
     }
 
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index c30fb21d5..2a9687bda 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -138,7 +138,7 @@ export namespace Docs {
         return webProto;
     }
     function CreateCollectionPrototype(): Doc {
-        let collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("DataKey"),
+        let collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("data"),
             { panX: 0, panY: 0, scale: 1, width: 500, height: 500 });
         return collProto;
     }
diff --git a/src/client/northstar/dash-nodes/HistogramBox.tsx b/src/client/northstar/dash-nodes/HistogramBox.tsx
index a9c68ccba..19d108676 100644
--- a/src/client/northstar/dash-nodes/HistogramBox.tsx
+++ b/src/client/northstar/dash-nodes/HistogramBox.tsx
@@ -26,7 +26,7 @@ import { Id } from "../../../new_fields/RefField";
 
 @observer
 export class HistogramBox extends React.Component<FieldViewProps> {
-    public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(HistogramBox, fieldStr); }
+    public static LayoutString(fieldStr: string = "data") { return FieldView.LayoutString(HistogramBox, fieldStr); }
     private _dropXRef = React.createRef<HTMLDivElement>();
     private _dropYRef = React.createRef<HTMLDivElement>();
     private _dropXDisposer?: DragManager.DragDropDisposer;
diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx
index e73b7b4a6..99438b4e8 100644
--- a/src/client/views/collections/CollectionPDFView.tsx
+++ b/src/client/views/collections/CollectionPDFView.tsx
@@ -13,7 +13,7 @@ import { NumCast } from "../../../new_fields/Types";
 @observer
 export class CollectionPDFView extends React.Component<FieldViewProps> {
 
-    public static LayoutString(fieldKey: string = "DataKey") {
+    public static LayoutString(fieldKey: string = "data") {
         return FieldView.LayoutString(CollectionPDFView, fieldKey);
     }
 
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 4d090b680..2c2d74302 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -53,6 +53,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
 
         @action
         protected async setCursorPosition(position: [number, number]) {
+            return;
             let ind;
             let doc = this.props.Document;
             let id = CurrentUserUtils.id;
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index d314e3fc0..d45be228a 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -18,7 +18,7 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
     @observable _currentTimecode: number = 0;
     @observable _isPlaying: boolean = false;
 
-    public static LayoutString(fieldKey: string = "DataKey") {
+    public static LayoutString(fieldKey: string = "data") {
         return FieldView.LayoutString(CollectionVideoView, fieldKey);
     }
     private get uIButtons() {
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index e7bf1e121..b72065bca 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -13,7 +13,7 @@ import { trace } from 'mobx';
 
 @observer
 export class CollectionView extends React.Component<FieldViewProps> {
-    public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(CollectionView, fieldStr); }
+    public static LayoutString(fieldStr: string = "data") { return FieldView.LayoutString(CollectionView, fieldStr); }
 
     private SubView = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
         let props = { ...this.props, ...renderProps };
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 18107e98a..dfacca204 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -314,7 +314,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                                 {this.childViews}
                             </InkingCanvas>
                         </CollectionFreeFormLinksView>
-                        <CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />
+                        {/* <CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" /> */}
                     </CollectionFreeFormViewPannableContents>
                     <CollectionFreeFormOverlayView {...this.getDocumentViewProps(this.props.Document)} />
                 </MarqueeView>
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index dc36c5914..df76f7cea 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -45,8 +45,8 @@ export interface FieldViewProps {
 
 @observer
 export class FieldView extends React.Component<FieldViewProps> {
-    public static LayoutString(fieldType: { name: string }, fieldStr: string = "DataKey") {
-        return `<${fieldType.name} {...props} fieldKey={${fieldStr}} />`;
+    public static LayoutString(fieldType: { name: string }, fieldStr: string = "data") {
+        return `<${fieldType.name} {...props} fieldKey={"${fieldStr}"} />`;
     }
 
     @computed
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 7a85c9dd3..96512718f 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -55,7 +55,7 @@ const RichTextDocument = makeInterface(richTextSchema);
 
 @observer
 export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTextBoxOverlay), RichTextDocument>(RichTextDocument) {
-    public static LayoutString(fieldStr: string = "DataKey") {
+    public static LayoutString(fieldStr: string = "data") {
         return FieldView.LayoutString(FormattedTextBox, fieldStr);
     }
     private _ref: React.RefObject<HTMLDivElement>;
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index ae39ebe2d..876a3c173 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -14,7 +14,7 @@ import { Doc, IsField } from "../../../new_fields/Doc";
 export class KeyValueBox extends React.Component<FieldViewProps> {
     private _mainCont = React.createRef<HTMLDivElement>();
 
-    public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(KeyValueBox, fieldStr); }
+    public static LayoutString(fieldStr: string = "data") { return FieldView.LayoutString(KeyValueBox, fieldStr); }
     @observable private _keyInput: string = "";
     @observable private _valueInput: string = "";
     @computed get splitPercentage() { return NumCast(this.props.Document.schemaSplitPercentage, 50); }
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 011e8c8d9..b2299f34a 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -5,8 +5,9 @@ import { ProxyField } from "./Proxy";
 import { FieldValue } from "./Types";
 import { RefField, Id } from "./RefField";
 import { ObjectField, Parent, OnUpdate } from "./ObjectField";
+import { action } from "mobx";
 
-export function setter(target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
+export const setter = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
     if (SerializationHelper.IsSerializing()) {
         target[prop] = value;
         return true;
@@ -46,7 +47,7 @@ export function setter(target: any, prop: string | symbol | number, value: any,
         undo: () => receiver[prop] = curValue
     });
     return true;
-}
+});
 
 export function getter(target: any, prop: string | symbol | number, receiver: any): any {
     if (typeof prop === "symbol") {
diff --git a/src/server/database.ts b/src/server/database.ts
index 6b3b6797f..4775c0eeb 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -60,19 +60,28 @@ export class Database {
     }
 
     public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = Database.DocumentsCollection) {
-        console.log("getDocument");
-        this.db && this.db.collection(collectionName).findOne({ id: id }, (err, result) =>
-            fn(result ? ({ id: result._id, type: result.type, data: result.data }) : undefined));
+        this.db && this.db.collection(collectionName).findOne({ _id: id }, (err, result) => {
+            if (result) {
+                result.id = result._id;
+                delete result._id;
+                fn(result);
+            } else {
+                fn(undefined);
+            }
+        });
     }
 
     public getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = Database.DocumentsCollection) {
-        console.log("getDocuments");
-        this.db && this.db.collection(collectionName).find({ id: { "$in": ids } }).toArray((err, docs) => {
+        this.db && this.db.collection(collectionName).find({ _id: { "$in": ids } }).toArray((err, docs) => {
             if (err) {
                 console.log(err.message);
                 console.log(err.errmsg);
             }
-            fn(docs.map(doc => ({ id: doc._id, type: doc.type, data: doc.data })));
+            fn(docs.map(doc => {
+                doc.id = doc._id;
+                delete doc._id;
+                return doc;
+            }));
         });
     }
 
diff --git a/src/server/index.ts b/src/server/index.ts
index 10158eb96..6801b3132 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -234,16 +234,18 @@ server.on("connection", function (socket: Socket) {
 
     Utils.AddServerHandler(socket, MessageStore.CreateField, CreateField);
     Utils.AddServerHandler(socket, MessageStore.UpdateField, diff => UpdateField(socket, diff));
-    Utils.AddServerHandler(socket, MessageStore.GetRefField, GetRefField);
-    Utils.AddServerHandler(socket, MessageStore.GetRefFields, GetRefFields);
+    Utils.AddServerHandlerCallback(socket, MessageStore.GetRefField, GetRefField);
+    Utils.AddServerHandlerCallback(socket, MessageStore.GetRefFields, GetRefFields);
 });
 
-function deleteFields() {
-    return Database.Instance.deleteAll();
+async function deleteFields() {
+    await Database.Instance.deleteAll();
+    await Database.Instance.deleteAll('newDocuments');
 }
 
 async function deleteAll() {
     await Database.Instance.deleteAll();
+    await Database.Instance.deleteAll('newDocuments');
     await Database.Instance.deleteAll('sessions');
     await Database.Instance.deleteAll('users');
 }
-- 
cgit v1.2.3-70-g09d2


From a2751d16babb38cde2b86b1cb8fc5d74c15762d7 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sun, 28 Apr 2019 00:23:18 -0400
Subject: Decent amount of stuff is working

---
 src/client/views/Main.tsx                                             | 2 +-
 src/client/views/collections/CollectionBaseView.tsx                   | 2 +-
 src/client/views/collections/CollectionPDFView.tsx                    | 3 ++-
 src/client/views/collections/CollectionVideoView.tsx                  | 3 ++-
 src/client/views/collections/CollectionView.tsx                       | 3 ++-
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx   | 2 +-
 src/client/views/nodes/CollectionFreeFormDocumentView.tsx             | 1 +
 src/client/views/nodes/DocumentView.tsx                               | 4 ++--
 src/client/views/nodes/FormattedTextBox.tsx                           | 3 ++-
 src/client/views/nodes/PDFBox.tsx                                     | 2 +-
 src/new_fields/RichTextField.ts                                       | 2 ++
 src/new_fields/Types.ts                                               | 2 +-
 12 files changed, 18 insertions(+), 11 deletions(-)

(limited to 'src/client/views/collections/CollectionVideoView.tsx')

diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 4a68d1c68..98c5a5306 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -165,7 +165,7 @@ export class Main extends React.Component {
     @action
     openWorkspace = async (doc: Doc, fromHistory = false) => {
         this.mainContainer = doc;
-        fromHistory || window.history.pushState(null, StrCast(doc.title), "/doc/" + doc.Id);
+        fromHistory || window.history.pushState(null, StrCast(doc.title), "/doc/" + doc[Id]);
         const col = await Cast(CurrentUserUtils.UserDocument.optionalRightCollection, Doc);
         // if there is a pending doc, and it has new data, show it (syip: we use a timeout to prevent collection docking view from being uninitialized)
         setTimeout(async () => {
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index b2fba1415..ed761d3f3 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -95,7 +95,7 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
             //TODO This won't create the field if it doesn't already exist
             const value = Cast(props.Document[props.fieldKey], listSpec(Doc));
             if (value !== undefined) {
-                if (allowDuplicates || !value.some(v => v.Id === doc.Id)) {
+                if (allowDuplicates || !value.some(v => v[Id] === doc[Id])) {
                     value.push(doc);
                 }
             } else {
diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx
index 99438b4e8..5a1af354a 100644
--- a/src/client/views/collections/CollectionPDFView.tsx
+++ b/src/client/views/collections/CollectionPDFView.tsx
@@ -8,6 +8,7 @@ import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import { CollectionRenderProps, CollectionBaseView, CollectionViewType } from "./CollectionBaseView";
 import { emptyFunction } from "../../../Utils";
 import { NumCast } from "../../../new_fields/Types";
+import { Id } from "../../../new_fields/RefField";
 
 
 @observer
@@ -33,7 +34,7 @@ export class CollectionPDFView extends React.Component<FieldViewProps> {
     }
 
     onContextMenu = (e: React.MouseEvent): void => {
-        if (!e.isPropagationStopped() && this.props.Document.Id !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
+        if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
             ContextMenu.Instance.addItem({ description: "PDFOptions", event: emptyFunction });
         }
     }
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index d45be228a..7232ecea2 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -8,6 +8,7 @@ import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormV
 import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import { emptyFunction } from "../../../Utils";
 import { NumCast } from "../../../new_fields/Types";
+import { Id } from "../../../new_fields/RefField";
 
 
 @observer
@@ -107,7 +108,7 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
     }
 
     onContextMenu = (e: React.MouseEvent): void => {
-        if (!e.isPropagationStopped() && this.props.Document.Id !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
+        if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
             ContextMenu.Instance.addItem({ description: "VideoOptions", event: emptyFunction });
         }
     }
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index b72065bca..c2049a09a 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -10,6 +10,7 @@ import { CurrentUserUtils } from '../../../server/authentication/models/current_
 import { observer } from 'mobx-react';
 import { undoBatch } from '../../util/UndoManager';
 import { trace } from 'mobx';
+import { Id } from '../../../new_fields/RefField';
 
 @observer
 export class CollectionView extends React.Component<FieldViewProps> {
@@ -31,7 +32,7 @@ export class CollectionView extends React.Component<FieldViewProps> {
     get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey === "annotations"; } // bcz: ? Why do we need to compare Id's?
 
     onContextMenu = (e: React.MouseEvent): void => {
-        if (!this.isAnnotationOverlay && !e.isPropagationStopped() && this.props.Document.Id !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
+        if (!this.isAnnotationOverlay && !e.isPropagationStopped() && this.props.Document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
             ContextMenu.Instance.addItem({ description: "Freeform", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Freeform) });
             ContextMenu.Instance.addItem({ description: "Schema", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Schema) });
             ContextMenu.Instance.addItem({ description: "Treeview", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Tree) });
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index dfacca204..dcded7648 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -257,7 +257,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             moveDocument: this.props.moveDocument,
             ScreenToLocalTransform: this.getTransform,
             isTopMost: false,
-            selectOnLoad: document.Id === this._selectOnLoaded,
+            selectOnLoad: document[Id] === this._selectOnLoaded,
             PanelWidth: () => Cast(document.width, "number", 0),//TODO Types These are inline functions
             PanelHeight: () => Cast(document.height, "number", 0),
             ContentScaling: returnOne,
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 376af0b36..8766eb7ea 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -20,6 +20,7 @@ const schema = createSchema({
     zIndex: "number"
 });
 
+//TODO Types: The import order is wrong, so positionSchema is undefined
 type FreeformDocument = makeInterface<[typeof schema, typeof positionSchema]>;
 const FreeformDocument = makeInterface(schema, positionSchema);
 
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c304b6a35..3814eeb9c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -139,7 +139,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     }
 
     onClick = (e: React.MouseEvent): void => {
-        if (CurrentUserUtils.MainDocId !== this.props.Document.Id &&
+        if (CurrentUserUtils.MainDocId !== this.props.Document[Id] &&
             (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD &&
                 Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) {
             SelectionManager.SelectDoc(this, e.ctrlKey);
@@ -247,7 +247,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         ContextMenu.Instance.addItem({ description: "Fields", event: this.fieldsClicked });
         ContextMenu.Instance.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) });
         ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) });
-        ContextMenu.Instance.addItem({ description: "Copy URL", event: () => Utils.CopyText(DocServer.prepend("/doc/" + this.props.Document.Id)) });
+        ContextMenu.Instance.addItem({ description: "Copy URL", event: () => Utils.CopyText(DocServer.prepend("/doc/" + this.props.Document[Id])) });
         ContextMenu.Instance.addItem({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]) });
         //ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) })
         ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked });
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 96512718f..c4c720ca9 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -22,6 +22,7 @@ import { observer } from "mobx-react";
 import { InkingControl } from "../InkingControl";
 import { StrCast, Cast } from "../../../new_fields/Types";
 import { RichTextField } from "../../../new_fields/RichTextField";
+import { Id } from "../../../new_fields/RefField";
 const { buildMenuItems } = require("prosemirror-example-setup");
 const { menuBar } = require("prosemirror-menu");
 
@@ -108,7 +109,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         };
 
         if (this.props.isOverlay) {
-            this._inputReactionDisposer = reaction(() => MainOverlayTextBox.Instance.TextDoc && MainOverlayTextBox.Instance.TextDoc.Id,
+            this._inputReactionDisposer = reaction(() => MainOverlayTextBox.Instance.TextDoc && MainOverlayTextBox.Instance.TextDoc[Id],
                 () => {
                     if (this._editorView) {
                         this._editorView.destroy();
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 7fbfed1c0..9f0849492 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -447,7 +447,7 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
         let pdfUrl = Cast(this.props.Document[this.props.fieldKey], PdfField);
         let xf = FieldValue(this.Document.nativeHeight, 0) / renderHeight;
         return <div className="pdfBox-contentContainer" key="container" style={{ transform: `scale(${xf}, ${xf})` }}>
-            <Document file={window.origin + RouteStore.corsProxy + `/${pdfUrl}`} renderMode={this._renderAsSvg ? "svg" : ""}>
+            <Document file={window.origin + RouteStore.corsProxy + `/${pdfUrl!.url.href}`} renderMode={this._renderAsSvg ? "svg" : ""}>
                 <Measure onResize={this.setScaling}>
                     {({ measureRef }) =>
                         <div className="pdfBox-page" ref={measureRef}>
diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts
index 0fa3cf73c..f2033d5a7 100644
--- a/src/new_fields/RichTextField.ts
+++ b/src/new_fields/RichTextField.ts
@@ -1,6 +1,8 @@
 import { ObjectField } from "./ObjectField";
 import { serializable } from "serializr";
+import { Deserializable } from "../client/util/SerializationHelper";
 
+@Deserializable("RichTextField")
 export class RichTextField extends ObjectField {
     @serializable(true)
     readonly Data: string;
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index 3f8eabd45..e179c2602 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -76,7 +76,7 @@ type WithoutList<T extends Field> = T extends List<infer R> ? R[] : T;
 export function FieldValue<T extends Field, U extends WithoutList<T>>(field: FieldResult<T>, defaultValue: U): WithoutList<T>;
 export function FieldValue<T extends Field>(field: FieldResult<T>): Opt<T>;
 export function FieldValue<T extends Field>(field: FieldResult<T>, defaultValue?: T): Opt<T> {
-    return field instanceof Promise ? defaultValue : field;
+    return (field instanceof Promise || field === undefined) ? defaultValue : field;
 }
 
 export interface PromiseLike<T> {
-- 
cgit v1.2.3-70-g09d2


From 105ba2402ad0da59d3d0750fa045a0f47eb73848 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 1 May 2019 10:51:17 -0400
Subject: cleaned up videos a bit.

---
 .../views/collections/CollectionVideoView.tsx      | 90 ++++++++--------------
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  4 +-
 src/client/views/nodes/DocumentView.tsx            |  5 +-
 src/client/views/nodes/FieldView.tsx               |  1 +
 src/client/views/nodes/VideoBox.tsx                | 37 ++++-----
 5 files changed, 55 insertions(+), 82 deletions(-)

(limited to 'src/client/views/collections/CollectionVideoView.tsx')

diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index 7232ecea2..9dee217cb 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -7,17 +7,16 @@ import "./CollectionVideoView.scss";
 import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView";
 import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import { emptyFunction } from "../../../Utils";
-import { NumCast } from "../../../new_fields/Types";
 import { Id } from "../../../new_fields/RefField";
+import { VideoBox } from "../nodes/VideoBox";
 
 
 @observer
 export class CollectionVideoView extends React.Component<FieldViewProps> {
-    private _intervalTimer: any = undefined;
-    private _player: HTMLVideoElement | undefined = undefined;
+    private _videoBox: VideoBox | undefined = undefined;
+    @observable _playTimer?: NodeJS.Timeout = undefined;
 
     @observable _currentTimecode: number = 0;
-    @observable _isPlaying: boolean = false;
 
     public static LayoutString(fieldKey: string = "data") {
         return FieldView.LayoutString(CollectionVideoView, fieldKey);
@@ -30,7 +29,7 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
                 <span style={{ fontSize: 8 }}>{" " + Math.round((this._currentTimecode - Math.trunc(this._currentTimecode)) * 100)}</span>
             </div>,
             <div className="collectionVideoView-play" key="play" onPointerDown={this.onPlayDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
-                {this._isPlaying ? "\"" : ">"}
+                {this._playTimer ? "\"" : ">"}
             </div>,
             <div className="collectionVideoView-full" key="full" onPointerDown={this.onFullDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
                 F
@@ -38,61 +37,37 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
         ]);
     }
 
-    _ele: HTMLDivElement | null = null;
     @action
-    mainCont = (ele: HTMLDivElement | null) => {
-        this._ele = ele;
-        if (ele) {
-            this._player = ele.getElementsByTagName("video")[0];
-            console.log(this._player);
-            const curPage = NumCast(this.props.Document.curPage, -1);
-            if (curPage >= 0) {
-                this._currentTimecode = curPage;
-            }
+    updateTimecode = () => {
+        if (this._videoBox && this._videoBox.player) {
+            this._currentTimecode = this._videoBox.player.currentTime;
+            this.props.Document.curPage = Math.round(this._currentTimecode);
         }
     }
 
-    componentDidMount() {
-        this._intervalTimer = setInterval(this.updateTimecode, 1000);
-    }
+    componentDidMount() { this.updateTimecode(); }
 
-    componentWillUnmount() {
-        clearInterval(this._intervalTimer);
-    }
-
-    @action
-    updateTimecode = () => {
-        this._player = this._player ? this._player : this._ele ? this._ele.getElementsByTagName("video")[0] : undefined;
-        if (this._player) {
-            let timecode = (this._player as any).hasOwnProperty("AHackBecauseSomethingResetsTheVideoToZero") ?
-                (this._player as any).AHackBecauseSomethingResetsTheVideoToZero : -1;
-            if (timecode !== -1 && Object) {
-                this._player.currentTime = timecode;
-                (this._player as any).AHackBecauseSomethingResetsTheVideoToZero = -1;
-            } else {
-                this._currentTimecode = this._player.currentTime;
-                this.props.Document.curPage = Math.round(this._currentTimecode);
-            }
-        }
-    }
+    componentWillUnmount() { if (this._playTimer) clearInterval(this._playTimer); }
 
     @action
     onPlayDown = () => {
-        if (this._player) {
-            if (this._player.paused) {
-                this._player.play();
-                this._isPlaying = true;
+        if (this._videoBox && this._videoBox.player) {
+            if (this._videoBox.player.paused) {
+                this._videoBox.player.play();
+                if (!this._playTimer) this._playTimer = setInterval(this.updateTimecode, 1000);
             } else {
-                this._player.pause();
-                this._isPlaying = false;
+                this._videoBox.player.pause();
+                if (this._playTimer) clearInterval(this._playTimer);
+                this._playTimer = undefined;
+
             }
         }
     }
 
     @action
     onFullDown = (e: React.PointerEvent) => {
-        if (this._player) {
-            this._player.requestFullscreen();
+        if (this._videoBox && this._videoBox.player) {
+            this._videoBox.player.requestFullscreen();
             e.stopPropagation();
             e.preventDefault();
         }
@@ -100,11 +75,13 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
 
     @action
     onResetDown = () => {
-        if (this._player) {
-            this._player.pause();
-            this._player.currentTime = 0;
+        if (this._videoBox && this._videoBox.player) {
+            this._videoBox.player.pause();
+            this._videoBox.player.currentTime = 0;
+            if (this._playTimer) clearInterval(this._playTimer);
+            this._playTimer = undefined;
+            this.updateTimecode();
         }
-
     }
 
     onContextMenu = (e: React.MouseEvent): void => {
@@ -113,20 +90,19 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
         }
     }
 
+    setVideoBox = (player: VideoBox) => { this._videoBox = player; }
+
     private subView = (_type: CollectionViewType, renderProps: CollectionRenderProps) => {
         let props = { ...this.props, ...renderProps };
-        return (
-            <>
-                <CollectionFreeFormView {...props} CollectionView={this} />
-                {this.props.isSelected() ? this.uIButtons : (null)}
-            </>
-        );
+        return (<>
+            <CollectionFreeFormView {...props} setVideoBox={this.setVideoBox} CollectionView={this} />
+            {this.props.isSelected() ? this.uIButtons : (null)}
+        </>);
     }
 
     render() {
-        trace();
         return (
-            <CollectionBaseView {...this.props} className="collectionVideoView-cont" contentRef={this.mainCont} onContextMenu={this.onContextMenu}>
+            <CollectionBaseView {...this.props} className="collectionVideoView-cont" onContextMenu={this.onContextMenu}>
                 {this.subView}
             </CollectionBaseView>);
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 4b759b948..54b721f7b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -71,7 +71,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     public getActiveDocuments = () => {
         const curPage = FieldValue(this.Document.curPage, -1);
         return FieldValue(this.children, [] as Doc[]).filter(doc => {
-            var page = Cast(doc.page, "number", -1);
+            var page = NumCast(doc.page, -1);
             return page === curPage || page === -1;
         });
     }
@@ -274,7 +274,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         let curPage = FieldValue(this.Document.curPage, -1);
         let docviews = (this.children || []).filter(doc => doc).reduce((prev, doc) => {
             if (!FieldValue(doc)) return prev;
-            var page = Cast(doc.page, "number", -1);
+            var page = NumCast(doc.page, -1);
             if (page === curPage || page === -1) {
                 let minim = Cast(doc.isMinimized, "boolean");
                 if (minim === undefined || !minim) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index cda9f9473..f58dc4a02 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -18,12 +18,11 @@ import "./DocumentView.scss";
 import React = require("react");
 import { Opt, Doc } from "../../../new_fields/Doc";
 import { DocComponent } from "../DocComponent";
-import { createSchema, makeInterface, listSpec } from "../../../new_fields/Schema";
-import { FieldValue, Cast, PromiseValue, StrCast } from "../../../new_fields/Types";
+import { createSchema, makeInterface } from "../../../new_fields/Schema";
+import { FieldValue, StrCast } from "../../../new_fields/Types";
 import { List } from "../../../new_fields/List";
 import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
 import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
-import { MarqueeView } from "../collections/collectionFreeForm/MarqueeView";
 import { DocServer } from "../../DocServer";
 import { Id } from "../../../new_fields/RefField";
 
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index c04b91c21..63009f2db 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -41,6 +41,7 @@ export interface FieldViewProps {
     focus: (doc: Doc) => void;
     PanelWidth: () => number;
     PanelHeight: () => number;
+    setVideoBox?: (player: VideoBox) => void;
 }
 
 @observer
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 184a89dbc..422508f90 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -2,15 +2,16 @@ import React = require("react");
 import { observer } from "mobx-react";
 import { FieldView, FieldViewProps } from './FieldView';
 import "./VideoBox.scss";
-import { action, computed } from "mobx";
+import { action, computed, trace } from "mobx";
 import { DocComponent } from "../DocComponent";
 import { positionSchema } from "./DocumentView";
 import { makeInterface } from "../../../new_fields/Schema";
 import { pageSchema } from "./ImageBox";
-import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
+import { Cast, FieldValue, NumCast, ToConstructor, ListSpec } from "../../../new_fields/Types";
 import { VideoField } from "../../../new_fields/URLField";
 import Measure from "react-measure";
 import "./VideoBox.scss";
+import { Field, FieldResult, Opt } from "../../../new_fields/Doc";
 
 type VideoDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>;
 const VideoDocument = makeInterface(positionSchema, pageSchema);
@@ -18,24 +19,20 @@ const VideoDocument = makeInterface(positionSchema, pageSchema);
 @observer
 export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoDocument) {
 
-    private _videoRef = React.createRef<HTMLVideoElement>();
+    private _videoRef: HTMLVideoElement | null = null;
+    private _loaded: boolean = false;
+    private get initialTimecode() { return FieldValue(this.Document.curPage, -1); }
     public static LayoutString() { return FieldView.LayoutString(VideoBox); }
 
-    constructor(props: FieldViewProps) {
-        super(props);
+    public get player(): HTMLVideoElement | undefined {
+        if (this._videoRef) {
+            return this._videoRef;
+        }
     }
-
-    @computed private get curPage() { return FieldValue(this.Document.curPage, -1); }
-
-
-    _loaded: boolean = false;
-
     @action
     setScaling = (r: any) => {
         if (this._loaded) {
             // bcz: the nativeHeight should really be set when the document is imported.
-            //      also, the native dimensions could be different for different pages of the PDF
-            //      so this design is flawed.
             var nativeWidth = FieldValue(this.Document.nativeWidth, 0);
             var nativeHeight = FieldValue(this.Document.nativeHeight, 0);
             var newNativeHeight = nativeWidth * r.entry.height / r.entry.width;
@@ -48,26 +45,26 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD
         }
     }
 
-    get player(): HTMLVideoElement | undefined {
-        return this._videoRef.current ? this._videoRef.current.getElementsByTagName("video")[0] : undefined;
+    componentDidMount() {
+        if (this.props.setVideoBox) this.props.setVideoBox(this);
     }
 
     @action
     setVideoRef = (vref: HTMLVideoElement | null) => {
-        if (this.curPage >= 0 && vref) {
-            vref.currentTime = this.curPage;
-            (vref as any).AHackBecauseSomethingResetsTheVideoToZero = this.curPage;
+        this._videoRef = vref;
+        if (this.initialTimecode >= 0 && vref) {
+            vref.currentTime = this.initialTimecode;
         }
     }
     videoContent(path: string) {
         return <video className="videobox-cont" ref={this.setVideoRef}>
             <source src={path} type="video/mp4" />
             Not supported.
-    </video>;
+        </video>;
     }
 
     render() {
-        let field = FieldValue(Cast(this.Document[this.props.fieldKey], VideoField));
+        let field = Cast(this.Document[this.props.fieldKey], VideoField);
         if (!field) {
             return <div>Loading</div>;
         }
-- 
cgit v1.2.3-70-g09d2

