From 8dfc0b0e9e3dc362ddb6074467b6be4213415b1c Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 8 Mar 2019 17:54:11 -0500
Subject: testing

---
 .../views/collections/CollectionFreeFormView.tsx   | 70 +++++++++++++++++++++-
 1 file changed, 68 insertions(+), 2 deletions(-)

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

diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 782313e55..195fe767f 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -1,4 +1,4 @@
-import { action, computed, observable } from "mobx";
+import { action, computed, observable, reaction, trace } from "mobx";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
 import { FieldWaiting } from "../../../fields/Field";
@@ -25,6 +25,7 @@ import "./CollectionFreeFormView.scss";
 import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
 import React = require("react");
+import { render } from "pug";
 const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
 
 @observer
@@ -296,6 +297,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
         const panx: number = -this.props.Document.GetNumber(KeyStore.PanX, 0);
         const pany: number = -this.props.Document.GetNumber(KeyStore.PanY, 0);
 
+        trace();
         return (
             <div className={`collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`}
                 onPointerDown={this.onPointerDown}
@@ -313,10 +315,74 @@ export class CollectionFreeFormView extends CollectionViewBase {
                     {this.backgroundView}
                     <InkingCanvas getScreenTransform={this.getTransform} Document={this.props.Document} />
                     {cursor}
-                    {this.views}
+                    <ViewRender {...this.props}></ViewRender>
                 </div>
                 {this.overlayView}
             </div>
         );
     }
+}
+
+@observer
+export class ViewRender extends CollectionViewBase {
+
+    @computed get panX(): number { return this.props.Document.GetNumber(KeyStore.PanX, 0) }
+    @computed get panY(): number { return this.props.Document.GetNumber(KeyStore.PanY, 0) }
+    @computed get scale(): number { return this.props.Document.GetNumber(KeyStore.Scale, 1); }
+    @computed get isAnnotationOverlay() { return this.props.fieldKey.Id === KeyStore.Annotations.Id; } // bcz: ? Why do we need to compare Id's?
+    @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); }
+    @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); }
+    @computed get zoomScaling() { return this.props.Document.GetNumber(KeyStore.Scale, 1); }
+    @computed get centeringShiftX() { return !this.props.Document.GetNumber(KeyStore.NativeWidth, 0) ? this.props.panelWidth() / 2 : 0; }  // shift so pan position is at center of window for non-overlay collections
+    @computed get centeringShiftY() { return !this.props.Document.GetNumber(KeyStore.NativeHeight, 0) ? this.props.panelHeight() / 2 : 0; }// shift so pan position is at center of window for non-overlay collections
+
+    @computed get views() { return this.props.Document.GetT<ListField<Document>>(this.props.fieldKey, ListField) }
+
+
+    focusDocument = (doc: Document) => {
+        let x = doc.GetNumber(KeyStore.X, 0) + doc.GetNumber(KeyStore.Width, 0) / 2;
+        let y = doc.GetNumber(KeyStore.Y, 0) + doc.GetNumber(KeyStore.Height, 0) / 2;
+        this.SetPan(x, y);
+        this.props.focus(this.props.Document);
+    }
+
+    @action
+    private SetPan(panX: number, panY: number) {
+        var x1 = this.getLocalTransform().inverse().Scale;
+        const newPanX = Math.min((1 - 1 / x1) * this.nativeWidth, Math.max(0, panX));
+        const newPanY = Math.min((1 - 1 / x1) * this.nativeHeight, Math.max(0, panY));
+        this.props.Document.SetNumber(KeyStore.PanX, this.isAnnotationOverlay ? newPanX : panX);
+        this.props.Document.SetNumber(KeyStore.PanY, this.isAnnotationOverlay ? newPanY : panY);
+    }
+
+
+    private _selectOnLoaded: string = ""; // id of document that should be selected once it's loaded (used for click-to-type)
+    getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).translate(-this.centeringShiftX, -this.centeringShiftY).transform(this.getLocalTransform())
+    getLocalTransform = (): Transform => Transform.Identity.scale(1 / this.scale).translate(this.panX, this.panY);
+    noScaling = () => 1;
+
+    render() {
+        var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1);
+        if (this.views && this.views != FieldWaiting) {
+            trace();
+            console.log("RENDER =" + this.views.Data.length);
+            return <div key="HERE">
+                {this.views.Data.map(doc => (doc.GetNumber(KeyStore.Page, 0) != curPage && doc.GetNumber(KeyStore.Page, 0) != 0) ? (null) :
+                    (<CollectionFreeFormDocumentView key={doc.Id} Document={doc}
+                        AddDocument={this.props.addDocument}
+                        RemoveDocument={this.props.removeDocument}
+                        ScreenToLocalTransform={this.getTransform}
+                        isTopMost={false}
+                        SelectOnLoad={doc.Id === this._selectOnLoaded}
+                        ContentScaling={this.noScaling}
+                        PanelWidth={doc.Width}
+                        PanelHeight={doc.Height}
+                        ContainingCollectionView={this.props.CollectionView}
+                        focus={this.focusDocument}
+                    />)
+                )}
+            </div>
+        }
+        return (null);
+    }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 96eede5f7d1706a3f7ac6ee02a85bb3da217f467 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 8 Mar 2019 20:22:22 -0500
Subject: diff lists to avoid rendering everything in a colletion free form
 view when an item is added/removed.

