From c3a24f3cd2d1d3baf5738c649552baadf3677385 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Tue, 14 May 2019 01:31:11 -0400
Subject: Refactored most of presentation view

---
 src/client/views/PresentationView.tsx | 166 ++++++++++++----------------------
 1 file changed, 59 insertions(+), 107 deletions(-)

(limited to 'src/client/views/PresentationView.tsx')

diff --git a/src/client/views/PresentationView.tsx b/src/client/views/PresentationView.tsx
index 3fb24a339..098e725c7 100644
--- a/src/client/views/PresentationView.tsx
+++ b/src/client/views/PresentationView.tsx
@@ -5,15 +5,20 @@ import "./PresentationView.scss"
 import "./Main.tsx";
 import { DocumentManager } from "../util/DocumentManager";
 import { Utils } from "../../Utils";
-import { Doc } from "../../new_fields/Doc";
+import { Doc, DocListCast, DocListCastAsync } from "../../new_fields/Doc";
 import { listSpec } from "../../new_fields/Schema";
-import { Cast, NumCast, FieldValue, PromiseValue } from "../../new_fields/Types";
+import { Cast, NumCast, FieldValue, PromiseValue, StrCast } from "../../new_fields/Types";
 import { Id } from "../../new_fields/RefField";
 import { List } from "../../new_fields/List";
 import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
 
 export interface PresViewProps {
-    //Document: Doc;
+    Document: Doc;
+}
+
+interface PresListProps extends PresViewProps {
+    deleteDocument(index: number): void;
+    gotoDocument(index: number): void;
 }
 
 
