From 215b73fbcfe0d6f205668e1bb7c755228e858ac9 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <mohammad_amoush@brown.edu>
Date: Mon, 29 Jul 2019 19:19:49 -0400
Subject: PresMode, CLoseable Pres, and some bug fixes

---
 .../presentationview/PresentationModeMenu.tsx      | 92 ++++++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 src/client/views/presentationview/PresentationModeMenu.tsx

(limited to 'src/client/views/presentationview/PresentationModeMenu.tsx')

diff --git a/src/client/views/presentationview/PresentationModeMenu.tsx b/src/client/views/presentationview/PresentationModeMenu.tsx
new file mode 100644
index 000000000..b3edeb1e2
--- /dev/null
+++ b/src/client/views/presentationview/PresentationModeMenu.tsx
@@ -0,0 +1,92 @@
+import React = require("react");
+import { observable, action, runInAction } from "mobx";
+import "./PresentationModeMenu.scss";
+import { observer } from "mobx-react";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+
+
+export interface PresModeMenuProps {
+    next: () => void;
+    back: () => void;
+    presStatus: boolean;
+    startOrResetPres: () => void;
+    closePresMode: () => void;
+}
+
+@observer
+export default class PresModeMenu extends React.Component<PresModeMenuProps> {
+
+    @observable private _top: number = 20;
+    @observable private _right: number = 0;
+    @observable private _opacity: number = 1;
+    @observable private _transition: string = "opacity 0.5s";
+    @observable private _transitionDelay: string = "";
+    //@observable private Pinned: boolean = false;
+
+
+    private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
+
+    @action
+    pointerEntered = (e: React.PointerEvent) => {
+        this._transition = "opacity 0.1s";
+        this._transitionDelay = "";
+        this._opacity = 1;
+    }
+
+    @action
+    dragging = (e: PointerEvent) => {
+        this._right -= e.movementX;
+        this._top += e.movementY;
+
+        e.stopPropagation();
+        e.preventDefault();
+    }
+
+    dragEnd = (e: PointerEvent) => {
+        document.removeEventListener("pointermove", this.dragging);
+        document.removeEventListener("pointerup", this.dragEnd);
+        e.stopPropagation();
+        e.preventDefault();
+    }
+
+    dragStart = (e: React.PointerEvent) => {
+        document.removeEventListener("pointermove", this.dragging);
+        document.addEventListener("pointermove", this.dragging);
+        document.removeEventListener("pointerup", this.dragEnd);
+        document.addEventListener("pointerup", this.dragEnd);
+        let clientRect = this._mainCont.current!.getBoundingClientRect();
+
+        // runInAction(() => this._left = (clientRect.width - e.nativeEvent.offsetX) + clientRect.left);
+        // runInAction(() => this._top = e.nativeEvent.offsetY);
+
+        e.stopPropagation();
+        e.preventDefault();
+    }
+
+    renderPlayPauseButton = () => {
+        if (this.props.presStatus) {
+            return <button title="Reset Presentation" className="presMenu-button" onClick={this.props.startOrResetPres}><FontAwesomeIcon icon="stop" /></button>;
+        } else {
+            return <button title="Start Presentation From Start" className="presMenu-button" onClick={this.props.startOrResetPres}><FontAwesomeIcon icon="play" /></button>;
+        }
+    }
+
+    render() {
+        return (
+            <div className="presMenu-cont" onPointerEnter={this.pointerEntered} ref={this._mainCont}
+                style={{ right: this._right, top: this._top, opacity: this._opacity, transition: this._transition, transitionDelay: this._transitionDelay }}>
+                <button title="Back" className="presMenu-button" onClick={this.props.back}><FontAwesomeIcon icon={"arrow-left"} /></button>
+                {this.renderPlayPauseButton()}
+                <button title="Next" className="presMenu-button" onClick={this.props.next}><FontAwesomeIcon icon={"arrow-right"} /></button>
+                <button className="presMenu-button" title="Close Presentation Menu" onClick={this.props.closePresMode}>
+                    <FontAwesomeIcon icon="times" size="lg" />
+                </button>
+                <div className="presMenu-dragger" onPointerDown={this.dragStart} style={{ width: "20px" }} />
+            </div >
+        );
+    }
+
+
+
+
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 3468440a4297a105cf4138892c3d163ca9a0c83c Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <mohammad_amoush@brown.edu>
Date: Tue, 30 Jul 2019 11:30:48 -0400
Subject: CleanUp and Documentation

---
 .../views/presentationview/PresentationElement.tsx | 37 ++++++-----
 .../views/presentationview/PresentationList.tsx    |  2 -
 .../presentationview/PresentationModeMenu.tsx      | 34 ++++++----
 .../views/presentationview/PresentationView.tsx    | 76 ++++++++++++++--------
 4 files changed, 92 insertions(+), 57 deletions(-)

(limited to 'src/client/views/presentationview/PresentationModeMenu.tsx')

diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx
index ccc3a72a9..11f3eb846 100644
--- a/src/client/views/presentationview/PresentationElement.tsx
+++ b/src/client/views/presentationview/PresentationElement.tsx
@@ -12,12 +12,8 @@ import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
 import { Utils, returnFalse, emptyFunction, returnOne } from "../../../Utils";
 import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager";
 import { SelectionManager } from "../../util/SelectionManager";
-import { indexOf } from "typescript-collections/dist/lib/arrays";
-import { map } from "bluebird";
 import { ContextMenu } from "../ContextMenu";
-import { DocumentContentsView } from "../nodes/DocumentContentsView";
 import { Transform } from "../../util/Transform";
-import { FieldView } from "../nodes/FieldView";
 import { DocumentView } from "../nodes/DocumentView";
 import { DocumentType } from "../../documents/Documents";
 import React = require("react");
@@ -73,9 +69,6 @@ export default class PresentationElement extends React.Component<PresentationEle
     private backUpDoc: Doc | undefined;
 
 
-
-
-
     constructor(props: PresentationElementProps) {
         super(props);
         this.selectedButtons = new Array(7);
@@ -114,6 +107,9 @@ export default class PresentationElement extends React.Component<PresentationEle
         }
     }
 