---
 .../views/collections/CollectionFreeFormView.tsx   | 68 +---------------------
 src/fields/ListField.ts                            | 34 ++++++-----
 2 files changed, 20 insertions(+), 82 deletions(-)

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

diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 195fe767f..16002ad9f 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -283,7 +283,6 @@ export class CollectionFreeFormView extends CollectionViewBase {
     }
 
     render() {
-
         //determines whether preview text cursor should be visible (ie when user taps this collection it should)
         let cursor = null;
         if (this._previewCursorVisible) {
@@ -297,7 +296,6 @@ export class CollectionFreeFormView extends CollectionViewBase {
         const panx: number = -this.props.Document.GetNumber(KeyStore.PanX, 0);
         const pany: number = -this.props.Document.GetNumber(KeyStore.PanY, 0);
 
-        trace();
         return (
             <div className={`collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`}
                 onPointerDown={this.onPointerDown}
@@ -315,74 +313,10 @@ export class CollectionFreeFormView extends CollectionViewBase {
                     {this.backgroundView}
                     <InkingCanvas getScreenTransform={this.getTransform} Document={this.props.Document} />
                     {cursor}
-                    <ViewRender {...this.props}></ViewRender>
+                    {this.views}
                 </div>
                 {this.overlayView}
             </div>
         );
     }
 }
-
-@observer
-export class ViewRender extends CollectionViewBase {
-
-    @computed get panX(): number { return this.props.Document.GetNumber(KeyStore.PanX, 0) }
-    @computed get panY(): number { return this.props.Document.GetNumber(KeyStore.PanY, 0) }
-    @computed get scale(): number { return this.props.Document.GetNumber(KeyStore.Scale, 1); }
-    @computed get isAnnotationOverlay() { return this.props.fieldKey.Id === KeyStore.Annotations.Id; } // bcz: ? Why do we need to compare Id's?
-    @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); }
-    @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); }
-    @computed get zoomScaling() { return this.props.Document.GetNumber(KeyStore.Scale, 1); }
-    @computed get centeringShiftX() { return !this.props.Document.GetNumber(KeyStore.NativeWidth, 0) ? this.props.panelWidth() / 2 : 0; }  // shift so pan position is at center of window for non-overlay collections
-    @computed get centeringShiftY() { return !this.props.Document.GetNumber(KeyStore.NativeHeight, 0) ? this.props.panelHeight() / 2 : 0; }// shift so pan position is at center of window for non-overlay collections
-
-    @computed get views() { return this.props.Document.GetT<ListField<Document>>(this.props.fieldKey, ListField) }
-
-
-    focusDocument = (doc: Document) => {
-        let x = doc.GetNumber(KeyStore.X, 0) + doc.GetNumber(KeyStore.Width, 0) / 2;
-        let y = doc.GetNumber(KeyStore.Y, 0) + doc.GetNumber(KeyStore.Height, 0) / 2;
-        this.SetPan(x, y);
-        this.props.focus(this.props.Document);
-    }
-
-    @action
-    private SetPan(panX: number, panY: number) {
-        var x1 = this.getLocalTransform().inverse().Scale;
-        const newPanX = Math.min((1 - 1 / x1) * this.nativeWidth, Math.max(0, panX));
-        const newPanY = Math.min((1 - 1 / x1) * this.nativeHeight, Math.max(0, panY));
-        this.props.Document.SetNumber(KeyStore.PanX, this.isAnnotationOverlay ? newPanX : panX);
-        this.props.Document.SetNumber(KeyStore.PanY, this.isAnnotationOverlay ? newPanY : panY);
-    }
-
-
-    private _selectOnLoaded: string = ""; // id of document that should be selected once it's loaded (used for click-to-type)
-    getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).translate(-this.centeringShiftX, -this.centeringShiftY).transform(this.getLocalTransform())
-    getLocalTransform = (): Transform => Transform.Identity.scale(1 / this.scale).translate(this.panX, this.panY);
-    noScaling = () => 1;
-
-    render() {
-        var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1);
-        if (this.views && this.views != FieldWaiting) {
-            trace();
-            console.log("RENDER =" + this.views.Data.length);
-            return <div key="HERE">
-                {this.views.Data.map(doc => (doc.GetNumber(KeyStore.Page, 0) != curPage && doc.GetNumber(KeyStore.Page, 0) != 0) ? (null) :
-                    (<CollectionFreeFormDocumentView key={doc.Id} Document={doc}
-                        AddDocument={this.props.addDocument}
-                        RemoveDocument={this.props.removeDocument}
-                        ScreenToLocalTransform={this.getTransform}
-                        isTopMost={false}
-                        SelectOnLoad={doc.Id === this._selectOnLoaded}
-                        ContentScaling={this.noScaling}
-                        PanelWidth={doc.Width}
-                        PanelHeight={doc.Height}
-                        ContainingCollectionView={this.props.CollectionView}
-                        focus={this.focusDocument}
-                    />)
-                )}
-            </div>
-        }
-        return (null);
-    }
-}
\ No newline at end of file
diff --git a/src/fields/ListField.ts b/src/fields/ListField.ts
index 6b8773920..ce32da0a6 100644
--- a/src/fields/ListField.ts
+++ b/src/fields/ListField.ts
@@ -49,20 +49,6 @@ export class ListField<T extends Field> extends BasicField<T[]> {
     }
 
     UpdateFromServer(fields: string[]) {
-        if (this._proxies.length < fields.length) {
-            var added = true;
-            for (let i = 0; i < this._proxies.length; i++) {
-                if (this._proxies[i] != fields[i]) {
-                    added = false;
-                    break;
-                }
-            }
-            if (added) {
-                for (let i = this._proxies.length; i < fields.length; i++)
-                    this._proxies.push(fields[i]);
-                return;
-            }
-        }
         this._proxies = fields;
     }
     private arraysEqual(a: any[], b: any[]) {
@@ -84,7 +70,25 @@ export class ListField<T extends Field> extends BasicField<T[]> {
     init(callback: (field: Field) => any) {
         Server.GetFields(this._proxies, action((fields: { [index: string]: Field }) => {
             if (!this.arraysEqual(this._proxies, this.Data.map(field => field.Id))) {
-                this.data = this._proxies.map(id => fields[id] as T)
+                var dataids = this.data.map(d => d.Id);
+                var added = this.data.length == this._proxies.length - 1;
+                var deleted = this.data.length > this._proxies.length;
+                for (let i = 0; i < dataids.length && added; i++)
+                    added = this._proxies.indexOf(dataids[i]) != -1;
+                for (let i = 0; i < this._proxies.length && deleted; i++)
+                    deleted = dataids.indexOf(this._proxies[i]) != -1;
+                if (added) { // if only 1 items was added
+                    for (let i = 0; i < this._proxies.length; i++)
+                        if (dataids.indexOf(this._proxies[i]) === -1)
+                            this.Data.splice(i, 0, fields[this._proxies[i]] as T);
+                } else if (deleted) { // if only items were deleted
+                    for (let i = this.data.length - 1; i >= 0; i--) {
+                        if (this._proxies.indexOf(this.data[i].Id) === -1) {
+                            this.Data.splice(i, 1);
+                        }
+                    }
+                } else // otherwise, just rebuild the whole list
+                    this.data = this._proxies.map(id => fields[id] as T)
                 observe(this.Data, () => {
                     this.updateProxies()
                     Server.UpdateField(this);
-- 
cgit v1.2.3-70-g09d2