@@ -21,72 +26,40 @@ export interface PresViewProps {
 /**
  * Component that takes in a document prop and a boolean whether it's collapsed or not.
  */
-class PresentationViewItem extends React.Component<PresViewProps> {
-
-    @observable Document: Doc;
-    constructor(props: PresViewProps) {
-        super(props);
-        this.Document = FieldValue(Cast(FieldValue(Cast(CurrentUserUtils.UserDocument.activeWorkspace, Doc))!.presentationView, Doc))!;
-    }
-    //look at CollectionFreeformView.focusDocument(d)
-    @action
-    openDoc = (doc: Doc) => {
-        let docView = DocumentManager.Instance.getDocumentView(doc);
-        if (docView) {
-            docView.props.focus(docView.props.Document);
-        }
-    }
-
-    /**
-  * Removes a document from the presentation view
-  **/
-    @action
-    public RemoveDoc(doc: Doc) {
-        const value = Cast(this.Document.data, listSpec(Doc), []);
-        let index = -1;
-        for (let i = 0; i < value.length; i++) {
-            if (value[i][Id] === doc[Id]) {
-                index = i;
-                break;
-            }
-        }
-        if (index !== -1) {
-            value.splice(index, 1);
-        }
-    }
+class PresentationViewList extends React.Component<PresListProps> {
 
     /**
      * Renders a single child document. It will just append a list element.
      * @param document The document to render.
      */
-    renderChild(document: Doc) {
+    renderChild = (document: Doc, index: number) => {
         let title = document.title;
 
         //to get currently selected presentation doc
-        let selected = NumCast(this.Document.selectedDoc, 0);
+        let selected = NumCast(this.props.Document.selectedDoc, 0);
 
-        // finally, if it's a normal document, then render it as such.
-        const children = Cast(this.Document.data, listSpec(Doc));
-        const styles: any = {};
-        if (children && children[selected] === document) {
+        let className = "presentationView-item";
+        if (selected === index) {
             //this doc is selected
-            styles.background = "gray";
+            className += " presentationView-selected";
         }
         return (
-            <li className="presentationView-item" style={styles} key={Utils.GenerateGuid()}>
-                <div className="presentationView-header" onClick={() => this.openDoc(document)}>{title}</div>
-                <div className="presentation-icon" onClick={() => this.RemoveDoc(document)}>X</div>
-            </li>
+            <div className={className} key={document[Id] + index} onClick={e => { this.props.gotoDocument(index); e.stopPropagation(); }}>
+                <strong className="presentationView-name">
+                    {`${index + 1}. ${title}`}
+                </strong>
+                <button className="presentation-icon" onClick={e => { this.props.deleteDocument(index); e.stopPropagation(); }}>X</button>
+            </div>
         );
 
     }
 
     render() {
-        const children = Cast(this.Document.data, listSpec(Doc), []);
+        const children = DocListCast(this.props.Document.data);
 
         return (
-            <div>
-                {children.map(value => this.renderChild(value))}
+            <div className="presentationView-listCont">
+                {children.map(this.renderChild)}
             </div>
         );
     }
@@ -100,59 +73,42 @@ export class PresentationView extends React.Component<PresViewProps>  {
     //observable means render is re-called every time variable is changed
     @observable
     collapsed: boolean = false;
-    closePresentation = action(() => this.Document!.width = 0);
+    closePresentation = action(() => this.props.Document.width = 0);
     next = () => {
-        const current = NumCast(this.Document!.selectedDoc);
-        const allDocs = FieldValue(Cast(this.Document!.data, listSpec(Doc)));
-        if (allDocs && current < allDocs.length + 1) {
-            //can move forwards
-            this.Document!.selectedDoc = current + 1;
-            const doc = allDocs[current + 1];
-            let docView = DocumentManager.Instance.getDocumentView(doc);
-            if (docView) {
-                docView.props.focus(docView.props.Document);
-            }
-        }
+        const current = NumCast(this.props.Document.selectedDoc);
+        this.gotoDocument(current + 1);
 
     }
     back = () => {
-        const current = NumCast(this.Document!.selectedDoc);
-        const allDocs = FieldValue(Cast(this.Document!.data, listSpec(Doc)));
-        if (allDocs && current - 1 >= 0) {
-            //can move forwards
-            this.Document!.selectedDoc = current - 1;
-            const doc = allDocs[current - 1];
-            let docView = DocumentManager.Instance.getDocumentView(doc);
-            if (docView) {
-                docView.props.focus(docView.props.Document);
-            }
+        const current = NumCast(this.props.Document.selectedDoc);
+        this.gotoDocument(current - 1);
+    }
+
+    @action
+    public RemoveDoc = (index: number) => {
+        const value = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
+        if (value) {
+            value.splice(index, 1);
         }
     }
 
-    private ref = React.createRef<HTMLDivElement>();
+    public gotoDocument = async (index: number) => {
+        const list = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
+        if (!list) {
+            return;
+        }
+        if (index < 0 || index >= list.length) {
+            return;
+        }
+
+        this.props.Document.selectedDoc = index;
+        const doc = await list[index];
+        DocumentManager.Instance.jumpToDocument(doc);
+    }
 
-    @observable Document?: Doc;
     //initilize class variables
     constructor(props: PresViewProps) {
         super(props);
-        let self = this;
-        reaction(() =>
-            CurrentUserUtils.UserDocument.activeWorkspace,
-            (activeW) => {
-                if (activeW && activeW instanceof Doc) {
-                    PromiseValue(Cast(activeW.presentationView, Doc)).
-                        then(pv => runInAction(() => {
-                            if (pv) self.Document = pv;
-                            else {
-                                pv = new Doc();
-                                pv.title = "Presentation Doc";
-                                activeW.presentationView = pv;
-                                self.Document = pv;
-                            }
-                        }))
-                }
-            },
-            { fireImmediately: true });
         PresentationView.Instance = this;
     }
 
@@ -162,36 +118,32 @@ export class PresentationView extends React.Component<PresViewProps>  {
     @action
     public PinDoc(doc: Doc) {
         //add this new doc to props.Document
-        const data = Cast(this.Document!.data, listSpec(Doc));
+        const data = Cast(this.props.Document.data, listSpec(Doc));
         if (data) {
             data.push(doc);
         } else {
-            this.Document!.data = new List([doc]);
+            this.props.Document.data = new List([doc]);
         }
 
-        this.Document!.width = 300;
+        this.props.Document.width = 300;
     }
 
     render() {
-        if (!this.Document)
-            return (null);
-        let titleStr = this.Document.Title;
-        let width = NumCast(this.Document.width);
+        let titleStr = StrCast(this.props.Document.title);
+        let width = NumCast(this.props.Document.width);
 
         //TODO: next and back should be icons
         return (
             <div className="presentationView-cont" style={{ width: width, overflow: "hidden" }}>
                 <div className="presentationView-heading">
                     <div className="presentationView-title">{titleStr}</div>
-                    <div className='presentation-icon' onClick={this.closePresentation}>X</div></div>
-                <div>
-                    <div className="presentation-back" onClick={this.back}>back</div>
-                    <div className="presentation-next" onClick={this.next}>next</div>
-
+                    <button className='presentation-icon' onClick={this.closePresentation}>X</button>
+                </div>
+                <div className="presentation-buttons">
+                    <button className="presentation-button" onClick={this.back}>back</button>
+                    <button className="presentation-button" onClick={this.next}>next</button>
                 </div>
-                <ul>
-                    <PresentationViewItem />
-                </ul>
+                <PresentationViewList Document={this.props.Document} deleteDocument={this.RemoveDoc} gotoDocument={this.gotoDocument} />
             </div>
         );
     }
-- 
cgit v1.2.3-70-g09d2