+    /**
+     * Function that will be called to receive stored backUp for buttons
+     */
     receiveButtonBackUp = async () => {
 
         //get the list that stores docs that keep track of buttons
@@ -404,6 +400,10 @@ export default class PresentationElement extends React.Component<PresentationEle
 
     }
 
+    /**
+     * Function that opens up the option to open a element on right when navigated,
+     * instead of openening it as tab as default.
+     */
     @action
     onRightTabClick = (e: React.MouseEvent) => {
         e.stopPropagation();
@@ -671,7 +671,6 @@ export default class PresentationElement extends React.Component<PresentationEle
 
     //This is used to add dragging as an event.
     onPointerEnter = (e: React.PointerEvent): void => {
-        // this.props.document.libraryBrush = true;
         if (e.buttons === 1 && SelectionManager.GetIsDragging()) {
             let selected = NumCast(this.props.mainDocument.selectedDoc, 0);
 
@@ -688,7 +687,6 @@ export default class PresentationElement extends React.Component<PresentationEle
 
     //This is used to remove the dragging when dropped.
     onPointerLeave = (e: React.PointerEvent): void => {
-        // this.props.document.libraryBrush = false;
         //to get currently selected presentation doc
         let selected = NumCast(this.props.mainDocument.selectedDoc, 0);
 
@@ -787,15 +785,23 @@ export default class PresentationElement extends React.Component<PresentationEle
             groupArray.push(tempStack.pop()!);
         }
     }
-
+    /**
+     * This function is a getter to get if a document is in previewMode.
+     */
     private get embedInline() {
         return BoolCast(this.props.document.embedOpen);
     }
 
+    /**
+     * This function sets document in presentation preview mode as the given value.
+     */
     private set embedInline(value: boolean) {
         this.props.document.embedOpen = value;
     }
 
+    /**
+     * The function that recreates that context menu of presentation elements.
+     */
     onContextMenu = (e: React.MouseEvent<HTMLDivElement>) => {
         e.preventDefault();
         e.stopPropagation();
@@ -803,20 +809,19 @@ export default class PresentationElement extends React.Component<PresentationEle
         ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
     }
 
+    /**
+     * The function that is responsible for rendering the a preview or not for this
+     * presentation element.
+     */
     renderEmbeddedInline = () => {
         if (!this.embedInline) {
             return (null);
         }
 
-        // return <ul key={this.props.document[Id] + "more"}>
-        //     {TreeView.GetChildElements([this.props.document], "", new Doc(), undefined, "", (doc: Doc, relativeTo?: Doc, before?: boolean) => false, this.props.removeDocByRef, this.move,
-        //         StrCast(this.props.document.dropAction) as dropActionType, (doc: Doc, dataDoc: Doc | undefined, where: string) => { }, Transform.Identity, () => ({ translateX: 0, translateY: 0 }), () => false, () => 400, 7)}
-        // </ul >;
         let propDocWidth = NumCast(this.props.document.nativeWidth);
         let propDocHeight = NumCast(this.props.document.nativeHeight);
         let scale = () => {
             let newScale = 175 / NumCast(this.props.document.nativeWidth, 175);
-            console.log("New Scale: ", newScale);
             return newScale;
         };
         return (
@@ -836,7 +841,7 @@ export default class PresentationElement extends React.Component<PresentationEle
                     addDocTab={returnFalse}
                     renderDepth={1}
                     PanelWidth={() => 350}
-                    PanelHeight={() => 100}
+                    PanelHeight={() => 90}
                     focus={emptyFunction}
                     selectOnLoad={false}
                     parentActive={returnFalse}
diff --git a/src/client/views/presentationview/PresentationList.tsx b/src/client/views/presentationview/PresentationList.tsx
index 2d63d41b5..e853c4070 100644
--- a/src/client/views/presentationview/PresentationList.tsx
+++ b/src/client/views/presentationview/PresentationList.tsx
@@ -7,8 +7,6 @@ import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc";
 import { NumCast, StrCast } from "../../../new_fields/Types";
 import { Id } from "../../../new_fields/FieldSymbols";
 import PresentationElement, { buttonIndex } from "./PresentationElement";
-import { DragManager } from "../../util/DragManager";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
 import "../../../new_fields/Doc";
 
 
diff --git a/src/client/views/presentationview/PresentationModeMenu.tsx b/src/client/views/presentationview/PresentationModeMenu.tsx
index b3edeb1e2..4de8da587 100644
--- a/src/client/views/presentationview/PresentationModeMenu.tsx
+++ b/src/client/views/presentationview/PresentationModeMenu.tsx
@@ -13,6 +13,10 @@ export interface PresModeMenuProps {
     closePresMode: () => void;
 }
 
+/**
+ * This class is responsible for modeling of the Presentation Mode Menu. The menu allows
+ * user to navigate through presentation elements, and start/stop the presentation.
+ */
 @observer
 export default class PresModeMenu extends React.Component<PresModeMenuProps> {
 
@@ -21,18 +25,14 @@ export default class PresModeMenu extends React.Component<PresModeMenuProps> {
     @observable private _opacity: number = 1;
     @observable private _transition: string = "opacity 0.5s";
     @observable private _transitionDelay: string = "";
-    //@observable private Pinned: boolean = false;
 
 
     private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
 
-    @action
-    pointerEntered = (e: React.PointerEvent) => {
-        this._transition = "opacity 0.1s";
-        this._transitionDelay = "";
-        this._opacity = 1;
-    }
-
+    /**
+     * The function that changes the coordinates of the menu, depending on the
+     * movement of the mouse when it's being dragged.
+     */
     @action
     dragging = (e: PointerEvent) => {
         this._right -= e.movementX;
@@ -42,6 +42,10 @@ export default class PresModeMenu extends React.Component<PresModeMenuProps> {
         e.preventDefault();
     }
 
+    /**
+     * The function that removes the event listeners that are responsible for
+     * dragging of the menu.
+     */
     dragEnd = (e: PointerEvent) => {
         document.removeEventListener("pointermove", this.dragging);
         document.removeEventListener("pointerup", this.dragEnd);
@@ -49,20 +53,24 @@ export default class PresModeMenu extends React.Component<PresModeMenuProps> {
         e.preventDefault();
     }
 
+    /**
+     * The function that starts the dragging of the presentation mode menu. When
+     * the lines on further right are clicked on.
+     */
     dragStart = (e: React.PointerEvent) => {
         document.removeEventListener("pointermove", this.dragging);
         document.addEventListener("pointermove", this.dragging);
         document.removeEventListener("pointerup", this.dragEnd);
         document.addEventListener("pointerup", this.dragEnd);
-        let clientRect = this._mainCont.current!.getBoundingClientRect();
-
-        // runInAction(() => this._left = (clientRect.width - e.nativeEvent.offsetX) + clientRect.left);
-        // runInAction(() => this._top = e.nativeEvent.offsetY);
 
         e.stopPropagation();
         e.preventDefault();
     }
 
+    /**
+     * The function that is responsible for rendering the play or pause button, depending on the
+     * status of the presentation.
+     */
     renderPlayPauseButton = () => {
         if (this.props.presStatus) {
             return <button title="Reset Presentation" className="presMenu-button" onClick={this.props.startOrResetPres}><FontAwesomeIcon icon="stop" /></button>;
@@ -73,7 +81,7 @@ export default class PresModeMenu extends React.Component<PresModeMenuProps> {
 
     render() {
         return (
-            <div className="presMenu-cont" onPointerEnter={this.pointerEntered} ref={this._mainCont}
+            <div className="presMenu-cont" ref={this._mainCont}
                 style={{ right: this._right, top: this._top, opacity: this._opacity, transition: this._transition, transitionDelay: this._transitionDelay }}>
                 <button title="Back" className="presMenu-button" onClick={this.props.back}><FontAwesomeIcon icon={"arrow-left"} /></button>
                 {this.renderPlayPauseButton()}
diff --git a/src/client/views/presentationview/PresentationView.tsx b/src/client/views/presentationview/PresentationView.tsx
index ea85a8c6a..4fe9d3a1b 100644
--- a/src/client/views/presentationview/PresentationView.tsx
+++ b/src/client/views/presentationview/PresentationView.tsx
@@ -16,7 +16,6 @@ import { faArrowRight, faArrowLeft, faPlay, faStop, faPlus, faTimes, faMinus, fa
 import { Docs } from "../../documents/Documents";
 import { undoBatch, UndoManager } from "../../util/UndoManager";
 import PresentationViewList from "./PresentationList";
-import { ContextMenu } from "../ContextMenu";
 import PresModeMenu from "./PresentationModeMenu";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
 
@@ -36,6 +35,7 @@ export interface PresViewProps {
 }
 
 const expandedWidth = 400;
+const presMinWidth = 300;
 
 @observer
 export class PresentationView extends React.Component<PresViewProps>  {
@@ -408,6 +408,10 @@ export class PresentationView extends React.Component<PresViewProps>  {
 
     }
 
+    /**
+     * This function  checks if right option is clicked on a presentation element, if not it does open it as a tab
+     * with help of CollectionDockingView.
+     */
     jumpToTabOrRight = (curDocButtons: boolean[], curDoc: Doc) => {
         if (curDocButtons[buttonIndex.OpenRight]) {
             DocumentManager.Instance.jumpToDocument(curDoc, false);
@@ -460,22 +464,6 @@ export class PresentationView extends React.Component<PresViewProps>  {
                 }
             }
 
-            //removing it from the backUp of selected Buttons
-            // let castedList = Cast(this.presButtonBackUp.selectedButtonDocs, listSpec(Doc));
-            // if (castedList) {
-            //     castedList.forEach(async (doc, indexOfDoc) => {
-            //         let curDoc = await doc;
-            //         let curDocId = StrCast(curDoc.docId);
-            //         if (curDocId === removedDoc[Id]) {
-            //             if (castedList) {
-            //                 castedList.splice(indexOfDoc, 1);
-            //                 return;
-            //             }
-            //         }
-            //     });
-
-            // }
-            //removing it from the backUp of selected Buttons
 
             let castedList = Cast(this.presButtonBackUp.selectedButtonDocs, listSpec(Doc));
             if (castedList) {
@@ -513,13 +501,16 @@ export class PresentationView extends React.Component<PresViewProps>  {
         }
     }
 
+    /**
+     * An alternative remove method that removes a doc from presentation by its actual
+     * reference.
+     */
     public removeDocByRef = (doc: Doc) => {
         let indexOfDoc = this.childrenDocs.indexOf(doc);
         const value = FieldValue(Cast(this.curPresentation.data, listSpec(Doc)));
         if (value) {
             value.splice(indexOfDoc, 1)[0];
         }
-        //this.RemoveDoc(indexOfDoc, true);
         if (indexOfDoc !== - 1) {
             return true;
         }
@@ -618,6 +609,11 @@ export class PresentationView extends React.Component<PresViewProps>  {
         this.curPresentation.presStatus = this.presStatus;
     }
 
+    /**
+     * This method is called to find the start document of presentation. So
+     * that when user presses on play, the correct presentation element will be
+     * selected.
+     */
     findStartDocument = async () => {
         let docAtZero = await this.getDocAtIndex(0);
         if (docAtZero === undefined) {
@@ -848,10 +844,11 @@ export class PresentationView extends React.Component<PresViewProps>  {
         this.curPresentation.title = newTitle;
     }
 
-    addPressElem = (keyDoc: Doc, elem: PresentationElement) => {
-        this.presElementsMappings.set(keyDoc, elem);
-    }
-
+    /**
+     * On pointer down element that is catched on resizer of te
+     * presentation view. Sets up the event listeners to change the size with
+     * mouse move.
+     */
     _downsize = 0;
     onPointerDown = (e: React.PointerEvent) => {
         this._downsize = e.clientX;
@@ -862,16 +859,26 @@ export class PresentationView extends React.Component<PresViewProps>  {
         e.stopPropagation();
         e.preventDefault();
     }
+    /**
+     * Changes the size of the presentation view, with mouse move.
+     * Minimum size is set to 300, so that every button is visible.
+     */
     @action
     onPointerMove = (e: PointerEvent) => {
 
-        this.curPresentation.width = Math.max(window.innerWidth - e.clientX, 300);
+        this.curPresentation.width = Math.max(window.innerWidth - e.clientX, presMinWidth);
     }
+
+    /**
+     * The method that is called on pointer up event. It checks if the button is just
+     * clicked so that presentation view will be closed. The way it's done is to check 
+     * for minimal pixel change like 4, and accept it as it's just a click on top of the dragger.
+     */
     @action
     onPointerUp = (e: PointerEvent) => {
         if (Math.abs(e.clientX - this._downsize) < 4) {
             let presWidth = NumCast(this.curPresentation.width);
-            if (presWidth - 300 !== 0) {
+            if (presWidth - presMinWidth !== 0) {
                 this.curPresentation.width = 0;
             }
         }
@@ -879,14 +886,23 @@ export class PresentationView extends React.Component<PresViewProps>  {
         document.removeEventListener("pointerup", this.onPointerUp);
     }
 
+    /**
+     * This function gets triggered on click of the dragger. It opens up the
+     * presentation view, if it was closed beforehand.
+     */
     togglePresView = (e: React.MouseEvent) => {
         e.stopPropagation();
         e.preventDefault();
         let width = NumCast(this.curPresentation.width);
         if (width === 0) {
-            this.curPresentation.width = 300;
+            this.curPresentation.width = presMinWidth;
         }
     }
+    /**
+     * This function is a setter that opens up the 
+     * presentation mode, by setting it's render flag
+     * to true. It also closes the presentation view.
+     */
     @action
     openPresMode = () => {
         if (!this.presMode) {
@@ -895,15 +911,23 @@ export class PresentationView extends React.Component<PresViewProps>  {
         }
     }
 
+    /**
+     * This function closes the presentation mode by setting its
+     * render flag to false. It also opens up the presentation view.
+     * By setting it to it's minimum size.
+     */
     @action
     closePresMode = () => {
         if (this.presMode) {
             this.presMode = false;
-            this.curPresentation.width = 300;
+            this.curPresentation.width = presMinWidth;
         }
 
     }
 
+    /**
+     * Function that is called to render the presentation mode, depending on its flag.
+     */
     renderPresMode = () => {
         if (this.presMode) {
             return <PresModeMenu next={this.next} back={this.back} startOrResetPres={this.startOrResetPres} presStatus={this.presStatus} closePresMode={this.closePresMode} />;
-- 
cgit v1.2.3-70-g09d2

