From 1a6feb447f9c4fd461ba02dc45a93e569a283be0 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Sat, 6 Jun 2020 00:04:54 -0700
Subject: initial commit

---
 src/mobile/MobileInterface.tsx | 526 +++++++++++++++++++++++++++++------------
 1 file changed, 379 insertions(+), 147 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 6c2e797d6..1f7244653 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1,47 +1,56 @@
 import React = require('react');
 import { library } from '@fortawesome/fontawesome-svg-core';
-import { faEraser, faHighlighter, faLongArrowAltLeft, faMousePointer, faPenNib } from '@fortawesome/free-solid-svg-icons';
+import { faEraser, faHighlighter, faLongArrowAltLeft, faMousePointer, faPenNib, faThumbtack, faHome } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
-import { DocServer } from '../client/DocServer';
+import * as rp from 'request-promise';
 import { Docs } from '../client/documents/Documents';
-import { DocumentManager } from '../client/util/DocumentManager';
-import RichTextMenu from '../client/views/nodes/formattedText/RichTextMenu';
-import { Scripting } from '../client/util/Scripting';
+import { DocumentView } from '../client/views/nodes/DocumentView';
+import { emptyPath, emptyFunction, returnFalse, returnOne, returnTrue, returnZero, Utils } from '../Utils';
 import { Transform } from '../client/util/Transform';
-import { DocumentDecorations } from '../client/views/DocumentDecorations';
-import GestureOverlay from '../client/views/GestureOverlay';
+import { Scripting } from '../client/util/Scripting';
 import { InkingControl } from '../client/views/InkingControl';
-import { DocumentView } from '../client/views/nodes/DocumentView';
-import { RadialMenu } from '../client/views/nodes/RadialMenu';
-import { PreviewCursor } from '../client/views/PreviewCursor';
+import "./MobileInterface.scss";
+import "./MobileMenu.scss";
+import { DocServer } from '../client/DocServer';
+import { DocumentManager } from '../client/util/DocumentManager';
+import SettingsManager from '../client/util/SettingsManager';
+import { Uploader } from "./ImageUpload";
+import { DockedFrameRenderer } from '../client/views/collections/CollectionDockingView';
 import { Doc, DocListCast, FieldResult } from '../fields/Doc';
-import { Id } from '../fields/FieldSymbols';
+import { FieldValue, Cast, StrCast } from '../fields/Types';
 import { InkTool } from '../fields/InkField';
 import { listSpec } from '../fields/Schema';
-import { Cast, FieldValue } from '../fields/Types';
-import { WebField } from "../fields/URLField";
+import { nullAudio, WebField } from '../fields/URLField';
+import { Id } from '../fields/FieldSymbols';
 import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
-import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero } from '../Utils';
-import "./MobileInterface.scss";
-import { CollectionView } from '../client/views/collections/CollectionView';
 
 library.add(faLongArrowAltLeft);
+library.add(faHome);
 
 @observer
-export default class MobileInterface extends React.Component {
+export class MobileInterface extends React.Component {
     @observable static Instance: MobileInterface;
     @computed private get userDoc() { return Doc.UserDoc(); }
     @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
+    @computed private get activeContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
     // @observable private currentView: "main" | "ink" | "upload" = "main";
-    private mainDoc: any = CurrentUserUtils.setupMobileDoc(this.userDoc);
+    @observable private mainDoc: any = CurrentUserUtils.setupMobileDoc(this.userDoc);
     @observable private renderView?: () => JSX.Element;
+    @observable private sidebarActive = true;
+
+    public _activeDoc: Doc = this.mainDoc;
 
     // private inkDoc?: Doc;
     public drawingInk: boolean = false;
 
-    // private uploadDoc?: Doc;
+    // private _uploadDoc: Doc = this.userDoc;
+    private _child: Doc | null = null;
+    private _parents: Array<Doc> = [];
+    private _menu: Doc = this.mainDoc;
+    private _open: boolean = false;
+    private _library: Doc = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
 
     constructor(props: Readonly<{}>) {
         super(props);
@@ -50,7 +59,7 @@ export default class MobileInterface extends React.Component {
 
     @action
     componentDidMount = () => {
-        library.add(...[faPenNib, faHighlighter, faEraser, faMousePointer]);
+        library.add(...[faPenNib, faHighlighter, faEraser, faMousePointer, faThumbtack]);
 
         if (this.userDoc && !this.mainContainer) {
             this.userDoc.activeMobile = this.mainDoc;
@@ -81,6 +90,7 @@ export default class MobileInterface extends React.Component {
     onSwitchUpload = async () => {
         let width = 300;
         let height = 300;
+        const res = await rp.get(Utils.prepend("/getUserDocumentId"));
 
         // get width and height of the collection doc
         if (this.mainContainer) {
@@ -102,34 +112,243 @@ export default class MobileInterface extends React.Component {
         });
     }
 
-    renderDefaultContent = () => {
+    back = () => {
+        const doc = Cast(this._parents.pop(), Doc) as Doc;
+        if (doc === Cast(this._menu, Doc) as Doc) {
+            this._child = null;
+            this.userDoc.activeMobile = this.mainDoc;
+        } else {
+            if (doc) {
+                this._child = doc;
+                this.switchCurrentView((userDoc: Doc) => doc);
+            }
+        }
+        if (doc) {
+            this._activeDoc = doc;
+        }
+    }
+
+    returnHome = () => {
+        this._parents = [];
+        this._activeDoc = this._menu;
+        this.switchCurrentView((userDoc: Doc) => this._menu);
+        this._child = null;
+    }
+
+    displayWorkspaces = () => {
         if (this.mainContainer) {
-            return <DocumentView
-                Document={this.mainContainer}
-                DataDoc={undefined}
-                LibraryPath={emptyPath}
-                addDocument={returnFalse}
-                addDocTab={returnFalse}
-                pinToPres={emptyFunction}
-                rootSelected={returnFalse}
-                removeDocument={undefined}
-                onClick={undefined}
-                ScreenToLocalTransform={Transform.Identity}
-                ContentScaling={returnOne}
-                NativeHeight={returnZero}
-                NativeWidth={returnZero}
-                PanelWidth={() => window.screen.width}
-                PanelHeight={() => window.screen.height}
-                renderDepth={0}
-                focus={emptyFunction}
-                backgroundColor={returnEmptyString}
-                parentActive={returnTrue}
-                whenActiveChanged={emptyFunction}
-                bringToFront={emptyFunction}
-                ContainingCollectionView={undefined}
-                ContainingCollectionDoc={undefined} />;
+            const backgroundColor = () => "white";
+            return (
+                <div style={{ position: "relative", top: '200px', height: `calc(100% - 250px)`, width: "100%", overflow: "hidden" }}>
+                    <DocumentView
+                        Document={this.mainContainer}
+                        DataDoc={undefined}
+                        LibraryPath={emptyPath}
+                        addDocument={returnFalse}
+                        addDocTab={returnFalse}
+                        pinToPres={emptyFunction}
+                        rootSelected={returnFalse}
+                        removeDocument={undefined}
+                        onClick={undefined}
+                        ScreenToLocalTransform={Transform.Identity}
+                        ContentScaling={returnOne}
+                        NativeHeight={returnZero}
+                        NativeWidth={returnZero}
+                        PanelWidth={() => window.screen.width}
+                        PanelHeight={() => window.screen.height}
+                        renderDepth={0}
+                        focus={emptyFunction}
+                        backgroundColor={backgroundColor}
+                        parentActive={returnTrue}
+                        whenActiveChanged={emptyFunction}
+                        bringToFront={emptyFunction}
+                        ContainingCollectionView={undefined}
+                        ContainingCollectionDoc={undefined}
+                    />
+                </div>
+            );
+        }
+    }
+
+    handleClick(doc: Doc) {
+        const children = DocListCast(doc.data);
+        if (doc.type !== "collection") {
+            this._parents.push(this._activeDoc);
+            this._activeDoc = doc;
+            this.switchCurrentView((userDoc: Doc) => doc);
+            this.toggleSidebar();
+        } else if (doc.type === "collection" && children.length === 0) {
+            console.log("This collection has no children");
+        } else {
+            this._parents.push(this._activeDoc);
+            this._activeDoc = doc;
+            this.switchCurrentView((userDoc: Doc) => doc);
+            this._child = doc;
+        }
+
+        // let sidebar = document.getElementById("sidebar") as HTMLElement;
+        // sidebar.classList.toggle('active');
+    }
+
+    createPathname = () => {
+        let pathname = "";
+        this._parents.map((doc: Doc, index: any) => {
+            if (doc === this.mainDoc) {
+                pathname = pathname + doc.title;
+            } else {
+                pathname = pathname + " > " + doc.title;
+            }
+        });
+        if (this._activeDoc === this.mainDoc) {
+            pathname = pathname + this._activeDoc.title;
+        } else {
+            pathname = pathname + " > " + this._activeDoc.title;
+        }
+        return pathname;
+    }
+
+    @action
+    toggleSidebar = () => this.sidebarActive = !this.sidebarActive
+
+    openLibrary() {
+        this._activeDoc = this.mainDoc;
+        this.switchCurrentView(() => this.mainDoc);
+        this._child = this._library;
+    }
+
+    renderDefaultContent = () => {
+        const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+        const buttons = DocListCast(this._child ? this._child.data : workspaces.data).map((doc: Doc, index: any) => {
+            return (
+                <div
+                    className="item"
+                    key={index}
+                    onClick={() => this.handleClick(doc)}>{doc.title}
+                    <div className="type">{doc.type}</div>
+                    <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
+                </div>);
+        });
+        return (
+            <>
+                <div className="navbar">
+                    <div className={"header"}>{this.sidebarActive ? StrCast(this._activeDoc.title) : "Menu"}</div>
+                    <div
+                        className={`toggle-btn ${this.sidebarActive ? "active" : ""}`}
+                        onClick={this.toggleSidebar}
+                    />
+                </div>
+                <div className="pathbar">
+                    <div className="pathname">{this.createPathname()}</div>
+                </div>
+                <div className={`sidebar ${this.sidebarActive ? "active" : ""}`}>
+                    <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
+                    {this._child ?
+                        <>
+                            <div className="back" onClick={this.back}>&#8592;</div>
+                            <div>{buttons}</div>
+                            <div className="item" key="home" onClick={this.returnHome}>Home</div>
+                        </> :
+                        <>
+                            {buttons}
+                            {/* <div className="item" key="library" onClick={this.openLibrary}>
+                                Library
+                                </div> */}
+                            <Uploader Document={workspaces} />
+                            <div className="item" key="audio" onClick={this.recordAudio}>Record Audio</div>
+                            <div className="item" key="presentation" onClick={this.openDefaultPresentation}>Presentation</div>
+                            <div className="item" key="settings" onClick={() => SettingsManager.Instance.open()}>Settings</div>
+                        </>
+                    }
+                </div>
+                {this._child ? null : <div>{this.renderView}</div>}
+            </>
+        );
+    }
+
+    pinToPresentation = () => {
+        // Only making button available if it is an image
+        if (this._activeDoc.type === "image") {
+            const isPinned = this._activeDoc && Doc.isDocPinned(this._activeDoc);
+            return <div className="pinButton"
+                title={Doc.isDocPinned(this._activeDoc) ? "Unpin from presentation" : "Pin to presentation"}
+                style={{ backgroundColor: isPinned ? "black" : "white", color: isPinned ? "white" : "black" }}
+                onClick={e => {
+                    if (isPinned) {
+                        DockedFrameRenderer.UnpinDoc(this._activeDoc);
+                    }
+                    else {
+                        DockedFrameRenderer.PinDoc(this._activeDoc);
+                    }
+                }}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
+                />
+            </div>;
+        }
+    }
+
+    recordAudio = async () => {
+        // upload to server with known URL 
+        this._parents.push(this._activeDoc);
+        const audioDoc = Cast(Docs.Create.AudioDocument(nullAudio, { _width: 200, _height: 100, title: "mobile audio" }), Doc) as Doc;
+        if (audioDoc) {
+            console.log("audioClicked: " + audioDoc.title);
+            this._activeDoc = audioDoc;
+            this.switchCurrentView((userDoc: Doc) => audioDoc);
+            this.toggleSidebar();
+        }
+        const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
+        if (audioRightSidebar) {
+            console.log(audioRightSidebar.title);
+            const data = Cast(audioRightSidebar.data, listSpec(Doc));
+            if (data) {
+                data.push(audioDoc);
+            }
+        }
+    }
+
+    openDefaultPresentation = () => {
+        this._parents.push(this._activeDoc);
+        const presentation = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
+
+        if (presentation) {
+            console.log("presentation clicked: " + presentation.title);
+            this._activeDoc = presentation;
+            this.switchCurrentView((userDoc: Doc) => presentation);
+            this.toggleSidebar();
+        }
+    }
+
+    // mobileHome = () => {
+    //     return (
+    //         <div className="homeContainer">
+    //             <div className="uploadButton">
+
+    //             </div>
+    //             <div className="presentationButton">
+
+    //             </div>
+    //             <div className="recordAudioButton">
+
+    //             </div>
+    //             <div className="inkButton">
+
+    //             </div>
+    //             <div className="settingsButton">
+
+    //             </div>
+    //         </div>
+    //     );
+    // }
+
+    renderActiveCollection = (userDoc: Doc) => {
+        if (this.activeContainer) {
+            const active = Cast(this.activeContainer.data, listSpec(Doc));
+            if (active) {
+                return (
+                    <div className="mobileInterface-background">HELLO!</div>
+                );
+            }
         }
-        return "hello";
     }
 
     onBack = (e: React.MouseEvent) => {
@@ -164,60 +383,15 @@ export default class MobileInterface extends React.Component {
 
     panelHeight = () => window.innerHeight;
     panelWidth = () => window.innerWidth;
-    renderInkingContent = () => {
-        console.log("rendering inking content");
-        // TODO: support panning and zooming
-        // TODO: handle moving of ink strokes
-        if (this.mainContainer) {
-            return (
-                <div className="mobileInterface">
-                    <div className="mobileInterface-inkInterfaceButtons">
-                        <div className="navButtons">
-                            <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing">BACK</button>
-                        </div>
-                        <div className="inkSettingButtons">
-                            <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing"><FontAwesomeIcon icon="long-arrow-alt-left" /></button>
-                        </div>
-                        <div className="navButtons">
-                            <button className="mobileInterface-button" onClick={this.shiftLeft} title="Shift left">left</button>
-                            <button className="mobileInterface-button" onClick={this.shiftRight} title="Shift right">right</button>
-                        </div>
-                    </div>
-                    <CollectionView
-                        Document={this.mainContainer}
-                        DataDoc={undefined}
-                        LibraryPath={emptyPath}
-                        fieldKey={""}
-                        dropAction={"alias"}
-                        bringToFront={emptyFunction}
-                        addDocTab={returnFalse}
-                        pinToPres={emptyFunction}
-                        PanelWidth={this.panelWidth}
-                        PanelHeight={this.panelHeight}
-                        NativeHeight={returnZero}
-                        NativeWidth={returnZero}
-                        focus={emptyFunction}
-                        isSelected={returnFalse}
-                        select={emptyFunction}
-                        active={returnFalse}
-                        ContentScaling={returnOne}
-                        whenActiveChanged={returnFalse}
-                        ScreenToLocalTransform={Transform.Identity}
-                        renderDepth={0}
-                        ContainingCollectionView={undefined}
-                        ContainingCollectionDoc={undefined}
-                        rootSelected={returnTrue}>
-                    </CollectionView>
-                </div>
-            );
-        }
-    }
+    //WAS 3
+
+    //WAS 1
 
     upload = async (e: React.MouseEvent) => {
         if (this.mainContainer) {
             const data = Cast(this.mainContainer.data, listSpec(Doc));
             if (data) {
-                const collectionDoc = await data[1]; // this should be the collection doc since the positions should be locked
+                const collectionDoc = await data[1]; //this should be the collection doc since the positions should be locked
                 const children = DocListCast(collectionDoc.data);
                 const uploadDoc = children.length === 1 ? children[0] : Docs.Create.StackingDocument(children, {
                     title: "Mobile Upload Collection", backgroundColor: "white", lockedPosition: true, _width: 300, _height: 300
@@ -260,45 +434,6 @@ export default class MobileInterface extends React.Component {
         }
     }
 
-    renderUploadContent() {
-        if (this.mainContainer) {
-            return (
-                <div className="mobileInterface" onDragOver={this.onDragOver}>
-                    <div className="mobileInterface-inkInterfaceButtons">
-                        <button className="mobileInterface-button cancel" onClick={this.onBack} title="Back">BACK</button>
-                        {/* <button className="mobileInterface-button" onClick={this.clearUpload} title="Clear Upload">CLEAR</button> */}
-                        {/* <button className="mobileInterface-button" onClick={this.addWeb} title="Add Web Doc to Upload Collection"></button> */}
-                        <button className="mobileInterface-button" onClick={this.upload} title="Upload">UPLOAD</button>
-                    </div>
-                    <DocumentView
-                        Document={this.mainContainer}
-                        DataDoc={undefined}
-                        LibraryPath={emptyPath}
-                        addDocument={returnFalse}
-                        addDocTab={returnFalse}
-                        pinToPres={emptyFunction}
-                        rootSelected={returnFalse}
-                        removeDocument={undefined}
-                        onClick={undefined}
-                        ScreenToLocalTransform={Transform.Identity}
-                        ContentScaling={returnOne}
-                        NativeHeight={returnZero}
-                        NativeWidth={returnZero}
-                        PanelWidth={() => window.screen.width}
-                        PanelHeight={() => window.screen.height}
-                        renderDepth={0}
-                        focus={emptyFunction}
-                        backgroundColor={returnEmptyString}
-                        parentActive={returnTrue}
-                        whenActiveChanged={emptyFunction}
-                        bringToFront={emptyFunction}
-                        ContainingCollectionView={undefined}
-                        ContainingCollectionDoc={undefined} />
-                </div>
-            );
-        }
-    }
-
     onDragOver = (e: React.DragEvent) => {
         e.preventDefault();
         e.stopPropagation();
@@ -314,18 +449,22 @@ export default class MobileInterface extends React.Component {
                 <GestureOverlay>
                     {this.renderView ? this.renderView() : this.renderDefaultContent()}
                 </GestureOverlay> */}
-
+                {/* <GestureOverlay> */}
+                <SettingsManager />
+                {this.displayWorkspaces()}
+                {this.pinToPresentation()}
+                {/* </GestureOverlay> */}
                 {/* <DictationOverlay />
                 <SharingManager />
                 <GoogleAuthenticationManager /> */}
-                <DocumentDecorations />
-                <GestureOverlay>
-                    {this.renderView ? this.renderView() : this.renderDefaultContent()}
-                </GestureOverlay>
-                <PreviewCursor />
+                {/* <DocumentDecorations /> */}
+                <div>
+                    {this.renderDefaultContent()}
+                </div>
+                {/* <PreviewCursor /> */}
                 {/* <ContextMenu /> */}
-                <RadialMenu />
-                <RichTextMenu />
+                {/* <RadialMenu />
+                <RichTextMenu /> */}
                 {/* <PDFMenu />
                 <MarqueeOptionsMenu />
                 <OverlayView /> */}
@@ -335,9 +474,102 @@ export default class MobileInterface extends React.Component {
 }
 
 Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); });
-Scripting.addGlobal(function onSwitchMobileInking() { return MobileInterface.Instance.onSwitchInking(); });
-Scripting.addGlobal(function renderMobileInking() { return MobileInterface.Instance.renderInkingContent(); });
-Scripting.addGlobal(function onSwitchMobileUpload() { return MobileInterface.Instance.onSwitchUpload(); });
-Scripting.addGlobal(function renderMobileUpload() { return MobileInterface.Instance.renderUploadContent(); });
-Scripting.addGlobal(function addWebToMobileUpload() { return MobileInterface.Instance.addWebToCollection(); });
+// WAS 2
+
+// 1
+// renderUploadContent() {
+//     if (this.mainContainer) {
+//         return (
+//             <div className="mobileInterface" onDragOver={this.onDragOver}>
+//                 <div className="mobileInterface-inkInterfaceButtons">
+//                     <button className="mobileInterface-button cancel" onClick={this.onBack} title="Back">BACK</button>
+//                     {/* <button className="mobileInterface-button" onClick={this.clearUpload} title="Clear Upload">CLEAR</button> */}
+//                     {/* <button className="mobileInterface-button" onClick={this.addWeb} title="Add Web Doc to Upload Collection"></button> */}
+//                     <button className="mobileInterface-button" onClick={this.upload} title="Upload">UPLOAD</button>
+//                 </div>
+//                 <DocumentView
+//                     Document={this.mainContainer}
+//                     DataDoc={undefined}
+//                     LibraryPath={emptyPath}
+//                     addDocument={returnFalse}
+//                     addDocTab={returnFalse}
+//                     pinToPres={emptyFunction}
+//                     rootSelected={returnFalse}
+//                     removeDocument={undefined}
+//                     onClick={undefined}
+//                     ScreenToLocalTransform={Transform.Identity}
+//                     ContentScaling={returnOne}
+//                     NativeHeight={returnZero}
+//                     NativeWidth={returnZero}
+//                     PanelWidth={() => window.screen.width}
+//                     PanelHeight={() => window.screen.height}
+//                     renderDepth={0}
+//                     focus={emptyFunction}
+//                     backgroundColor={returnEmptyString}
+//                     parentActive={returnTrue}
+//                     whenActiveChanged={emptyFunction}
+//                     bringToFront={emptyFunction}
+//                     ContainingCollectionView={undefined}
+//                     ContainingCollectionDoc={undefined} />
+//             </div>
+//         );
+//     }
+// }
+
+// 2
+// Scripting.addGlobal(function onSwitchMobileInking() { return MobileInterface.Instance.onSwitchInking(); });
+// Scripting.addGlobal(function renderMobileInking() { return MobileInterface.Instance.renderInkingContent(); });
+// Scripting.addGlobal(function onSwitchMobileUpload() { return MobileInterface.Instance.onSwitchUpload(); });
+// Scripting.addGlobal(function renderMobileUpload() { return MobileInterface.Instance.renderUploadContent(); });
+    // Scripting.addGlobal(function addWebToMobileUpload() { return MobileInterface.Instance.addWebToCollection(); });
+
 
+// 3   
+    // renderInkingContent = () => {
+        //     console.log("rendering inking content");
+        //     // TODO: support panning and zooming
+        //     // TODO: handle moving of ink strokes
+        //     if (this.mainContainer) {
+        //         return (
+        //             <div className="mobileInterface">
+        //                 <div className="mobileInterface-inkInterfaceButtons">
+        //                     <div className="navButtons">
+        //                         <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing">BACK</button>
+        //                     </div>
+        //                     <div className="inkSettingButtons">
+        //                         <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing"><FontAwesomeIcon icon="long-arrow-alt-left" /></button>
+        //                     </div>
+        //                     <div className="navButtons">
+        //                         <button className="mobileInterface-button" onClick={this.shiftLeft} title="Shift left">left</button>
+        //                         <button className="mobileInterface-button" onClick={this.shiftRight} title="Shift right">right</button>
+        //                     </div>
+        //                 </div>
+        //                 <CollectionView
+        //                     Document={this.mainContainer}
+        //                     DataDoc={undefined}
+        //                     LibraryPath={emptyPath}
+        //                     fieldKey={""}
+        //                     dropAction={"alias"}
+        //                     bringToFront={emptyFunction}
+        //                     addDocTab={returnFalse}
+        //                     pinToPres={emptyFunction}
+        //                     PanelWidth={this.panelWidth}
+        //                     PanelHeight={this.panelHeight}
+        //                     NativeHeight={returnZero}
+        //                     NativeWidth={returnZero}
+        //                     focus={emptyFunction}
+        //                     isSelected={returnFalse}
+        //                     select={emptyFunction}
+        //                     active={returnFalse}
+        //                     ContentScaling={returnOne}
+        //                     whenActiveChanged={returnFalse}
+        //                     ScreenToLocalTransform={Transform.Identity}
+        //                     renderDepth={0}
+        //                     ContainingCollectionView={undefined}
+        //                     ContainingCollectionDoc={undefined}
+        //                     rootSelected={returnTrue}>
+        //                 </CollectionView>
+        //             </div>
+        //         );
+        //     }
+        // }
-- 
cgit v1.2.3-70-g09d2


From 1f437abfeabf897887fb9e3097df06a1934ae884 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Sat, 6 Jun 2020 01:14:09 -0700
Subject: fixed import ordering

---
 src/client/views/webcam/WebCamLogic.js |  5 +----
 src/mobile/MobileInterface.tsx         | 33 ++++++++++++++++++++++-----------
 src/mobile/MobileMain.tsx              | 14 +++++++-------
 3 files changed, 30 insertions(+), 22 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/webcam/WebCamLogic.js b/src/client/views/webcam/WebCamLogic.js
index a8a2f5fa4..5f6202bc8 100644
--- a/src/client/views/webcam/WebCamLogic.js
+++ b/src/client/views/webcam/WebCamLogic.js
@@ -1,8 +1,5 @@
 'use strict';
 import io from "socket.io-client";
-import {
-    resolvedPorts
-} from "../Main";
 
 var socket;
 var isChannelReady = false;
@@ -32,7 +29,7 @@ export function initialize(roomName, handlerUI) {
 
     room = roomName;
 
-    socket = io.connect(`${window.location.protocol}//${window.location.hostname}:${resolvedPorts.socket}`);
+    socket = io.connect(`${window.location.protocol}//${window.location.hostname}:4321`);
 
     if (room !== '') {
         socket.emit('create or join', room);
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 1f7244653..052c8975a 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1,33 +1,44 @@
-import React = require('react');
+import * as React from "react";
 import { library } from '@fortawesome/fontawesome-svg-core';
-import { faEraser, faHighlighter, faLongArrowAltLeft, faMousePointer, faPenNib, faThumbtack, faHome } from '@fortawesome/free-solid-svg-icons';
+import {
+    faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+    faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
+    faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
+    faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
+    faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote,
+    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft
+} from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as rp from 'request-promise';
+import { Doc, DocListCast, FieldResult } from '../fields/Doc';
+import { Id } from '../fields/FieldSymbols';
+import { FieldValue, Cast, StrCast } from '../fields/Types';
+import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
+import { emptyPath, emptyFunction, returnFalse, returnOne, returnTrue, returnZero, Utils } from '../Utils';
+import { DocServer } from '../client/DocServer';
 import { Docs } from '../client/documents/Documents';
+import { Scripting } from '../client/util/Scripting';
 import { DocumentView } from '../client/views/nodes/DocumentView';
-import { emptyPath, emptyFunction, returnFalse, returnOne, returnTrue, returnZero, Utils } from '../Utils';
 import { Transform } from '../client/util/Transform';
-import { Scripting } from '../client/util/Scripting';
 import { InkingControl } from '../client/views/InkingControl';
 import "./MobileInterface.scss";
 import "./MobileMenu.scss";
-import { DocServer } from '../client/DocServer';
 import { DocumentManager } from '../client/util/DocumentManager';
 import SettingsManager from '../client/util/SettingsManager';
 import { Uploader } from "./ImageUpload";
 import { DockedFrameRenderer } from '../client/views/collections/CollectionDockingView';
-import { Doc, DocListCast, FieldResult } from '../fields/Doc';
-import { FieldValue, Cast, StrCast } from '../fields/Types';
 import { InkTool } from '../fields/InkField';
 import { listSpec } from '../fields/Schema';
 import { nullAudio, WebField } from '../fields/URLField';
-import { Id } from '../fields/FieldSymbols';
-import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
 
-library.add(faLongArrowAltLeft);
-library.add(faHome);
+library.add(faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+    faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
+    faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
+    faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
+    faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote,
+    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft);
 
 @observer
 export class MobileInterface extends React.Component {
diff --git a/src/mobile/MobileMain.tsx b/src/mobile/MobileMain.tsx
index 34f06438f..3d4680d58 100644
--- a/src/mobile/MobileMain.tsx
+++ b/src/mobile/MobileMain.tsx
@@ -1,10 +1,10 @@
-import { DocServer } from '../client/DocServer';
-import { Docs } from '../client/documents/Documents';
-import * as ReactDOM from "react-dom";
-import { MobileInterface } from './MobileInterface';
-import * as React from "react";
-import { AssignAllExtensions } from '../extensions/General/Extensions';
-import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
+import { MobileInterface } from "./MobileInterface";
+import { Docs } from "../client/documents/Documents";
+import { CurrentUserUtils } from "../client/util/CurrentUserUtils";
+import * as ReactDOM from 'react-dom';
+import * as React from 'react';
+import { DocServer } from "../client/DocServer";
+import { AssignAllExtensions } from "../extensions/General/Extensions";
 
 AssignAllExtensions();
 
-- 
cgit v1.2.3-70-g09d2


From 0bd7f4f85be56de4326f0671453fc5e5e917a5d0 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Sun, 7 Jun 2020 21:22:25 -0700
Subject: pull current work in

---
 deploy/mobile/image.html                           |    3 +-
 src/client/util/CurrentUserUtils.ts                |  105 +-
 src/client/views/GestureOverlay.tsx                |   14 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |    2 +-
 src/mobile/MobileHome.scss                         |  101 ++
 src/mobile/MobileInterface.tsx                     | 1819 ++++++++++++++++++--
 src/mobile/MobileMenu.scss                         |  122 +-
 src/mobile/SideBar.scss                            |   79 -
 src/mobile/SideBar.tsx                             |   39 -
 src/mobile/WorkSpaceButton.scss                    |    0
 src/mobile/WorkSpaceButton.tsx                     |   14 -
 11 files changed, 1916 insertions(+), 382 deletions(-)
 create mode 100644 src/mobile/MobileHome.scss
 delete mode 100644 src/mobile/SideBar.scss
 delete mode 100644 src/mobile/SideBar.tsx
 delete mode 100644 src/mobile/WorkSpaceButton.scss
 delete mode 100644 src/mobile/WorkSpaceButton.tsx

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/deploy/mobile/image.html b/deploy/mobile/image.html
index beca8b68b..d30ad6ac2 100644
--- a/deploy/mobile/image.html
+++ b/deploy/mobile/image.html
@@ -1,13 +1,12 @@
 <html>
 
 <head>
-    <title>Test view</title>
+    <title>Dash Mobile</title>
     <link href="https://fonts.googleapis.com/css?family=Fjalla+One|Hind+Siliguri:300" rel="stylesheet">
 </head>
 
 <body>
     <div id="root">
-        <p>Capture Image: <input type="file" accept="image/*" id="capture">
     </div>
     <script src="../mobileInterface.js"></script>
 </body>
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 496099557..8ed275efc 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -386,25 +386,56 @@ export class CurrentUserUtils {
         return doc.myItemCreators as Doc;
     }
 
-    static setupMobileButtons(doc: Doc, buttons?: string[]) {
+    // static setupMobileButtons(doc: Doc, buttons?: string[]) {
+    //     const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
+    //         { title: "record", icon: "microphone", ignoreClick: true, click: "FILL" },
+    //         { title: "use pen", icon: "pen-nib", click: 'activatePen(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this,2, this.backgroundColor)', backgroundColor: "blue", ischecked: `sameDocs(this.activePen.inkPen,  this)`, activePen: doc },
+    //         { title: "use highlighter", icon: "highlighter", click: 'activateBrush(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this,20,this.backgroundColor)', backgroundColor: "yellow", ischecked: `sameDocs(this.activePen.inkPen, this)`, activePen: doc },
+    //         { title: "use eraser", icon: "eraser", click: 'activateEraser(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this);', ischecked: `sameDocs(this.activePen.inkPen, this)`, backgroundColor: "pink", activePen: doc },
+    //         { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activePen.inkPen = this;', ischecked: `sameDocs(this.activePen.inkPen, this)`, backgroundColor: "white", activePen: doc },
+    //         // { title: "draw", icon: "pen-nib", click: 'switchMobileView(setupMobileInkingDoc, renderMobileInking, onSwitchMobileInking);', ischecked: `sameDocs(this.activePen.inkPen, this)`, backgroundColor: "red", activePen: doc },
+    //         { title: "upload", icon: "upload", click: 'switchMobileView(setupMobileUploadDoc, renderMobileUpload, onSwitchMobileUpload);', backgroundColor: "orange" },
+    //         // { title: "upload", icon: "upload", click: 'uploadImageMobile();', backgroundColor: "cyan" },
+    //     ];
+    //     return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => Docs.Create.FontIconDocument({
+    //         _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, dropAction: data.click ? "copy" : undefined, title: data.title, icon: data.icon, ignoreClick: data.ignoreClick,
+    //         onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
+    //         ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined, activePen: data.activePen,
+    //         backgroundColor: data.backgroundColor, removeDropProperties: new List<string>(["dropAction"]), dragFactory: data.dragFactory,
+    //     }));
+    // }
+
+    static setupMobileButtons(doc?: Doc, buttons?: string[]) {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
-            { title: "record", icon: "microphone", ignoreClick: true, click: "FILL" },
-            { title: "use pen", icon: "pen-nib", click: 'activatePen(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this,2, this.backgroundColor)', backgroundColor: "blue", ischecked: `sameDocs(this.activePen.inkPen,  this)`, activePen: doc },
-            { title: "use highlighter", icon: "highlighter", click: 'activateBrush(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this,20,this.backgroundColor)', backgroundColor: "yellow", ischecked: `sameDocs(this.activePen.inkPen, this)`, activePen: doc },
-            { title: "use eraser", icon: "eraser", click: 'activateEraser(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this);', ischecked: `sameDocs(this.activePen.inkPen, this)`, backgroundColor: "pink", activePen: doc },
-            { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activePen.inkPen = this;', ischecked: `sameDocs(this.activePen.inkPen, this)`, backgroundColor: "white", activePen: doc },
-            // { title: "draw", icon: "pen-nib", click: 'switchMobileView(setupMobileInkingDoc, renderMobileInking, onSwitchMobileInking);', ischecked: `sameDocs(this.activePen.inkPen, this)`, backgroundColor: "red", activePen: doc },
-            { title: "upload", icon: "upload", click: 'switchMobileView(setupMobileUploadDoc, renderMobileUpload, onSwitchMobileUpload);', backgroundColor: "orange" },
-            // { title: "upload", icon: "upload", click: 'uploadImageMobile();', backgroundColor: "cyan" },
+            { title: "library", icon: "bars", click: 'switchToLibrary()', backgroundColor: "lightgrey" },
+            { title: "record", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "lightgrey" },
+            { title: "upload", icon: "upload", click: 'uploadMobileImage()', backgroundColor: "lightgrey" },
+            { title: "presentation", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "lightgrey" },
+            { title: "ink", icon: "pen-nib", backgroundColor: "lightgrey" },
+            { title: "settings", icon: "cog", click: 'openMobileSettings()', backgroundColor: "lightgrey" }
         ];
         return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => Docs.Create.FontIconDocument({
-            _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, dropAction: data.click ? "copy" : undefined, title: data.title, icon: data.icon, ignoreClick: data.ignoreClick,
-            onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
-            ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined, activePen: data.activePen,
-            backgroundColor: data.backgroundColor, removeDropProperties: new List<string>(["dropAction"]), dragFactory: data.dragFactory,
+            _nativeWidth: 150, _nativeHeight: 150, _width: 150, _height: 150,
+            dropAction: undefined,
+            title: data.title,
+            icon: data.icon,
+            ignoreClick: data.ignoreClick,
+            onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined,
+            onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
+            ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined,
+            activePen: data.activePen,
+            backgroundColor: data.backgroundColor, removeDropProperties: new List<string>(["dropAction"]),
+            dragFactory: data.dragFactory,
         }));
     }
 
+    static setupMobileMenu() {
+        const menu = Cast(Docs.Create.StackingDocument(CurrentUserUtils.setupMobileButtons(), {
+            _width: 980, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "home", _autoHeight: true, _yMargin: 80
+        }), Doc) as Doc;
+        return menu;
+    }
+
     static setupThumbButtons(doc: Doc) {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, pointerDown?: string, pointerUp?: string, ischecked?: string, clipboard?: Doc, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
             { title: "use pen", icon: "pen-nib", pointerUp: "resetPen()", pointerDown: 'setPen(2, this.backgroundColor)', backgroundColor: "blue", ischecked: `sameDocs(this.activePen.inkPen,  this)`, activePen: doc },
@@ -438,16 +469,20 @@ export class CurrentUserUtils {
         return Cast(userDoc.thumbDoc, Doc);
     }
 
-    static setupMobileDoc(userDoc: Doc) {
-        return userDoc.activeMoble ?? Docs.Create.MasonryDocument(CurrentUserUtils.setupMobileButtons(userDoc), {
-            columnWidth: 100, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons", _autoHeight: true, _yMargin: 5
-        });
+    static setupLibrary(userDoc: Doc) {
+        return CurrentUserUtils.setupWorkspaces(userDoc);
     }
 
     static setupMobileInkingDoc(userDoc: Doc) {
         return Docs.Create.FreeformDocument([], { title: "Mobile Inking", backgroundColor: "white" });
     }
 
+    static setupMobileDoc(userDoc: Doc) {
+        return userDoc.activeMoble ?? Docs.Create.MasonryDocument(CurrentUserUtils.setupMobileButtons2(userDoc), {
+            columnWidth: 100, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons", _autoHeight: true, _yMargin: 5
+        });
+    }
+
     static setupMobileUploadDoc(userDoc: Doc) {
         // const addButton = Docs.Create.FontIconDocument({ onDragStart: ScriptField.MakeScript('addWebToMobileUpload()'), title: "Add Web Doc to Upload Collection", icon: "plus", backgroundColor: "black" })
         const webDoc = Docs.Create.WebDocument("https://www.britannica.com/biography/Miles-Davis", {
@@ -608,6 +643,42 @@ export class CurrentUserUtils {
         dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100
     })) as any as Doc
 
+    static setupMobileButtons2(doc?: Doc, buttons?: string[]) {
+        const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
+            { title: "LIBRARY", icon: "bars", click: 'switchToLibrary()', backgroundColor: "#ffd6d6", info: "Navigate and access all of your documents within their respective collections" },
+            { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your mobile to record audio and access it on Dash Web." },
+            { title: "UPLOAD", icon: "upload", click: 'uploadMobileImage()', backgroundColor: "#ff9e9e", info: "Upload an image from your mobile device so it can be accessed on Dash Web" },
+            { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "#ff8080", info: "Use your phone as a remote for you presentation." },
+            // { title: "INK", icon: "pen-nib", backgroundColor: "lightgrey", info: "Doodle and draw with ink on your mobile and have it directly available on Dash Web" },
+            { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "#ff5e5e", info: "Change your password, log out, or manage your account security" }
+        ];
+        return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => this.mobileButton({ title: data.title, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined, _backgroundColor: data.backgroundColor }, [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)" }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])]));
+    }
+
+    static mobileButton = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.MulticolumnDocument(docs, {
+        ...opts,
+        dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 900, _nativeHeight: 250, _width: 900, _height: 250, _yMargin: 15,
+        borderRounding: "0", boxShadow: "0 0", _chromeStatus: "disabled",
+    })) as any as Doc
+
+    static mobileTextContainer = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.MultirowDocument(docs, {
+        ...opts,
+        dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 450, _nativeHeight: 250, _width: 450, _height: 250, _yMargin: 25,
+        backgroundColor: "rgba(0,0,0,0)", borderRounding: "0", boxShadow: "0 0", _chromeStatus: "disabled",
+    })) as any as Doc
+
+
+    static mobileButtonText = (opts: DocumentOptions, buttonTitle: string) => new PrefetchProxy(Docs.Create.TextDocument(buttonTitle, {
+        ...opts,
+        title: buttonTitle, _fontSize: 37, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)"
+    })) as any as Doc
+
+    static mobileButtonInfo = (opts: DocumentOptions, buttonInfo: string) => new PrefetchProxy(Docs.Create.TextDocument(buttonInfo, {
+        ...opts,
+        title: "info", _fontSize: 25, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)", _dimMagnitude: 2,
+    })) as any as Doc
+
+
     /// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window
     static setupDockedButtons(doc: Doc) {
         if (doc["dockedBtn-pen"] === undefined) {
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 4352ac52c..a11c97b09 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -27,7 +27,7 @@ import { listSpec } from "../../fields/Schema";
 import { List } from "../../fields/List";
 import { CollectionViewType } from "./collections/CollectionView";
 import TouchScrollableMenu, { TouchScrollableMenuItem } from "./TouchScrollableMenu";
-import MobileInterface from "../../mobile/MobileInterface";
+import { MobileInterface } from "../../mobile/MobileInterface";
 import { MobileInkOverlayContent } from "../../server/Message";
 import MobileInkOverlay from "../../mobile/MobileInkOverlay";
 import { RadialMenu } from "./nodes/RadialMenu";
@@ -115,12 +115,12 @@ export default class GestureOverlay extends Touchable {
     onReactTouchStart = (te: React.TouchEvent) => {
         document.removeEventListener("touchmove", this.onReactHoldTouchMove);
         document.removeEventListener("touchend", this.onReactHoldTouchEnd);
-        if (RadialMenu.Instance._display === true) {
-            te.preventDefault();
-            te.stopPropagation();
-            RadialMenu.Instance.closeMenu();
-            return;
-        }
+        // if (RadialMenu.Instance._display === true) {
+        //     te.preventDefault();
+        //     te.stopPropagation();
+        //     RadialMenu.Instance.closeMenu();
+        //     return;
+        // }
 
         // this chunk adds new touch targets to a map of pointer events; this helps us keep track of individual fingers
         // so that we can know, for example, if two fingers are pinching out or in.
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 80ee2a65d..8b0c72f5e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -597,7 +597,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     pan = (e: PointerEvent | React.Touch | { clientX: number, clientY: number }): void => {
         // bcz: theres should be a better way of doing these than referencing these static instances directly
         MarqueeOptionsMenu.Instance?.fadeOut(true);// I think it makes sense for the marquee menu to go away when panned. -syip2
-        PDFMenu.Instance.fadeOut(true);
+        // PDFMenu.Instance.fadeOut(true);
 
         const [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
         this.setPan((this.Document._panX || 0) - dx, (this.Document._panY || 0) - dy, undefined, true);
diff --git a/src/mobile/MobileHome.scss b/src/mobile/MobileHome.scss
new file mode 100644
index 000000000..e1566b622
--- /dev/null
+++ b/src/mobile/MobileHome.scss
@@ -0,0 +1,101 @@
+$navbar-height: 120px;
+$pathbar-height: 50px;
+
+* {
+    margin: 0px;
+    padding: 0px;
+    box-sizing: border-box;
+    font-family: "Open Sans";
+}
+
+.homeContainer {
+    position: relative;
+    top: 200px;
+    overflow: scroll;
+    width: 100%;
+    left: 0;
+    height: calc(100% - 120px);
+    overflow-y: scroll;
+}
+
+.homeButton {
+    width: 96%;
+    margin-left: 2.5%;
+    height: 250px;
+    border-radius: 30px;
+    margin-top: 15px;
+    margin-bottom: 15px;
+}
+
+.iconRight {
+    position: absolute;
+    width: 50%;
+    height: 80px;
+    transform: translate(0, 50%);
+    right: 0px;
+    text-align: center;
+    font-size: 80;
+}
+
+.iconLeft {
+    position: absolute;
+    width: 50%;
+    height: 80px;
+    transform: translate(0%, 50%);
+    left: 0px;
+    text-align: center;
+    font-size: 80;
+}
+
+.textLeft {
+    position: absolute;
+    width: 50%;
+    left: 0px;
+    font-size: 40px;
+    text-align: left;
+    margin-left: 110px;
+    margin-top: 40px;
+    font-family: sans-serif;
+    font-weight: bold;
+}
+
+.textRight {
+    position: absolute;
+    width: 50%;
+    right: 0px;
+    font-size: 40px;
+    text-align: right;
+    margin-right: 110px;
+    margin-top: 40px;
+    font-family: sans-serif;
+    font-weight: bold;
+}
+
+.menuView {
+    position: absolute;
+    top: 135px;
+    left: 50%;
+    transform: translate(-50%, 0%);
+    display: flex;
+}
+
+.iconView {
+    height: 60px;
+    width: 60px;
+    background-color: darkgray;
+    border-radius: 5px;
+    border-style: solid;
+    border-width: 2px;
+    border-color: black;
+}
+
+.listView {
+    height: 60px;
+    width: 60px;
+    margin-left: 20;
+    background-color: darkgray;
+    border-radius: 5px;
+    border-style: solid;
+    border-width: 2px;
+    border-color: black;
+}
\ No newline at end of file
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 052c8975a..6b75ce07d 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -6,7 +6,7 @@ import {
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
     faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote,
-    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft
+    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft, faBars, faTh, faChevronLeft
 } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable } from 'mobx';
@@ -25,6 +25,7 @@ import { Transform } from '../client/util/Transform';
 import { InkingControl } from '../client/views/InkingControl';
 import "./MobileInterface.scss";
 import "./MobileMenu.scss";
+import "./MobileHome.scss";
 import { DocumentManager } from '../client/util/DocumentManager';
 import SettingsManager from '../client/util/SettingsManager';
 import { Uploader } from "./ImageUpload";
@@ -32,26 +33,1056 @@ import { DockedFrameRenderer } from '../client/views/collections/CollectionDocki
 import { InkTool } from '../fields/InkField';
 import { listSpec } from '../fields/Schema';
 import { nullAudio, WebField } from '../fields/URLField';
+import GestureOverlay from "../client/views/GestureOverlay";
 
 library.add(faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
     faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote,
-    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft);
+    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft, faBars, faTh, faChevronLeft);
+
+// @observer
+// export class MobileInterface extends React.Component {
+//     @observable static Instance: MobileInterface;
+//     @computed private get userDoc() { return Doc.UserDoc(); }
+//     @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
+//     @computed private get activeContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
+//     // @observable private currentView: "main" | "ink" | "upload" = "main";
+//     @observable private mainDoc: any = CurrentUserUtils.setupMobileDoc(this.userDoc);
+//     @observable private renderView?: () => JSX.Element;
+//     @observable private sidebarActive = true;
+
+//     public _activeDoc: Doc = this.mainDoc;
+//     public _homeDoc: Doc = this.mainDoc;
+//     private _homeMenu: boolean = true;
+
+//     // private inkDoc?: Doc;
+//     public drawingInk: boolean = false;
+//     private _ink: boolean = false;
+
+//     // private _uploadDoc: Doc = this.userDoc;
+//     private _child: Doc | null = null;
+//     private _parents: Array<Doc> = [];
+//     private _library: Doc = CurrentUserUtils.setupLibrary(this.userDoc);
+//     private _open: boolean = false;
+
+//     constructor(props: Readonly<{}>) {
+//         super(props);
+//         MobileInterface.Instance = this;
+//     }
+
+//     @action
+//     componentDidMount = () => {
+//         library.add(...[faPenNib, faHighlighter, faEraser, faMousePointer, faThumbtack]);
+
+//         if (this.userDoc && !this.mainContainer) {
+//             this.userDoc.activeMobile = this._homeDoc;
+//         }
+
+//         InkingControl.Instance.switchTool(InkTool.None);
+//         MobileInterface.Instance.drawingInk = false;
+//         InkingControl.Instance.updateSelectedColor("#FF0000");
+//         InkingControl.Instance.switchWidth("2");
+//         this.switchCurrentView((userDoc: Doc) => this._homeDoc);
+//     }
+
+//     @action
+//     switchCurrentView = (doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) => {
+//         if (!this.userDoc) return;
+
+//         this.userDoc.activeMobile = doc(this.userDoc);
+//         onSwitch && onSwitch();
+
+//         this.renderView = renderView;
+//     }
+
+//     onSwitchInking = () => {
+//         const button = document.getElementById("inkButton") as HTMLElement;
+//         const color = InkingControl.Instance.selectedColor;
+//         button.style.backgroundColor = this._ink ? "white" : color;
+//         button.style.color = this._ink ? "black" : "white";
+
+//         if (!this._ink) {
+//             console.log("INK IS ACTIVE");
+//             InkingControl.Instance.switchTool(InkTool.Pen);
+//             MobileInterface.Instance.drawingInk = true;
+//             this._ink = true;
+//         } else {
+//             console.log("INK IS INACTIVE");
+//             InkingControl.Instance.switchTool(InkTool.None);
+//             MobileInterface.Instance.drawingInk = false;
+//             this._ink = false;
+//         }
+//     }
+
+//     onSwitchUpload = async () => {
+//         let width = 300;
+//         let height = 300;
+//         const res = await rp.get(Utils.prepend("/getUserDocumentId"));
+
+//         // get width and height of the collection doc
+//         if (this.mainContainer) {
+//             const data = Cast(this.mainContainer.data, listSpec(Doc));
+//             if (data) {
+//                 const collectionDoc = await data[1]; // this should be the collection doc since the positions should be locked
+//                 const docView = DocumentManager.Instance.getDocumentView(collectionDoc);
+//                 if (docView) {
+//                     width = docView.nativeWidth ? docView.nativeWidth : 300;
+//                     height = docView.nativeHeight ? docView.nativeHeight : 300;
+//                 }
+//             }
+//         }
+//         DocServer.Mobile.dispatchOverlayTrigger({
+//             enableOverlay: true,
+//             width: width,
+//             height: height,
+//             text: "Documents uploaded from mobile will show here",
+//         });
+//     }
+
+//     back = () => {
+//         let header = document.getElementById("header") as HTMLElement;
+//         let doc = Cast(this._parents.pop(), Doc) as Doc;
+//         if (doc === Cast(this._library, Doc) as Doc) {
+//             this._child = null;
+//             this.userDoc.activeMobile = this._library;
+//         } else if (doc === Cast(this._homeDoc, Doc) as Doc) {
+//             this._homeMenu = true;
+//             this._parents = [];
+//             this._activeDoc = this._homeDoc;
+//             this._child = null;
+//             this.switchCurrentView((userDoc: Doc) => this._homeDoc);
+//         } else {
+//             if (doc) {
+//                 this._child = doc;
+//                 this.switchCurrentView((userDoc: Doc) => doc);
+//                 this._homeMenu = false;
+//                 header.textContent = String(doc.title);
+//             }
+//         }
+//         if (doc) {
+//             this._activeDoc = doc;
+//         }
+//         this._ink = false;
+//     }
+
+//     returnHome = () => {
+//         if (this._homeMenu === false || this._open === true) {
+//             this._homeMenu = true;
+//             this._parents = [];
+//             this._activeDoc = this._homeDoc;
+//             this._child = null;
+//             this.switchCurrentView((userDoc: Doc) => this._homeDoc);
+//         }
+//         if (this._open) {
+//             this.toggleSidebar();
+//         }
+//     }
+
+//     returnMain = () => {
+//         this._parents = [];
+//         // this.toggleSidebar();
+//         this._activeDoc = this._library;
+//         this.switchCurrentView((userDoc: Doc) => this._library);
+//         this._homeMenu = false;
+//         this._child = null;
+//     }
+
+//     displayWorkspaces = () => {
+//         if (this.mainContainer) {
+//             const backgroundColor = () => "white";
+//             if (this._activeDoc.title === "mobile audio") {
+//                 return (
+//                     <div style={{ position: "relative", top: '600px', height: `calc(50% - 450px)`, width: "80%", overflow: "hidden", left: "10%", cursor: "pointer" }}>
+//                         <DocumentView
+//                             Document={this.mainContainer}
+//                             DataDoc={undefined}
+//                             LibraryPath={emptyPath}
+//                             addDocument={returnFalse}
+//                             addDocTab={returnFalse}
+//                             pinToPres={emptyFunction}
+//                             rootSelected={returnFalse}
+//                             removeDocument={undefined}
+//                             onClick={undefined}
+//                             ScreenToLocalTransform={Transform.Identity}
+//                             ContentScaling={returnOne}
+//                             NativeHeight={returnZero}
+//                             NativeWidth={returnZero}
+//                             PanelWidth={() => window.screen.width}
+//                             PanelHeight={() => window.screen.height}
+//                             renderDepth={0}
+//                             focus={emptyFunction}
+//                             backgroundColor={backgroundColor}
+//                             parentActive={returnTrue}
+//                             whenActiveChanged={emptyFunction}
+//                             bringToFront={emptyFunction}
+//                             ContainingCollectionView={undefined}
+//                             ContainingCollectionDoc={undefined}
+//                         />
+//                     </div>
+//                 );
+//             } else {
+//                 return (
+//                     <div style={{ position: "relative", top: '200px', height: `calc(100% - 200px)`, width: "100%", overflow: "hidden", left: "0%" }}>
+//                         <DocumentView
+//                             Document={this.mainContainer}
+//                             DataDoc={undefined}
+//                             LibraryPath={emptyPath}
+//                             addDocument={returnFalse}
+//                             addDocTab={returnFalse}
+//                             pinToPres={emptyFunction}
+//                             rootSelected={returnFalse}
+//                             removeDocument={undefined}
+//                             onClick={undefined}
+//                             ScreenToLocalTransform={Transform.Identity}
+//                             ContentScaling={returnOne}
+//                             PanelWidth={this.returnWidth}
+//                             PanelHeight={this.returnHeight}
+//                             NativeHeight={returnZero}
+//                             NativeWidth={returnZero}
+//                             renderDepth={0}
+//                             focus={emptyFunction}
+//                             backgroundColor={backgroundColor}
+//                             parentActive={returnTrue}
+//                             whenActiveChanged={emptyFunction}
+//                             bringToFront={emptyFunction}
+//                             ContainingCollectionView={undefined}
+//                             ContainingCollectionDoc={undefined}
+//                         // mobile={true}
+//                         />
+//                     </div>
+//                 );
+//             }
+//         }
+//     }
+
+//     returnWidth = () => 2000;
+//     returnHeight = () => 2000;
+
+//     handleClick(doc: Doc) {
+//         let children = DocListCast(doc.data);
+//         if (doc.type !== "collection") {
+//             this._parents.push(this._activeDoc);
+//             this._activeDoc = doc;
+//             this.switchCurrentView((userDoc: Doc) => doc);
+//             this._homeMenu = false;
+//             this.toggleSidebar();
+//         } else if (doc.type === "collection" && children.length === 0) {
+//             console.log("This collection has no children");
+//         } else {
+//             this._parents.push(this._activeDoc);
+//             this._activeDoc = doc;
+//             this.switchCurrentView((userDoc: Doc) => doc);
+//             this._homeMenu = false;
+//             this._child = doc;
+//         }
+
+//         // let sidebar = document.getElementById("sidebar") as HTMLElement;
+//         // sidebar.classList.toggle('active');
+//     }
+
+//     createPathname = () => {
+//         let docArray = [];
+//         this._parents.map((doc: Doc, index: any) => {
+//             // if (doc === this.mainDoc) {
+//             //     pathname = pathname;
+//             // } else if (doc.type === "audio" || doc.type === "presentation") {
+//             //     pathname = pathname;
+//             // } else if (doc.type !== "collection") {
+//             //     pathname = pathname;
+//             // } else {
+//             //     pathname = pathname + " > " + doc.title;
+//             //     titleArray.push(doc.title);
+//             //     docArray.push(doc);
+//             // }
+//             docArray.push(doc);
+//         });
+//         docArray.push(this._activeDoc);
+//         // if (this._activeDoc.title === "mobile audio") {
+//         //     pathname = this._activeDoc.title;
+//         // } else if (this._activeDoc.title === "Presentation") {
+//         //     pathname = this._activeDoc.title;
+//         // } else if (this._activeDoc === this.mainDoc) {
+//         //     pathname = pathname;
+//         // } else {
+//         //     pathname = pathname + " > " + this._activeDoc.title;
+//         //     docArray.push(this._activeDoc);
+//         //     titleArray.push(this._activeDoc.title);
+//         // }
+
+//         return docArray;
+//     }
+
+//     renderPathbar = () => {
+//         // if (this._homeMenu == false) {
+//         let docArray = this.createPathname();
+//         let items = docArray.map((doc: Doc, index: any) => {
+//             if (index == 0) {
+//                 return (
+//                     <div className="pathbarItem">
+//                         <div className="pathbarText"
+//                             key={index}
+//                             onClick={() => this.handlePathClick(doc, index)}>{doc.title}
+//                         </div>
+//                     </div>);
+//             } else if (doc === this._activeDoc) {
+//                 return (
+//                     <div className="pathbarItem">
+//                         <FontAwesomeIcon className="pathIcon" icon="angle-right" size="lg" />
+//                         <div className="pathbarText"
+//                             style={{ backgroundColor: "rgb(119, 37, 37)" }}
+//                             key={index}
+//                             onClick={() => this.handlePathClick(doc, index)}>{doc.title}
+//                         </div>
+//                     </div>);
+//             } else {
+//                 return (
+//                     <div className="pathbarItem">
+//                         <FontAwesomeIcon className="pathIcon" icon="angle-right" size="lg" />
+//                         <div className="pathbarText"
+//                             key={index}
+//                             onClick={() => this.handlePathClick(doc, index)}>{doc.title}
+//                         </div>
+//                     </div>);
+//             }
+
+//         });
+//         if (this._parents.length !== 0) {
+//             return (<div className="pathbar">
+//                 <div className="scrollmenu">
+//                     {items}
+//                 </div>
+//                 <div className="back" >
+//                     <FontAwesomeIcon onClick={this.back} icon={"chevron-left"} color="white" size={"2x"} />
+//                 </div>
+//                 <div className="hidePath" />
+//             </div>);
+//         } else {
+//             return (<div className="pathbar">
+//                 <div className="scrollmenu">
+//                     {items}
+//                 </div>
+//                 <div className="hidePath" />
+//             </div>);
+//         }
+//         //     }
+//         // } else {
+
+//         //     return (
+//         //         <div className="pathbar">
+//         //             <div className="scrollmenu">
+//         //                 <div className="pathbarItem">
+//         //                     <div className="pathbarText"
+//         //                         style={{ backgroundColor: "rgb(119, 37, 37)" }}
+//         //                         key={0}
+//         //                         onClick={() => this.returnHome()}>Home
+//         //                     </div>
+//         //                 </div>
+//         //             </div>
+//         //             <div className="hidePath" />
+//         //         </div>
+//         //     );
+//         // }
+
+//         // }
+//     }
+
+//     handlePathClick = (doc: Doc, index: number) => {
+//         if (doc === this._library) {
+//             this._activeDoc = doc;
+//             this._child = null;
+//             this.switchCurrentView((userDoc: Doc) => doc);
+//             this._parents.length = index;
+//         } else if (doc === this._homeDoc) {
+//             this.returnHome();
+//         } else {
+//             console.log(index);
+//             this._activeDoc = doc;
+//             this._child = doc;
+//             this.switchCurrentView((userDoc: Doc) => doc);
+//             this._parents.length = index;
+//         }
+//     }
+
+//     @action
+//     toggleSidebar = () => this.sidebarActive = !this.sidebarActive
+
+//     switchToLibrary = () => {
+//         this._parents.push(this._activeDoc);
+//         this.switchCurrentView((userDoc: Doc) => this._library);
+//         this._activeDoc = this._library;
+//         this._homeMenu = false;
+//         this.toggleSidebar();
+//     }
+
+//     // renderDefaultContent = () => {
+//     //     let menuButtons = DocListCast(this._homeDoc.data).map((doc: Doc, index: any) => {
+//     //         if (doc.type !== "ink") {
+//     //             return (
+//     //                 <div
+//     //                     className="item"
+//     //                     key={index}
+//     //                     onClick={() => doc.click}>{doc.title}
+//     //                 </div>);
+//     //         }
+//     //     });
+
+//     //     if (this._homeMenu === true) {
+//     //         return (
+//     //             <div>
+//     //                 <div className="navbar">
+//     //                     <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
+//     //                     <div className="header" id="header">{this._homeDoc.title}</div>
+//     //                     <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
+//     //                         <span></span>
+//     //                         <span></span>
+//     //                         <span></span>
+//     //                     </div>
+//     //                 </div>
+//     //                 {this.renderPathbar()}
+//     //                 <div className="sidebar" id="sidebar">
+//     //                     <div className="sidebarButtons">
+//     //                         {menuButtons}
+//     //                     </div>
+//     //                 </div>
+//     //             </div>
+//     //         );
+//     //     }
+
+//     //     const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+//     //     const buttons = DocListCast(this._child ? this._child.data : workspaces.data).map((doc: Doc, index: any) => {
+//     //         return (
+//     //             <div
+//     //                 className="item"
+//     //                 key={index}
+//     //                 onClick={() => this.handleClick(doc)}>{doc.title}
+//     //                 <div className="type">{doc.type}</div>
+//     //                 <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
+//     //             </div>);
+//     //     });
+//     //     return (
+//     //         <>
+//     //             <div className="navbar">
+//     //                 <div className={"header"}>{this.sidebarActive ? StrCast(this._activeDoc.title) : "Menu"}</div>
+//     //                 <div
+//     //                     className={`toggle-btn ${this.sidebarActive ? "active" : ""}`}
+//     //                     onClick={this.toggleSidebar}
+//     //                 />
+//     //             </div>
+//     //             <div className="pathbar">
+//     //                 <div className="pathname">{this.createPathname()}</div>
+//     //             </div>
+//     //             <div className={`sidebar ${this.sidebarActive ? "active" : ""}`}>
+//     //                 <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
+//     //                 {this._child ?
+//     //                     <>
+//     //                         <div className="back" onClick={this.back}>&#8592;</div>
+//     //                         <div>{buttons}</div>
+//     //                         <div className="item" key="home" onClick={this.returnHome}>Home</div>
+//     //                     </> :
+//     //                     <>
+//     //                         {buttons}
+//     //                         {/* <div className="item" key="library" onClick={this.openLibrary}>
+//     //                             Library
+//     //                             </div> */}
+//     //                         <Uploader Document={workspaces} />
+//     //                         <div className="item" key="audio" onClick={this.recordAudio}>Record Audio</div>
+//     //                         <div className="item" key="presentation" onClick={this.setupDefaultPresentation}>Presentation</div>
+//     //                         <div className="item" key="settings" onClick={() => SettingsManager.Instance.open()}>Settings</div>
+//     //                     </>
+//     //                 }
+//     //             </div>
+//     //             {this._child ? null : <div>{this.renderView}</div>}
+//     //         </>
+//     //     );
+//     // }
+
+//     renderDefaultContent = () => {
+//         let menuButtons = DocListCast(this._homeDoc.data).map((doc: Doc, index: any) => {
+//             if (doc.type !== "ink") {
+//                 return (
+//                     <div
+//                         className="item"
+//                         key={index}
+//                         onClick={() => doc.click}>{doc.title}
+//                     </div>);
+//             }
+//         });
+
+//         if (this._homeMenu === true) {
+//             return (
+//                 <div>
+//                     <div className="navbar">
+//                         <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
+//                         <div className="header" id="header">{this._homeDoc.title}</div>
+//                         <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
+//                             <span></span>
+//                             <span></span>
+//                             <span></span>
+//                         </div>
+//                     </div>
+//                     {this.renderPathbar()}
+//                     <div className="sidebar" id="sidebar">
+//                         <div className="sidebarButtons">
+//                             {menuButtons}
+//                         </div>
+//                     </div>
+//                 </div>
+//             );
+//         }
+//         const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+//         let buttons = DocListCast(workspaces.data).map((doc: Doc, index: any) => {
+//             if (doc.type !== "ink") {
+//                 return (
+//                     <div
+//                         className="item"
+//                         key={index}
+//                         onClick={() => this.handleClick(doc)}>{doc.title}
+//                         <div className="type">{doc.type}</div>
+//                         <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
+//                     </div>);
+//             }
+//         });
+
+//         if (this._child) {
+//             buttons = DocListCast(this._child.data).map((doc: Doc, index: any) => {
+//                 if (doc.type !== "ink") {
+//                     return (
+//                         <div
+//                             className="item"
+//                             key={index}
+//                             onClick={() => this.handleClick(doc)}>{doc.title}
+//                             <div className="type">{doc.type}</div>
+//                             <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
+//                         </div>);
+//                 }
+//             });
+//         }
+
+//         if (!this._child) {
+//             return (
+//                 <div>
+//                     <div className="navbar">
+//                         <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
+//                         <div className="header" id="header">{this._homeDoc.title}</div>
+//                         <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
+//                             <span></span>
+//                             <span></span>
+//                             <span></span>
+//                         </div>
+//                     </div>
+//                     {this.renderPathbar()}
+//                     <div className="sidebar" id="sidebar">
+//                         <div className="sidebarButtons">
+//                             {buttons}
+//                             {/* <div className="item" key="library" onClick={this.openLibrary}>
+//                                 Library
+//                             </div> */}
+//                             {/* <Uploader Document={workspaces} />
+//                             <div className="item" key="audio" onClick={this.recordAudio}>
+//                                 Record Audio
+//                             </div>
+//                             <div className="item" key="presentation" onClick={this.openDefaultPresentation}>
+//                                 Presentation
+//                             </div> */}
+//                             {/* <div className="item" key="settings" onClick={() => SettingsManager.Instance.open()}>
+//                                 Settings
+//                             </div> */}
+//                             <div className="item" key="ink" id="ink" onClick={() => this.onSwitchInking()}>
+//                                 Ink On
+//                             </div>
+//                         </div>
+//                     </div>
+//                     {/* <div>
+//                         {this.renderView}
+//                     </div> */}
+//                 </div>
+//             );
+//         }
+//         else {
+//             return (
+//                 <div>
+//                     <div className="navbar">
+//                         <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
+//                         <div className="header" id="header">library</div>
+//                         <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
+//                             <span></span>
+//                             <span></span>
+//                             <span></span>
+//                         </div>
+//                     </div>
+//                     {this.renderPathbar()}
+//                     <div className="sidebar" id="sidebar">
+//                         <div className="sidebarButtons">
+//                             {buttons}
+//                             <div className="item" key="ink" id="ink" onClick={() => this.onSwitchInking()}>
+//                                 Ink On
+//                             </div>
+//                             <div className="item" key="home" onClick={this.returnMain}>
+//                                 Home
+//                             </div>
+//                         </div>
+//                     </div>
+//                 </div>
+//             );
+//         }
+//     }
+
+//     recordAudio = async () => {
+//         // upload to server with known URL
+//         if (this._activeDoc.title !== "mobile audio") {
+//             this._parents.push(this._activeDoc);
+//         }
+//         const audioDoc = Cast(Docs.Create.AudioDocument(nullAudio, { _width: 200, _height: 100, title: "mobile audio" }), Doc) as Doc;
+//         console.log(audioDoc);
+//         if (audioDoc) {
+//             console.log("audioClicked: " + audioDoc.title);
+//             this._activeDoc = audioDoc;
+//             this.switchCurrentView((userDoc: Doc) => audioDoc);
+//             this._homeMenu = false;
+//             // this.toggleSidebar();
+//         }
+//         // const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
+//         // this.audioState = await audioDoc.getProto;
+//         // if (this.audioState) {
+//         //     console.log(this.audioState);
+//         //     const data = Cast(audioRightSidebar.data, listSpec(Doc));
+//         //     if (data) {
+//         //         data.push(audioDoc);
+//         //     }
+//         // }
+//     }
+
+//     uploadAudio = () => {
+//         const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
+//         const audioDoc = this._activeDoc;
+//         const data = Cast(audioRightSidebar.data, listSpec(Doc));
+//         console.log(audioDoc.proto);
+//         if (data) {
+//             data.push(audioDoc);
+//         }
+//         // this.recordAudio();
+//     }
+
+//     uploadAudioButton = () => {
+//         if (this._activeDoc.type === "audio") {
+//             return <div className="docButton"
+//                 title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
+//                 style={{ backgroundColor: "black", color: "white" }}
+//                 onClick={this.uploadAudio}
+//             >
+//                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
+//                 />
+//             </div>;
+//         }
+//     }
+
+//     toggleSelector = () => {
+//         console.log("toggle selector!");
+//         let toolbar = document.getElementById("toolbar") as HTMLElement;
+//         toolbar.classList.toggle('active');
+//     }
+
+//     colorTool = () => {
+//         if (this._activeDoc._viewType === "docking") {
+//             const color = InkingControl.Instance.selectedColor;
+//             console.log(color);
+//             return (
+//                 <div
+//                     className="docButton"
+//                     style={{ backgroundColor: color }}
+//                     onClick={this.toggleSelector}
+//                 >
+//                     <div className="toolbar" id="toolbar">
+//                         <div className="colorSelector">
+//                             <div className="colorButton"
+//                                 style={{ backgroundColor: "red" }}
+//                                 onClick={() => {
+//                                     InkingControl.Instance.updateSelectedColor("rgb(255,0,0)");
+//                                     Doc.UserDoc().inkColor = "rgb(255,0,0)";
+//                                     console.log(InkingControl.Instance.selectedColor);
+//                                 }}>
+//                             </div>
+//                             <div className="colorButton"
+//                                 style={{ backgroundColor: "green" }}
+//                                 onClick={e => {
+//                                     InkingControl.Instance.updateSelectedColor("rgb(0,128,0)");
+//                                     Doc.UserDoc().inkColor = "rgb(0,128,0)";
+//                                     console.log(InkingControl.Instance.selectedColor);
+//                                 }}>
+//                             </div>
+//                             <div className="colorButton"
+//                                 style={{ backgroundColor: "blue" }}
+//                                 onClick={e => {
+//                                     InkingControl.Instance.updateSelectedColor("rgb(0,0,255)");
+//                                     Doc.UserDoc().inkColor = "rgb(0,0,255)";
+//                                     console.log(InkingControl.Instance.selectedColor);
+//                                 }}>
+//                             </div>
+//                         </div>
+//                         <div className="widthSelector">
+//                             <input type="range" min="1" max="100" defaultValue="2" id="myRange" onChange={(e: React.ChangeEvent<HTMLInputElement>) => InkingControl.Instance.switchWidth(e.target.value)} />
+//                         </div>
+//                     </div>
+//                 </div>
+//             );
+//         }
+//     }
+
+//     drawInk = () => {
+//         if (this._activeDoc._viewType === "docking") {
+//             const inkIsOn = this._ink;
+//             return <div className="docButton"
+//                 id="inkButton"
+//                 title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
+//                 onClick={this.onSwitchInking}>
+//                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="pen-nib"
+//                 />
+//             </div>;
+//         }
+//     }
+
+//     downloadDocument = () => {
+//         if (this._activeDoc.type === "image") {
+//             const url = this._activeDoc["data-path"]?.toString();
+//             return <div className="docButton"
+//                 title={"Download Image"}
+//                 style={{ backgroundColor: "white", color: "black" }}
+//                 onClick={e => {
+//                     window.open(url);
+//                     console.log(url);
+//                 }}>
+//                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="download"
+//                 />
+//             </div>;
+//         }
+//     }
+
+//     pinToPresentation = () => {
+//         // Only making button available if it is an image
+//         if (this._activeDoc.type === "image") {
+//             const isPinned = this._activeDoc && Doc.isDocPinned(this._activeDoc);
+//             return <div className="docButton"
+//                 title={Doc.isDocPinned(this._activeDoc) ? "Unpin from presentation" : "Pin to presentation"}
+//                 style={{ backgroundColor: isPinned ? "black" : "white", color: isPinned ? "white" : "black" }}
+//                 onClick={e => {
+//                     if (isPinned) {
+//                         DockedFrameRenderer.UnpinDoc(this._activeDoc);
+//                     }
+//                     else {
+//                         DockedFrameRenderer.PinDoc(this._activeDoc);
+//                     }
+//                 }}>
+//                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
+//                 />
+//             </div>;
+//         }
+//     }
+
+//     setupDefaultPresentation = () => {
+//         if (this._activeDoc.title !== "Presentation") {
+//             this._parents.push(this._activeDoc);
+//         }
+
+//         const presentation = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
+
+//         if (presentation) {
+//             console.log(this._activeDoc.mobile);
+//             console.log("presentation clicked: " + presentation.title);
+//             this._activeDoc = presentation;
+//             this.switchCurrentView((userDoc: Doc) => presentation);
+//             this._homeMenu = false;
+//             // this.toggleSidebar();
+//         }
+//     }
+
+//     // mobileHome = () => {
+//     //     return (
+//     //         <div className="homeContainer">
+//     //             <div className="uploadButton">
+
+//     //             </div>
+//     //             <div className="presentationButton">
+
+//     //             </div>
+//     //             <div className="recordAudioButton">
+
+//     //             </div>
+//     //             <div className="inkButton">
+
+//     //             </div>
+//     //             <div className="settingsButton">
+
+//     //             </div>
+//     //         </div>
+//     //     );
+//     // }
+
+//     renderActiveCollection = (userDoc: Doc) => {
+//         if (this.activeContainer) {
+//             const active = Cast(this.activeContainer.data, listSpec(Doc));
+//             if (active) {
+//                 return (
+//                     <div className="mobileInterface-background">HELLO!</div>
+//                 );
+//             }
+//         }
+//     }
+
+//     onBack = (e: React.MouseEvent) => {
+//         this.switchCurrentView((userDoc: Doc) => this.mainDoc);
+//         InkingControl.Instance.switchTool(InkTool.None); // TODO: switch to previous tool
+
+//         DocServer.Mobile.dispatchOverlayTrigger({
+//             enableOverlay: false,
+//             width: window.innerWidth,
+//             height: window.innerHeight
+//         });
+
+//         // this.inkDoc = undefined;
+//         this.drawingInk = false;
+//     }
+
+//     shiftLeft = (e: React.MouseEvent) => {
+//         DocServer.Mobile.dispatchOverlayPositionUpdate({
+//             dx: -10
+//         });
+//         e.preventDefault();
+//         e.stopPropagation();
+//     }
+
+//     shiftRight = (e: React.MouseEvent) => {
+//         DocServer.Mobile.dispatchOverlayPositionUpdate({
+//             dx: 10
+//         });
+//         e.preventDefault();
+//         e.stopPropagation();
+//     }
+
+//     panelHeight = () => window.innerHeight;
+//     panelWidth = () => window.innerWidth;
+//     //WAS 3
+
+//     //WAS 1
+
+//     upload = async (e: React.MouseEvent) => {
+//         if (this.mainContainer) {
+//             const data = Cast(this.mainContainer.data, listSpec(Doc));
+//             if (data) {
+//                 const collectionDoc = await data[1]; //this should be the collection doc since the positions should be locked
+//                 const children = DocListCast(collectionDoc.data);
+//                 const uploadDoc = children.length === 1 ? children[0] : Docs.Create.StackingDocument(children, {
+//                     title: "Mobile Upload Collection", backgroundColor: "white", lockedPosition: true, _width: 300, _height: 300
+//                 });
+//                 if (uploadDoc) {
+//                     DocServer.Mobile.dispatchMobileDocumentUpload({
+//                         docId: uploadDoc[Id],
+//                     });
+//                 }
+//             }
+//         }
+//         e.stopPropagation();
+//         e.preventDefault();
+//     }
+
+//     addWebToCollection = async () => {
+//         let url = "https://en.wikipedia.org/wiki/Hedgehog";
+//         if (this.mainContainer) {
+//             const data = Cast(this.mainContainer.data, listSpec(Doc));
+//             if (data) {
+//                 const webDoc = await data[0];
+//                 const urlField: FieldResult<WebField> = Cast(webDoc.data, WebField);
+//                 url = urlField ? urlField.url.toString() : "https://en.wikipedia.org/wiki/Hedgehog";
+
+//             }
+//         }
+//         Docs.Create.WebDocument(url, { _width: 300, _height: 300, title: "Mobile Upload Web Doc" });
+//     }
+
+//     clearUpload = async () => {
+//         if (this.mainContainer) {
+//             const data = Cast(this.mainContainer.data, listSpec(Doc));
+//             if (data) {
+//                 const collectionDoc = await data[1];
+//                 const children = DocListCast(collectionDoc.data);
+//                 children.forEach(doc => {
+//                 });
+//                 // collectionDoc[data] = new List<Doc>();
+//             }
+//         }
+//     }
+
+//     onDragOver = (e: React.DragEvent) => {
+//         e.preventDefault();
+//         e.stopPropagation();
+//     }
+
+//     render() {
+//         // const content = this.currentView === "main" ? this.mainContent :
+//         //     this.currentView === "ink" ? this.inkContent :
+//         //         this.currentView === "upload" ? this.uploadContent : <></>;
+//         return (
+//             <div className="mobileInterface-container" onDragOver={this.onDragOver}>
+//                 {/* <DocumentDecorations />
+//                 <GestureOverlay>
+//                     {this.renderView ? this.renderView() : this.renderDefaultContent()}
+//                 </GestureOverlay> */}
+//                 {/* <GestureOverlay> */}
+//                 <SettingsManager />
+//                 {/* {this.menuOptions()} */}
+//                 {/* {this.displayHome()} */}
+//                 <div className="docButtonContainer">
+//                     {this.pinToPresentation()}
+//                     {this.downloadDocument()}
+//                     {this.drawInk()}
+//                     {this.uploadAudioButton()}
+//                     {this.colorTool()}
+//                 </div>
+//                 <GestureOverlay>
+
+//                 </GestureOverlay>
+//                 {this.renderDefaultContent()}
+//                 {this.displayWorkspaces()}
+//                 {/* </GestureOverlay> */}
+//                 {/* <DictationOverlay />
+//                 <SharingManager />
+//                 <GoogleAuthenticationManager /> */}
+//                 {/* <DocumentDecorations /> */}
+//                 {/* <div>
+//                     {this.renderDefaultContent()}
+//                 </div> */}
+//                 {/* <PreviewCursor /> */}
+//                 {/* <ContextMenu /> */}
+//                 {/* <RadialMenu />
+//                 <RichTextMenu /> */}
+//                 {/* <PDFMenu />
+//                 <MarqueeOptionsMenu />
+//                 <OverlayView /> */}
+//             </div>
+//         );
+//     }
+// }
+
+// Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); });
+// Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); });
+// Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); });
+// Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.recordAudio(); });
+// Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); });
+// Scripting.addGlobal(function switchToLibrary() { return MobileInterface.Instance.switchToLibrary(); });
+// // WAS 2
+
+// // 1
+// // renderUploadContent() {
+// //     if (this.mainContainer) {
+// //         return (
+// //             <div className="mobileInterface" onDragOver={this.onDragOver}>
+// //                 <div className="mobileInterface-inkInterfaceButtons">
+// //                     <button className="mobileInterface-button cancel" onClick={this.onBack} title="Back">BACK</button>
+// //                     {/* <button className="mobileInterface-button" onClick={this.clearUpload} title="Clear Upload">CLEAR</button> */}
+// //                     {/* <button className="mobileInterface-button" onClick={this.addWeb} title="Add Web Doc to Upload Collection"></button> */}
+// //                     <button className="mobileInterface-button" onClick={this.upload} title="Upload">UPLOAD</button>
+// //                 </div>
+// //                 <DocumentView
+// //                     Document={this.mainContainer}
+// //                     DataDoc={undefined}
+// //                     LibraryPath={emptyPath}
+// //                     addDocument={returnFalse}
+// //                     addDocTab={returnFalse}
+// //                     pinToPres={emptyFunction}
+// //                     rootSelected={returnFalse}
+// //                     removeDocument={undefined}
+// //                     onClick={undefined}
+// //                     ScreenToLocalTransform={Transform.Identity}
+// //                     ContentScaling={returnOne}
+// //                     NativeHeight={returnZero}
+// //                     NativeWidth={returnZero}
+// //                     PanelWidth={() => window.screen.width}
+// //                     PanelHeight={() => window.screen.height}
+// //                     renderDepth={0}
+// //                     focus={emptyFunction}
+// //                     backgroundColor={returnEmptyString}
+// //                     parentActive={returnTrue}
+// //                     whenActiveChanged={emptyFunction}
+// //                     bringToFront={emptyFunction}
+// //                     ContainingCollectionView={undefined}
+// //                     ContainingCollectionDoc={undefined} />
+// //             </div>
+// //         );
+// //     }
+// // }
+
+// // 2
+// // Scripting.addGlobal(function onSwitchMobileInking() { return MobileInterface.Instance.onSwitchInking(); });
+// // Scripting.addGlobal(function renderMobileInking() { return MobileInterface.Instance.renderInkingContent(); });
+// // Scripting.addGlobal(function onSwitchMobileUpload() { return MobileInterface.Instance.onSwitchUpload(); });
+// // Scripting.addGlobal(function renderMobileUpload() { return MobileInterface.Instance.renderUploadContent(); });
+//     // Scripting.addGlobal(function addWebToMobileUpload() { return MobileInterface.Instance.addWebToCollection(); });
+
+
+// // 3   
+//     // renderInkingContent = () => {
+//         //     console.log("rendering inking content");
+//         //     // TODO: support panning and zooming
+//         //     // TODO: handle moving of ink strokes
+//         //     if (this.mainContainer) {
+//         //         return (
+//         //             <div className="mobileInterface">
+//         //                 <div className="mobileInterface-inkInterfaceButtons">
+//         //                     <div className="navButtons">
+//         //                         <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing">BACK</button>
+//         //                     </div>
+//         //                     <div className="inkSettingButtons">
+//         //                         <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing"><FontAwesomeIcon icon="long-arrow-alt-left" /></button>
+//         //                     </div>
+//         //                     <div className="navButtons">
+//         //                         <button className="mobileInterface-button" onClick={this.shiftLeft} title="Shift left">left</button>
+//         //                         <button className="mobileInterface-button" onClick={this.shiftRight} title="Shift right">right</button>
+//         //                     </div>
+//         //                 </div>
+//         //                 <CollectionView
+//         //                     Document={this.mainContainer}
+//         //                     DataDoc={undefined}
+//         //                     LibraryPath={emptyPath}
+//         //                     fieldKey={""}
+//         //                     dropAction={"alias"}
+//         //                     bringToFront={emptyFunction}
+//         //                     addDocTab={returnFalse}
+//         //                     pinToPres={emptyFunction}
+//         //                     PanelWidth={this.panelWidth}
+//         //                     PanelHeight={this.panelHeight}
+//         //                     NativeHeight={returnZero}
+//         //                     NativeWidth={returnZero}
+//         //                     focus={emptyFunction}
+//         //                     isSelected={returnFalse}
+//         //                     select={emptyFunction}
+//         //                     active={returnFalse}
+//         //                     ContentScaling={returnOne}
+//         //                     whenActiveChanged={returnFalse}
+//         //                     ScreenToLocalTransform={Transform.Identity}
+//         //                     renderDepth={0}
+//         //                     ContainingCollectionView={undefined}
+//         //                     ContainingCollectionDoc={undefined}
+//         //                     rootSelected={returnTrue}>
+//         //                 </CollectionView>
+//         //             </div>
+//         //         );
+//         //     }
+//         // }
 
 @observer
 export class MobileInterface extends React.Component {
     @observable static Instance: MobileInterface;
     @computed private get userDoc() { return Doc.UserDoc(); }
     @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
-    @computed private get activeContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
-    // @observable private currentView: "main" | "ink" | "upload" = "main";
-    @observable private mainDoc: any = CurrentUserUtils.setupMobileDoc(this.userDoc);
+    // @computed private get activeContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
+    @observable private mainDoc: any = CurrentUserUtils.setupMobileMenu();
     @observable private renderView?: () => JSX.Element;
-    @observable private sidebarActive = true;
+    @observable private audioState: any;
 
     public _activeDoc: Doc = this.mainDoc;
+    public _homeDoc: Doc = this.mainDoc;
+    private _homeMenu: boolean = true;
 
     // private inkDoc?: Doc;
     public drawingInk: boolean = false;
@@ -59,9 +1090,11 @@ export class MobileInterface extends React.Component {
     // private _uploadDoc: Doc = this.userDoc;
     private _child: Doc | null = null;
     private _parents: Array<Doc> = [];
-    private _menu: Doc = this.mainDoc;
+    private _library: Doc = CurrentUserUtils.setupLibrary(this.userDoc);
     private _open: boolean = false;
-    private _library: Doc = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+
+    // private _library: Doc = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+    private _ink: boolean = false;
 
     constructor(props: Readonly<{}>) {
         super(props);
@@ -71,33 +1104,31 @@ export class MobileInterface extends React.Component {
     @action
     componentDidMount = () => {
         library.add(...[faPenNib, faHighlighter, faEraser, faMousePointer, faThumbtack]);
-
+        if (this.userDoc.activeMobile) {
+            console.log(Doc.UserDoc().activeMobile)
+        }
         if (this.userDoc && !this.mainContainer) {
-            this.userDoc.activeMobile = this.mainDoc;
+            this.userDoc.activeMobile = this._homeDoc;
         }
+        InkingControl.Instance.switchTool(InkTool.None);
+        MobileInterface.Instance.drawingInk = false;
+        InkingControl.Instance.updateSelectedColor("#FF0000");
+        console.log(this.userDoc.inkColor);
+        console.log(InkingControl.Instance.selectedColor);
+        InkingControl.Instance.switchWidth("2");
+        this.switchCurrentView((userDoc: Doc) => this._homeDoc);
     }
 
     @action
     switchCurrentView = (doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) => {
         if (!this.userDoc) return;
 
-        this.userDoc.activeMobile = doc(this.userDoc);
+        Doc.UserDoc().activeMobile = doc(this.userDoc);
         onSwitch && onSwitch();
 
         this.renderView = renderView;
     }
 
-    onSwitchInking = () => {
-        InkingControl.Instance.switchTool(InkTool.Pen);
-        MobileInterface.Instance.drawingInk = true;
-
-        DocServer.Mobile.dispatchOverlayTrigger({
-            enableOverlay: true,
-            width: window.innerWidth,
-            height: window.innerHeight
-        });
-    }
-
     onSwitchUpload = async () => {
         let width = 300;
         let height = 300;
@@ -123,70 +1154,167 @@ export class MobileInterface extends React.Component {
         });
     }
 
+    toggleSidebar = () => {
+        if (this._open === false) {
+            this._open = true;
+        } else {
+            this._open = false;
+        }
+        console.log("clicked");
+        let menuButton = document.getElementById("menuButton") as HTMLElement;
+        menuButton.classList.toggle('active');
+
+        let sidebar = document.getElementById("sidebar") as HTMLElement;
+        sidebar.classList.toggle('active');
+
+        let header = document.getElementById("header") as HTMLElement;
+
+        if (!sidebar.classList.contains('active')) {
+            header.textContent = String(this._activeDoc.title);
+        } else {
+            header.textContent = "library";
+        }
+    }
+
+    switchToLibrary = () => {
+        this._parents.push(this._activeDoc);
+        this.switchCurrentView((userDoc: Doc) => this._library);
+        this._activeDoc = this._library;
+        this._homeMenu = false;
+        this.toggleSidebar();
+    }
+
     back = () => {
-        const doc = Cast(this._parents.pop(), Doc) as Doc;
-        if (doc === Cast(this._menu, Doc) as Doc) {
+        let header = document.getElementById("header") as HTMLElement;
+        let doc = Cast(this._parents.pop(), Doc) as Doc;
+        if (doc === Cast(this._library, Doc) as Doc) {
+            this._child = null;
+            this.userDoc.activeMobile = this._library;
+        } else if (doc === Cast(this._homeDoc, Doc) as Doc) {
+            this._homeMenu = true;
+            this._parents = [];
+            this._activeDoc = this._homeDoc;
             this._child = null;
-            this.userDoc.activeMobile = this.mainDoc;
+            this.switchCurrentView((userDoc: Doc) => this._homeDoc);
         } else {
             if (doc) {
                 this._child = doc;
                 this.switchCurrentView((userDoc: Doc) => doc);
+                this._homeMenu = false;
+                header.textContent = String(doc.title);
             }
         }
         if (doc) {
             this._activeDoc = doc;
         }
+        this._ink = false;
     }
 
     returnHome = () => {
+        if (this._homeMenu === false || this._open === true) {
+            this._homeMenu = true;
+            this._parents = [];
+            this._activeDoc = this._homeDoc;
+            this._child = null;
+            this.switchCurrentView((userDoc: Doc) => this._homeDoc);
+        }
+        if (this._open) {
+            this.toggleSidebar();
+        }
+    }
+
+    returnMain = () => {
+        console.log("home");
         this._parents = [];
-        this._activeDoc = this._menu;
-        this.switchCurrentView((userDoc: Doc) => this._menu);
+        // this.toggleSidebar();
+        this._activeDoc = this._library;
+        this.switchCurrentView((userDoc: Doc) => this._library);
+        this._homeMenu = false;
         this._child = null;
     }
 
+    // @computed get onChildClickHandler() { return ScriptCast(Doc.UserDoc.onClick); }
+
     displayWorkspaces = () => {
         if (this.mainContainer) {
             const backgroundColor = () => "white";
-            return (
-                <div style={{ position: "relative", top: '200px', height: `calc(100% - 250px)`, width: "100%", overflow: "hidden" }}>
-                    <DocumentView
-                        Document={this.mainContainer}
-                        DataDoc={undefined}
-                        LibraryPath={emptyPath}
-                        addDocument={returnFalse}
-                        addDocTab={returnFalse}
-                        pinToPres={emptyFunction}
-                        rootSelected={returnFalse}
-                        removeDocument={undefined}
-                        onClick={undefined}
-                        ScreenToLocalTransform={Transform.Identity}
-                        ContentScaling={returnOne}
-                        NativeHeight={returnZero}
-                        NativeWidth={returnZero}
-                        PanelWidth={() => window.screen.width}
-                        PanelHeight={() => window.screen.height}
-                        renderDepth={0}
-                        focus={emptyFunction}
-                        backgroundColor={backgroundColor}
-                        parentActive={returnTrue}
-                        whenActiveChanged={emptyFunction}
-                        bringToFront={emptyFunction}
-                        ContainingCollectionView={undefined}
-                        ContainingCollectionDoc={undefined}
-                    />
-                </div>
-            );
+            if (this._activeDoc.title === "mobile audio") {
+                return (
+                    <div style={{ position: "relative", top: '600px', height: `calc(50% - 450px)`, width: "80%", overflow: "hidden", left: "10%", cursor: "pointer" }}>
+                        <DocumentView
+                            Document={this.mainContainer}
+                            DataDoc={undefined}
+                            LibraryPath={emptyPath}
+                            addDocument={returnFalse}
+                            addDocTab={returnFalse}
+                            pinToPres={emptyFunction}
+                            rootSelected={returnFalse}
+                            removeDocument={undefined}
+                            onClick={undefined}
+                            ScreenToLocalTransform={Transform.Identity}
+                            ContentScaling={returnOne}
+                            NativeHeight={returnZero}
+                            NativeWidth={returnZero}
+                            PanelWidth={() => window.screen.width}
+                            PanelHeight={() => window.screen.height}
+                            renderDepth={0}
+                            focus={emptyFunction}
+                            backgroundColor={backgroundColor}
+                            parentActive={returnTrue}
+                            whenActiveChanged={emptyFunction}
+                            bringToFront={emptyFunction}
+                            ContainingCollectionView={undefined}
+                            ContainingCollectionDoc={undefined}
+                        />
+                    </div>
+                );
+            } else {
+                return (
+                    <div style={{ position: "relative", top: '200px', height: `calc(100% - 200px)`, width: "100%", overflow: "hidden", left: "0%" }}>
+                        <DocumentView
+                            Document={this.mainContainer}
+                            DataDoc={undefined}
+                            LibraryPath={emptyPath}
+                            addDocument={returnFalse}
+                            addDocTab={returnFalse}
+                            pinToPres={emptyFunction}
+                            rootSelected={returnFalse}
+                            removeDocument={undefined}
+                            onClick={undefined}
+                            ScreenToLocalTransform={Transform.Identity}
+                            ContentScaling={returnOne}
+                            PanelWidth={this.returnWidth}
+                            PanelHeight={this.returnHeight}
+                            NativeHeight={returnZero}
+                            NativeWidth={returnZero}
+                            renderDepth={0}
+                            focus={emptyFunction}
+                            backgroundColor={backgroundColor}
+                            parentActive={returnTrue}
+                            whenActiveChanged={emptyFunction}
+                            bringToFront={emptyFunction}
+                            ContainingCollectionView={undefined}
+                            ContainingCollectionDoc={undefined}
+                        // mobile={true}
+                        />
+                    </div>
+                );
+            }
         }
     }
 
+    returnWidth = () => 2000;
+    returnHeight = () => 2000;
+
     handleClick(doc: Doc) {
-        const children = DocListCast(doc.data);
+        console.log(screen.height)
+        console.log(screen.width)
+        let children = DocListCast(doc.data);
         if (doc.type !== "collection") {
             this._parents.push(this._activeDoc);
             this._activeDoc = doc;
             this.switchCurrentView((userDoc: Doc) => doc);
+            this._homeMenu = false;
             this.toggleSidebar();
         } else if (doc.type === "collection" && children.length === 0) {
             console.log("This collection has no children");
@@ -194,6 +1322,7 @@ export class MobileInterface extends React.Component {
             this._parents.push(this._activeDoc);
             this._activeDoc = doc;
             this.switchCurrentView((userDoc: Doc) => doc);
+            this._homeMenu = false;
             this._child = doc;
         }
 
@@ -201,167 +1330,426 @@ export class MobileInterface extends React.Component {
         // sidebar.classList.toggle('active');
     }
 
+    /**
+     * Handles creation of array which is then rendered in renderPathbar()
+     */
     createPathname = () => {
-        let pathname = "";
+        // let pathname = 'workspaces';
+        // let titleArray = [];
+        let docArray = [];
         this._parents.map((doc: Doc, index: any) => {
-            if (doc === this.mainDoc) {
-                pathname = pathname + doc.title;
+            // if (doc === this.mainDoc) {
+            //     pathname = pathname;
+            // } else if (doc.type === "audio" || doc.type === "presentation") {
+            //     pathname = pathname;
+            // } else if (doc.type !== "collection") {
+            //     pathname = pathname;
+            // } else {
+            //     pathname = pathname + " > " + doc.title;
+            //     titleArray.push(doc.title);
+            //     docArray.push(doc);
+            // }
+            docArray.push(doc);
+        });
+        docArray.push(this._activeDoc);
+        // if (this._activeDoc.title === "mobile audio") {
+        //     pathname = this._activeDoc.title;
+        // } else if (this._activeDoc.title === "Presentation") {
+        //     pathname = this._activeDoc.title;
+        // } else if (this._activeDoc === this.mainDoc) {
+        //     pathname = pathname;
+        // } else {
+        //     pathname = pathname + " > " + this._activeDoc.title;
+        //     docArray.push(this._activeDoc);
+        //     titleArray.push(this._activeDoc.title);
+        // }
+
+        return docArray;
+    }
+
+    // Renders the graphical pathbar
+    renderPathbar = () => {
+        // if (this._homeMenu == false) {
+        let docArray = this.createPathname();
+        let items = docArray.map((doc: Doc, index: any) => {
+            if (index == 0) {
+                return (
+                    <div className="pathbarItem">
+                        <div className="pathbarText"
+                            key={index}
+                            onClick={() => this.handlePathClick(doc, index)}>{doc.title}
+                        </div>
+                    </div>);
+            } else if (doc === this._activeDoc) {
+                return (
+                    <div className="pathbarItem">
+                        <FontAwesomeIcon className="pathIcon" icon="angle-right" size="lg" />
+                        <div className="pathbarText"
+                            style={{ backgroundColor: "rgb(119, 37, 37)" }}
+                            key={index}
+                            onClick={() => this.handlePathClick(doc, index)}>{doc.title}
+                        </div>
+                    </div>);
             } else {
-                pathname = pathname + " > " + doc.title;
+                return (
+                    <div className="pathbarItem">
+                        <FontAwesomeIcon className="pathIcon" icon="angle-right" size="lg" />
+                        <div className="pathbarText"
+                            key={index}
+                            onClick={() => this.handlePathClick(doc, index)}>{doc.title}
+                        </div>
+                    </div>);
             }
+
         });
-        if (this._activeDoc === this.mainDoc) {
-            pathname = pathname + this._activeDoc.title;
+        if (this._parents.length !== 0) {
+            return (<div className="pathbar">
+                <div className="scrollmenu">
+                    {items}
+                </div>
+                <div className="back" >
+                    <FontAwesomeIcon onClick={this.back} icon={"chevron-left"} color="white" size={"2x"} />
+                </div>
+                <div className="hidePath" />
+            </div>);
         } else {
-            pathname = pathname + " > " + this._activeDoc.title;
+            return (<div className="pathbar">
+                <div className="scrollmenu">
+                    {items}
+                </div>
+                <div className="hidePath" />
+            </div>);
         }
-        return pathname;
-    }
+        //     }
+        // } else {
 
-    @action
-    toggleSidebar = () => this.sidebarActive = !this.sidebarActive
+        //     return (
+        //         <div className="pathbar">
+        //             <div className="scrollmenu">
+        //                 <div className="pathbarItem">
+        //                     <div className="pathbarText"
+        //                         style={{ backgroundColor: "rgb(119, 37, 37)" }}
+        //                         key={0}
+        //                         onClick={() => this.returnHome()}>Home
+        //                     </div>
+        //                 </div>
+        //             </div>
+        //             <div className="hidePath" />
+        //         </div>
+        //     );
+        // }
 
-    openLibrary() {
-        this._activeDoc = this.mainDoc;
-        this.switchCurrentView(() => this.mainDoc);
-        this._child = this._library;
+        // }
+    }
+
+    handlePathClick = (doc: Doc, index: number) => {
+        if (doc === this._library) {
+            this._activeDoc = doc;
+            this._child = null;
+            this.switchCurrentView((userDoc: Doc) => doc);
+            this._parents.length = index;
+        } else if (doc === this._homeDoc) {
+            this.returnHome();
+        } else {
+            console.log(index);
+            this._activeDoc = doc;
+            this._child = doc;
+            this.switchCurrentView((userDoc: Doc) => doc);
+            this._parents.length = index;
+        }
     }
 
     renderDefaultContent = () => {
-        const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
-        const buttons = DocListCast(this._child ? this._child.data : workspaces.data).map((doc: Doc, index: any) => {
-            return (
-                <div
-                    className="item"
-                    key={index}
-                    onClick={() => this.handleClick(doc)}>{doc.title}
-                    <div className="type">{doc.type}</div>
-                    <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
-                </div>);
-        });
-        return (
-            <>
-                <div className="navbar">
-                    <div className={"header"}>{this.sidebarActive ? StrCast(this._activeDoc.title) : "Menu"}</div>
+        let menuButtons = DocListCast(this._homeDoc.data).map((doc: Doc, index: any) => {
+            if (doc.type !== "ink") {
+                return (
                     <div
-                        className={`toggle-btn ${this.sidebarActive ? "active" : ""}`}
-                        onClick={this.toggleSidebar}
-                    />
-                </div>
-                <div className="pathbar">
-                    <div className="pathname">{this.createPathname()}</div>
+                        className="item"
+                        key={index}
+                        onClick={() => doc.click}>{doc.title}
+                    </div>);
+            }
+        });
+
+        if (this._homeMenu === true) {
+            return (
+                <div>
+                    <div className="navbar">
+                        <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
+                        <div className="header" id="header">{this._homeDoc.title}</div>
+                        <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
+                            <span></span>
+                            <span></span>
+                            <span></span>
+                        </div>
+                    </div>
+                    {this.renderPathbar()}
+                    <div className="sidebar" id="sidebar">
+                        <div className="sidebarButtons">
+                            {menuButtons}
+                        </div>
+                    </div>
                 </div>
-                <div className={`sidebar ${this.sidebarActive ? "active" : ""}`}>
-                    <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
-                    {this._child ?
-                        <>
-                            <div className="back" onClick={this.back}>&#8592;</div>
-                            <div>{buttons}</div>
-                            <div className="item" key="home" onClick={this.returnHome}>Home</div>
-                        </> :
-                        <>
+            );
+        }
+        const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+        let buttons = DocListCast(workspaces.data).map((doc: Doc, index: any) => {
+            if (doc.type !== "ink") {
+                return (
+                    <div
+                        className="item"
+                        key={index}
+                        onClick={() => this.handleClick(doc)}>{doc.title}
+                        <div className="type">{doc.type}</div>
+                        <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
+                    </div>);
+            }
+        });
+
+        if (this._child) {
+            buttons = DocListCast(this._child.data).map((doc: Doc, index: any) => {
+                if (doc.type !== "ink") {
+                    return (
+                        <div
+                            className="item"
+                            key={index}
+                            onClick={() => this.handleClick(doc)}>{doc.title}
+                            <div className="type">{doc.type}</div>
+                            <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
+                        </div>);
+                }
+            });
+        }
+
+        if (!this._child) {
+            return (
+                <div>
+                    <div className="navbar">
+                        <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
+                        <div className="header" id="header">{this._homeDoc.title}</div>
+                        <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
+                            <span></span>
+                            <span></span>
+                            <span></span>
+                        </div>
+                    </div>
+                    {this.renderPathbar()}
+                    <div className="sidebar" id="sidebar">
+                        <div className="sidebarButtons">
                             {buttons}
                             {/* <div className="item" key="library" onClick={this.openLibrary}>
                                 Library
-                                </div> */}
-                            <Uploader Document={workspaces} />
-                            <div className="item" key="audio" onClick={this.recordAudio}>Record Audio</div>
-                            <div className="item" key="presentation" onClick={this.openDefaultPresentation}>Presentation</div>
-                            <div className="item" key="settings" onClick={() => SettingsManager.Instance.open()}>Settings</div>
-                        </>
-                    }
+                            </div> */}
+                            {/* <Uploader Document={workspaces} />
+                            <div className="item" key="audio" onClick={this.recordAudio}>
+                                Record Audio
+                            </div>
+                            <div className="item" key="presentation" onClick={this.openDefaultPresentation}>
+                                Presentation
+                            </div> */}
+                            {/* <div className="item" key="settings" onClick={() => SettingsManager.Instance.open()}>
+                                Settings
+                            </div> */}
+                            <div className="item" key="ink" id="ink" onClick={() => this.onSwitchInking()}>
+                                Ink On
+                            </div>
+                        </div>
+                    </div>
+                    {/* <div>
+                        {this.renderView}
+                    </div> */}
                 </div>
-                {this._child ? null : <div>{this.renderView}</div>}
-            </>
-        );
+            );
+        }
+        else {
+            return (
+                <div>
+                    <div className="navbar">
+                        <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
+                        <div className="header" id="header">library</div>
+                        <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
+                            <span></span>
+                            <span></span>
+                            <span></span>
+                        </div>
+                    </div>
+                    {this.renderPathbar()}
+                    <div className="sidebar" id="sidebar">
+                        <div className="sidebarButtons">
+                            {buttons}
+                            <div className="item" key="ink" id="ink" onClick={() => this.onSwitchInking()}>
+                                Ink On
+                            </div>
+                            <div className="item" key="home" onClick={this.returnMain}>
+                                Home
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            );
+        }
     }
 
-    pinToPresentation = () => {
-        // Only making button available if it is an image
+    uploadAudioButton = () => {
+        if (this._activeDoc.type === "audio") {
+            return <div className="docButton"
+                title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
+                style={{ backgroundColor: "black", color: "white" }}
+                onClick={this.uploadAudio}
+            >
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
+                />
+            </div>;
+        }
+    }
+
+    toggleSelector = () => {
+        console.log("toggle selector!");
+        let toolbar = document.getElementById("toolbar") as HTMLElement;
+        toolbar.classList.toggle('active');
+    }
+
+    colorTool = () => {
+        if (this._activeDoc._viewType === "docking") {
+            const color = InkingControl.Instance.selectedColor;
+            console.log(color);
+            return (
+                <div
+                    className="docButton"
+                    style={{ backgroundColor: color }}
+                    onClick={this.toggleSelector}
+                >
+                    <div className="toolbar" id="toolbar">
+                        <div className="colorSelector">
+                            <div className="colorButton"
+                                style={{ backgroundColor: "red" }}
+                                onClick={() => {
+                                    InkingControl.Instance.updateSelectedColor("rgb(255,0,0)");
+                                    Doc.UserDoc().inkColor = "rgb(255,0,0)";
+                                    console.log(InkingControl.Instance.selectedColor);
+                                }}>
+                            </div>
+                            <div className="colorButton"
+                                style={{ backgroundColor: "green" }}
+                                onClick={e => {
+                                    InkingControl.Instance.updateSelectedColor("rgb(0,128,0)");
+                                    Doc.UserDoc().inkColor = "rgb(0,128,0)";
+                                    console.log(InkingControl.Instance.selectedColor);
+                                }}>
+                            </div>
+                            <div className="colorButton"
+                                style={{ backgroundColor: "blue" }}
+                                onClick={e => {
+                                    InkingControl.Instance.updateSelectedColor("rgb(0,0,255)");
+                                    Doc.UserDoc().inkColor = "rgb(0,0,255)";
+                                    console.log(InkingControl.Instance.selectedColor);
+                                }}>
+                            </div>
+                        </div>
+                        <div className="widthSelector">
+                            <input type="range" min="1" max="100" defaultValue="2" id="myRange" onChange={(e: React.ChangeEvent<HTMLInputElement>) => InkingControl.Instance.switchWidth(e.target.value)} />
+                        </div>
+                    </div>
+                </div>
+            );
+        }
+    }
+
+    onSwitchInking = () => {
+        const button = document.getElementById("inkButton") as HTMLElement;
+        const color = InkingControl.Instance.selectedColor;
+        button.style.backgroundColor = this._ink ? "white" : color;
+        button.style.color = this._ink ? "black" : "white";
+
+        if (!this._ink) {
+            console.log("INK IS ACTIVE");
+            InkingControl.Instance.switchTool(InkTool.Pen);
+            MobileInterface.Instance.drawingInk = true;
+            this._ink = true;
+        } else {
+            console.log("INK IS INACTIVE");
+            InkingControl.Instance.switchTool(InkTool.None);
+            MobileInterface.Instance.drawingInk = false;
+            this._ink = false;
+        }
+    }
+
+    drawInk = () => {
+        if (this._activeDoc._viewType === "docking") {
+            const inkIsOn = this._ink;
+            return <div className="docButton"
+                id="inkButton"
+                title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
+                onClick={this.onSwitchInking}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="pen-nib"
+                />
+            </div>;
+        }
+    }
+
+    downloadDocument = () => {
         if (this._activeDoc.type === "image") {
-            const isPinned = this._activeDoc && Doc.isDocPinned(this._activeDoc);
-            return <div className="pinButton"
-                title={Doc.isDocPinned(this._activeDoc) ? "Unpin from presentation" : "Pin to presentation"}
-                style={{ backgroundColor: isPinned ? "black" : "white", color: isPinned ? "white" : "black" }}
+            const url = this._activeDoc["data-path"]?.toString();
+            return <div className="docButton"
+                title={"Download Image"}
+                style={{ backgroundColor: "white", color: "black" }}
                 onClick={e => {
-                    if (isPinned) {
-                        DockedFrameRenderer.UnpinDoc(this._activeDoc);
-                    }
-                    else {
-                        DockedFrameRenderer.PinDoc(this._activeDoc);
-                    }
+                    window.open(url);
+                    console.log(url);
                 }}>
-                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="download"
                 />
             </div>;
         }
     }
 
     recordAudio = async () => {
-        // upload to server with known URL 
-        this._parents.push(this._activeDoc);
+        // upload to server with known URL
+        if (this._activeDoc.title !== "mobile audio") {
+            this._parents.push(this._activeDoc);
+        }
         const audioDoc = Cast(Docs.Create.AudioDocument(nullAudio, { _width: 200, _height: 100, title: "mobile audio" }), Doc) as Doc;
+        console.log(audioDoc);
         if (audioDoc) {
             console.log("audioClicked: " + audioDoc.title);
             this._activeDoc = audioDoc;
             this.switchCurrentView((userDoc: Doc) => audioDoc);
-            this.toggleSidebar();
-        }
-        const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
-        if (audioRightSidebar) {
-            console.log(audioRightSidebar.title);
-            const data = Cast(audioRightSidebar.data, listSpec(Doc));
-            if (data) {
-                data.push(audioDoc);
-            }
+            this._homeMenu = false;
+            // this.toggleSidebar();
         }
+        // const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
+        // this.audioState = await audioDoc.getProto;
+        // if (this.audioState) {
+        //     console.log(this.audioState);
+        //     const data = Cast(audioRightSidebar.data, listSpec(Doc));
+        //     if (data) {
+        //         data.push(audioDoc);
+        //     }
+        // }
     }
 
-    openDefaultPresentation = () => {
-        this._parents.push(this._activeDoc);
-        const presentation = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
-
-        if (presentation) {
-            console.log("presentation clicked: " + presentation.title);
-            this._activeDoc = presentation;
-            this.switchCurrentView((userDoc: Doc) => presentation);
-            this.toggleSidebar();
+    uploadAudio = () => {
+        const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
+        const audioDoc = this._activeDoc;
+        const data = Cast(audioRightSidebar.data, listSpec(Doc));
+        console.log(audioDoc.proto);
+        if (data) {
+            data.push(audioDoc);
         }
+        // this.recordAudio();
     }
 
-    // mobileHome = () => {
-    //     return (
-    //         <div className="homeContainer">
-    //             <div className="uploadButton">
-
-    //             </div>
-    //             <div className="presentationButton">
-
-    //             </div>
-    //             <div className="recordAudioButton">
-
-    //             </div>
-    //             <div className="inkButton">
-
-    //             </div>
-    //             <div className="settingsButton">
-
-    //             </div>
-    //         </div>
-    //     );
+    // renderActiveCollection = (userDoc: Doc) => {
+    //     if (this.activeContainer) {
+    //         const active = Cast(this.activeContainer.data, listSpec(Doc));
+    //         if (active) {
+    //             return (
+    //                 <div className="mobileInterface-background">HELLO!</div>
+    //             );
+    //         }
+    //     }
     // }
 
-    renderActiveCollection = (userDoc: Doc) => {
-        if (this.activeContainer) {
-            const active = Cast(this.activeContainer.data, listSpec(Doc));
-            if (active) {
-                return (
-                    <div className="mobileInterface-background">HELLO!</div>
-                );
-            }
-        }
-    }
-
     onBack = (e: React.MouseEvent) => {
         this.switchCurrentView((userDoc: Doc) => this.mainDoc);
         InkingControl.Instance.switchTool(InkTool.None); // TODO: switch to previous tool
@@ -445,6 +1833,44 @@ export class MobileInterface extends React.Component {
         }
     }
 
+    pinToPresentation = () => {
+        // Only making button available if it is an image
+        if (this._activeDoc.type === "image") {
+            const isPinned = this._activeDoc && Doc.isDocPinned(this._activeDoc);
+            return <div className="docButton"
+                title={Doc.isDocPinned(this._activeDoc) ? "Unpin from presentation" : "Pin to presentation"}
+                style={{ backgroundColor: isPinned ? "black" : "white", color: isPinned ? "white" : "black" }}
+                onClick={e => {
+                    if (isPinned) {
+                        DockedFrameRenderer.UnpinDoc(this._activeDoc);
+                    }
+                    else {
+                        DockedFrameRenderer.PinDoc(this._activeDoc);
+                    }
+                }}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
+                />
+            </div>;
+        }
+    }
+
+    setupDefaultPresentation = () => {
+        if (this._activeDoc.title !== "Presentation") {
+            this._parents.push(this._activeDoc);
+        }
+
+        const presentation = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
+
+        if (presentation) {
+            console.log(this._activeDoc.mobile);
+            console.log("presentation clicked: " + presentation.title);
+            this._activeDoc = presentation;
+            this.switchCurrentView((userDoc: Doc) => presentation);
+            this._homeMenu = false;
+            // this.toggleSidebar();
+        }
+    }
+
     onDragOver = (e: React.DragEvent) => {
         e.preventDefault();
         e.stopPropagation();
@@ -453,7 +1879,7 @@ export class MobileInterface extends React.Component {
     render() {
         // const content = this.currentView === "main" ? this.mainContent :
         //     this.currentView === "ink" ? this.inkContent :
-        //         this.currentView === "upload" ? this.uploadContent : <></>;
+        //         this.currentView === "upload" ? this.uploadContent : <></>;onDragOver={this.onDragOver}
         return (
             <div className="mobileInterface-container" onDragOver={this.onDragOver}>
                 {/* <DocumentDecorations />
@@ -462,16 +1888,28 @@ export class MobileInterface extends React.Component {
                 </GestureOverlay> */}
                 {/* <GestureOverlay> */}
                 <SettingsManager />
-                {this.displayWorkspaces()}
-                {this.pinToPresentation()}
+                {/* {this.menuOptions()} */}
+                {/* {this.displayHome()} */}
+                <div className="docButtonContainer">
+                    {this.pinToPresentation()}
+                    {this.downloadDocument()}
+                    {this.drawInk()}
+                    {this.uploadAudioButton()}
+                    {this.colorTool()}
+                </div>
+                <GestureOverlay>
+                    {this.displayWorkspaces()}
+                    {this.renderDefaultContent()}
+                </GestureOverlay>
+
                 {/* </GestureOverlay> */}
                 {/* <DictationOverlay />
                 <SharingManager />
                 <GoogleAuthenticationManager /> */}
                 {/* <DocumentDecorations /> */}
-                <div>
+                {/* <div>
                     {this.renderDefaultContent()}
-                </div>
+                </div> */}
                 {/* <PreviewCursor /> */}
                 {/* <ContextMenu /> */}
                 {/* <RadialMenu />
@@ -485,6 +1923,13 @@ export class MobileInterface extends React.Component {
 }
 
 Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); });
+Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); });
+Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); });
+Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.recordAudio(); });
+Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); });
+Scripting.addGlobal(function switchToLibrary() { return MobileInterface.Instance.switchToLibrary(); });
+
+
 // WAS 2
 
 // 1
@@ -527,15 +1972,7 @@ Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, render
 //     }
 // }
 
-// 2
-// Scripting.addGlobal(function onSwitchMobileInking() { return MobileInterface.Instance.onSwitchInking(); });
-// Scripting.addGlobal(function renderMobileInking() { return MobileInterface.Instance.renderInkingContent(); });
-// Scripting.addGlobal(function onSwitchMobileUpload() { return MobileInterface.Instance.onSwitchUpload(); });
-// Scripting.addGlobal(function renderMobileUpload() { return MobileInterface.Instance.renderUploadContent(); });
-    // Scripting.addGlobal(function addWebToMobileUpload() { return MobileInterface.Instance.addWebToCollection(); });
-
-
-// 3   
+// 3
     // renderInkingContent = () => {
         //     console.log("rendering inking content");
         //     // TODO: support panning and zooming
@@ -583,4 +2020,4 @@ Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, render
         //             </div>
         //         );
         //     }
-        // }
+        // }
\ No newline at end of file
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 250340e36..f600ff637 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -83,15 +83,17 @@ body {
 
 .sidebar {
     position: absolute;
-    top: 200px;
+    top: 120px;
     opacity: 0;
     right: -100%;
     width: 100%;
-    height: calc(100% - (200px));
-    z-index: 5;
+    height: calc(100% - (120px));
+    z-index: 101;
     background-color: whitesmoke;
     transition: all 400ms ease 50ms;
     padding: 20px;
+    // overflow-y: auto;
+    // -webkit-overflow-scrolling: touch;
     // border-right: 5px solid black;
 }
 
@@ -106,14 +108,23 @@ body {
     font-size: 35px;
     text-transform: uppercase;
     color: black;
+    
 }
 
-.sidebar .home {
+.sidebar .ink:focus {
+    outline: 1px solid blue;
+}
+
+.sidebarButtons {
+    top: 80px;
+    position: relative;
+}
+
+.home {
     position: absolute;
-    top: -135px;
-    right: calc(50% + 80px);
-    transform: translate(0%, -50%);
-    font-size: 40;
+    top: 30px;
+    left: 30px;
+    font-size: 60;
     user-select: none;
     text-transform: uppercase;
     font-family: Arial, Helvetica, sans-serif;
@@ -173,23 +184,26 @@ body {
 
 .back {
     position: absolute;
-    top: -140px;
-    left: 50px;
-    transform: translate(0%, -50%);
-    color: black;
-    font-size: 60;
+    top: 44%;
+    left: 42px;
+    background-color: black;
+    width: 50px;
+    height: 50px;
+    text-align: center;
+    border-radius: 10px;
+    transform: translate(0, -50%);
+    font-size: 25px;
     user-select: none;
-    text-transform: uppercase;
     z-index: 100;
-    font-family: Arial, Helvetica, sans-serif;
 }
 
 
 .pathbar {
     position: absolute;
     top: 118px;
+    left: 0px;
     background: #1a1a1a;
-    z-index: 20;
+    z-index: 120;
     border-radius: 0px;
     width: 100%;
     height: 80px;
@@ -200,8 +214,8 @@ body {
     position: relative;
     font-size: 25;
     top: 50%;
-    width: 90%;
-    left: 3%;
+    width: 86%;
+    left: 12%;
     color: whitesmoke;
     transform: translate(0%, -50%);
     z-index: 20;
@@ -214,27 +228,71 @@ body {
     text-transform: uppercase;
 }
 
-.homeContainer {
-    position: relative;
-    top: 200px;
-    height: calc(100% - 250px);
-    width: 90%;
-    overflow: scroll;
-    left: 5%;
-    background-color: lightpink;
-}
-
-.pinButton {
+.docButton {
     position: relative;
     width: 100px;
     height: 100px;
     font-size: 90px;
     text-align: center;
-    left: 50%;
-    transform: translate(-50%, 0);
     border-style: solid;
     border-radius: 50px;
     border-width: medium;
-    background-color: pink;
+    margin: 10px;
     z-index: 100;
+}
+
+.docButtonContainer {
+    top: 90%;
+    position: absolute;
+    display: flex;
+    transform: translate(-50%, 0);
+    left: 50%;
+    z-index: 100;
+}
+
+.scrollmenu {
+    overflow: auto;
+    white-space: nowrap;
+}
+
+.pathbarItem {
+    position: relative;
+    display: inline-flex;
+    color: whitesmoke;
+    text-align: center;
+    transform: translate(100px, 0px);
+    font-size: 30px;
+    padding: 10px;
+    text-transform: uppercase;
+}
+
+.pathbarText {
+    font-family: sans-serif;
+    text-align: center;
+    height: 50px;
+    padding: 10px;
+    background-color: rgb(48, 40, 40);
+    font-size: 30px;
+    border-radius: 10px;
+    text-transform: uppercase;
+    margin-left: 20px;
+    position: relative;
+}
+
+
+.pathIcon {
+    transform: translate(0px, 8px);
+    position: relative;
+}
+
+.hidePath {
+    position: absolute;
+    height: 100%;
+    width: 200px;
+    left: 0px;
+    top: 0px;
+    background-image: linear-gradient(to right, #1a1a1a, rgba(255, 0, 0, 0));
+    text-align: center;
+    user-select: none;
+    z-index: 99;
 }
\ No newline at end of file
diff --git a/src/mobile/SideBar.scss b/src/mobile/SideBar.scss
deleted file mode 100644
index fb6d13a2b..000000000
--- a/src/mobile/SideBar.scss
+++ /dev/null
@@ -1,79 +0,0 @@
-* {
-    margin:0px;
-    padding:0px;
-    box-sizing:border-box;
-    font-family:"Open Sans";
-}
-body {
-    overflow:hidden;
-}
-.navbar {
-    position:fixed;
-    top:0px;
-    left:0px;
-    width:100vw;
-    height:50px;
-    background:rgba(0,0,0,0.95);
-}
-.navbar .toggle-btn {
-    position:absolute;
-    right:20px;
-    height:50px;
-    width:50px;
-    transition:all 300ms ease-in-out 200ms;
-}
-.navbar .toggle-btn span {
-    position:absolute;
-    top:50%;
-    left:50%;
-    transform:translate(-50%,-50%);
-    width:70%;
-    height:4px;
-    background:#eee;
-    transition:all 200ms ease;
-}
-.navbar .toggle-btn span:nth-child(1) {
-    transition:top 200ms ease-in-out;
-    top:30%;
-}
-.navbar .toggle-btn span:nth-child(3) {
-    transition:top 200ms ease-in-out;
-    top:70%;
-}
-.navbar .toggle-btn.active {
-    transition:transform 200ms ease-in-out 200ms;
-    transform:rotate(135deg);
-}
-.navbar .toggle-btn.active span:nth-child(1) {
-    top:50%;
-}
-.navbar .toggle-btn.active span:nth-child(2) {
-    transform:translate(-50%,-50%) rotate(90deg);
-}
-.navbar .toggle-btn.active span:nth-child(3) {
-    top:50%;
-}
-.sidebar {
-    position:absolute;
-    top:50px;
-    opacity:0;
-    right:-100%;
-    width:100vw;
-    height:calc(100vh - 45px);
-    z-index:5;
-    background:rgba(40,40,40,1);
-    transition:all 400ms ease 50ms;
-    padding:15px;
-}
-.sidebar .item {
-    width:100%;
-    padding:13px 6px;
-    border-bottom:1px solid rgba(200,200,200,0.7);
-    font-size:18px;
-    text-transform:uppercase;
-    color:rgba(250,250,250,0.95);
-}
-.sidebar.active {
-    right:0%;
-    opacity:1;
-}
\ No newline at end of file
diff --git a/src/mobile/SideBar.tsx b/src/mobile/SideBar.tsx
deleted file mode 100644
index a06069ed8..000000000
--- a/src/mobile/SideBar.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import React = require("react");
-import { observer } from "mobx-react";
-import "./SideBar.scss";
-import { computed } from "mobx";
-import { DocumentView } from '../client/views/nodes/DocumentView';
-
-@observer
-export class SideBar extends React.Component<{ views: (DocumentView | undefined)[], stack?: any }, {}>{
-
-    constructor(props: { views: (DocumentView | undefined)[] }) {
-        super(props);
-    }
-
-    @computed
-    onClick() {
-        document.getElementsByClassName('sidebar')
-        [0].classList.toggle('active');
-    }
-
-    render() {
-        return (
-            <>
-                <div className="navbar">
-                    <div className="toggle-btn" onClick={this.onClick}>
-                        <span></span>
-                        <span></span>
-                        <span></span>
-                    </div>
-                </div>
-                <div className="sidebar">
-                    <div className="item">Workspace1</div>
-                    <div className="item">Workspace2</div>
-                    <div className="item">Workspace3</div>
-                </div>
-            </>
-        );
-    }
-
-}
\ No newline at end of file
diff --git a/src/mobile/WorkSpaceButton.scss b/src/mobile/WorkSpaceButton.scss
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/mobile/WorkSpaceButton.tsx b/src/mobile/WorkSpaceButton.tsx
deleted file mode 100644
index 70c3e6edc..000000000
--- a/src/mobile/WorkSpaceButton.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import React = require('react');
-import { observer } from "mobx-react";
-import { observable } from 'mobx';
-
-interface IProps {
-    open: boolean;
-}
-
-@observer
-export class MenuButton extends React.Component<IProps> {
-    @observable static Instance: MenuButton;
-
-
-}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 673be18526a5591b9021993fe4e9421e6373017c Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Mon, 8 Jun 2020 14:06:02 +0800
Subject: updated window height

---
 src/mobile/MobileInterface.tsx | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 6b75ce07d..f3fa7de30 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1250,7 +1250,6 @@ export class MobileInterface extends React.Component {
                             pinToPres={emptyFunction}
                             rootSelected={returnFalse}
                             removeDocument={undefined}
-                            onClick={undefined}
                             ScreenToLocalTransform={Transform.Identity}
                             ContentScaling={returnOne}
                             NativeHeight={returnZero}
@@ -1295,7 +1294,6 @@ export class MobileInterface extends React.Component {
                             bringToFront={emptyFunction}
                             ContainingCollectionView={undefined}
                             ContainingCollectionDoc={undefined}
-                        // mobile={true}
                         />
                     </div>
                 );
@@ -1303,12 +1301,10 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    returnWidth = () => 2000;
-    returnHeight = () => 2000;
+    returnWidth = () => window.innerWidth;
+    returnHeight = () => (window.innerHeight - 300);
 
     handleClick(doc: Doc) {
-        console.log(screen.height)
-        console.log(screen.width)
         let children = DocListCast(doc.data);
         if (doc.type !== "collection") {
             this._parents.push(this._activeDoc);
-- 
cgit v1.2.3-70-g09d2


From 4bcefa13f3e2d48cd6a7ca77af32ae4f3917fbfb Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Sun, 7 Jun 2020 23:45:45 -0700
Subject: added color picker (bit buggy)

---
 src/mobile/MobileInterface.tsx | 177 ++++-------------------------------------
 src/mobile/MobileMenu.scss     |  61 +++++++++++++-
 2 files changed, 74 insertions(+), 164 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 6b75ce07d..8a0432d06 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -34,6 +34,9 @@ import { InkTool } from '../fields/InkField';
 import { listSpec } from '../fields/Schema';
 import { nullAudio, WebField } from '../fields/URLField';
 import GestureOverlay from "../client/views/GestureOverlay";
+import { SelectionManager } from "../client/util/SelectionManager";
+import { SketchPicker } from "react-color";
+import { ScriptField } from "../fields/ScriptField";
 
 library.add(faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
@@ -498,137 +501,6 @@ library.add(faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTras
 //     //     );
 //     // }
 
-//     renderDefaultContent = () => {
-//         let menuButtons = DocListCast(this._homeDoc.data).map((doc: Doc, index: any) => {
-//             if (doc.type !== "ink") {
-//                 return (
-//                     <div
-//                         className="item"
-//                         key={index}
-//                         onClick={() => doc.click}>{doc.title}
-//                     </div>);
-//             }
-//         });
-
-//         if (this._homeMenu === true) {
-//             return (
-//                 <div>
-//                     <div className="navbar">
-//                         <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
-//                         <div className="header" id="header">{this._homeDoc.title}</div>
-//                         <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
-//                             <span></span>
-//                             <span></span>
-//                             <span></span>
-//                         </div>
-//                     </div>
-//                     {this.renderPathbar()}
-//                     <div className="sidebar" id="sidebar">
-//                         <div className="sidebarButtons">
-//                             {menuButtons}
-//                         </div>
-//                     </div>
-//                 </div>
-//             );
-//         }
-//         const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
-//         let buttons = DocListCast(workspaces.data).map((doc: Doc, index: any) => {
-//             if (doc.type !== "ink") {
-//                 return (
-//                     <div
-//                         className="item"
-//                         key={index}
-//                         onClick={() => this.handleClick(doc)}>{doc.title}
-//                         <div className="type">{doc.type}</div>
-//                         <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
-//                     </div>);
-//             }
-//         });
-
-//         if (this._child) {
-//             buttons = DocListCast(this._child.data).map((doc: Doc, index: any) => {
-//                 if (doc.type !== "ink") {
-//                     return (
-//                         <div
-//                             className="item"
-//                             key={index}
-//                             onClick={() => this.handleClick(doc)}>{doc.title}
-//                             <div className="type">{doc.type}</div>
-//                             <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
-//                         </div>);
-//                 }
-//             });
-//         }
-
-//         if (!this._child) {
-//             return (
-//                 <div>
-//                     <div className="navbar">
-//                         <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
-//                         <div className="header" id="header">{this._homeDoc.title}</div>
-//                         <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
-//                             <span></span>
-//                             <span></span>
-//                             <span></span>
-//                         </div>
-//                     </div>
-//                     {this.renderPathbar()}
-//                     <div className="sidebar" id="sidebar">
-//                         <div className="sidebarButtons">
-//                             {buttons}
-//                             {/* <div className="item" key="library" onClick={this.openLibrary}>
-//                                 Library
-//                             </div> */}
-//                             {/* <Uploader Document={workspaces} />
-//                             <div className="item" key="audio" onClick={this.recordAudio}>
-//                                 Record Audio
-//                             </div>
-//                             <div className="item" key="presentation" onClick={this.openDefaultPresentation}>
-//                                 Presentation
-//                             </div> */}
-//                             {/* <div className="item" key="settings" onClick={() => SettingsManager.Instance.open()}>
-//                                 Settings
-//                             </div> */}
-//                             <div className="item" key="ink" id="ink" onClick={() => this.onSwitchInking()}>
-//                                 Ink On
-//                             </div>
-//                         </div>
-//                     </div>
-//                     {/* <div>
-//                         {this.renderView}
-//                     </div> */}
-//                 </div>
-//             );
-//         }
-//         else {
-//             return (
-//                 <div>
-//                     <div className="navbar">
-//                         <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
-//                         <div className="header" id="header">library</div>
-//                         <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
-//                             <span></span>
-//                             <span></span>
-//                             <span></span>
-//                         </div>
-//                     </div>
-//                     {this.renderPathbar()}
-//                     <div className="sidebar" id="sidebar">
-//                         <div className="sidebarButtons">
-//                             {buttons}
-//                             <div className="item" key="ink" id="ink" onClick={() => this.onSwitchInking()}>
-//                                 Ink On
-//                             </div>
-//                             <div className="item" key="home" onClick={this.returnMain}>
-//                                 Home
-//                             </div>
-//                         </div>
-//                     </div>
-//                 </div>
-//             );
-//         }
-//     }
-
 //     recordAudio = async () => {
 //         // upload to server with known URL
 //         if (this._activeDoc.title !== "mobile audio") {
@@ -1079,6 +951,7 @@ export class MobileInterface extends React.Component {
     @observable private mainDoc: any = CurrentUserUtils.setupMobileMenu();
     @observable private renderView?: () => JSX.Element;
     @observable private audioState: any;
+    @observable private activeToolbar: boolean = false;
 
     public _activeDoc: Doc = this.mainDoc;
     public _homeDoc: Doc = this.mainDoc;
@@ -1466,7 +1339,7 @@ export class MobileInterface extends React.Component {
                     <div
                         className="item"
                         key={index}
-                        onClick={() => doc.click}>{doc.title}
+                        onClick={() => doc.proto?.onClick}>{doc.title}
                     </div>);
             }
         });
@@ -1603,48 +1476,26 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    toggleSelector = () => {
-        console.log("toggle selector!");
-        let toolbar = document.getElementById("toolbar") as HTMLElement;
-        toolbar.classList.toggle('active');
-    }
+
+    @action
+    toggleSelector = () => this.activeToolbar = !this.activeToolbar
+
 
     colorTool = () => {
         if (this._activeDoc._viewType === "docking") {
             const color = InkingControl.Instance.selectedColor;
-            console.log(color);
+            const selDoc = SelectionManager.SelectedDocuments()?.[0]?.rootDoc;
             return (
                 <div
                     className="docButton"
                     style={{ backgroundColor: color }}
                     onClick={this.toggleSelector}
                 >
-                    <div className="toolbar" id="toolbar">
+                    <div className={`toolbar ${this.activeToolbar ? "active" : ""}`}>
                         <div className="colorSelector">
-                            <div className="colorButton"
-                                style={{ backgroundColor: "red" }}
-                                onClick={() => {
-                                    InkingControl.Instance.updateSelectedColor("rgb(255,0,0)");
-                                    Doc.UserDoc().inkColor = "rgb(255,0,0)";
-                                    console.log(InkingControl.Instance.selectedColor);
-                                }}>
-                            </div>
-                            <div className="colorButton"
-                                style={{ backgroundColor: "green" }}
-                                onClick={e => {
-                                    InkingControl.Instance.updateSelectedColor("rgb(0,128,0)");
-                                    Doc.UserDoc().inkColor = "rgb(0,128,0)";
-                                    console.log(InkingControl.Instance.selectedColor);
-                                }}>
-                            </div>
-                            <div className="colorButton"
-                                style={{ backgroundColor: "blue" }}
-                                onClick={e => {
-                                    InkingControl.Instance.updateSelectedColor("rgb(0,0,255)");
-                                    Doc.UserDoc().inkColor = "rgb(0,0,255)";
-                                    console.log(InkingControl.Instance.selectedColor);
-                                }}>
-                            </div>
+                            <SketchPicker onChange={InkingControl.Instance.switchColor} presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
+                                color={StrCast(CurrentUserUtils.ActivePen ? CurrentUserUtils.ActivePen.backgroundColor : undefined,
+                                    StrCast(selDoc?._backgroundColor, StrCast(selDoc?.backgroundColor, "black")))} />
                         </div>
                         <div className="widthSelector">
                             <input type="range" min="1" max="100" defaultValue="2" id="myRange" onChange={(e: React.ChangeEvent<HTMLInputElement>) => InkingControl.Instance.switchWidth(e.target.value)} />
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index f600ff637..2641cdfd2 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -237,7 +237,7 @@ body {
     border-style: solid;
     border-radius: 50px;
     border-width: medium;
-    margin: 10px;
+    margin: 20px;
     z-index: 100;
 }
 
@@ -295,4 +295,63 @@ body {
     text-align: center;
     user-select: none;
     z-index: 99;
+}
+
+.toolbar {
+    left: 50%;
+    transform: translate(-50%);
+    position: absolute;
+    height: max-content;
+    top: 0px;
+    border-radius: 20px;
+    background-color: lightgrey;
+    opacity: 0;
+    transition: all 400ms ease 50ms;
+}
+
+.toolbar.active {
+    display: inline-block;
+    width: fit-content;
+    padding: 5px;
+    opacity: 1;
+    height: max-content;
+    top: -450px;
+}
+
+.toolbar .colorSelector {
+    display: inline-flex;
+    width: fit-content;
+    padding: 5px;
+    height: max-content;
+    pointer-events: all;
+}
+
+.widthSelector {
+    display: inline-flex;
+    width: 90%;
+    height: 100px;
+    padding: 5px;
+}
+
+.slider {
+    -webkit-appearance: none;
+    /* Override default CSS styles */
+    appearance: none;
+    width: 100%;
+    /* Full-width */
+    height: 25px;
+    /* Specified height */
+    background: #d3d3d3;
+    /* Grey background */
+    outline: none;
+    /* Remove outline */
+}
+
+.colorButton {
+    width: 70px;
+    margin: 10px;
+    height: 70px;
+    border-style: solid;
+    border-width: 3px;
+    border-radius: 100%;
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 520200a2a63a4189d5c6cac2b2ff48f009bb6f72 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Tue, 9 Jun 2020 00:21:50 -0700
Subject: cleaned code

---
 src/client/util/CurrentUserUtils.ts |   4 +-
 src/mobile/ImageUpload.tsx          |   1 +
 src/mobile/MobileInterface.tsx      | 190 ++++++++++++------------------------
 src/mobile/MobileMenu.scss          |  22 ++++-
 4 files changed, 82 insertions(+), 135 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 8ed275efc..f2278bf3d 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -409,7 +409,7 @@ export class CurrentUserUtils {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
             { title: "library", icon: "bars", click: 'switchToLibrary()', backgroundColor: "lightgrey" },
             { title: "record", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "lightgrey" },
-            { title: "upload", icon: "upload", click: 'uploadMobileImage()', backgroundColor: "lightgrey" },
+            { title: "upload", icon: "upload", click: 'console.log("hi")', backgroundColor: "lightgrey" },
             { title: "presentation", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "lightgrey" },
             { title: "ink", icon: "pen-nib", backgroundColor: "lightgrey" },
             { title: "settings", icon: "cog", click: 'openMobileSettings()', backgroundColor: "lightgrey" }
@@ -647,7 +647,7 @@ export class CurrentUserUtils {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
             { title: "LIBRARY", icon: "bars", click: 'switchToLibrary()', backgroundColor: "#ffd6d6", info: "Navigate and access all of your documents within their respective collections" },
             { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your mobile to record audio and access it on Dash Web." },
-            { title: "UPLOAD", icon: "upload", click: 'uploadMobileImage()', backgroundColor: "#ff9e9e", info: "Upload an image from your mobile device so it can be accessed on Dash Web" },
+            { title: "UPLOAD", icon: "upload", click: 'console.log("hi")', backgroundColor: "#ff9e9e", info: "Upload an image from your mobile device so it can be accessed on Dash Web" },
             { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "#ff8080", info: "Use your phone as a remote for you presentation." },
             // { title: "INK", icon: "pen-nib", backgroundColor: "lightgrey", info: "Doodle and draw with ink on your mobile and have it directly available on Dash Web" },
             { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "#ff5e5e", info: "Change your password, log out, or manage your account security" }
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index c35c4a917..8d7ccf450 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -12,6 +12,7 @@ import { Doc, Opt } from '../fields/Doc';
 import { Cast } from '../fields/Types';
 import { listSpec } from '../fields/Schema';
 import { List } from '../fields/List';
+import { Scripting } from '../client/util/Scripting';
 
 export interface ImageUploadProps {
     Document: Doc;
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index c51b5b654..e9d35096d 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -952,6 +952,7 @@ export class MobileInterface extends React.Component {
     @observable private renderView?: () => JSX.Element;
     @observable private audioState: any;
     @observable private activeToolbar: boolean = false;
+    @observable private sidebarActive: boolean = false;
 
     public _activeDoc: Doc = this.mainDoc;
     public _homeDoc: Doc = this.mainDoc;
@@ -986,8 +987,6 @@ export class MobileInterface extends React.Component {
         InkingControl.Instance.switchTool(InkTool.None);
         MobileInterface.Instance.drawingInk = false;
         InkingControl.Instance.updateSelectedColor("#FF0000");
-        console.log(this.userDoc.inkColor);
-        console.log(InkingControl.Instance.selectedColor);
         InkingControl.Instance.switchWidth("2");
         this.switchCurrentView((userDoc: Doc) => this._homeDoc);
     }
@@ -1027,34 +1026,37 @@ export class MobileInterface extends React.Component {
         });
     }
 
-    toggleSidebar = () => {
-        if (this._open === false) {
-            this._open = true;
-        } else {
-            this._open = false;
-        }
-        console.log("clicked");
-        let menuButton = document.getElementById("menuButton") as HTMLElement;
-        menuButton.classList.toggle('active');
+    @action
+    toggleSidebar = () => this.sidebarActive = !this.sidebarActive
 
-        let sidebar = document.getElementById("sidebar") as HTMLElement;
-        sidebar.classList.toggle('active');
+    // toggleSidebar = () => {
+    //     if (this._open === false) {
+    //         this._open = true;
+    //     } else {
+    //         this._open = false;
+    //     }
+    //     console.log("clicked");
+    //     let menuButton = document.getElementById("menuButton") as HTMLElement;
+    //     //menuButton.classList.toggle('active');
 
-        let header = document.getElementById("header") as HTMLElement;
+    //     let sidebar = document.getElementById("sidebar") as HTMLElement;
+    //     //sidebar.classList.toggle('active');
 
-        if (!sidebar.classList.contains('active')) {
-            header.textContent = String(this._activeDoc.title);
-        } else {
-            header.textContent = "library";
-        }
-    }
+    //     let header = document.getElementById("header") as HTMLElement;
+
+    //     if (!sidebar.classList.contains('active')) {
+    //         header.textContent = String(this._activeDoc.title);
+    //     } else {
+    //         header.textContent = "library";
+    //     }
+    // }
 
     switchToLibrary = () => {
         this._parents.push(this._activeDoc);
         this.switchCurrentView((userDoc: Doc) => this._library);
         this._activeDoc = this._library;
         this._homeMenu = false;
-        this.toggleSidebar();
+        this.sidebarActive = true;
     }
 
     back = () => {
@@ -1084,14 +1086,14 @@ export class MobileInterface extends React.Component {
     }
 
     returnHome = () => {
-        if (this._homeMenu === false || this._open === true) {
+        if (this._homeMenu === false || this.sidebarActive === true) {
             this._homeMenu = true;
             this._parents = [];
             this._activeDoc = this._homeDoc;
             this._child = null;
             this.switchCurrentView((userDoc: Doc) => this._homeDoc);
         }
-        if (this._open) {
+        if (this.sidebarActive) {
             this.toggleSidebar();
         }
     }
@@ -1207,32 +1209,9 @@ export class MobileInterface extends React.Component {
         // let titleArray = [];
         let docArray = [];
         this._parents.map((doc: Doc, index: any) => {
-            // if (doc === this.mainDoc) {
-            //     pathname = pathname;
-            // } else if (doc.type === "audio" || doc.type === "presentation") {
-            //     pathname = pathname;
-            // } else if (doc.type !== "collection") {
-            //     pathname = pathname;
-            // } else {
-            //     pathname = pathname + " > " + doc.title;
-            //     titleArray.push(doc.title);
-            //     docArray.push(doc);
-            // }
             docArray.push(doc);
         });
         docArray.push(this._activeDoc);
-        // if (this._activeDoc.title === "mobile audio") {
-        //     pathname = this._activeDoc.title;
-        // } else if (this._activeDoc.title === "Presentation") {
-        //     pathname = this._activeDoc.title;
-        // } else if (this._activeDoc === this.mainDoc) {
-        //     pathname = pathname;
-        // } else {
-        //     pathname = pathname + " > " + this._activeDoc.title;
-        //     docArray.push(this._activeDoc);
-        //     titleArray.push(this._activeDoc.title);
-        // }
-
         return docArray;
     }
 
@@ -1320,7 +1299,6 @@ export class MobileInterface extends React.Component {
         } else if (doc === this._homeDoc) {
             this.returnHome();
         } else {
-            console.log(index);
             this._activeDoc = doc;
             this._child = doc;
             this.switchCurrentView((userDoc: Doc) => doc);
@@ -1335,7 +1313,7 @@ export class MobileInterface extends React.Component {
                     <div
                         className="item"
                         key={index}
-                        onClick={() => doc.proto?.onClick}>{doc.title}
+                        onClick={() => doc.onClick}>{doc.title}
                     </div>);
             }
         });
@@ -1346,6 +1324,7 @@ export class MobileInterface extends React.Component {
                     <div className="navbar">
                         <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
                         <div className="header" id="header">{this._homeDoc.title}</div>
+                        <div className="cover" id="cover" onClick={(e) => this.stop(e)}></div>
                         <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
                             <span></span>
                             <span></span>
@@ -1361,7 +1340,12 @@ export class MobileInterface extends React.Component {
                 </div>
             );
         }
-        const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+
+        let workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+        if (this._child) {
+            workspaces = this._child
+        }
+
         let buttons = DocListCast(workspaces.data).map((doc: Doc, index: any) => {
             if (doc.type !== "ink") {
                 return (
@@ -1375,88 +1359,39 @@ export class MobileInterface extends React.Component {
             }
         });
 
-        if (this._child) {
-            buttons = DocListCast(this._child.data).map((doc: Doc, index: any) => {
-                if (doc.type !== "ink") {
-                    return (
-                        <div
-                            className="item"
-                            key={index}
-                            onClick={() => this.handleClick(doc)}>{doc.title}
-                            <div className="type">{doc.type}</div>
-                            <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
-                        </div>);
-                }
-            });
-        }
-
-        if (!this._child) {
-            return (
-                <div>
-                    <div className="navbar">
-                        <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
-                        <div className="header" id="header">{this._homeDoc.title}</div>
-                        <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
-                            <span></span>
-                            <span></span>
-                            <span></span>
-                        </div>
-                    </div>
-                    {this.renderPathbar()}
-                    <div className="sidebar" id="sidebar">
-                        <div className="sidebarButtons">
-                            {buttons}
-                            {/* <div className="item" key="library" onClick={this.openLibrary}>
-                                Library
-                            </div> */}
-                            {/* <Uploader Document={workspaces} />
-                            <div className="item" key="audio" onClick={this.recordAudio}>
-                                Record Audio
-                            </div>
-                            <div className="item" key="presentation" onClick={this.openDefaultPresentation}>
-                                Presentation
-                            </div> */}
-                            {/* <div className="item" key="settings" onClick={() => SettingsManager.Instance.open()}>
-                                Settings
-                            </div> */}
-                            <div className="item" key="ink" id="ink" onClick={() => this.onSwitchInking()}>
-                                Ink On
-                            </div>
-                        </div>
+        return (
+            <div>
+                <div className="navbar">
+                    <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
+                    <div className="header" id="header">{this.sidebarActive ? "library" : this._activeDoc.title}</div>
+                    <div className={`toggle-btn ${this.sidebarActive ? "active" : ""}`} onClick={this.toggleSidebar}>
+                        <span></span>
+                        <span></span>
+                        <span></span>
                     </div>
-                    {/* <div>
-                        {this.renderView}
-                    </div> */}
                 </div>
-            );
-        }
-        else {
-            return (
-                <div>
-                    <div className="navbar">
-                        <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
-                        <div className="header" id="header">library</div>
-                        <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
-                            <span></span>
-                            <span></span>
-                            <span></span>
-                        </div>
-                    </div>
-                    {this.renderPathbar()}
-                    <div className="sidebar" id="sidebar">
-                        <div className="sidebarButtons">
-                            {buttons}
-                            <div className="item" key="ink" id="ink" onClick={() => this.onSwitchInking()}>
-                                Ink On
-                            </div>
-                            <div className="item" key="home" onClick={this.returnMain}>
-                                Home
+                {this.renderPathbar()}
+                <div className={`sidebar ${this.sidebarActive ? "active" : ""}`}>
+                    <div className="sidebarButtons">
+                        {this._child ?
+                            <>
+                                {buttons}
+                                <div className="item" key="home" onClick={this.returnMain}>
+                                    Return to library
                             </div>
-                        </div>
+                            </> :
+                            <>
+                                {buttons}
+                            </>
+                        }
                     </div>
                 </div>
-            );
-        }
+            </div>
+        );
+    }
+
+    stop = (e: React.MouseEvent) => {
+        e.stopPropagation();
     }
 
     uploadAudioButton = () => {
@@ -1556,9 +1491,7 @@ export class MobileInterface extends React.Component {
             this._parents.push(this._activeDoc);
         }
         const audioDoc = Cast(Docs.Create.AudioDocument(nullAudio, { _width: 200, _height: 100, title: "mobile audio" }), Doc) as Doc;
-        console.log(audioDoc);
         if (audioDoc) {
-            console.log("audioClicked: " + audioDoc.title);
             this._activeDoc = audioDoc;
             this.switchCurrentView((userDoc: Doc) => audioDoc);
             this._homeMenu = false;
@@ -1579,7 +1512,6 @@ export class MobileInterface extends React.Component {
         const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
         const audioDoc = this._activeDoc;
         const data = Cast(audioRightSidebar.data, listSpec(Doc));
-        console.log(audioDoc.proto);
         if (data) {
             data.push(audioDoc);
         }
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 2641cdfd2..669b55601 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -22,6 +22,16 @@ body {
     border-bottom: 5px solid black;
 }
 
+.navbar .cover {
+    position: absolute;
+    right: 20px;
+    top: 30px;
+    height: 70px;
+    width: 70px;
+    background-color: whitesmoke;
+    z-index: 200;
+}
+
 .navbar .toggle-btn {
     position: absolute;
     right: 20px;
@@ -31,6 +41,10 @@ body {
     transition: all 300ms ease-in-out 200ms;
 }
 
+.navbar .toggle-btn-home {
+    right: -200px;
+}
+
 .navbar .header {
     position: absolute;
     top: 50%;
@@ -311,7 +325,7 @@ body {
 
 .toolbar.active {
     display: inline-block;
-    width: fit-content;
+    width: 300px;
     padding: 5px;
     opacity: 1;
     height: max-content;
@@ -320,7 +334,7 @@ body {
 
 .toolbar .colorSelector {
     display: inline-flex;
-    width: fit-content;
+    width: max-content;
     padding: 5px;
     height: max-content;
     pointer-events: all;
@@ -328,9 +342,9 @@ body {
 
 .widthSelector {
     display: inline-flex;
-    width: 90%;
+    width: max-content;
     height: 100px;
-    padding: 5px;
+    padding: 10px;
 }
 
 .slider {
-- 
cgit v1.2.3-70-g09d2


From 8d6fdb9460bd826c2be3a03cca9fa28a018b3e22 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Tue, 9 Jun 2020 22:06:14 +0800
Subject: adjust presentation view

---
 src/client/util/CurrentUserUtils.ts                |  2 +-
 src/client/util/SettingsManager.scss               |  4 +-
 src/client/views/nodes/PresBox.scss                | 62 ++++++++++++++++++++--
 .../views/presentationview/PresElementBox.scss     | 48 ++++++++++++++---
 src/mobile/ImageUpload.scss                        | 60 ++++++++++-----------
 src/mobile/ImageUpload.tsx                         |  1 +
 src/mobile/MobileInterface.tsx                     | 49 ++++++++++++++---
 7 files changed, 174 insertions(+), 52 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 8ed275efc..3d38e7370 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -409,7 +409,7 @@ export class CurrentUserUtils {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
             { title: "library", icon: "bars", click: 'switchToLibrary()', backgroundColor: "lightgrey" },
             { title: "record", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "lightgrey" },
-            { title: "upload", icon: "upload", click: 'uploadMobileImage()', backgroundColor: "lightgrey" },
+            { title: "upload", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "lightgrey" },
             { title: "presentation", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "lightgrey" },
             { title: "ink", icon: "pen-nib", backgroundColor: "lightgrey" },
             { title: "settings", icon: "cog", click: 'openMobileSettings()', backgroundColor: "lightgrey" }
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index 6513cb223..eb1045f70 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -133,4 +133,6 @@
 
 
     }
-}
\ No newline at end of file
+}
+
+@media only screen and (max-width: 1000px) {}
\ No newline at end of file
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index d48000e16..61641c989 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -16,6 +16,7 @@
         height: calc(100% - 25px);
         width: 100%;
     }
+
     .presBox-buttons {
         width: 100%;
         background: gray;
@@ -24,6 +25,7 @@
         display: grid;
         grid-column-end: 4;
         grid-column-start: 1;
+
         .presBox-viewPicker {
             height: 25;
             position: relative;
@@ -31,10 +33,12 @@
             grid-column: 1/2;
             min-width: 15px;
         }
+
         select {
             background: #323232;
             color: white;
         }
+
         .presBox-button {
             margin-right: 2.5%;
             margin-left: 2.5%;
@@ -44,10 +48,12 @@
             align-items: center;
             background: #323232;
             color: white;
+
             svg {
                 margin: auto;
             }
         }
+
         .collectionViewBaseChrome-viewPicker {
             min-width: 50;
             width: 5%;
@@ -56,17 +62,65 @@
             display: inline-block;
         }
     }
-    .presBox-backward, .presBox-forward {
+
+    .presBox-backward,
+    .presBox-forward {
         width: 25px;
         border-radius: 5px;
-        top:50%;
+        top: 50%;
         position: absolute;
         display: inline-block;
     }
+
     .presBox-backward {
-        left:5;
+        left: 5;
     }
+
     .presBox-forward {
-        right:5;
+        right: 5;
+    }
+}
+
+@media only screen and (max-width: 1000px) {    .presBox-cont .presBox-buttons {
+        position: absolute;
+        top: 85%;
+        left: 50%;
+        transform: translate(-50%, 0);
+        width: max-content;
+        height: 15%;
+        z-index: 2;
+        align-items: center;
+        background: rgba(0, 0, 0, 0);
+        padding-top: 5px;
+        padding-bottom: 5px;
+        display: inline-flex;
+    }
+
+    .presBox-cont .presBox-listCont {
+        position: absolute;
+        top: 50;
+        height: calc(100% - 80px);
+        width: 100%;
+    }
+
+    .presBox-cont .presBox-buttons .presBox-button {
+        margin-right: 10px;
+        margin-left: 10px;
+        height: 130px;
+        width: 130px;
+        font-size: 50;
+        border-radius: 5px;
+        display: flex;
+        align-items: center;
+        background: #323232;
+        color: white;
+    }
+
+    .presBox-cont .presBox-buttons .presBox-viewPicker {
+        height: 50;
+        width: 100;
+        font-size: 30px;
+        position: relative;
+        min-width: 50px;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index ccd2e8947..1ddf3d8bc 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -13,9 +13,10 @@
     -moz-user-select: none;
     -ms-user-select: none;
     user-select: none;
-    transition: all .1s; 
+    transition: all .1s;
     padding: 0px;
     padding-bottom: 3px;
+
     .documentView-node {
         position: absolute;
         z-index: 1;
@@ -45,7 +46,7 @@
 
 .presElementBox-closeIcon {
     border-radius: 20px;
-    transform:scale(0.7);
+    transform: scale(0.7);
     position: absolute;
     right: 0;
     top: 0;
@@ -58,6 +59,7 @@
     position: relative;
     width: 100%;
     height: auto;
+
     .presElementBox-interaction {
         color: gray;
         float: left;
@@ -65,6 +67,7 @@
         width: 20px;
         height: 20px;
     }
+
     .presElementBox-interaction-selected {
         color: white;
         float: left;
@@ -90,15 +93,44 @@
     display: flex;
     width: auto;
     justify-content: center;
-    margin:auto;
+    margin: auto;
 }
 
 .presElementBox-embeddedMask {
-    width:100%;
-    height:100%;
+    width: 100%;
+    height: 100%;
     position: absolute;
-    left:0;
-    top:0;
+    left: 0;
+    top: 0;
     background: transparent;
-    z-index:2;
+    z-index: 2;
+}
+
+@media only screen and (max-width: 1000px) {
+    .presElementBox-buttons {
+        display: inline-flex;
+        position: relative;
+        width: 100%;
+    }
+
+    .presElementBox-item {
+        display: inline-flex;
+    }
+
+    .presElementBox-buttons .presElementBox-interaction {
+        color: gray;
+        float: left;
+        padding: 0px;
+        width: 50;
+        height: 40;
+    }
+
+    .presElementBox-buttons .presElementBox-interaction-selected {
+        color: white;
+        float: left;
+        padding: 0px;
+        width: 50;
+        height: 50;
+        border: solid 1px darkgray;
+    }
 }
\ No newline at end of file
diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss
index 6ebf33438..afc4cc21e 100644
--- a/src/mobile/ImageUpload.scss
+++ b/src/mobile/ImageUpload.scss
@@ -1,12 +1,12 @@
 @import "../client/views/globalCssVariables.scss";
 
 .imgupload_cont {
-    // display: flex;
-    // justify-content: center;
-    // flex-direction: column;
-    // align-items: center;
-    // width: 100vw;
-    // height: 100vh;
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
+    align-items: center;
+    width: 90vw;
+    height: 90vh;
 
     .upload_label {
         font-weight: normal !important;
@@ -31,31 +31,31 @@
         font-size: 3em;
     }
 
-    .input_file {
-        display: none;
-    }
+    // .input_file {
+    //     display: none;
+    // }
+
+    // // .upload_label,
+    // // .upload_button {
+    // //     background: $dark-color;
+    // //     font-size: 500%;
+    // //     font-family: $sans-serif;
+    // //     text-align: center;
+    // //     padding: 5vh;
+    // //     margin-bottom: 20px;
+    // //     color: white;
+    // // }
 
-    // .upload_label,
     // .upload_button {
-    //     background: $dark-color;
-    //     font-size: 500%;
-    //     font-family: $sans-serif;
-    //     text-align: center;
-    //     padding: 5vh;
-    //     margin-bottom: 20px;
-    //     color: white;
+    //     width: 100%;
+    //     padding: 13px 12px;
+    //     border-bottom: 1px solid rgba(200, 200, 200, 0.7);
+    //     font-family: Arial, Helvetica, sans-serif;
+    //     font-style: normal;
+    //     font-weight: normal;
+    //     user-select: none;
+    //     font-size: 35px;
+    //     text-transform: uppercase;
+    //     color: black;
     // }
-
-    .upload_button {
-        width: 100%;
-        padding: 13px 12px;
-        border-bottom: 1px solid rgba(200, 200, 200, 0.7);
-        font-family: Arial, Helvetica, sans-serif;
-        font-style: normal;
-        font-weight: normal;
-        user-select: none;
-        font-size: 35px;
-        text-transform: uppercase;
-        color: black;
-    }
 }
\ No newline at end of file
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index c35c4a917..8d7ccf450 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -12,6 +12,7 @@ import { Doc, Opt } from '../fields/Doc';
 import { Cast } from '../fields/Types';
 import { listSpec } from '../fields/Schema';
 import { List } from '../fields/List';
+import { Scripting } from '../client/util/Scripting';
 
 export interface ImageUploadProps {
     Document: Doc;
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index c51b5b654..e2de7fed2 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -6,7 +6,7 @@ import {
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
     faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote,
-    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft, faBars, faTh, faChevronLeft
+    faThumbtack, faTree, faTv, faBook, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft, faBars, faTh, faChevronLeft
 } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable } from 'mobx';
@@ -43,7 +43,7 @@ library.add(faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTras
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
     faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote,
-    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft, faBars, faTh, faChevronLeft);
+    faThumbtack, faTree, faTv, faUndoAlt, faBook, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft, faBars, faTh, faChevronLeft);
 
 // @observer
 // export class MobileInterface extends React.Component {
@@ -948,7 +948,8 @@ export class MobileInterface extends React.Component {
     @computed private get userDoc() { return Doc.UserDoc(); }
     @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
     // @computed private get activeContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
-    @observable private mainDoc: any = CurrentUserUtils.setupMobileMenu();
+    // Sets up new mobile menu only if activeMobile already exists
+    @observable private mainDoc: any = Doc.UserDoc().activeMobile !== undefined ? console.log("true") : CurrentUserUtils.setupMobileMenu();
     @observable private renderView?: () => JSX.Element;
     @observable private audioState: any;
     @observable private activeToolbar: boolean = false;
@@ -978,7 +979,7 @@ export class MobileInterface extends React.Component {
     componentDidMount = () => {
         library.add(...[faPenNib, faHighlighter, faEraser, faMousePointer, faThumbtack]);
         if (this.userDoc.activeMobile) {
-            console.log(Doc.UserDoc().activeMobile)
+            console.log(Doc.UserDoc().activeMobile);
         }
         if (this.userDoc && !this.mainContainer) {
             this.userDoc.activeMobile = this._homeDoc;
@@ -1027,6 +1028,9 @@ export class MobileInterface extends React.Component {
         });
     }
 
+    /**
+     * Handles the functionality to toggle the sidebar
+     */
     toggleSidebar = () => {
         if (this._open === false) {
             this._open = true;
@@ -1049,6 +1053,9 @@ export class MobileInterface extends React.Component {
         }
     }
 
+    /**
+     * Method called when 'Library' button is pressed
+     */
     switchToLibrary = () => {
         this._parents.push(this._activeDoc);
         this.switchCurrentView((userDoc: Doc) => this._library);
@@ -1057,6 +1064,9 @@ export class MobileInterface extends React.Component {
         this.toggleSidebar();
     }
 
+    /**
+     * Back method for navigating within library
+     */
     back = () => {
         let header = document.getElementById("header") as HTMLElement;
         let doc = Cast(this._parents.pop(), Doc) as Doc;
@@ -1083,6 +1093,9 @@ export class MobileInterface extends React.Component {
         this._ink = false;
     }
 
+    /**
+     * Return 'Home", which implies returning to 'Home' buttons
+     */
     returnHome = () => {
         if (this._homeMenu === false || this._open === true) {
             this._homeMenu = true;
@@ -1096,6 +1109,9 @@ export class MobileInterface extends React.Component {
         }
     }
 
+    /**
+     * Return to primary Workspace in library (Workspaces Doc)
+     */
     returnMain = () => {
         console.log("home");
         this._parents = [];
@@ -1108,6 +1124,9 @@ export class MobileInterface extends React.Component {
 
     // @computed get onChildClickHandler() { return ScriptCast(Doc.UserDoc.onClick); }
 
+    /**
+     * DocumentView for graphic display of all documents
+     */
     displayWorkspaces = () => {
         if (this.mainContainer) {
             const backgroundColor = () => "white";
@@ -1174,9 +1193,13 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    returnWidth = () => window.innerWidth;
-    returnHeight = () => (window.innerHeight - 300);
+    returnWidth = () => window.innerWidth; //The windows width
+    returnHeight = () => (window.innerHeight - 300); //Calculating the windows height (-300 to account for topbar)
 
+    /**
+     * Handles the click functionality in the library panel
+     * @param doc: doc for which the method is called
+     */
     handleClick(doc: Doc) {
         let children = DocListCast(doc.data);
         if (doc.type !== "collection") {
@@ -1311,6 +1334,7 @@ export class MobileInterface extends React.Component {
         // }
     }
 
+    // Handles when user clicks on document in the pathbar
     handlePathClick = (doc: Doc, index: number) => {
         if (doc === this._library) {
             this._activeDoc = doc;
@@ -1709,7 +1733,6 @@ export class MobileInterface extends React.Component {
         const presentation = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
 
         if (presentation) {
-            console.log(this._activeDoc.mobile);
             console.log("presentation clicked: " + presentation.title);
             this._activeDoc = presentation;
             this.switchCurrentView((userDoc: Doc) => presentation);
@@ -1748,7 +1771,6 @@ export class MobileInterface extends React.Component {
                     {this.displayWorkspaces()}
                     {this.renderDefaultContent()}
                 </GestureOverlay>
-
                 {/* </GestureOverlay> */}
                 {/* <DictationOverlay />
                 <SharingManager />
@@ -1767,14 +1789,25 @@ export class MobileInterface extends React.Component {
             </div>
         );
     }
+
+    uploadImage = () => {
+        console.log("hello world of images");
+    }
 }
 
+
+
+const inputRef = React.createRef<HTMLInputElement>();
+
+
 Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); });
 Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); });
 Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); });
 Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.recordAudio(); });
 Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); });
 Scripting.addGlobal(function switchToLibrary() { return MobileInterface.Instance.switchToLibrary(); });
+Scripting.addGlobal(function uploadImageMobile() { return MobileInterface.Instance.uploadImage(); });
+
 
 
 // WAS 2
-- 
cgit v1.2.3-70-g09d2


From 7a7adfdb6fb6131ba2012d3e8aeb145e87773c81 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Tue, 9 Jun 2020 22:43:16 +0800
Subject: updated settings view for mobile

---
 src/client/util/SettingsManager.scss | 31 ++++++++++++++++++++++++++++++-
 src/client/views/nodes/PresBox.scss  | 30 +++++++++++++++++++++++++++++-
 src/mobile/MobileInterface.tsx       |  2 +-
 3 files changed, 60 insertions(+), 3 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index eb1045f70..4d0fe5b8a 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -135,4 +135,33 @@
     }
 }
 
-@media only screen and (max-width: 1000px) {}
\ No newline at end of file
+@media only screen and (max-width: 1000px) {
+    .settings-interface {
+        background-color: whitesmoke !important;
+        color: grey;
+        width: 80vw;
+        height: 25vh;
+    }
+
+    .settings-interface .settings-body .settings-content input {
+        border-radius: 5px;
+        border: none;
+        font-size: 30;
+        padding: 4px;
+        min-width: 100%;
+        margin: 2px 0;
+    }
+
+    .settings-interface button {
+        width: 100%;
+        font-size: 30px;
+        align-self: center;
+        background: #b2cef8;
+        margin-top: 4px;
+    }
+
+    .settings-interface .settings-heading {
+        letter-spacing: .5em;
+        font-size: 25;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 61641c989..56c6b4357 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -81,7 +81,8 @@
     }
 }
 
-@media only screen and (max-width: 1000px) {    .presBox-cont .presBox-buttons {
+@media only screen and (max-width: 1000px) {
+    .presBox-cont .presBox-buttons {
         position: absolute;
         top: 85%;
         left: 50%;
@@ -123,4 +124,31 @@
         position: relative;
         min-width: 50px;
     }
+
+    .presElementBox-closeIcon {
+        border-radius: 20px;
+        transform: scale(2);
+        position: absolute;
+        right: 20;
+        top: 20;
+        padding: 8px;
+    }
+
+    .presElementBox-buttons {
+        display: inline-flex;
+        position: absolute;
+        right: 0;
+        width: 50%;
+    }
+
+    .presElementBox-name {
+        font-size: 30px;
+        position: absolute;
+        display: inline-block;
+        top: 10px;
+        width: 50%;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        white-space: pre;
+    }
 }
\ No newline at end of file
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 0f6f51295..d8ac7d1f1 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -949,7 +949,7 @@ export class MobileInterface extends React.Component {
     @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
     // @computed private get activeContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
     // Sets up new mobile menu only if activeMobile already exists
-    @observable private mainDoc: any = Doc.UserDoc().activeMobile !== undefined ? console.log("true") : CurrentUserUtils.setupMobileMenu();
+    @observable private mainDoc: any = CurrentUserUtils.setupMobileMenu();
     @observable private renderView?: () => JSX.Element;
     @observable private audioState: any;
     @observable private activeToolbar: boolean = false;
-- 
cgit v1.2.3-70-g09d2


From bc80c711e7ab3044a0859c4b5d74e8e49cc5d077 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Wed, 10 Jun 2020 03:21:32 +0800
Subject: image upload functions w/ bugs

- choose an image does not immediately update
- close button does not move with rest of upload image
---
 src/client/util/CurrentUserUtils.ts                |   7 +-
 src/client/util/SettingsManager.scss               |   2 +-
 src/client/views/nodes/PresBox.scss                |  43 ++-----
 .../views/presentationview/PresElementBox.scss     |  51 +++++++-
 src/mobile/ImageUpload.scss                        | 138 +++++++++++++++------
 src/mobile/ImageUpload.tsx                         |  74 ++++++++++-
 src/mobile/MobileInterface.tsx                     |  46 ++++++-
 7 files changed, 273 insertions(+), 88 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index d99d11c1f..563f8cfe4 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -430,7 +430,7 @@ export class CurrentUserUtils {
     }
 
     static setupMobileMenu() {
-        const menu = Cast(Docs.Create.StackingDocument(CurrentUserUtils.setupMobileButtons(), {
+        const menu = Cast(Docs.Create.StackingDocument(CurrentUserUtils.setupMobileButtons2(), {
             _width: 980, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "home", _autoHeight: true, _yMargin: 80
         }), Doc) as Doc;
         return menu;
@@ -647,7 +647,7 @@ export class CurrentUserUtils {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
             { title: "LIBRARY", icon: "bars", click: 'switchToLibrary()', backgroundColor: "#ffd6d6", info: "Navigate and access all of your documents within their respective collections" },
             { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your mobile to record audio and access it on Dash Web." },
-            { title: "UPLOAD", icon: "upload", click: 'console.log("hi")', backgroundColor: "#ff9e9e", info: "Upload an image from your mobile device so it can be accessed on Dash Web" },
+            { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "#ff9e9e", info: "Upload an image from your mobile device so it can be accessed on Dash Web" },
             { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "#ff8080", info: "Use your phone as a remote for you presentation." },
             // { title: "INK", icon: "pen-nib", backgroundColor: "lightgrey", info: "Doodle and draw with ink on your mobile and have it directly available on Dash Web" },
             { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "#ff5e5e", info: "Change your password, log out, or manage your account security" }
@@ -658,7 +658,7 @@ export class CurrentUserUtils {
     static mobileButton = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.MulticolumnDocument(docs, {
         ...opts,
         dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 900, _nativeHeight: 250, _width: 900, _height: 250, _yMargin: 15,
-        borderRounding: "0", boxShadow: "0 0", _chromeStatus: "disabled",
+        borderRounding: "5px", boxShadow: "0 0", _chromeStatus: "disabled",
     })) as any as Doc
 
     static mobileTextContainer = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.MultirowDocument(docs, {
@@ -720,6 +720,7 @@ export class CurrentUserUtils {
         }
     }
 
+
     static setupClickEditorTemplates(doc: Doc) {
         if (doc["clickFuncs-child"] === undefined) {
             const openInTarget = Docs.Create.ScriptingDocument(ScriptField.MakeScript(
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index 4d0fe5b8a..1eac9303b 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -140,7 +140,7 @@
         background-color: whitesmoke !important;
         color: grey;
         width: 80vw;
-        height: 25vh;
+        height: 400px;
     }
 
     .settings-interface .settings-body .settings-content input {
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 56c6b4357..2bb249ee4 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -84,7 +84,7 @@
 @media only screen and (max-width: 1000px) {
     .presBox-cont .presBox-buttons {
         position: absolute;
-        top: 85%;
+        top: 70%;
         left: 50%;
         transform: translate(-50%, 0);
         width: max-content;
@@ -107,10 +107,10 @@
     .presBox-cont .presBox-buttons .presBox-button {
         margin-right: 10px;
         margin-left: 10px;
-        height: 130px;
-        width: 130px;
-        font-size: 50;
-        border-radius: 5px;
+        height: 250;
+        width: 250;
+        font-size: 70;
+        border-radius: 25px;
         display: flex;
         align-items: center;
         background: #323232;
@@ -118,37 +118,12 @@
     }
 
     .presBox-cont .presBox-buttons .presBox-viewPicker {
+        top: -70;
+        left: 2.5%;
         height: 50;
-        width: 100;
-        font-size: 30px;
-        position: relative;
-        min-width: 50px;
-    }
-
-    .presElementBox-closeIcon {
-        border-radius: 20px;
-        transform: scale(2);
-        position: absolute;
-        right: 20;
-        top: 20;
-        padding: 8px;
-    }
-
-    .presElementBox-buttons {
-        display: inline-flex;
-        position: absolute;
-        right: 0;
-        width: 50%;
-    }
-
-    .presElementBox-name {
+        width: 95%;
         font-size: 30px;
         position: absolute;
-        display: inline-block;
-        top: 10px;
-        width: 50%;
-        text-overflow: ellipsis;
-        overflow: hidden;
-        white-space: pre;
+        min-width: 50px;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index 1ddf3d8bc..ec82b0c51 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -122,7 +122,7 @@
         float: left;
         padding: 0px;
         width: 50;
-        height: 40;
+        height: 50;
     }
 
     .presElementBox-buttons .presElementBox-interaction-selected {
@@ -133,4 +133,53 @@
         height: 50;
         border: solid 1px darkgray;
     }
+
+    .presElementBox-closeIcon {
+        border-radius: 20px;
+        transform: scale(1.5);
+        position: absolute;
+        right: 10;
+        top: 10;
+        padding: 8px;
+    }
+
+    .presElementBox-buttons {
+        display: inline-flex;
+        position: absolute;
+        top: 0;
+        right: 0;
+        width: 50%;
+    }
+
+    .presElementBox-name {
+        font-size: 30px;
+        position: absolute;
+        display: inline-block;
+        top: 10px;
+        width: 50%;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        white-space: pre;
+    }
+
+    .presElementBox-item {
+        display: inline-block;
+        background-color: #eeeeee;
+        pointer-events: all;
+        width: 100%;
+        min-height: 100%;
+        height: max-content;
+        outline-color: maroon;
+        outline-style: dashed;
+        border-radius: 6px;
+        -webkit-touch-callout: none;
+        -webkit-user-select: none;
+        -khtml-user-select: none;
+        -moz-user-select: none;
+        -ms-user-select: none;
+        user-select: none;
+        transition: all .1s;
+        padding: 0px;
+        padding-bottom: 3px;
+    }
 }
\ No newline at end of file
diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss
index afc4cc21e..6c782d4d8 100644
--- a/src/mobile/ImageUpload.scss
+++ b/src/mobile/ImageUpload.scss
@@ -5,21 +5,20 @@
     justify-content: center;
     flex-direction: column;
     align-items: center;
-    width: 90vw;
-    height: 90vh;
 
     .upload_label {
-        font-weight: normal !important;
+        font-size: 3em;
+        font-weight: 700;
+        color: white;
+        background-color: black;
+        display: inline-block;
+        margin: 10;
         width: 100%;
-        padding: 13px 12px;
-        border-bottom: 1px solid rgba(200, 200, 200, 0.7);
-        font-family: Arial, Helvetica, sans-serif;
-        font-style: normal;
-        font-weight: normal;
-        user-select: none;
-        font-size: 35px;
-        text-transform: uppercase;
-        color: black;
+        border-radius: 10px;
+    }
+
+    .upload_label:hover {
+        background-color: darkred;
     }
 
     .button_file {
@@ -31,31 +30,92 @@
         font-size: 3em;
     }
 
-    // .input_file {
-    //     display: none;
-    // }
-
-    // // .upload_label,
-    // // .upload_button {
-    // //     background: $dark-color;
-    // //     font-size: 500%;
-    // //     font-family: $sans-serif;
-    // //     text-align: center;
-    // //     padding: 5vh;
-    // //     margin-bottom: 20px;
-    // //     color: white;
-    // // }
-
-    // .upload_button {
-    //     width: 100%;
-    //     padding: 13px 12px;
-    //     border-bottom: 1px solid rgba(200, 200, 200, 0.7);
-    //     font-family: Arial, Helvetica, sans-serif;
-    //     font-style: normal;
-    //     font-weight: normal;
-    //     user-select: none;
-    //     font-size: 35px;
-    //     text-transform: uppercase;
-    //     color: black;
-    // }
+    .inputfile {
+        width: 0.1px;
+        height: 0.1px;
+        opacity: 0;
+        overflow: hidden;
+        position: absolute;
+        z-index: -1;
+    }
+
+    .inputfile+label {
+        font-size: 3em;
+        font-weight: 700;
+        color: white;
+        background-color: black;
+        display: inline-block;
+        margin: 10px;
+        width: 100%;
+        border-radius: 10px;
+    }
+
+    .inputfile:focus+label,
+    .inputfile+label:hover {
+        background-color: darkred;
+    }
+
+}
+
+.backgroundUpload {
+    height: 100vh;
+    top: 0;
+    z-index: 999;
+    width: 100vw;
+    position: absolute;
+    background-color: lightgrey;
+    opacity: 0.4;
+}
+
+.image-upload {
+    top: 100%;
+    opacity: 0;
+}
+
+.image-upload.active {
+    top: 0;
+    position: absolute;
+    z-index: 999;
+    height: 100vh;
+    width: 100vw;
+    opacity: 1;
+}
+
+.uploadContainer {
+    top: 40;
+    position: absolute;
+    z-index: 1000;
+    height: 20vh;
+    width: 80vw;
+    opacity: 1;
+}
+
+.closeUpload {
+    position: absolute;
+    border-radius: 10px;
+    top: 39.7%;
+    color: grey;
+    font-size: 40;
+    left: 65.8%;
+    z-index: 1002;
+    padding: 0px 3px;
+    background: aliceblue;
+    transition: 0.5s ease all;
+    border: 3px solid;
+    border-color: black;
+}
+
+.loadingImage {
+    display: inline-flex;
+    width: max-content;
+}
+
+.loadingSlab {
+    position: relative;
+    width: 30px;
+    height: 30px;
+    margin: 10;
+    border-radius: 20px;
+    opacity: 0.3;
+    background-color: black;
 }
\ No newline at end of file
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 8d7ccf450..df2beb85a 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -13,6 +13,7 @@ import { Cast } from '../fields/Types';
 import { listSpec } from '../fields/Schema';
 import { List } from '../fields/List';
 import { Scripting } from '../client/util/Scripting';
+import MainViewModal from '../client/views/MainViewModal';
 
 export interface ImageUploadProps {
     Document: Doc;
@@ -35,6 +36,10 @@ export class Uploader extends React.Component<ImageUploadProps> {
         console.log("uploader click");
         try {
             this.status = "initializing protos";
+            const slab1 = document.getElementById("slab1");
+            if (slab1) {
+                slab1.style.opacity = "1";
+            }
             await Docs.Prototypes.initialize();
             const imgPrev = document.getElementById("img_preview");
             if (imgPrev) {
@@ -44,8 +49,15 @@ export class Uploader extends React.Component<ImageUploadProps> {
                     const name = files[0].name;
                     const res = await Networking.UploadFilesToServer(files[0]);
                     this.status = "uploading image";
+                    const slab2 = document.getElementById("slab2");
+                    if (slab2) {
+                        slab2.style.opacity = "1";
+                    }
                     this.status = "upload image, getting json";
-
+                    const slab3 = document.getElementById("slab3");
+                    if (slab3) {
+                        slab3.style.opacity = "1";
+                    }
                     res.map(async ({ result }) => {
                         if (result instanceof Error) {
                             return;
@@ -54,7 +66,15 @@ export class Uploader extends React.Component<ImageUploadProps> {
                         const doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name });
 
                         this.status = "getting user document";
-
+                        const slab4 = document.getElementById("slab4");
+                        if (slab4) {
+                            slab4.style.opacity = "1";
+                        }
+                        this.status = "upload image, getting json";
+                        const slab5 = document.getElementById("slab5");
+                        if (slab5) {
+                            slab5.style.opacity = "1";
+                        }
                         const res = await rp.get(Utils.prepend("/getUserDocumentId"));
                         if (!res) {
                             throw new Error("No user id returned");
@@ -66,6 +86,10 @@ export class Uploader extends React.Component<ImageUploadProps> {
                         }
                         if (pending) {
                             this.status = "has pending docs";
+                            const slab6 = document.getElementById("slab6");
+                            if (slab6) {
+                                slab6.style.opacity = "1";
+                            }
                             const data = await Cast(pending.data, listSpec(Doc));
                             if (data) {
                                 data.push(doc);
@@ -74,6 +98,10 @@ export class Uploader extends React.Component<ImageUploadProps> {
                             }
                             this.status = "finished";
                             console.log("hi");
+                            const slab7 = document.getElementById("slab7");
+                            if (slab7) {
+                                slab7.style.opacity = "1";
+                            }
                         }
 
                     });
@@ -84,19 +112,55 @@ export class Uploader extends React.Component<ImageUploadProps> {
         }
     }
 
-    render() {
+    // Updates label after a files is selected (so user knows a file is uploaded)
+    inputLabel = async () => {
+        const files: FileList | null = inputRef.current!.files;
+        await files;
+        var inputs = document.querySelectorAll('.inputFile');
+        const label = document.getElementById("label");
+        if (files && label) {
+            label.innerText = files[0].name;
+        }
+    }
+
+    private get uploadInterface() {
         return (
             <div className="imgupload_cont">
-                <label htmlFor="input_image_file" className="upload_label" onClick={this.onClick}>Upload Image</label>
-                <input type="file" accept="image/*" className="input_file" id="input_image_file" ref={inputRef}></input>
+                <input type="file" accept="image/*" className="inputFile" id="input_image_file" onClick={this.inputLabel} ref={inputRef}></input>
+                <label id="label" htmlFor="input_image_file">Choose an image</label>
+                <div className="upload_label" onClick={this.onClick}>Upload Image</div>
                 {/* <div onClick={this.onClick} className="upload_button">Upload</div> */}
                 <img id="img_preview" src=""></img>
                 {/* <p>{this.status}</p>
                 <p>{this.error}</p> */}
+                <div className="loadingImage">
+                    <div className="loadingSlab" id="slab1" />
+                    <div className="loadingSlab" id="slab2" />
+                    <div className="loadingSlab" id="slab3" />
+                    <div className="loadingSlab" id="slab4" />
+                    <div className="loadingSlab" id="slab5" />
+                    <div className="loadingSlab" id="slab6" />
+                    <div className="loadingSlab" id="slab7" />
+                </div>
             </div>
         );
     }
 
+    @observable private dialogueBoxOpacity = 1;
+    @observable private overlayOpacity = 0.4;
+
+    render() {
+        return (
+            <MainViewModal
+                contents={this.uploadInterface}
+                isDisplayed={true}
+                interactive={true}
+                dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
+                overlayDisplayedOpacity={this.overlayOpacity}
+            />
+        );
+    }
+
 }
 
 
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index d8ac7d1f1..c4b2ffbc1 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1,7 +1,7 @@
 import * as React from "react";
 import { library } from '@fortawesome/fontawesome-svg-core';
 import {
-    faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+    faTasks, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -26,6 +26,7 @@ import { InkingControl } from '../client/views/InkingControl';
 import "./MobileInterface.scss";
 import "./MobileMenu.scss";
 import "./MobileHome.scss";
+import "./ImageUpload.scss";
 import { DocumentManager } from '../client/util/DocumentManager';
 import SettingsManager from '../client/util/SettingsManager';
 import { Uploader } from "./ImageUpload";
@@ -38,7 +39,7 @@ import { SelectionManager } from "../client/util/SelectionManager";
 import { SketchPicker } from "react-color";
 import { ScriptField } from "../fields/ScriptField";
 
-library.add(faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+library.add(faTasks, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -1240,7 +1241,7 @@ export class MobileInterface extends React.Component {
         // if (this._homeMenu == false) {
         let docArray = this.createPathname();
         let items = docArray.map((doc: Doc, index: any) => {
-            if (index == 0) {
+            if (index === 0) {
                 return (
                     <div className="pathbarItem">
                         <div className="pathbarText"
@@ -1689,6 +1690,9 @@ export class MobileInterface extends React.Component {
                 <SettingsManager />
                 {/* {this.menuOptions()} */}
                 {/* {this.displayHome()} */}
+                <div className={`image-upload ${this.imageUploadActive ? "active" : ""}`}>
+                    {this.uploadImage()}
+                </div>
                 <div className="docButtonContainer">
                     {this.pinToPresentation()}
                     {this.downloadDocument()}
@@ -1719,8 +1723,40 @@ export class MobileInterface extends React.Component {
         );
     }
 
+    @observable private imageUploadActive: boolean = false;
+
+    @action
+    toggleUpload = () => this.imageUploadActive = !this.imageUploadActive
+
+    @action
+    closeUpload = () => {
+        this.imageUploadActive = false;
+    }
+
+    // toggleUpload = () => {
+    //     if (this.imageUploadActive === true) {
+    //         this.imageUploadActive = false;
+    //     } else {
+    //         this.imageUploadActive = true;
+    //     }
+    // }
+
     uploadImage = () => {
-        console.log("hello world of images");
+        if (this.imageUploadActive) {
+            console.log("active");
+        } else if (!this.imageUploadActive) {
+
+        }
+        console.log("upload");
+        const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+        return (
+            <div>
+                <div className="closeUpload" onClick={this.toggleUpload}>
+                    <FontAwesomeIcon icon="window-close" size={"lg"} />
+                </div>
+                <Uploader Document={workspaces} />
+            </div>
+        );
     }
 }
 
@@ -1735,7 +1771,7 @@ Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Inst
 Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.recordAudio(); });
 Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); });
 Scripting.addGlobal(function switchToLibrary() { return MobileInterface.Instance.switchToLibrary(); });
-Scripting.addGlobal(function uploadImageMobile() { return MobileInterface.Instance.uploadImage(); });
+Scripting.addGlobal(function uploadImageMobile() { return MobileInterface.Instance.toggleUpload(); });
 
 
 
-- 
cgit v1.2.3-70-g09d2


From a37ca793caefc203071f082490097b6231b0daf8 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Tue, 9 Jun 2020 21:25:26 -0700
Subject: fix some bugs in ImageUpload

---
 src/mobile/ImageUpload.tsx     | 64 ++++++++++++++++++++++++++++++++++++++----
 src/mobile/MobileInterface.tsx |  7 +++--
 2 files changed, 63 insertions(+), 8 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index df2beb85a..d5e7cec1b 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -5,7 +5,7 @@ import "./ImageUpload.scss";
 import React = require('react');
 import { DocServer } from '../client/DocServer';
 import { observer } from 'mobx-react';
-import { observable } from 'mobx';
+import { observable, action } from 'mobx';
 import { Utils } from '../Utils';
 import { Networking } from '../client/Network';
 import { Doc, Opt } from '../fields/Doc';
@@ -28,9 +28,10 @@ export interface ImageUploadProps {
 const inputRef = React.createRef<HTMLInputElement>();
 
 @observer
-export class Uploader extends React.Component<ImageUploadProps> {
+export class Uploader extends React.Component {
     @observable error: string = "";
     @observable status: string = "";
+    @observable nm: string = "Choose an image";
 
     onClick = async () => {
         console.log("uploader click");
@@ -102,14 +103,17 @@ export class Uploader extends React.Component<ImageUploadProps> {
                             if (slab7) {
                                 slab7.style.opacity = "1";
                             }
+                            setTimeout(this.clearUpload, 3000);
                         }
 
                     });
                 }
+
             }
         } catch (error) {
             this.error = JSON.stringify(error);
         }
+
     }
 
     // Updates label after a files is selected (so user knows a file is uploaded)
@@ -118,16 +122,66 @@ export class Uploader extends React.Component<ImageUploadProps> {
         await files;
         var inputs = document.querySelectorAll('.inputFile');
         const label = document.getElementById("label");
-        if (files && label) {
-            label.innerText = files[0].name;
+        if (files && label && files.length !== 0) {
+            label.innerText = await files[0].name;
+            setTimeout(this.updateName, 1000);
+        }
+    }
+
+    @action
+    updateName = () => {
+        const label = document.getElementById("label");
+        if (label) {
+            this.nm = label.innerText;
+
+        }
+        console.log("lol");
+    }
+
+    @action
+    clearUpload = () => {
+        const slab1 = document.getElementById("slab1");
+        if (slab1) {
+            slab1.style.opacity = "0.4";
+        }
+        const slab2 = document.getElementById("slab2");
+        if (slab2) {
+            slab2.style.opacity = "0.4";
+        }
+        const slab3 = document.getElementById("slab3");
+        if (slab3) {
+            slab3.style.opacity = "0.4";
+        }
+        const slab4 = document.getElementById("slab4");
+        if (slab4) {
+            slab4.style.opacity = "0.4";
+        }
+        const slab5 = document.getElementById("slab5");
+        if (slab5) {
+            slab5.style.opacity = "0.4";
+        }
+        const slab6 = document.getElementById("slab6");
+        if (slab6) {
+            slab6.style.opacity = "0.4";
+        }
+        const slab7 = document.getElementById("slab7");
+        if (slab7) {
+            slab7.style.opacity = "0.4";
+        }
+
+        const label = document.getElementById("label");
+        if (label) {
+            label.innerText = "Choose an image"
+            this.nm = "Choose an image";
         }
     }
 
+
     private get uploadInterface() {
         return (
             <div className="imgupload_cont">
                 <input type="file" accept="image/*" className="inputFile" id="input_image_file" onClick={this.inputLabel} ref={inputRef}></input>
-                <label id="label" htmlFor="input_image_file">Choose an image</label>
+                <label id="label" htmlFor="input_image_file">{this.nm}</label>
                 <div className="upload_label" onClick={this.onClick}>Upload Image</div>
                 {/* <div onClick={this.onClick} className="upload_button">Upload</div> */}
                 <img id="img_preview" src=""></img>
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index c4b2ffbc1..73dcabac8 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -955,6 +955,7 @@ export class MobileInterface extends React.Component {
     @observable private audioState: any;
     @observable private activeToolbar: boolean = false;
     @observable private sidebarActive: boolean = false;
+    @observable private imageUploadActive: boolean = false;
 
     public _activeDoc: Doc = this.mainDoc;
     public _homeDoc: Doc = this.mainDoc;
@@ -1723,14 +1724,14 @@ export class MobileInterface extends React.Component {
         );
     }
 
-    @observable private imageUploadActive: boolean = false;
-
     @action
     toggleUpload = () => this.imageUploadActive = !this.imageUploadActive
 
+
     @action
     closeUpload = () => {
         this.imageUploadActive = false;
+        console.log("1dude");
     }
 
     // toggleUpload = () => {
@@ -1754,7 +1755,7 @@ export class MobileInterface extends React.Component {
                 <div className="closeUpload" onClick={this.toggleUpload}>
                     <FontAwesomeIcon icon="window-close" size={"lg"} />
                 </div>
-                <Uploader Document={workspaces} />
+                <Uploader />
             </div>
         );
     }
-- 
cgit v1.2.3-70-g09d2


From 69fc5cff21c212a6eca9d125836844eea018fad0 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Wed, 10 Jun 2020 00:24:07 -0700
Subject: functioning image upload

---
 src/mobile/ImageUpload.tsx     | 35 +++++++++++++----------------------
 src/mobile/MobileInterface.tsx |  2 --
 2 files changed, 13 insertions(+), 24 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index d5e7cec1b..504e4ceae 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -43,7 +43,9 @@ export class Uploader extends React.Component {
             }
             await Docs.Prototypes.initialize();
             const imgPrev = document.getElementById("img_preview");
+            console.log("buddy");
             if (imgPrev) {
+                console.log("hi");
                 const files: FileList | null = inputRef.current!.files;
                 if (files && files.length !== 0) {
                     console.log(files[0]);
@@ -103,12 +105,12 @@ export class Uploader extends React.Component {
                             if (slab7) {
                                 slab7.style.opacity = "1";
                             }
-                            setTimeout(this.clearUpload, 3000);
+
                         }
 
                     });
                 }
-
+                setTimeout(this.clearUpload, 3000);
             }
         } catch (error) {
             this.error = JSON.stringify(error);
@@ -120,22 +122,10 @@ export class Uploader extends React.Component {
     inputLabel = async () => {
         const files: FileList | null = inputRef.current!.files;
         await files;
-        var inputs = document.querySelectorAll('.inputFile');
-        const label = document.getElementById("label");
-        if (files && label && files.length !== 0) {
-            label.innerText = await files[0].name;
-            setTimeout(this.updateName, 1000);
-        }
-    }
-
-    @action
-    updateName = () => {
-        const label = document.getElementById("label");
-        if (label) {
-            this.nm = label.innerText;
-
+        if (files && files.length !== 0) {
+            console.log(files);
+            this.nm = files[0].name;
         }
-        console.log("lol");
     }
 
     @action
@@ -168,19 +158,20 @@ export class Uploader extends React.Component {
         if (slab7) {
             slab7.style.opacity = "0.4";
         }
+        this.nm = "Choose an image";
 
-        const label = document.getElementById("label");
-        if (label) {
-            label.innerText = "Choose an image"
-            this.nm = "Choose an image";
+        if (inputRef.current) {
+            inputRef.current.value = "";
         }
+        console.log(inputRef.current!.files);
     }
 
 
+
     private get uploadInterface() {
         return (
             <div className="imgupload_cont">
-                <input type="file" accept="image/*" className="inputFile" id="input_image_file" onClick={this.inputLabel} ref={inputRef}></input>
+                <input type="file" accept="image/*" className="inputFile" id="input_image_file" ref={inputRef} onChange={this.inputLabel}></input>
                 <label id="label" htmlFor="input_image_file">{this.nm}</label>
                 <div className="upload_label" onClick={this.onClick}>Upload Image</div>
                 {/* <div onClick={this.onClick} className="upload_button">Upload</div> */}
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 73dcabac8..820a6885d 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1731,7 +1731,6 @@ export class MobileInterface extends React.Component {
     @action
     closeUpload = () => {
         this.imageUploadActive = false;
-        console.log("1dude");
     }
 
     // toggleUpload = () => {
@@ -1749,7 +1748,6 @@ export class MobileInterface extends React.Component {
 
         }
         console.log("upload");
-        const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
         return (
             <div>
                 <div className="closeUpload" onClick={this.toggleUpload}>
-- 
cgit v1.2.3-70-g09d2


From ecf1853d1f086292cb9dae678df6f06aec2db6f6 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Thu, 11 Jun 2020 00:54:21 +0800
Subject: mobile menu w/ switch + phone button on web

---
 src/client/util/CurrentUserUtils.ts | 128 +++++++++++++-----------------------
 src/mobile/MobileInterface.tsx      |  65 +++++++++++++++++-
 2 files changed, 110 insertions(+), 83 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 563f8cfe4..e9eddb103 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -319,6 +319,9 @@ export class CurrentUserUtils {
         if (doc.emptyWebpage === undefined) {
             doc.emptyWebpage = Docs.Create.WebDocument("", { title: "New Webpage", _nativeWidth: 850, _nativeHeight: 962, _width: 600, UseCors: true });
         }
+        if (doc.activeMobile === undefined) {
+            doc.activeMobile = CurrentUserUtils.setupMobileMenu();
+        }
         return [
             { title: "Drag a comparison box", label: "Comp", icon: "columns", ignoreClick: true, drag: 'Docs.Create.ComparisonDocument()' },
             { title: "Drag a collection", label: "Col", icon: "folder", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyCollection as Doc },
@@ -332,7 +335,7 @@ export class CurrentUserUtils {
             { title: "Drag a search box", label: "Query", icon: "search", ignoreClick: true, drag: 'Docs.Create.QueryDocument({ _width: 200, title: "an image of a cat" })' },
             { title: "Drag a scripting box", label: "Script", icon: "terminal", ignoreClick: true, drag: 'Docs.Create.ScriptingDocument(undefined, { _width: 200, _height: 250 title: "untitled script" })' },
             { title: "Drag an import folder", label: "Load", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' },
-            { title: "Drag a mobile view", label: "Phone", icon: "phone", ignoreClick: true, drag: 'Doc.UserDoc().activeMobile' },
+            { title: "Drag a mobile view", label: "Phone", icon: "mobile", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory,true)', dragFactory: doc.activeMobile as Doc },
             { title: "Drag an instance of the device collection", label: "Buxton", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.Buxton()' },
             // { title: "use pen", icon: "pen-nib", click: 'activatePen(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this,2, this.backgroundColor)', backgroundColor: "blue", ischecked: `sameDocs(this.activePen.inkPen,  this)`, activePen: doc },
             // { title: "use highlighter", icon: "highlighter", click: 'activateBrush(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this,20,this.backgroundColor)', backgroundColor: "yellow", ischecked: `sameDocs(this.activePen.inkPen, this)`, activePen: doc },
@@ -386,56 +389,54 @@ export class CurrentUserUtils {
         return doc.myItemCreators as Doc;
     }
 
-    // static setupMobileButtons(doc: Doc, buttons?: string[]) {
-    //     const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
-    //         { title: "record", icon: "microphone", ignoreClick: true, click: "FILL" },
-    //         { title: "use pen", icon: "pen-nib", click: 'activatePen(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this,2, this.backgroundColor)', backgroundColor: "blue", ischecked: `sameDocs(this.activePen.inkPen,  this)`, activePen: doc },
-    //         { title: "use highlighter", icon: "highlighter", click: 'activateBrush(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this,20,this.backgroundColor)', backgroundColor: "yellow", ischecked: `sameDocs(this.activePen.inkPen, this)`, activePen: doc },
-    //         { title: "use eraser", icon: "eraser", click: 'activateEraser(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this);', ischecked: `sameDocs(this.activePen.inkPen, this)`, backgroundColor: "pink", activePen: doc },
-    //         { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activePen.inkPen = this;', ischecked: `sameDocs(this.activePen.inkPen, this)`, backgroundColor: "white", activePen: doc },
-    //         // { title: "draw", icon: "pen-nib", click: 'switchMobileView(setupMobileInkingDoc, renderMobileInking, onSwitchMobileInking);', ischecked: `sameDocs(this.activePen.inkPen, this)`, backgroundColor: "red", activePen: doc },
-    //         { title: "upload", icon: "upload", click: 'switchMobileView(setupMobileUploadDoc, renderMobileUpload, onSwitchMobileUpload);', backgroundColor: "orange" },
-    //         // { title: "upload", icon: "upload", click: 'uploadImageMobile();', backgroundColor: "cyan" },
-    //     ];
-    //     return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => Docs.Create.FontIconDocument({
-    //         _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, dropAction: data.click ? "copy" : undefined, title: data.title, icon: data.icon, ignoreClick: data.ignoreClick,
-    //         onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
-    //         ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined, activePen: data.activePen,
-    //         backgroundColor: data.backgroundColor, removeDropProperties: new List<string>(["dropAction"]), dragFactory: data.dragFactory,
-    //     }));
+    // static setupActiveMobile(doc: Doc) {
+    //     if (doc.activeMobile === undefined) {
+    //         doc.activeMobile = CurrentUserUtils.setupMobileMenu();
+    //     }
     // }
 
-    static setupMobileButtons(doc?: Doc, buttons?: string[]) {
-        const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
-            { title: "library", icon: "bars", click: 'switchToLibrary()', backgroundColor: "lightgrey" },
-            { title: "record", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "lightgrey" },
-            { title: "upload", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "lightgrey" },
-            { title: "presentation", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "lightgrey" },
-            { title: "ink", icon: "pen-nib", backgroundColor: "lightgrey" },
-            { title: "settings", icon: "cog", click: 'openMobileSettings()', backgroundColor: "lightgrey" }
-        ];
-        return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => Docs.Create.FontIconDocument({
-            _nativeWidth: 150, _nativeHeight: 150, _width: 150, _height: 150,
-            dropAction: undefined,
-            title: data.title,
-            icon: data.icon,
-            ignoreClick: data.ignoreClick,
-            onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined,
-            onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
-            ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined,
-            activePen: data.activePen,
-            backgroundColor: data.backgroundColor, removeDropProperties: new List<string>(["dropAction"]),
-            dragFactory: data.dragFactory,
-        }));
-    }
-
     static setupMobileMenu() {
-        const menu = Cast(Docs.Create.StackingDocument(CurrentUserUtils.setupMobileButtons2(), {
-            _width: 980, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "home", _autoHeight: true, _yMargin: 80
+        const menu = Cast(Docs.Create.StackingDocument(CurrentUserUtils.setupMobileButtons(), {
+            _width: 980, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "home", _yMargin: 100
         }), Doc) as Doc;
         return menu;
     }
 
+    static setupMobileButtons(doc?: Doc, buttons?: string[]) {
+        const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
+            { title: "LIBRARY", icon: "bars", click: 'switchToLibrary()', backgroundColor: "#ffd6d6", info: "Navigate and access all of your documents within their respective collections" },
+            { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your mobile to record audio and access it on Dash Web." },
+            { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "#ff9e9e", info: "Upload an image from your mobile device so it can be accessed on Dash Web" },
+            { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "#ff8080", info: "Use your phone as a remote for you presentation." },
+            { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "#ff5e5e", info: "Change your password, log out, or manage your account security" }
+        ];
+        return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => this.mobileButton({ title: data.title, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined, _backgroundColor: data.backgroundColor }, [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)" }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])]));
+    }
+
+    static mobileButton = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.MulticolumnDocument(docs, {
+        ...opts,
+        dropAction: undefined, removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 900, _nativeHeight: 250, _width: 900, _height: 250, _yMargin: 15,
+        borderRounding: "5px", boxShadow: "0 0", _chromeStatus: "disabled",
+    })) as any as Doc
+
+    static mobileTextContainer = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.MultirowDocument(docs, {
+        ...opts,
+        dropAction: undefined, removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 450, _nativeHeight: 250, _width: 450, _height: 250, _yMargin: 25,
+        backgroundColor: "rgba(0,0,0,0)", borderRounding: "0", boxShadow: "0 0", _chromeStatus: "disabled", ignoreClick: true
+    })) as any as Doc
+
+
+    static mobileButtonText = (opts: DocumentOptions, buttonTitle: string) => new PrefetchProxy(Docs.Create.TextDocument(buttonTitle, {
+        ...opts,
+        dropAction: undefined, title: buttonTitle, _fontSize: 37, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)"
+    })) as any as Doc
+
+    static mobileButtonInfo = (opts: DocumentOptions, buttonInfo: string) => new PrefetchProxy(Docs.Create.TextDocument(buttonInfo, {
+        ...opts,
+        dropAction: undefined, title: "info", _fontSize: 25, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)", _dimMagnitude: 2,
+    })) as any as Doc
+
+
     static setupThumbButtons(doc: Doc) {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, pointerDown?: string, pointerUp?: string, ischecked?: string, clipboard?: Doc, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
             { title: "use pen", icon: "pen-nib", pointerUp: "resetPen()", pointerDown: 'setPen(2, this.backgroundColor)', backgroundColor: "blue", ischecked: `sameDocs(this.activePen.inkPen,  this)`, activePen: doc },
@@ -643,42 +644,6 @@ export class CurrentUserUtils {
         dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100
     })) as any as Doc
 
-    static setupMobileButtons2(doc?: Doc, buttons?: string[]) {
-        const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
-            { title: "LIBRARY", icon: "bars", click: 'switchToLibrary()', backgroundColor: "#ffd6d6", info: "Navigate and access all of your documents within their respective collections" },
-            { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your mobile to record audio and access it on Dash Web." },
-            { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "#ff9e9e", info: "Upload an image from your mobile device so it can be accessed on Dash Web" },
-            { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "#ff8080", info: "Use your phone as a remote for you presentation." },
-            // { title: "INK", icon: "pen-nib", backgroundColor: "lightgrey", info: "Doodle and draw with ink on your mobile and have it directly available on Dash Web" },
-            { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "#ff5e5e", info: "Change your password, log out, or manage your account security" }
-        ];
-        return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => this.mobileButton({ title: data.title, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined, _backgroundColor: data.backgroundColor }, [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)" }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])]));
-    }
-
-    static mobileButton = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.MulticolumnDocument(docs, {
-        ...opts,
-        dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 900, _nativeHeight: 250, _width: 900, _height: 250, _yMargin: 15,
-        borderRounding: "5px", boxShadow: "0 0", _chromeStatus: "disabled",
-    })) as any as Doc
-
-    static mobileTextContainer = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.MultirowDocument(docs, {
-        ...opts,
-        dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 450, _nativeHeight: 250, _width: 450, _height: 250, _yMargin: 25,
-        backgroundColor: "rgba(0,0,0,0)", borderRounding: "0", boxShadow: "0 0", _chromeStatus: "disabled",
-    })) as any as Doc
-
-
-    static mobileButtonText = (opts: DocumentOptions, buttonTitle: string) => new PrefetchProxy(Docs.Create.TextDocument(buttonTitle, {
-        ...opts,
-        title: buttonTitle, _fontSize: 37, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)"
-    })) as any as Doc
-
-    static mobileButtonInfo = (opts: DocumentOptions, buttonInfo: string) => new PrefetchProxy(Docs.Create.TextDocument(buttonInfo, {
-        ...opts,
-        title: "info", _fontSize: 25, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)", _dimMagnitude: 2,
-    })) as any as Doc
-
-
     /// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window
     static setupDockedButtons(doc: Doc) {
         if (doc["dockedBtn-pen"] === undefined) {
@@ -716,7 +681,7 @@ export class CurrentUserUtils {
 
     static setupRightSidebar(doc: Doc) {
         if (doc.rightSidebarCollection === undefined) {
-            doc.rightSidebarCollection = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "Right Sidebar" }));
+            doc.rightSidebarCollection = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "Mobile Uploads" }));
         }
     }
 
@@ -771,6 +736,7 @@ export class CurrentUserUtils {
         this.setupDefaultIconTemplates(doc);  // creates a set of icon templates triggered by the document deoration icon
         this.setupDocTemplates(doc); // sets up the template menu of templates
         this.setupRightSidebar(doc);  // sets up the right sidebar collection for mobile upload documents and sharing
+        // this.setupActiveMobile(doc);
         this.setupOverlays(doc);  // documents in overlay layer
         this.setupDockedButtons(doc);  // the bottom bar of font icons
         this.setupDefaultPresentation(doc); // presentation that's initially triggered
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 820a6885d..a16139f1c 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1,7 +1,7 @@
 import * as React from "react";
 import { library } from '@fortawesome/fontawesome-svg-core';
 import {
-    faTasks, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+    faTasks, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -39,7 +39,7 @@ import { SelectionManager } from "../client/util/SelectionManager";
 import { SketchPicker } from "react-color";
 import { ScriptField } from "../fields/ScriptField";
 
-library.add(faTasks, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+library.add(faTasks, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -950,12 +950,14 @@ export class MobileInterface extends React.Component {
     @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
     // @computed private get activeContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
     // Sets up new mobile menu only if activeMobile already exists
+    // @observable private mainDoc: any = this.userDoc.activeMobile === undefined ? CurrentUserUtils.setupMobileMenu() : this.userDoc.activeMobile;
     @observable private mainDoc: any = CurrentUserUtils.setupMobileMenu();
     @observable private renderView?: () => JSX.Element;
     @observable private audioState: any;
     @observable private activeToolbar: boolean = false;
     @observable private sidebarActive: boolean = false;
     @observable private imageUploadActive: boolean = false;
+    @observable private menuListView: boolean = false;
 
     public _activeDoc: Doc = this.mainDoc;
     public _homeDoc: Doc = this.mainDoc;
@@ -987,6 +989,7 @@ export class MobileInterface extends React.Component {
         if (this.userDoc && !this.mainContainer) {
             this.userDoc.activeMobile = this._homeDoc;
         }
+        this._homeDoc._viewType === "stacking" ? this.menuListView = true : this.menuListView = false;
         InkingControl.Instance.switchTool(InkTool.None);
         MobileInterface.Instance.drawingInk = false;
         InkingControl.Instance.updateSelectedColor("#FF0000");
@@ -1656,6 +1659,63 @@ export class MobileInterface extends React.Component {
         }
     }
 
+    switchMenuView = () => {
+        if (this._activeDoc.title === this._homeDoc.title) {
+            return (
+                <div className="homeSwitch">
+                    <div className={`list ${!this.menuListView ? "active" : ""}`} onClick={this.changeToIconView}>
+                        <FontAwesomeIcon size="sm" icon="th-large" />
+                    </div>
+                    <div className={`list ${this.menuListView ? "active" : ""}`} onClick={this.changeToListView}>
+                        <FontAwesomeIcon size="sm" icon="bars" />
+                    </div>
+                </div>
+            );
+        }
+    }
+
+    @action
+    changeToIconView = () => {
+        if (this._homeDoc._viewType = "stacking") {
+            this.menuListView = false;
+            this._homeDoc._viewType = "masonry";
+            this._homeDoc.columnWidth = 300;
+            const menuButtons = DocListCast(this._homeDoc.data);
+            console.log('hello');
+            menuButtons.map((doc: Doc, index: any) => {
+                console.log(index);
+                const buttonData = DocListCast(doc.data);
+                buttonData[1]._nativeWidth = 0.1;
+                buttonData[1]._width = 0.1;
+                buttonData[1]._dimMagnitude = 0;
+                buttonData[1]._opacity = 0;
+                console.log(buttonData);
+                console.log(doc._nativeWidth);
+                doc._nativeWidth = 400;
+                console.log(doc._nativeWidth);
+            });
+        }
+    }
+
+    @action
+    changeToListView = () => {
+        if (this._homeDoc._viewType = "masonry") {
+            this._homeDoc._viewType = "stacking";
+            this.menuListView = true;
+            const menuButtons = DocListCast(this._homeDoc.data);
+            console.log('hello');
+            menuButtons.map((doc: Doc, index: any) => {
+                const buttonData = DocListCast(doc.data);
+                buttonData[1]._nativeWidth = 450;
+                buttonData[1]._dimMagnitude = 2;
+                buttonData[1]._opacity = 1;
+                console.log(doc._nativeWidth);
+                doc._nativeWidth = 900;
+                console.log(doc._nativeWidth);
+            });
+        }
+    }
+
     setupDefaultPresentation = () => {
         if (this._activeDoc.title !== "Presentation") {
             this._parents.push(this._activeDoc);
@@ -1694,6 +1754,7 @@ export class MobileInterface extends React.Component {
                 <div className={`image-upload ${this.imageUploadActive ? "active" : ""}`}>
                     {this.uploadImage()}
                 </div>
+                {this.switchMenuView()}
                 <div className="docButtonContainer">
                     {this.pinToPresentation()}
                     {this.downloadDocument()}
-- 
cgit v1.2.3-70-g09d2


From b13adb6e2620d80c019c7c8f6d344ba5ca2fcec2 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Wed, 10 Jun 2020 22:43:35 -0700
Subject: finished up image upload and fixed bugs with pathbar and clicking
 workspaces twice

---
 src/client/views/GestureOverlay.tsx | 12 ++++++------
 src/mobile/ImageUpload.scss         | 12 ++++++++++++
 src/mobile/ImageUpload.tsx          | 11 +++++++++--
 src/mobile/MobileInterface.tsx      | 28 ++++++++++++++++++++--------
 src/mobile/MobileMenu.scss          |  1 +
 5 files changed, 48 insertions(+), 16 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index a11c97b09..8cf2cdf55 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -115,12 +115,12 @@ export default class GestureOverlay extends Touchable {
     onReactTouchStart = (te: React.TouchEvent) => {
         document.removeEventListener("touchmove", this.onReactHoldTouchMove);
         document.removeEventListener("touchend", this.onReactHoldTouchEnd);
-        // if (RadialMenu.Instance._display === true) {
-        //     te.preventDefault();
-        //     te.stopPropagation();
-        //     RadialMenu.Instance.closeMenu();
-        //     return;
-        // }
+        if (RadialMenu.Instance?._display === true) {
+            te.preventDefault();
+            te.stopPropagation();
+            RadialMenu.Instance.closeMenu();
+            return;
+        }
 
         // this chunk adds new touch targets to a map of pointer events; this helps us keep track of individual fingers
         // so that we can know, for example, if two fingers are pinching out or in.
diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss
index 6c782d4d8..d5ab31469 100644
--- a/src/mobile/ImageUpload.scss
+++ b/src/mobile/ImageUpload.scss
@@ -5,6 +5,7 @@
     justify-content: center;
     flex-direction: column;
     align-items: center;
+    max-width: 400px;
 
     .upload_label {
         font-size: 3em;
@@ -17,6 +18,13 @@
         border-radius: 10px;
     }
 
+    .file {
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        direction: ltr;
+    }
+
     .upload_label:hover {
         background-color: darkred;
     }
@@ -55,6 +63,10 @@
         background-color: darkred;
     }
 
+    .status {
+        font-size: 2em;
+    }
+
 }
 
 .backgroundUpload {
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 504e4ceae..8f050aedd 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -32,6 +32,7 @@ export class Uploader extends React.Component {
     @observable error: string = "";
     @observable status: string = "";
     @observable nm: string = "Choose an image";
+    @observable process: string = "";
 
     onClick = async () => {
         console.log("uploader click");
@@ -48,6 +49,7 @@ export class Uploader extends React.Component {
                 console.log("hi");
                 const files: FileList | null = inputRef.current!.files;
                 if (files && files.length !== 0) {
+                    this.process = "Uploading Image"
                     console.log(files[0]);
                     const name = files[0].name;
                     const res = await Networking.UploadFilesToServer(files[0]);
@@ -100,15 +102,18 @@ export class Uploader extends React.Component {
                                 pending.data = new List([doc]);
                             }
                             this.status = "finished";
+
                             console.log("hi");
                             const slab7 = document.getElementById("slab7");
                             if (slab7) {
                                 slab7.style.opacity = "1";
                             }
-
+                            this.process = "Image Uploaded";
                         }
 
                     });
+                } else {
+                    this.process = "No file selected";
                 }
                 setTimeout(this.clearUpload, 3000);
             }
@@ -163,6 +168,7 @@ export class Uploader extends React.Component {
         if (inputRef.current) {
             inputRef.current.value = "";
         }
+        this.process = "";
         console.log(inputRef.current!.files);
     }
 
@@ -172,7 +178,7 @@ export class Uploader extends React.Component {
         return (
             <div className="imgupload_cont">
                 <input type="file" accept="image/*" className="inputFile" id="input_image_file" ref={inputRef} onChange={this.inputLabel}></input>
-                <label id="label" htmlFor="input_image_file">{this.nm}</label>
+                <label className="file" id="label" htmlFor="input_image_file">{this.nm}</label>
                 <div className="upload_label" onClick={this.onClick}>Upload Image</div>
                 {/* <div onClick={this.onClick} className="upload_button">Upload</div> */}
                 <img id="img_preview" src=""></img>
@@ -187,6 +193,7 @@ export class Uploader extends React.Component {
                     <div className="loadingSlab" id="slab6" />
                     <div className="loadingSlab" id="slab7" />
                 </div>
+                <p className="status">{this.process}</p>
             </div>
         );
     }
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 820a6885d..0b5855e1f 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1115,7 +1115,7 @@ export class MobileInterface extends React.Component {
      */
     returnMain = () => {
         console.log("home");
-        this._parents = [];
+        this._parents = [this._homeDoc];
         // this.toggleSidebar();
         this._activeDoc = this._library;
         this.switchCurrentView((userDoc: Doc) => this._library);
@@ -1201,7 +1201,7 @@ export class MobileInterface extends React.Component {
      * Handles the click functionality in the library panel
      * @param doc: doc for which the method is called
      */
-    handleClick(doc: Doc) {
+    handleClick = async (doc: Doc) => {
         let children = DocListCast(doc.data);
         if (doc.type !== "collection") {
             this._parents.push(this._activeDoc);
@@ -1244,12 +1244,24 @@ export class MobileInterface extends React.Component {
         let items = docArray.map((doc: Doc, index: any) => {
             if (index === 0) {
                 return (
-                    <div className="pathbarItem">
-                        <div className="pathbarText"
-                            key={index}
-                            onClick={() => this.handlePathClick(doc, index)}>{doc.title}
-                        </div>
-                    </div>);
+                    <>
+                        {this._homeMenu ?
+                            <div className="pathbarItem">
+                                <div className="pathbarText"
+                                    style={{ backgroundColor: "rgb(119, 37, 37)" }}
+                                    key={index}
+                                    onClick={() => this.handlePathClick(doc, index)}>{doc.title}
+                                </div>
+                            </div>
+                            :
+                            <div className="pathbarItem">
+                                <div className="pathbarText"
+                                    key={index}
+                                    onClick={() => this.handlePathClick(doc, index)}>{doc.title}
+                                </div>
+                            </div>}
+                    </>);
+
             } else if (doc === this._activeDoc) {
                 return (
                     <div className="pathbarItem">
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 669b55601..b98b51f31 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -309,6 +309,7 @@ body {
     text-align: center;
     user-select: none;
     z-index: 99;
+    pointer-events: none;
 }
 
 .toolbar {
-- 
cgit v1.2.3-70-g09d2


From 2f1714f0175f8fc766ba030848f5469e429307f4 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Fri, 12 Jun 2020 11:17:40 +0800
Subject: menu bug fix

---
 src/client/views/GestureOverlay.tsx  |    2 +-
 src/client/views/nodes/AudioBox.scss |  206 +++++--
 src/client/views/nodes/ColorBox.tsx  |    4 +-
 src/mobile/MobileInterface.tsx       | 1012 ++--------------------------------
 src/mobile/MobileMenu.scss           |    5 +-
 5 files changed, 192 insertions(+), 1037 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 1879f3096..3bb80abd0 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -107,7 +107,7 @@ export default class GestureOverlay extends Touchable {
     onReactTouchStart = (te: React.TouchEvent) => {
         document.removeEventListener("touchmove", this.onReactHoldTouchMove);
         document.removeEventListener("touchend", this.onReactHoldTouchEnd);
-        if (RadialMenu.Instance._display === true) {
+        if (RadialMenu.Instance?._display === true) {
             te.preventDefault();
             te.stopPropagation();
             RadialMenu.Instance.closeMenu();
diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 53b54d7e4..61ce4bd13 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -1,141 +1,169 @@
-.audiobox-container, .audiobox-container-interactive {
+.audiobox-container,
+.audiobox-container-interactive {
     width: 100%;
     height: 100%;
     position: inherit;
-    display:flex;
+    display: flex;
     pointer-events: all;
-    cursor:default;
+    cursor: default;
+
     .audiobox-buttons {
         display: flex;
         width: 100%;
         align-items: center;
     }
+
     .audiobox-handle {
-        width:20px;
-        height:100%;
-        display:inline-block;
+        width: 20px;
+        height: 100%;
+        display: inline-block;
     }
-    .audiobox-control, .audiobox-control-interactive {
-        top:0;
+
+    .audiobox-control,
+    .audiobox-control-interactive {
+        top: 0;
         max-height: 32px;
         width: 100%;
-        display:inline-block;
+        display: inline-block;
         pointer-events: none;
     }
+
     .audiobox-control-interactive {
         pointer-events: all;
     }
+
     .audiobox-record {
         pointer-events: all;
-        width:100%;
-        height:100%;
+        width: 100%;
+        height: 100%;
         position: relative;
         pointer-events: none;
     }
+
     .audiobox-record-interactive {
         pointer-events: all;
-        width:100%;
-        height:100%;
+        width: 100%;
+        height: 100%;
         position: relative;
     }
+
     .audiobox-controls {
-        width:100%;
-        height:100%;
+        width: 100%;
+        height: 100%;
         position: relative;
         display: flex;
         padding-left: 2px;
+
         .audiobox-player {
-            margin-top:auto;
-            margin-bottom:auto;
-            width:100%;
+            margin-top: auto;
+            margin-bottom: auto;
+            width: 100%;
             height: 80%;
             position: relative;
             padding-right: 5px;
             display: flex;
-            .audiobox-playhead, .audiobox-dictation {
+
+            .audiobox-playhead,
+            .audiobox-dictation {
                 position: relative;
                 margin-top: auto;
                 margin-bottom: auto;
                 width: 25px;
                 padding: 2px;
             }
+
             .audiobox-dictation {
                 align-items: center;
                 display: inherit;
                 background: dimgray;
             }
+
             .audiobox-timeline {
-                position:relative;
-                height:100%;
-                width:100%;
+                position: relative;
+                height: 100%;
+                width: 100%;
                 background: white;
                 border: gray solid 1px;
                 border-radius: 3px;
+
                 .audiobox-current {
                     width: 1px;
-                    height:100%;
+                    height: 100%;
                     background-color: red;
                     position: absolute;
                 }
-                .audiobox-linker, .audiobox-linker-mini {
-                    position:absolute;
-                    width:15px;
-                    min-height:10px;
-                    height:15px;
-                    margin-left:-2.55px;
-                    background:gray;
+
+                .audiobox-linker,
+                .audiobox-linker-mini {
+                    position: absolute;
+                    width: 15px;
+                    min-height: 10px;
+                    height: 15px;
+                    margin-left: -2.55px;
+                    background: gray;
                     border-radius: 100%;
-                    opacity:0.9;
+                    opacity: 0.9;
                     background-color: transparent;
                     box-shadow: black 2px 2px 1px;
+
                     .linkAnchorBox-cont {
                         position: relative !important;
-                        height: 100%  !important;
+                        height: 100% !important;
                         width: 100% !important;
-                        left:unset !important;
-                        top:unset !important;
+                        left: unset !important;
+                        top: unset !important;
                     }
                 }
+
                 .audiobox-linker-mini {
-                    width:8px;
-                    min-height:8px;
-                    height:8px;
+                    width: 8px;
+                    min-height: 8px;
+                    height: 8px;
                     box-shadow: black 1px 1px 1px;
                     margin-left: -1;
                     margin-top: -2;
+
                     .linkAnchorBox-cont {
                         position: relative !important;
-                        height: 100%  !important;
+                        height: 100% !important;
                         width: 100% !important;
-                        left:unset !important;
-                        top:unset !important;
+                        left: unset !important;
+                        top: unset !important;
                     }
                 }
-                .audiobox-linker:hover, .audiobox-linker-mini:hover {
-                    opacity:1;
+
+                .audiobox-linker:hover,
+                .audiobox-linker-mini:hover {
+                    opacity: 1;
                 }
-                .audiobox-marker-container, .audiobox-marker-minicontainer {
-                    position:absolute;
-                    width:10px;
-                    height:90%;
-                    top:2.5%;
-                    background:gray;
+
+                .audiobox-marker-container,
+                .audiobox-marker-minicontainer {
+                    position: absolute;
+                    width: 10px;
+                    height: 90%;
+                    top: 2.5%;
+                    background: gray;
                     border-radius: 5px;
                     box-shadow: black 2px 2px 1px;
+
                     .audiobox-marker {
-                        position:relative;
+                        position: relative;
                         height: calc(100% - 15px);
                         margin-top: 15px;
                     }
+
                     .audio-marker:hover {
                         border: orange 2px solid;
                     }
                 }
+
                 .audiobox-marker-minicontainer {
-                    width:5px;
+                    width: 5px;
                     border-radius: 1px;
+
                     .audiobox-marker {
-                        position:relative;
+                        position: relative;
                         height: calc(100% - 8px);
                         margin-top: 8px;
                     }
@@ -143,4 +171,80 @@
             }
         }
     }
+}
+
+
+@media only screen and (max-width: 1000px) {
+
+    .audiobox-container,
+    .audiobox-container-interactive {
+        width: max-content;
+        /* align-self: center; */
+        left: 50%;
+        top: 40%;
+        transform: translate(-50%, 0);
+        height: 100px;
+        position: absolute;
+        display: flex;
+        pointer-events: all;
+        /* cursor: default; */
+    }
+
+    .audiobox-container .audiobox-buttons,
+    .audiobox-container-interactive .audiobox-buttons {
+        display: flex;
+        width: 500px;
+        /* left: 50%; */
+        /* transform: translate(-50%,0); */
+        align-items: center;
+    }
+
+    .audiobox-dictation {
+        width: 100;
+        height: 100;
+        font-size: 50;
+        /* background-color: white; */
+    }
+
+    .audiobox-container .audiobox-record-interactive,
+    .audiobox-container-interactive .audiobox-record-interactive {
+        width: 95%;
+        user-select: none;
+        font-size: 50px;
+        font-weight: 100;
+        left: 5%;
+        height: 100%;
+        position: relative;
+    }
+
+    .audiobox-container .audiobox-controls .audiobox-player .audiobox-playhead,
+    .audiobox-container .audiobox-controls .audiobox-player .audiobox-dictation,
+    .audiobox-container-interactive .audiobox-controls .audiobox-player .audiobox-playhead,
+    .audiobox-container-interactive .audiobox-controls .audiobox-player .audiobox-dictation {
+        position: relative;
+        align-self: center;
+        width: 50px;
+        height: max-content;
+        padding: 0;
+    }
+
+    .audiobox-container .audiobox-controls .audiobox-player,
+    .audiobox-container-interactive .audiobox-controls .audiobox-player {
+        margin-top: auto;
+        margin-bottom: auto;
+        width: 100%;
+        height: 100%;
+        position: relative;
+        padding-right: 5px;
+        display: flex;
+    }
+
+    .audiobox-container .audiobox-controls,
+    .audiobox-container-interactive .audiobox-controls {
+        width: 500px;
+        height: 100%;
+        position: relative;
+        display: flex;
+        padding-left: 2px;
+    }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx
index 0d6258cf3..f49b1f763 100644
--- a/src/client/views/nodes/ColorBox.tsx
+++ b/src/client/views/nodes/ColorBox.tsx
@@ -60,9 +60,9 @@ export class ColorBox extends ViewBoxBaseComponent<FieldViewProps, ColorDocument
                     StrCast(selDoc?._backgroundColor, StrCast(selDoc?.backgroundColor, "black")))} />
             <div style={{ display: "grid", gridTemplateColumns: "20% 80%", paddingTop: "10px" }}>
                 <div> {ActiveInkWidth() ?? 2}</div>
-                <input type="range" value={ActiveInkWidth() ?? 2} defaultValue={2} min={1} max={100} onChange={(e: React.ChangeEvent<HTMLInputElement>) => SetActiveInkWidth(e.target.value)} />
+                <input type="range" value={ActiveInkWidth() ?? 2} min={1} max={100} onChange={(e: React.ChangeEvent<HTMLInputElement>) => SetActiveInkWidth(e.target.value)} />
                 <div> {ActiveInkBezierApprox() ?? 2}</div>
-                <input type="range" value={ActiveInkBezierApprox() ?? 2} defaultValue={2} min={0} max={300} onChange={(e: React.ChangeEvent<HTMLInputElement>) => SetActiveBezierApprox(e.target.value)} />
+                <input type="range" value={ActiveInkBezierApprox() ?? 2} min={0} max={300} onChange={(e: React.ChangeEvent<HTMLInputElement>) => SetActiveBezierApprox(e.target.value)} />
                 <br />
                 <br />
             </div>
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index d9399d549..687422cf2 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -46,903 +46,6 @@ library.add(faTasks, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faP
     faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote,
     faThumbtack, faTree, faTv, faUndoAlt, faBook, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft, faBars, faTh, faChevronLeft);
 
-// @observer
-// export class MobileInterface extends React.Component {
-//     @observable static Instance: MobileInterface;
-//     @computed private get userDoc() { return Doc.UserDoc(); }
-//     @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
-//     @computed private get activeContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
-//     // @observable private currentView: "main" | "ink" | "upload" = "main";
-//     @observable private mainDoc: any = CurrentUserUtils.setupMobileDoc(this.userDoc);
-//     @observable private renderView?: () => JSX.Element;
-//     @observable private sidebarActive = true;
-
-//     public _activeDoc: Doc = this.mainDoc;
-//     public _homeDoc: Doc = this.mainDoc;
-//     private _homeMenu: boolean = true;
-
-//     // private inkDoc?: Doc;
-//     public drawingInk: boolean = false;
-//     private _ink: boolean = false;
-
-//     // private _uploadDoc: Doc = this.userDoc;
-//     private _child: Doc | null = null;
-//     private _parents: Array<Doc> = [];
-//     private _library: Doc = CurrentUserUtils.setupLibrary(this.userDoc);
-//     private _open: boolean = false;
-
-//     constructor(props: Readonly<{}>) {
-//         super(props);
-//         MobileInterface.Instance = this;
-//     }
-
-//     @action
-//     componentDidMount = () => {
-//         library.add(...[faPenNib, faHighlighter, faEraser, faMousePointer, faThumbtack]);
-
-//         if (this.userDoc && !this.mainContainer) {
-//             this.userDoc.activeMobile = this._homeDoc;
-//         }
-
-//         InkingControl.Instance.switchTool(InkTool.None);
-//         MobileInterface.Instance.drawingInk = false;
-//         InkingControl.Instance.updateSelectedColor("#FF0000");
-//         InkingControl.Instance.switchWidth("2");
-//         this.switchCurrentView((userDoc: Doc) => this._homeDoc);
-//     }
-
-//     @action
-//     switchCurrentView = (doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) => {
-//         if (!this.userDoc) return;
-
-//         this.userDoc.activeMobile = doc(this.userDoc);
-//         onSwitch && onSwitch();
-
-//         this.renderView = renderView;
-//     }
-
-//     onSwitchInking = () => {
-//         const button = document.getElementById("inkButton") as HTMLElement;
-//         const color = InkingControl.Instance.selectedColor;
-//         button.style.backgroundColor = this._ink ? "white" : color;
-//         button.style.color = this._ink ? "black" : "white";
-
-//         if (!this._ink) {
-//             console.log("INK IS ACTIVE");
-//             InkingControl.Instance.switchTool(InkTool.Pen);
-//             MobileInterface.Instance.drawingInk = true;
-//             this._ink = true;
-//         } else {
-//             console.log("INK IS INACTIVE");
-//             InkingControl.Instance.switchTool(InkTool.None);
-//             MobileInterface.Instance.drawingInk = false;
-//             this._ink = false;
-//         }
-//     }
-
-//     onSwitchUpload = async () => {
-//         let width = 300;
-//         let height = 300;
-//         const res = await rp.get(Utils.prepend("/getUserDocumentId"));
-
-//         // get width and height of the collection doc
-//         if (this.mainContainer) {
-//             const data = Cast(this.mainContainer.data, listSpec(Doc));
-//             if (data) {
-//                 const collectionDoc = await data[1]; // this should be the collection doc since the positions should be locked
-//                 const docView = DocumentManager.Instance.getDocumentView(collectionDoc);
-//                 if (docView) {
-//                     width = docView.nativeWidth ? docView.nativeWidth : 300;
-//                     height = docView.nativeHeight ? docView.nativeHeight : 300;
-//                 }
-//             }
-//         }
-//         DocServer.Mobile.dispatchOverlayTrigger({
-//             enableOverlay: true,
-//             width: width,
-//             height: height,
-//             text: "Documents uploaded from mobile will show here",
-//         });
-//     }
-
-//     back = () => {
-//         let header = document.getElementById("header") as HTMLElement;
-//         let doc = Cast(this._parents.pop(), Doc) as Doc;
-//         if (doc === Cast(this._library, Doc) as Doc) {
-//             this._child = null;
-//             this.userDoc.activeMobile = this._library;
-//         } else if (doc === Cast(this._homeDoc, Doc) as Doc) {
-//             this._homeMenu = true;
-//             this._parents = [];
-//             this._activeDoc = this._homeDoc;
-//             this._child = null;
-//             this.switchCurrentView((userDoc: Doc) => this._homeDoc);
-//         } else {
-//             if (doc) {
-//                 this._child = doc;
-//                 this.switchCurrentView((userDoc: Doc) => doc);
-//                 this._homeMenu = false;
-//                 header.textContent = String(doc.title);
-//             }
-//         }
-//         if (doc) {
-//             this._activeDoc = doc;
-//         }
-//         this._ink = false;
-//     }
-
-//     returnHome = () => {
-//         if (this._homeMenu === false || this._open === true) {
-//             this._homeMenu = true;
-//             this._parents = [];
-//             this._activeDoc = this._homeDoc;
-//             this._child = null;
-//             this.switchCurrentView((userDoc: Doc) => this._homeDoc);
-//         }
-//         if (this._open) {
-//             this.toggleSidebar();
-//         }
-//     }
-
-//     returnMain = () => {
-//         this._parents = [];
-//         // this.toggleSidebar();
-//         this._activeDoc = this._library;
-//         this.switchCurrentView((userDoc: Doc) => this._library);
-//         this._homeMenu = false;
-//         this._child = null;
-//     }
-
-//     displayWorkspaces = () => {
-//         if (this.mainContainer) {
-//             const backgroundColor = () => "white";
-//             if (this._activeDoc.title === "mobile audio") {
-//                 return (
-//                     <div style={{ position: "relative", top: '600px', height: `calc(50% - 450px)`, width: "80%", overflow: "hidden", left: "10%", cursor: "pointer" }}>
-//                         <DocumentView
-//                             Document={this.mainContainer}
-//                             DataDoc={undefined}
-//                             LibraryPath={emptyPath}
-//                             addDocument={returnFalse}
-//                             addDocTab={returnFalse}
-//                             pinToPres={emptyFunction}
-//                             rootSelected={returnFalse}
-//                             removeDocument={undefined}
-//                             onClick={undefined}
-//                             ScreenToLocalTransform={Transform.Identity}
-//                             ContentScaling={returnOne}
-//                             NativeHeight={returnZero}
-//                             NativeWidth={returnZero}
-//                             PanelWidth={() => window.screen.width}
-//                             PanelHeight={() => window.screen.height}
-//                             renderDepth={0}
-//                             focus={emptyFunction}
-//                             backgroundColor={backgroundColor}
-//                             parentActive={returnTrue}
-//                             whenActiveChanged={emptyFunction}
-//                             bringToFront={emptyFunction}
-//                             ContainingCollectionView={undefined}
-//                             ContainingCollectionDoc={undefined}
-//                         />
-//                     </div>
-//                 );
-//             } else {
-//                 return (
-//                     <div style={{ position: "relative", top: '200px', height: `calc(100% - 200px)`, width: "100%", overflow: "hidden", left: "0%" }}>
-//                         <DocumentView
-//                             Document={this.mainContainer}
-//                             DataDoc={undefined}
-//                             LibraryPath={emptyPath}
-//                             addDocument={returnFalse}
-//                             addDocTab={returnFalse}
-//                             pinToPres={emptyFunction}
-//                             rootSelected={returnFalse}
-//                             removeDocument={undefined}
-//                             onClick={undefined}
-//                             ScreenToLocalTransform={Transform.Identity}
-//                             ContentScaling={returnOne}
-//                             PanelWidth={this.returnWidth}
-//                             PanelHeight={this.returnHeight}
-//                             NativeHeight={returnZero}
-//                             NativeWidth={returnZero}
-//                             renderDepth={0}
-//                             focus={emptyFunction}
-//                             backgroundColor={backgroundColor}
-//                             parentActive={returnTrue}
-//                             whenActiveChanged={emptyFunction}
-//                             bringToFront={emptyFunction}
-//                             ContainingCollectionView={undefined}
-//                             ContainingCollectionDoc={undefined}
-//                         // mobile={true}
-//                         />
-//                     </div>
-//                 );
-//             }
-//         }
-//     }
-
-//     returnWidth = () => 2000;
-//     returnHeight = () => 2000;
-
-//     handleClick(doc: Doc) {
-//         let children = DocListCast(doc.data);
-//         if (doc.type !== "collection") {
-//             this._parents.push(this._activeDoc);
-//             this._activeDoc = doc;
-//             this.switchCurrentView((userDoc: Doc) => doc);
-//             this._homeMenu = false;
-//             this.toggleSidebar();
-//         } else if (doc.type === "collection" && children.length === 0) {
-//             console.log("This collection has no children");
-//         } else {
-//             this._parents.push(this._activeDoc);
-//             this._activeDoc = doc;
-//             this.switchCurrentView((userDoc: Doc) => doc);
-//             this._homeMenu = false;
-//             this._child = doc;
-//         }
-
-//         // let sidebar = document.getElementById("sidebar") as HTMLElement;
-//         // sidebar.classList.toggle('active');
-//     }
-
-//     createPathname = () => {
-//         let docArray = [];
-//         this._parents.map((doc: Doc, index: any) => {
-//             // if (doc === this.mainDoc) {
-//             //     pathname = pathname;
-//             // } else if (doc.type === "audio" || doc.type === "presentation") {
-//             //     pathname = pathname;
-//             // } else if (doc.type !== "collection") {
-//             //     pathname = pathname;
-//             // } else {
-//             //     pathname = pathname + " > " + doc.title;
-//             //     titleArray.push(doc.title);
-//             //     docArray.push(doc);
-//             // }
-//             docArray.push(doc);
-//         });
-//         docArray.push(this._activeDoc);
-//         // if (this._activeDoc.title === "mobile audio") {
-//         //     pathname = this._activeDoc.title;
-//         // } else if (this._activeDoc.title === "Presentation") {
-//         //     pathname = this._activeDoc.title;
-//         // } else if (this._activeDoc === this.mainDoc) {
-//         //     pathname = pathname;
-//         // } else {
-//         //     pathname = pathname + " > " + this._activeDoc.title;
-//         //     docArray.push(this._activeDoc);
-//         //     titleArray.push(this._activeDoc.title);
-//         // }
-
-//         return docArray;
-//     }
-
-//     renderPathbar = () => {
-//         // if (this._homeMenu == false) {
-//         let docArray = this.createPathname();
-//         let items = docArray.map((doc: Doc, index: any) => {
-//             if (index == 0) {
-//                 return (
-//                     <div className="pathbarItem">
-//                         <div className="pathbarText"
-//                             key={index}
-//                             onClick={() => this.handlePathClick(doc, index)}>{doc.title}
-//                         </div>
-//                     </div>);
-//             } else if (doc === this._activeDoc) {
-//                 return (
-//                     <div className="pathbarItem">
-//                         <FontAwesomeIcon className="pathIcon" icon="angle-right" size="lg" />
-//                         <div className="pathbarText"
-//                             style={{ backgroundColor: "rgb(119, 37, 37)" }}
-//                             key={index}
-//                             onClick={() => this.handlePathClick(doc, index)}>{doc.title}
-//                         </div>
-//                     </div>);
-//             } else {
-//                 return (
-//                     <div className="pathbarItem">
-//                         <FontAwesomeIcon className="pathIcon" icon="angle-right" size="lg" />
-//                         <div className="pathbarText"
-//                             key={index}
-//                             onClick={() => this.handlePathClick(doc, index)}>{doc.title}
-//                         </div>
-//                     </div>);
-//             }
-
-//         });
-//         if (this._parents.length !== 0) {
-//             return (<div className="pathbar">
-//                 <div className="scrollmenu">
-//                     {items}
-//                 </div>
-//                 <div className="back" >
-//                     <FontAwesomeIcon onClick={this.back} icon={"chevron-left"} color="white" size={"2x"} />
-//                 </div>
-//                 <div className="hidePath" />
-//             </div>);
-//         } else {
-//             return (<div className="pathbar">
-//                 <div className="scrollmenu">
-//                     {items}
-//                 </div>
-//                 <div className="hidePath" />
-//             </div>);
-//         }
-//         //     }
-//         // } else {
-
-//         //     return (
-//         //         <div className="pathbar">
-//         //             <div className="scrollmenu">
-//         //                 <div className="pathbarItem">
-//         //                     <div className="pathbarText"
-//         //                         style={{ backgroundColor: "rgb(119, 37, 37)" }}
-//         //                         key={0}
-//         //                         onClick={() => this.returnHome()}>Home
-//         //                     </div>
-//         //                 </div>
-//         //             </div>
-//         //             <div className="hidePath" />
-//         //         </div>
-//         //     );
-//         // }
-
-//         // }
-//     }
-
-//     handlePathClick = (doc: Doc, index: number) => {
-//         if (doc === this._library) {
-//             this._activeDoc = doc;
-//             this._child = null;
-//             this.switchCurrentView((userDoc: Doc) => doc);
-//             this._parents.length = index;
-//         } else if (doc === this._homeDoc) {
-//             this.returnHome();
-//         } else {
-//             console.log(index);
-//             this._activeDoc = doc;
-//             this._child = doc;
-//             this.switchCurrentView((userDoc: Doc) => doc);
-//             this._parents.length = index;
-//         }
-//     }
-
-//     @action
-//     toggleSidebar = () => this.sidebarActive = !this.sidebarActive
-
-//     switchToLibrary = () => {
-//         this._parents.push(this._activeDoc);
-//         this.switchCurrentView((userDoc: Doc) => this._library);
-//         this._activeDoc = this._library;
-//         this._homeMenu = false;
-//         this.toggleSidebar();
-//     }
-
-//     // renderDefaultContent = () => {
-//     //     let menuButtons = DocListCast(this._homeDoc.data).map((doc: Doc, index: any) => {
-//     //         if (doc.type !== "ink") {
-//     //             return (
-//     //                 <div
-//     //                     className="item"
-//     //                     key={index}
-//     //                     onClick={() => doc.click}>{doc.title}
-//     //                 </div>);
-//     //         }
-//     //     });
-
-//     //     if (this._homeMenu === true) {
-//     //         return (
-//     //             <div>
-//     //                 <div className="navbar">
-//     //                     <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
-//     //                     <div className="header" id="header">{this._homeDoc.title}</div>
-//     //                     <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
-//     //                         <span></span>
-//     //                         <span></span>
-//     //                         <span></span>
-//     //                     </div>
-//     //                 </div>
-//     //                 {this.renderPathbar()}
-//     //                 <div className="sidebar" id="sidebar">
-//     //                     <div className="sidebarButtons">
-//     //                         {menuButtons}
-//     //                     </div>
-//     //                 </div>
-//     //             </div>
-//     //         );
-//     //     }
-
-//     //     const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
-//     //     const buttons = DocListCast(this._child ? this._child.data : workspaces.data).map((doc: Doc, index: any) => {
-//     //         return (
-//     //             <div
-//     //                 className="item"
-//     //                 key={index}
-//     //                 onClick={() => this.handleClick(doc)}>{doc.title}
-//     //                 <div className="type">{doc.type}</div>
-//     //                 <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
-//     //             </div>);
-//     //     });
-//     //     return (
-//     //         <>
-//     //             <div className="navbar">
-//     //                 <div className={"header"}>{this.sidebarActive ? StrCast(this._activeDoc.title) : "Menu"}</div>
-//     //                 <div
-//     //                     className={`toggle-btn ${this.sidebarActive ? "active" : ""}`}
-//     //                     onClick={this.toggleSidebar}
-//     //                 />
-//     //             </div>
-//     //             <div className="pathbar">
-//     //                 <div className="pathname">{this.createPathname()}</div>
-//     //             </div>
-//     //             <div className={`sidebar ${this.sidebarActive ? "active" : ""}`}>
-//     //                 <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
-//     //                 {this._child ?
-//     //                     <>
-//     //                         <div className="back" onClick={this.back}>&#8592;</div>
-//     //                         <div>{buttons}</div>
-//     //                         <div className="item" key="home" onClick={this.returnHome}>Home</div>
-//     //                     </> :
-//     //                     <>
-//     //                         {buttons}
-//     //                         {/* <div className="item" key="library" onClick={this.openLibrary}>
-//     //                             Library
-//     //                             </div> */}
-//     //                         <Uploader Document={workspaces} />
-//     //                         <div className="item" key="audio" onClick={this.recordAudio}>Record Audio</div>
-//     //                         <div className="item" key="presentation" onClick={this.setupDefaultPresentation}>Presentation</div>
-//     //                         <div className="item" key="settings" onClick={() => SettingsManager.Instance.open()}>Settings</div>
-//     //                     </>
-//     //                 }
-//     //             </div>
-//     //             {this._child ? null : <div>{this.renderView}</div>}
-//     //         </>
-//     //     );
-//     // }
-
-//     recordAudio = async () => {
-//         // upload to server with known URL
-//         if (this._activeDoc.title !== "mobile audio") {
-//             this._parents.push(this._activeDoc);
-//         }
-//         const audioDoc = Cast(Docs.Create.AudioDocument(nullAudio, { _width: 200, _height: 100, title: "mobile audio" }), Doc) as Doc;
-//         console.log(audioDoc);
-//         if (audioDoc) {
-//             console.log("audioClicked: " + audioDoc.title);
-//             this._activeDoc = audioDoc;
-//             this.switchCurrentView((userDoc: Doc) => audioDoc);
-//             this._homeMenu = false;
-//             // this.toggleSidebar();
-//         }
-//         // const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
-//         // this.audioState = await audioDoc.getProto;
-//         // if (this.audioState) {
-//         //     console.log(this.audioState);
-//         //     const data = Cast(audioRightSidebar.data, listSpec(Doc));
-//         //     if (data) {
-//         //         data.push(audioDoc);
-//         //     }
-//         // }
-//     }
-
-//     uploadAudio = () => {
-//         const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
-//         const audioDoc = this._activeDoc;
-//         const data = Cast(audioRightSidebar.data, listSpec(Doc));
-//         console.log(audioDoc.proto);
-//         if (data) {
-//             data.push(audioDoc);
-//         }
-//         // this.recordAudio();
-//     }
-
-//     uploadAudioButton = () => {
-//         if (this._activeDoc.type === "audio") {
-//             return <div className="docButton"
-//                 title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
-//                 style={{ backgroundColor: "black", color: "white" }}
-//                 onClick={this.uploadAudio}
-//             >
-//                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
-//                 />
-//             </div>;
-//         }
-//     }
-
-//     toggleSelector = () => {
-//         console.log("toggle selector!");
-//         let toolbar = document.getElementById("toolbar") as HTMLElement;
-//         toolbar.classList.toggle('active');
-//     }
-
-//     colorTool = () => {
-//         if (this._activeDoc._viewType === "docking") {
-//             const color = InkingControl.Instance.selectedColor;
-//             console.log(color);
-//             return (
-//                 <div
-//                     className="docButton"
-//                     style={{ backgroundColor: color }}
-//                     onClick={this.toggleSelector}
-//                 >
-//                     <div className="toolbar" id="toolbar">
-//                         <div className="colorSelector">
-//                             <div className="colorButton"
-//                                 style={{ backgroundColor: "red" }}
-//                                 onClick={() => {
-//                                     InkingControl.Instance.updateSelectedColor("rgb(255,0,0)");
-//                                     Doc.UserDoc().inkColor = "rgb(255,0,0)";
-//                                     console.log(InkingControl.Instance.selectedColor);
-//                                 }}>
-//                             </div>
-//                             <div className="colorButton"
-//                                 style={{ backgroundColor: "green" }}
-//                                 onClick={e => {
-//                                     InkingControl.Instance.updateSelectedColor("rgb(0,128,0)");
-//                                     Doc.UserDoc().inkColor = "rgb(0,128,0)";
-//                                     console.log(InkingControl.Instance.selectedColor);
-//                                 }}>
-//                             </div>
-//                             <div className="colorButton"
-//                                 style={{ backgroundColor: "blue" }}
-//                                 onClick={e => {
-//                                     InkingControl.Instance.updateSelectedColor("rgb(0,0,255)");
-//                                     Doc.UserDoc().inkColor = "rgb(0,0,255)";
-//                                     console.log(InkingControl.Instance.selectedColor);
-//                                 }}>
-//                             </div>
-//                         </div>
-//                         <div className="widthSelector">
-//                             <input type="range" min="1" max="100" defaultValue="2" id="myRange" onChange={(e: React.ChangeEvent<HTMLInputElement>) => InkingControl.Instance.switchWidth(e.target.value)} />
-//                         </div>
-//                     </div>
-//                 </div>
-//             );
-//         }
-//     }
-
-//     drawInk = () => {
-//         if (this._activeDoc._viewType === "docking") {
-//             const inkIsOn = this._ink;
-//             return <div className="docButton"
-//                 id="inkButton"
-//                 title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
-//                 onClick={this.onSwitchInking}>
-//                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="pen-nib"
-//                 />
-//             </div>;
-//         }
-//     }
-
-//     downloadDocument = () => {
-//         if (this._activeDoc.type === "image") {
-//             const url = this._activeDoc["data-path"]?.toString();
-//             return <div className="docButton"
-//                 title={"Download Image"}
-//                 style={{ backgroundColor: "white", color: "black" }}
-//                 onClick={e => {
-//                     window.open(url);
-//                     console.log(url);
-//                 }}>
-//                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="download"
-//                 />
-//             </div>;
-//         }
-//     }
-
-//     pinToPresentation = () => {
-//         // Only making button available if it is an image
-//         if (this._activeDoc.type === "image") {
-//             const isPinned = this._activeDoc && Doc.isDocPinned(this._activeDoc);
-//             return <div className="docButton"
-//                 title={Doc.isDocPinned(this._activeDoc) ? "Unpin from presentation" : "Pin to presentation"}
-//                 style={{ backgroundColor: isPinned ? "black" : "white", color: isPinned ? "white" : "black" }}
-//                 onClick={e => {
-//                     if (isPinned) {
-//                         DockedFrameRenderer.UnpinDoc(this._activeDoc);
-//                     }
-//                     else {
-//                         DockedFrameRenderer.PinDoc(this._activeDoc);
-//                     }
-//                 }}>
-//                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
-//                 />
-//             </div>;
-//         }
-//     }
-
-//     setupDefaultPresentation = () => {
-//         if (this._activeDoc.title !== "Presentation") {
-//             this._parents.push(this._activeDoc);
-//         }
-
-//         const presentation = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
-
-//         if (presentation) {
-//             console.log(this._activeDoc.mobile);
-//             console.log("presentation clicked: " + presentation.title);
-//             this._activeDoc = presentation;
-//             this.switchCurrentView((userDoc: Doc) => presentation);
-//             this._homeMenu = false;
-//             // this.toggleSidebar();
-//         }
-//     }
-
-//     // mobileHome = () => {
-//     //     return (
-//     //         <div className="homeContainer">
-//     //             <div className="uploadButton">
-
-//     //             </div>
-//     //             <div className="presentationButton">
-
-//     //             </div>
-//     //             <div className="recordAudioButton">
-
-//     //             </div>
-//     //             <div className="inkButton">
-
-//     //             </div>
-//     //             <div className="settingsButton">
-
-//     //             </div>
-//     //         </div>
-//     //     );
-//     // }
-
-//     renderActiveCollection = (userDoc: Doc) => {
-//         if (this.activeContainer) {
-//             const active = Cast(this.activeContainer.data, listSpec(Doc));
-//             if (active) {
-//                 return (
-//                     <div className="mobileInterface-background">HELLO!</div>
-//                 );
-//             }
-//         }
-//     }
-
-//     onBack = (e: React.MouseEvent) => {
-//         this.switchCurrentView((userDoc: Doc) => this.mainDoc);
-//         InkingControl.Instance.switchTool(InkTool.None); // TODO: switch to previous tool
-
-//         DocServer.Mobile.dispatchOverlayTrigger({
-//             enableOverlay: false,
-//             width: window.innerWidth,
-//             height: window.innerHeight
-//         });
-
-//         // this.inkDoc = undefined;
-//         this.drawingInk = false;
-//     }
-
-//     shiftLeft = (e: React.MouseEvent) => {
-//         DocServer.Mobile.dispatchOverlayPositionUpdate({
-//             dx: -10
-//         });
-//         e.preventDefault();
-//         e.stopPropagation();
-//     }
-
-//     shiftRight = (e: React.MouseEvent) => {
-//         DocServer.Mobile.dispatchOverlayPositionUpdate({
-//             dx: 10
-//         });
-//         e.preventDefault();
-//         e.stopPropagation();
-//     }
-
-//     panelHeight = () => window.innerHeight;
-//     panelWidth = () => window.innerWidth;
-//     //WAS 3
-
-//     //WAS 1
-
-//     upload = async (e: React.MouseEvent) => {
-//         if (this.mainContainer) {
-//             const data = Cast(this.mainContainer.data, listSpec(Doc));
-//             if (data) {
-//                 const collectionDoc = await data[1]; //this should be the collection doc since the positions should be locked
-//                 const children = DocListCast(collectionDoc.data);
-//                 const uploadDoc = children.length === 1 ? children[0] : Docs.Create.StackingDocument(children, {
-//                     title: "Mobile Upload Collection", backgroundColor: "white", lockedPosition: true, _width: 300, _height: 300
-//                 });
-//                 if (uploadDoc) {
-//                     DocServer.Mobile.dispatchMobileDocumentUpload({
-//                         docId: uploadDoc[Id],
-//                     });
-//                 }
-//             }
-//         }
-//         e.stopPropagation();
-//         e.preventDefault();
-//     }
-
-//     addWebToCollection = async () => {
-//         let url = "https://en.wikipedia.org/wiki/Hedgehog";
-//         if (this.mainContainer) {
-//             const data = Cast(this.mainContainer.data, listSpec(Doc));
-//             if (data) {
-//                 const webDoc = await data[0];
-//                 const urlField: FieldResult<WebField> = Cast(webDoc.data, WebField);
-//                 url = urlField ? urlField.url.toString() : "https://en.wikipedia.org/wiki/Hedgehog";
-
-//             }
-//         }
-//         Docs.Create.WebDocument(url, { _width: 300, _height: 300, title: "Mobile Upload Web Doc" });
-//     }
-
-//     clearUpload = async () => {
-//         if (this.mainContainer) {
-//             const data = Cast(this.mainContainer.data, listSpec(Doc));
-//             if (data) {
-//                 const collectionDoc = await data[1];
-//                 const children = DocListCast(collectionDoc.data);
-//                 children.forEach(doc => {
-//                 });
-//                 // collectionDoc[data] = new List<Doc>();
-//             }
-//         }
-//     }
-
-//     onDragOver = (e: React.DragEvent) => {
-//         e.preventDefault();
-//         e.stopPropagation();
-//     }
-
-//     render() {
-//         // const content = this.currentView === "main" ? this.mainContent :
-//         //     this.currentView === "ink" ? this.inkContent :
-//         //         this.currentView === "upload" ? this.uploadContent : <></>;
-//         return (
-//             <div className="mobileInterface-container" onDragOver={this.onDragOver}>
-//                 {/* <DocumentDecorations />
-//                 <GestureOverlay>
-//                     {this.renderView ? this.renderView() : this.renderDefaultContent()}
-//                 </GestureOverlay> */}
-//                 {/* <GestureOverlay> */}
-//                 <SettingsManager />
-//                 {/* {this.menuOptions()} */}
-//                 {/* {this.displayHome()} */}
-//                 <div className="docButtonContainer">
-//                     {this.pinToPresentation()}
-//                     {this.downloadDocument()}
-//                     {this.drawInk()}
-//                     {this.uploadAudioButton()}
-//                     {this.colorTool()}
-//                 </div>
-//                 <GestureOverlay>
-
-//                 </GestureOverlay>
-//                 {this.renderDefaultContent()}
-//                 {this.displayWorkspaces()}
-//                 {/* </GestureOverlay> */}
-//                 {/* <DictationOverlay />
-//                 <SharingManager />
-//                 <GoogleAuthenticationManager /> */}
-//                 {/* <DocumentDecorations /> */}
-//                 {/* <div>
-//                     {this.renderDefaultContent()}
-//                 </div> */}
-//                 {/* <PreviewCursor /> */}
-//                 {/* <ContextMenu /> */}
-//                 {/* <RadialMenu />
-//                 <RichTextMenu /> */}
-//                 {/* <PDFMenu />
-//                 <MarqueeOptionsMenu />
-//                 <OverlayView /> */}
-//             </div>
-//         );
-//     }
-// }
-
-// Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); });
-// Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); });
-// Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); });
-// Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.recordAudio(); });
-// Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); });
-// Scripting.addGlobal(function switchToLibrary() { return MobileInterface.Instance.switchToLibrary(); });
-// // WAS 2
-
-// // 1
-// // renderUploadContent() {
-// //     if (this.mainContainer) {
-// //         return (
-// //             <div className="mobileInterface" onDragOver={this.onDragOver}>
-// //                 <div className="mobileInterface-inkInterfaceButtons">
-// //                     <button className="mobileInterface-button cancel" onClick={this.onBack} title="Back">BACK</button>
-// //                     {/* <button className="mobileInterface-button" onClick={this.clearUpload} title="Clear Upload">CLEAR</button> */}
-// //                     {/* <button className="mobileInterface-button" onClick={this.addWeb} title="Add Web Doc to Upload Collection"></button> */}
-// //                     <button className="mobileInterface-button" onClick={this.upload} title="Upload">UPLOAD</button>
-// //                 </div>
-// //                 <DocumentView
-// //                     Document={this.mainContainer}
-// //                     DataDoc={undefined}
-// //                     LibraryPath={emptyPath}
-// //                     addDocument={returnFalse}
-// //                     addDocTab={returnFalse}
-// //                     pinToPres={emptyFunction}
-// //                     rootSelected={returnFalse}
-// //                     removeDocument={undefined}
-// //                     onClick={undefined}
-// //                     ScreenToLocalTransform={Transform.Identity}
-// //                     ContentScaling={returnOne}
-// //                     NativeHeight={returnZero}
-// //                     NativeWidth={returnZero}
-// //                     PanelWidth={() => window.screen.width}
-// //                     PanelHeight={() => window.screen.height}
-// //                     renderDepth={0}
-// //                     focus={emptyFunction}
-// //                     backgroundColor={returnEmptyString}
-// //                     parentActive={returnTrue}
-// //                     whenActiveChanged={emptyFunction}
-// //                     bringToFront={emptyFunction}
-// //                     ContainingCollectionView={undefined}
-// //                     ContainingCollectionDoc={undefined} />
-// //             </div>
-// //         );
-// //     }
-// // }
-
-// // 2
-// // Scripting.addGlobal(function onSwitchMobileInking() { return MobileInterface.Instance.onSwitchInking(); });
-// // Scripting.addGlobal(function renderMobileInking() { return MobileInterface.Instance.renderInkingContent(); });
-// // Scripting.addGlobal(function onSwitchMobileUpload() { return MobileInterface.Instance.onSwitchUpload(); });
-// // Scripting.addGlobal(function renderMobileUpload() { return MobileInterface.Instance.renderUploadContent(); });
-//     // Scripting.addGlobal(function addWebToMobileUpload() { return MobileInterface.Instance.addWebToCollection(); });
-
-
-// // 3
-//     // renderInkingContent = () => {
-//         //     console.log("rendering inking content");
-//         //     // TODO: support panning and zooming
-//         //     // TODO: handle moving of ink strokes
-//         //     if (this.mainContainer) {
-//         //         return (
-//         //             <div className="mobileInterface">
-//         //                 <div className="mobileInterface-inkInterfaceButtons">
-//         //                     <div className="navButtons">
-//         //                         <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing">BACK</button>
-//         //                     </div>
-//         //                     <div className="inkSettingButtons">
-//         //                         <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing"><FontAwesomeIcon icon="long-arrow-alt-left" /></button>
-//         //                     </div>
-//         //                     <div className="navButtons">
-//         //                         <button className="mobileInterface-button" onClick={this.shiftLeft} title="Shift left">left</button>
-//         //                         <button className="mobileInterface-button" onClick={this.shiftRight} title="Shift right">right</button>
-//         //                     </div>
-//         //                 </div>
-//         //                 <CollectionView
-//         //                     Document={this.mainContainer}
-//         //                     DataDoc={undefined}
-//         //                     LibraryPath={emptyPath}
-//         //                     fieldKey={""}
-//         //                     dropAction={"alias"}
-//         //                     bringToFront={emptyFunction}
-//         //                     addDocTab={returnFalse}
-//         //                     pinToPres={emptyFunction}
-//         //                     PanelWidth={this.panelWidth}
-//         //                     PanelHeight={this.panelHeight}
-//         //                     NativeHeight={returnZero}
-//         //                     NativeWidth={returnZero}
-//         //                     focus={emptyFunction}
-//         //                     isSelected={returnFalse}
-//         //                     select={emptyFunction}
-//         //                     active={returnFalse}
-//         //                     ContentScaling={returnOne}
-//         //                     whenActiveChanged={returnFalse}
-//         //                     ScreenToLocalTransform={Transform.Identity}
-//         //                     renderDepth={0}
-//         //                     ContainingCollectionView={undefined}
-//         //                     ContainingCollectionDoc={undefined}
-//         //                     rootSelected={returnTrue}>
-//         //                 </CollectionView>
-//         //             </div>
-//         //         );
-//         //     }
-//         // }
-
 @observer
 export class MobileInterface extends React.Component {
     @observable static Instance: MobileInterface;
@@ -1035,28 +138,6 @@ export class MobileInterface extends React.Component {
     @action
     toggleSidebar = () => this.sidebarActive = !this.sidebarActive
 
-    // toggleSidebar = () => {
-    //     if (this._open === false) {
-    //         this._open = true;
-    //     } else {
-    //         this._open = false;
-    //     }
-    //     console.log("clicked");
-    //     let menuButton = document.getElementById("menuButton") as HTMLElement;
-    //     //menuButton.classList.toggle('active');
-
-    //     let sidebar = document.getElementById("sidebar") as HTMLElement;
-    //     //sidebar.classList.toggle('active');
-
-    //     let header = document.getElementById("header") as HTMLElement;
-
-    //     if (!sidebar.classList.contains('active')) {
-    //         header.textContent = String(this._activeDoc.title);
-    //     } else {
-    //         header.textContent = "library";
-    //     }
-    // }
-
     /**
      * Method called when 'Library' button is pressed
      */
@@ -1134,66 +215,35 @@ export class MobileInterface extends React.Component {
     displayWorkspaces = () => {
         if (this.mainContainer) {
             const backgroundColor = () => "white";
-            if (this._activeDoc.title === "mobile audio") {
-                return (
-                    <div style={{ position: "relative", top: '600px', height: `calc(50% - 450px)`, width: "80%", overflow: "hidden", left: "10%", cursor: "pointer" }}>
-                        <DocumentView
-                            Document={this.mainContainer}
-                            DataDoc={undefined}
-                            LibraryPath={emptyPath}
-                            addDocument={returnFalse}
-                            addDocTab={returnFalse}
-                            pinToPres={emptyFunction}
-                            rootSelected={returnFalse}
-                            removeDocument={undefined}
-                            ScreenToLocalTransform={Transform.Identity}
-                            ContentScaling={returnOne}
-                            NativeHeight={returnZero}
-                            NativeWidth={returnZero}
-                            PanelWidth={() => window.screen.width}
-                            PanelHeight={() => window.screen.height}
-                            renderDepth={0}
-                            focus={emptyFunction}
-                            backgroundColor={backgroundColor}
-                            parentActive={returnTrue}
-                            whenActiveChanged={emptyFunction}
-                            bringToFront={emptyFunction}
-                            ContainingCollectionView={undefined}
-                            ContainingCollectionDoc={undefined}
-                        />
-                    </div>
-                );
-            } else {
-                return (
-                    <div style={{ position: "relative", top: '200px', height: `calc(100% - 200px)`, width: "100%", overflow: "hidden", left: "0%" }}>
-                        <DocumentView
-                            Document={this.mainContainer}
-                            DataDoc={undefined}
-                            LibraryPath={emptyPath}
-                            addDocument={returnFalse}
-                            addDocTab={returnFalse}
-                            pinToPres={emptyFunction}
-                            rootSelected={returnFalse}
-                            removeDocument={undefined}
-                            onClick={undefined}
-                            ScreenToLocalTransform={Transform.Identity}
-                            ContentScaling={returnOne}
-                            PanelWidth={this.returnWidth}
-                            PanelHeight={this.returnHeight}
-                            NativeHeight={returnZero}
-                            NativeWidth={returnZero}
-                            renderDepth={0}
-                            focus={emptyFunction}
-                            backgroundColor={backgroundColor}
-                            parentActive={returnTrue}
-                            whenActiveChanged={emptyFunction}
-                            bringToFront={emptyFunction}
-                            ContainingCollectionView={undefined}
-                            ContainingCollectionDoc={undefined}
-                        />
-                    </div>
-                );
-            }
+            return (
+                <div style={{ position: "relative", top: '200px', height: `calc(100% - 200px)`, width: "100%", overflow: "hidden", left: "0%" }}>
+                    <DocumentView
+                        Document={this.mainContainer}
+                        DataDoc={undefined}
+                        LibraryPath={emptyPath}
+                        addDocument={returnFalse}
+                        addDocTab={returnFalse}
+                        pinToPres={emptyFunction}
+                        rootSelected={returnFalse}
+                        removeDocument={undefined}
+                        onClick={undefined}
+                        ScreenToLocalTransform={Transform.Identity}
+                        ContentScaling={returnOne}
+                        PanelWidth={this.returnWidth}
+                        PanelHeight={this.returnHeight}
+                        NativeHeight={returnZero}
+                        NativeWidth={returnZero}
+                        renderDepth={0}
+                        focus={emptyFunction}
+                        backgroundColor={backgroundColor}
+                        parentActive={returnTrue}
+                        whenActiveChanged={emptyFunction}
+                        bringToFront={emptyFunction}
+                        ContainingCollectionView={undefined}
+                        ContainingCollectionDoc={undefined}
+                    />
+                </div>
+            );
         }
     }
 
@@ -1451,9 +501,9 @@ export class MobileInterface extends React.Component {
                 >
                     <div className={`toolbar ${this.activeToolbar ? "active" : ""}`}>
                         <div className="colorSelector">
-                            {/* <SketchPicker onChange={InkingControl.Instance.switchColor} presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']} */}
+                            {/* <SketchPicker onChange={InkingControl.Instance.switchColor} presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
                                 color={StrCast(CurrentUserUtils.ActivePen ? CurrentUserUtils.ActivePen.backgroundColor : undefined,
-                                StrCast(selDoc?._backgroundColor, StrCast(selDoc?.backgroundColor, "black")))} />
+                                StrCast(selDoc?._backgroundColor, StrCast(selDoc?.backgroundColor, "black")))} /> */}
                         </div>
                         <div className="widthSelector">
                             {/* <input type="range" min="1" max="100" defaultValue="2" id="myRange" onChange={(e: React.ChangeEvent<HTMLInputElement>) => InkingControl.Instance.switchWidth(e.target.value)} /> */}
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 16eb035b3..f602b85a0 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -245,11 +245,12 @@ body {
     position: relative;
     width: 100px;
     height: 100px;
-    font-size: 90px;
+    font-size: 70px;
+    padding: 5px;
     text-align: center;
     border-style: solid;
     border-radius: 50px;
-    border-width: medium;
+    border-width: 5px;
     margin: 20px;
     z-index: 100;
 }
-- 
cgit v1.2.3-70-g09d2


From ba0d831691e81903ab1fb9482ba5dcad0a769881 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Thu, 11 Jun 2020 23:40:49 -0700
Subject: functioning with new ink

---
 src/client/views/AntimodeMenu.scss                 |  9 ++---
 .../collectionFreeForm/InkOptionsMenu.scss         | 38 ++++++++++++++++++++--
 .../collectionFreeForm/InkOptionsMenu.tsx          | 16 +++++++--
 src/mobile/MobileInterface.tsx                     | 15 +++++----
 src/mobile/MobileMenu.scss                         |  9 +++--
 5 files changed, 71 insertions(+), 16 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss
index 9c5bf0a1f..170631422 100644
--- a/src/client/views/AntimodeMenu.scss
+++ b/src/client/views/AntimodeMenu.scss
@@ -53,18 +53,19 @@
         display: flex;
     
         &.with-rows {
-            flex-direction: column
+            flex-direction: column-reverse;
         }
     
         .antimodeMenu-row {
             display: flex;
-            height: 35px;
+            height: 100%;
+            width:100%;
         }
     
         .antimodeMenu-button {
             background-color: transparent;
-            width: 35px;
-            height: 35px;
+            width: 100px;
+            height: 100px;
     
             &.active {
                 background-color: #121212;
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
index 3671a84b9..72fdf5af9 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
@@ -4,7 +4,6 @@
         height: 100%;
     }
 
-
 }
 
 .sketch-picker {
@@ -31,7 +30,42 @@
         background: #323232;
         display: block;
 
-
     }
 }
 
+@media only screen and (max-width: 1000px) {
+    .antimodeMenu-button {
+        .color-preview {
+            width: 100%;
+            height: 100%;
+        }
+    
+    }
+    
+    .sketch-picker {
+        background: #323232;
+    
+        .flexbox-fit {
+            background: #323232;
+        }
+    }
+    
+    .btn-group {
+        display: grid;
+        grid-template-columns: auto auto;
+        /* Make the buttons appear below each other */
+    }
+    
+    .btn2-group {
+        display: block;
+        background: #323232;
+        grid-template-columns: auto;
+    
+        /* Make the buttons appear below each other */
+        .antimodeMenu-button {
+            background: #323232;
+            display: block;
+    
+        }
+    }
+}
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
index 5a27f74e5..46f7bc2e2 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
@@ -11,6 +11,8 @@ import { Utils } from "../../../../Utils";
 import GestureOverlay from "../../GestureOverlay";
 import { Doc } from "../../../../fields/Doc";
 
+
+
 @observer
 export default class InkOptionsMenu extends AntimodeMenu {
     static Instance: InkOptionsMenu;
@@ -23,6 +25,8 @@ export default class InkOptionsMenu extends AntimodeMenu {
     @observable _colorBtn = false;
     @observable _widthBtn = false;
 
+
+
     constructor(props: Readonly<{}>) {
         super(props);
         InkOptionsMenu.Instance = this;
@@ -113,7 +117,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
             title="Bezier changer"
             key="bezier"
             onPointerDown={e => this.changeBezier(e)}
-            style={ { backgroundColor:ActiveInkBezierApprox() ? "121212":"" } }>
+            style={{ backgroundColor: ActiveInkBezierApprox() ? "121212" : "" }}>
             B
         </button>;
     }
@@ -126,7 +130,15 @@ export default class InkOptionsMenu extends AntimodeMenu {
             this.widthPicker,
             this.colorPicker,
         ];
-        return this.getElement(buttons);
+
+        const mobileButtons = [
+            this.shapeButtons,
+            this.bezierButton,
+            this.widthPicker,
+            this.colorPicker,
+        ];
+
+        return (window.innerWidth < 1000 ? this.getElement(mobileButtons) : this.getElement(buttons));
     }
 }
 Scripting.addGlobal(function activatePen(penBtn: any) {
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index ba52e3df9..3a7a1594b 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1481,20 +1481,20 @@ export class MobileInterface extends React.Component {
         const button = document.getElementById("inkButton") as HTMLElement;
         // const color = InkingControl.Instance.selectedColor;
         const color = "lightpink";
-        button.style.backgroundColor = this._ink ? "white" : color;
+        button.style.backgroundColor = this._ink ? "white" : "black";
         button.style.color = this._ink ? "black" : "white";
 
         if (!this._ink) {
             console.log("INK IS ACTIVE");
             // InkingControl.Instance.switchTool(InkTool.Pen);
             Doc.SetSelectedTool(InkTool.Pen);
-            InkOptionsMenu.Instance.jumpTo(300, 300);
+            //InkOptionsMenu.Instance.jumpTo(300, 300);
             this._ink = true;
         } else {
             console.log("INK IS INACTIVE");
             // InkingControl.Instance.switchTool(InkTool.None);
             Doc.SetSelectedTool(InkTool.None);
-            InkOptionsMenu.Instance.fadeOut(true);
+            //InkOptionsMenu.Instance.fadeOut(true);
             this._ink = false;
         }
     }
@@ -1502,7 +1502,11 @@ export class MobileInterface extends React.Component {
     inkMenu = () => {
         if (this._activeDoc._viewType === "docking") {
             if (this._ink) {
-                return <InkOptionsMenu />
+                console.log("here");
+                return <div className="colorSelector">
+                    <InkOptionsMenu />
+                </div>
+
             }
         }
     }
@@ -1794,9 +1798,8 @@ export class MobileInterface extends React.Component {
                     {this.drawInk()}
                     {this.uploadAudioButton()}
                     {/* {this.colorTool()} */}
-                    {this.inkMenu()}
-                    <InkOptionsMenu />
                 </div>
+                {this.inkMenu()}
                 <GestureOverlay>
                     {this.displayWorkspaces()}
                     {this.renderDefaultContent()}
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 6d450bc6d..54156a735 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -333,12 +333,17 @@ body {
     top: -450px;
 }
 
-.toolbar .colorSelector {
+.colorSelector {
+    position: absolute;
+    top: 550px;
+    left: 300px;
+    transform: translate(-50%, 0);
+    z-index: 100;
     display: inline-flex;
     width: max-content;
-    padding: 5px;
     height: max-content;
     pointer-events: all;
+    font-size: 90px;
 }
 
 .widthSelector {
-- 
cgit v1.2.3-70-g09d2


From 3dab85351e1fe862a54294cec70e7139abea0d7d Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Mon, 15 Jun 2020 00:10:16 -0700
Subject: added ? to a lot of things

---
 .../views/collections/CollectionCarouselView.tsx   |   2 +-
 .../views/collections/CollectionDockingView.tsx    |   2 +-
 src/client/views/collections/CollectionView.tsx    |  18 +-
 src/client/views/nodes/DocumentView.tsx            |   2 +-
 src/client/views/nodes/ImageBox.tsx                |  10 +-
 .../nodes/formattedText/FormattedTextBox.scss      | 283 ++++++++++++++++++++-
 .../views/nodes/formattedText/FormattedTextBox.tsx |   4 +-
 src/mobile/MobileInterface.scss                    |   8 +
 src/mobile/MobileInterface.tsx                     |  10 +-
 src/server/index.ts                                |   1 +
 10 files changed, 319 insertions(+), 21 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index f65a89422..bd0e4fc9a 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -87,7 +87,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
     onContextMenu = (e: React.MouseEvent): void => {
         // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
         if (!e.isPropagationStopped()) {
-            ContextMenu.Instance.addItem({
+            ContextMenu.Instance?.addItem({
                 description: "Make Hero Image", event: () => {
                     const index = NumCast(this.layoutDoc._itemIndex);
                     (this.dataDoc || Doc.GetProto(this.props.Document)).hero = ObjectField.MakeCopy(this.childLayoutPairs[index].layout.data as ObjectField);
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 6f5a3dfe4..02ba45f9c 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -840,7 +840,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
             parentActive={returnTrue}
             whenActiveChanged={emptyFunction}
             focus={emptyFunction}
-            backgroundColor={CollectionDockingView.Instance.props.backgroundColor}
+            backgroundColor={CollectionDockingView.Instance?.props.backgroundColor}
             addDocTab={this.addDocTab}
             pinToPres={DockedFrameRenderer.PinDoc}
             ContainingCollectionView={undefined}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index a25a864af..00a1d27f0 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -213,12 +213,12 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
 
 
     setupViewTypes(category: string, func: (viewType: CollectionViewType) => Doc, addExtras: boolean) {
-        const existingVm = ContextMenu.Instance.findByDescription(category);
+        const existingVm = ContextMenu.Instance?.findByDescription(category);
         const subItems = existingVm && "subitems" in existingVm ? existingVm.subitems : [];
 
         subItems.push({ description: "Freeform", event: () => func(CollectionViewType.Freeform), icon: "signature" });
         if (addExtras && CollectionView._safeMode) {
-            ContextMenu.Instance.addItem({ description: "Test Freeform", event: () => func(CollectionViewType.Invalid), icon: "project-diagram" });
+            ContextMenu.Instance?.addItem({ description: "Test Freeform", event: () => func(CollectionViewType.Invalid), icon: "project-diagram" });
         }
         subItems.push({ description: "Schema", event: () => func(CollectionViewType.Schema), icon: "th-list" });
         subItems.push({ description: "Tree", event: () => func(CollectionViewType.Tree), icon: "tree" });
@@ -235,7 +235,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
             subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) });
         }
         addExtras && subItems.push({ description: "lightbox", event: action(() => this._isLightboxOpen = true), icon: "eye" });
-        !existingVm && ContextMenu.Instance.addItem({ description: category, subitems: subItems, icon: "eye" });
+        !existingVm && ContextMenu.Instance?.addItem({ description: category, subitems: subItems, icon: "eye" });
     }
 
     onContextMenu = (e: React.MouseEvent): void => {
@@ -248,7 +248,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                 return newRendition;
             }, false);
 
-            const existing = ContextMenu.Instance.findByDescription("Options...");
+            const existing = ContextMenu.Instance?.findByDescription("Options...");
             const layoutItems = existing && "subitems" in existing ? existing.subitems : [];
             layoutItems.push({ description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" });
             if (this.props.Document.childLayout instanceof Doc) {
@@ -259,9 +259,9 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
             }
             layoutItems.push({ description: `${this.props.Document.isInPlaceContainer ? "Unset" : "Set"} inPlace Container`, event: () => this.props.Document.isInPlaceContainer = !this.props.Document.isInPlaceContainer, icon: "project-diagram" });
 
-            !existing && ContextMenu.Instance.addItem({ description: "Options...", subitems: layoutItems, icon: "hand-point-right" });
+            !existing && ContextMenu.Instance?.addItem({ description: "Options...", subitems: layoutItems, icon: "hand-point-right" });
 
-            const existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
+            const existingOnClick = ContextMenu.Instance?.findByDescription("OnClick...");
             const onClicks = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
             const funcs = [
                 { key: "onChildClick", name: "On Child Clicked" },
@@ -277,12 +277,12 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                     icon: "edit",
                     event: () => this.props.Document[StrCast(childClick.targetScriptKey)] = ObjectField.MakeCopy(ScriptCast(childClick.data)),
                 }));
-            !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
+            !existingOnClick && ContextMenu.Instance?.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
 
-            const more = ContextMenu.Instance.findByDescription("More...");
+            const more = ContextMenu.Instance?.findByDescription("More...");
             const moreItems = more && "subitems" in more ? more.subitems : [];
             moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) });
-            !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
+            !more && ContextMenu.Instance?.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
         }
     }
 
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 1d98a2628..66bc73617 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -138,7 +138,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         document.removeEventListener("pointerup", this.onPointerUp);
         console.log(SelectionManager.SelectedDocuments());
         console.log("START");
-        if (RadialMenu.Instance._display === false) {
+        if (RadialMenu.Instance?._display === false) {
             this.addHoldMoveListeners();
             this.addHoldEndListeners();
             this.onRadialMenu(e, me);
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index cabf30c13..73410e02f 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -174,19 +174,19 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
             //     }), icon: "expand-arrows-alt"
             // });
 
-            const existingAnalyze = ContextMenu.Instance.findByDescription("Analyzers...");
+            const existingAnalyze = ContextMenu.Instance?.findByDescription("Analyzers...");
             const modes: ContextMenuProps[] = existingAnalyze && "subitems" in existingAnalyze ? existingAnalyze.subitems : [];
             modes.push({ description: "Generate Tags", event: this.generateMetadata, icon: "tag" });
             modes.push({ description: "Find Faces", event: this.extractFaces, icon: "camera" });
             //modes.push({ description: "Recommend", event: this.extractText, icon: "brain" });
-            !existingAnalyze && ContextMenu.Instance.addItem({ description: "Analyzers...", subitems: modes, icon: "hand-point-right" });
+            !existingAnalyze && ContextMenu.Instance?.addItem({ description: "Analyzers...", subitems: modes, icon: "hand-point-right" });
 
-            ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
+            ContextMenu.Instance?.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
 
 
-            const existingMore = ContextMenu.Instance.findByDescription("More...");
+            const existingMore = ContextMenu.Instance?.findByDescription("More...");
             const mores: ContextMenuProps[] = existingMore && "subitems" in existingMore ? existingMore.subitems : [];
-            !existingMore && ContextMenu.Instance.addItem({ description: "More...", subitems: mores, icon: "hand-point-right" });
+            !existingMore && ContextMenu.Instance?.addItem({ description: "More...", subitems: mores, icon: "hand-point-right" });
         }
     }
 
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index 49114d967..e608f9951 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -37,6 +37,7 @@
         position: absolute;
     }
 }
+
 .formattedTextBox-outer {
     position: relative;
     overflow: auto;
@@ -273,4 +274,284 @@ footnote::after {
     .multi2:before { transition: 0.5s;counter-increment: multi2; display: inline-block; margin-left: -2em;    width:   2em;  content: counter(multi1, upper-alpha) "."counter(multi2, decimal) ". "; }
     .multi3:before { transition: 0.5s;counter-increment: multi3; display: inline-block; margin-left: -2.85em; width:2.85em;  content: counter(multi1, upper-alpha) "."counter(multi2, decimal) "."counter(multi3, lower-alpha) ". "; }
     .multi4:before { transition: 0.5s;counter-increment: multi4; display: inline-block; margin-left:   -4.2em;  width: 4.2em;    content: counter(multi1, upper-alpha) "."counter(multi2, decimal) "."counter(multi3, lower-alpha) "."counter(multi4, lower-roman) ". "; }
-}
\ No newline at end of file
+}
+
+@media only screen and (max-width: 1000px) {
+    @import "../../globalCssVariables";
+
+    .ProseMirror {
+        width: 100%;
+        height: 100%;
+        min-height: 100%;
+    }
+    
+    .ProseMirror:focus {
+        outline: none !important;
+    }
+    
+    .formattedTextBox-cont {
+        touch-action: none;
+        cursor: text;
+        background: inherit;
+        padding: 0;
+        border-width: 0px;
+        border-radius: inherit;
+        border-color: $intermediate-color;
+        box-sizing: border-box;
+        background-color: inherit;
+        border-style: solid;
+        overflow-y: auto;
+        overflow-x: hidden;
+        color: initial;
+        max-height: 100%;
+        display: flex;
+        flex-direction: row;
+        transition: opacity 1s;
+    
+        .formattedTextBox-dictation {
+            height: 12px;
+            width: 10px;
+            top: 0px;
+            left: 0px;
+            position: absolute;
+        }
+    }
+    
+    .formattedTextBox-outer {
+        position: relative;
+        overflow: auto;
+        display: inline-block;
+        width: 100%;
+        height: 100%;
+    }
+    
+    .formattedTextBox-sidebar-handle {
+        position: absolute;
+        top: calc(50% - 17.5px);
+        width: 10px;
+        height: 35px;
+        background: lightgray;
+        border-radius: 20px;
+        cursor:grabbing;
+    }
+    
+    .formattedTextBox-cont>.formattedTextBox-sidebar-handle {
+        right: 0;
+        left: unset;
+    }
+    
+    .formattedTextBox-sidebar,
+    .formattedTextBox-sidebar-inking {
+        border-left: dashed 1px black;
+        height: 100%;
+        display: inline-block;
+        position: absolute;
+        right: 0;
+    
+        .collectionfreeformview-container {
+            position: relative;
+        }
+        
+        >.formattedTextBox-sidebar-handle {
+            right: unset;
+            left: -5;
+        }
+    }
+    
+    .formattedTextBox-sidebar-inking {
+        pointer-events: all;
+    }
+    
+    .formattedTextBox-inner-rounded {
+        height: 70%;
+        width: 85%;
+        position: absolute;
+        overflow: auto;
+        top: 15%;
+        left: 10%;
+    }
+    
+    .formattedTextBox-inner-rounded,
+    .formattedTextBox-inner {
+        height: 100%;
+        white-space: pre-wrap; 
+        hr {
+            display: block;
+            unicode-bidi: isolate;
+            margin-block-start: 0.5em;
+            margin-block-end: 0.5em;
+            margin-inline-start: auto;
+            margin-inline-end: auto;
+            overflow: hidden;
+            border-style: inset;
+            border-width: 1px;
+        }
+    }
+    
+    // .menuicon {
+    //     display: inline-block;
+    //     border-right: 1px solid rgba(0, 0, 0, 0.2);
+    //     color: #888;
+    //     line-height: 1;
+    //     padding: 0 7px;
+    //     margin: 1px;
+    //     cursor: pointer;
+    //     text-align: center;
+    //     min-width: 1.4em;
+    // }
+    
+    .strong,
+    .heading {
+        font-weight: bold;
+    }
+    
+    .em {
+        font-style: italic;
+    }
+    
+    .userMarkOpen {
+        background: rgba(255, 255, 0, 0.267);
+        display: inline;
+    }
+    
+    .userMark {
+        background: rgba(255, 255, 0, 0.267);
+        font-size: 2px;
+        display: inline-grid;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        width: 10px;
+        min-height: 10px;
+        text-align: center;
+        align-content: center;
+    }
+    
+    footnote {
+        display: inline-block;
+        position: relative;
+        cursor: pointer;
+    
+        div {
+            padding: 0 !important;
+        }
+    }
+    
+    footnote::after {
+        content: counter(prosemirror-footnote);
+        vertical-align: super;
+        font-size: 75%;
+        counter-increment: prosemirror-footnote;
+    }
+    
+    .ProseMirror {
+        counter-reset: prosemirror-footnote;
+    }
+    
+    .footnote-tooltip {
+        cursor: auto;
+        font-size: 75%;
+        position: absolute;
+        left: -30px;
+        top: calc(100% + 10px);
+        background: silver;
+        padding: 3px;
+        border-radius: 2px;
+        max-width: 100px;
+        min-width: 50px;
+        width: max-content;
+    }
+    
+    .prosemirror-attribution {
+        font-size: 8px;
+    }
+    
+    .footnote-tooltip::before {
+        border: 5px solid silver;
+        border-top-width: 0px;
+        border-left-color: transparent;
+        border-right-color: transparent;
+        position: absolute;
+        top: -5px;
+        left: 27px;
+        content: " ";
+        height: 0;
+        width: 0;
+    }
+    
+    
+    .formattedTextBox-inlineComment {
+        position: relative;
+        width: 40px;
+        height: 20px;
+        &::before {
+            content: "→";
+        }
+        &:hover {
+            background: orange;
+        }
+    }
+    
+    .formattedTextBox-summarizer {
+        opacity: 0.5;
+        position: relative;
+        width: 40px;
+        height: 20px;
+        &::after {
+            content: "←";
+        }
+    }
+    
+    .formattedTextBox-summarizer-collapsed {
+        opacity: 0.5;
+        position: relative;
+        width: 40px;
+        height: 20px;
+        &::after {
+            content: "...";
+        }
+    }
+    
+    .ProseMirror {
+        touch-action: none;
+        span {
+            font-family: inherit;
+        }
+    
+        ol, ul {
+            counter-reset: deci1 0 multi1 0;
+            padding-left: 1em;
+            font-family: inherit;
+        }
+        ol {
+            margin-left: 1em;
+            font-family: inherit;
+        }
+    
+        .decimal1-ol { counter-reset: deci1; p {display: inline; font-family: inherit} margin-left: 0; }
+        .decimal2-ol { counter-reset: deci2; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 1em;}
+        .decimal3-ol { counter-reset: deci3; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 2em;}
+        .decimal4-ol { counter-reset: deci4; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 3em;}
+        .decimal5-ol { counter-reset: deci5; p {display: inline; font-family: inherit} font-size: smaller; }
+        .decimal6-ol { counter-reset: deci6; p {display: inline; font-family: inherit} font-size: smaller; }
+        .decimal7-ol { counter-reset: deci7; p {display: inline; font-family: inherit} font-size: smaller; }
+    
+        .multi1-ol { counter-reset: multi1; p {display: inline; font-family: inherit} margin-left: 0;     padding-left: 1.2em }
+        .multi2-ol { counter-reset: multi2; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 1.4em;}
+        .multi3-ol { counter-reset: multi3; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 2em;}
+        .multi4-ol { counter-reset: multi4; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 3.4em;}
+    
+        .decimal1:before { transition: 0.5s;counter-increment: deci1; display: inline-block; margin-left: -1em;   width:  1em;   content: counter(deci1) ". ";  }
+        .decimal2:before { transition: 0.5s;counter-increment: deci2; display: inline-block; margin-left: -2.1em; width: 2.1em;  content: counter(deci1) "."counter(deci2) ". ";  }
+        .decimal3:before { transition: 0.5s;counter-increment: deci3; display: inline-block; margin-left: -2.85em;width: 2.85em; content: counter(deci1) "."counter(deci2) "."counter(deci3) ". "; }
+        .decimal4:before { transition: 0.5s;counter-increment: deci4; display: inline-block; margin-left: -3.85em;width: 3.85em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) ". "; }
+        .decimal5:before { transition: 0.5s;counter-increment: deci5; display: inline-block; margin-left: -2em;   width:  5em;   content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) ". "; }
+        .decimal6:before { transition: 0.5s;counter-increment: deci6; display: inline-block; margin-left: -2em;   width:  6em;   content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) "."counter(deci6) ". "; }
+        .decimal7:before { transition: 0.5s;counter-increment: deci7; display: inline-block; margin-left: -2em;   width:  7em;   content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) "."counter(deci6) "."counter(deci7) ". "; }
+        
+        .multi1:before { transition: 0.5s;counter-increment: multi1; display: inline-block; margin-left: -1em;    width: 1.2em;  content: counter(multi1, upper-alpha) ". ";  }
+        .multi2:before { transition: 0.5s;counter-increment: multi2; display: inline-block; margin-left: -2em;    width:   2em;  content: counter(multi1, upper-alpha) "."counter(multi2, decimal) ". "; }
+        .multi3:before { transition: 0.5s;counter-increment: multi3; display: inline-block; margin-left: -2.85em; width:2.85em;  content: counter(multi1, upper-alpha) "."counter(multi2, decimal) "."counter(multi3, lower-alpha) ". "; }
+        .multi4:before { transition: 0.5s;counter-increment: multi4; display: inline-block; margin-left:   -4.2em;  width: 4.2em;    content: counter(multi1, upper-alpha) "."counter(multi2, decimal) "."counter(multi3, lower-alpha) "."counter(multi4, lower-roman) ". "; }
+    }
+}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 1fab54d7e..b0b648b66 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -188,7 +188,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 }
             }
             const state = this._editorView.state.apply(tx);
-            this._editorView.updateState(state);
+            this?._editorView?.updateState(state);
             (tx.storedMarks && !this._editorView.state.storedMarks) && (this._editorView.state.storedMarks = tx.storedMarks);
 
             const tsel = this._editorView.state.selection.$from;
@@ -1213,7 +1213,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
         const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground;
         if (this.props.isSelected()) {
-            this._editorView && RichTextMenu.Instance.updateFromDash(this._editorView, undefined, this.props);
+            this._editorView && RichTextMenu.Instance?.updateFromDash(this._editorView, undefined, this.props);
         } else if (FormattedTextBoxComment.textBox === this) {
             FormattedTextBoxComment.Hide();
         }
diff --git a/src/mobile/MobileInterface.scss b/src/mobile/MobileInterface.scss
index f75e60a37..215ce02e5 100644
--- a/src/mobile/MobileInterface.scss
+++ b/src/mobile/MobileInterface.scss
@@ -17,6 +17,14 @@
     position: relative;
     touch-action: none;
     width: 100%;
+
+    -webkit-touch-callout:none;
+    -webkit-user-select:none;
+    -khtml-user-select:none;
+    -moz-user-select:none;
+    -ms-user-select:none;
+    user-select:none;
+    -webkit-tap-highlight-color:rgba(0,0,0,0);
 }
 
 .mobileInterface-background {
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 6cb8e3486..a2d3f63dc 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -39,6 +39,7 @@ import { SelectionManager } from "../client/util/SelectionManager";
 import { SketchPicker } from "react-color";
 import { ScriptField } from "../fields/ScriptField";
 import InkOptionsMenu from "../client/views/collections/collectionFreeForm/InkOptionsMenu";
+import { RadialMenu } from "../client/views/nodes/RadialMenu";
 
 library.add(faTasks, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
@@ -96,6 +97,14 @@ export class MobileInterface extends React.Component {
         this._homeDoc._viewType === "stacking" ? this.menuListView = true : this.menuListView = false;
         Doc.SetSelectedTool(InkTool.None);
         this.switchCurrentView((userDoc: Doc) => this._homeDoc);
+
+        document.removeEventListener("dblclick", this.onReactDoubleClick);
+        document.addEventListener("dblclick", this.onReactDoubleClick);
+    }
+
+    onReactDoubleClick = (e: MouseEvent) => {
+        console.log("tapped");
+        e.stopPropagation();
     }
 
     @action
@@ -896,7 +905,6 @@ export class MobileInterface extends React.Component {
         } else if (!this.imageUploadActive) {
 
         }
-        console.log("upload");
         return (
             <div>
                 <div className="closeUpload" onClick={this.toggleUpload}>
diff --git a/src/server/index.ts b/src/server/index.ts
index 590affd06..083173bb5 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -104,6 +104,7 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }:
     const serve: PublicHandler = ({ req, res }) => {
         const detector = new mobileDetect(req.headers['user-agent'] || "");
         const filename = detector.mobile() !== null ? 'mobile/image.html' : 'index.html';
+        console.log(detector.is("iPhone"));
         res.sendFile(path.join(__dirname, '../../deploy/' + filename));
     };
 
-- 
cgit v1.2.3-70-g09d2


From 87aa11c70be1ae0270c69adc0c1e0219f79ce820 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Tue, 16 Jun 2020 01:34:12 +0800
Subject: uploader + menu changes

image upload w/ video and other files
menu updates
---
 src/client/util/CurrentUserUtils.ts                |  23 +--
 src/client/views/GestureOverlay.scss               |   2 +-
 .../views/collections/CollectionStackingView.scss  |  10 +-
 .../collectionFreeForm/InkOptionsMenu.tsx          |   4 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |   2 +-
 .../views/presentationview/PresElementBox.tsx      |   2 +-
 src/mobile/ImageUpload.scss                        |   1 +
 src/mobile/ImageUpload.tsx                         | 139 +++++++++---------
 src/mobile/MobileInterface.tsx                     | 156 ++-------------------
 src/mobile/MobileMenu.scss                         |   8 +-
 10 files changed, 109 insertions(+), 238 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 1b0622f6d..e1605473c 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -329,7 +329,8 @@ export class CurrentUserUtils {
             doc.emptyWebpage = Docs.Create.WebDocument("", { title: "New Webpage", _nativeWidth: 850, _nativeHeight: 962, _width: 600, UseCors: true });
         }
         if (doc.activeMobile === undefined) {
-            doc.activeMobile = CurrentUserUtils.setupMobileMenu();
+            console.log("phone setup");
+            this.setupActiveMobile(doc);
         }
         return [
             { title: "Drag a comparison box", label: "Comp", icon: "columns", ignoreClick: true, drag: 'Docs.Create.ComparisonDocument()' },
@@ -398,16 +399,18 @@ export class CurrentUserUtils {
         return doc.myItemCreators as Doc;
     }
 
-    // static setupActiveMobile(doc: Doc) {
-    //     if (doc.activeMobile === undefined) {
-    //         doc.activeMobile = CurrentUserUtils.setupMobileMenu();
-    //     }
-    // }
+    static setupActiveMobile(doc: Doc) {
+        if (doc.activeMobile === undefined) {
+            console.log("undefined");
+            doc.activeMobile = this.setupMobileMenu();
+        }
+        return doc.activeMobile as Doc;
+    }
 
     static setupMobileMenu() {
-        const menu = Cast(Docs.Create.StackingDocument(CurrentUserUtils.setupMobileButtons(), {
-            _width: 980, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "home", _yMargin: 100
-        }), Doc) as Doc;
+        const menu = new PrefetchProxy(Docs.Create.StackingDocument(this.setupMobileButtons(), {
+            _width: 980, ignoreClick: true, lockedPosition: false, _chromeStatus: "disabled", title: "home", _yMargin: 100
+        }));
         return menu;
     }
 
@@ -740,7 +743,7 @@ export class CurrentUserUtils {
         this.setupDefaultIconTemplates(doc);  // creates a set of icon templates triggered by the document deoration icon
         this.setupDocTemplates(doc); // sets up the template menu of templates
         this.setupRightSidebar(doc);  // sets up the right sidebar collection for mobile upload documents and sharing
-        // this.setupActiveMobile(doc);
+        this.setupActiveMobile(doc);
         this.setupOverlays(doc);  // documents in overlay layer
         this.setupDockedButtons(doc);  // the bottom bar of font icons
         this.setupDefaultPresentation(doc); // presentation that's initially triggered
diff --git a/src/client/views/GestureOverlay.scss b/src/client/views/GestureOverlay.scss
index 107077792..f61f4a05e 100644
--- a/src/client/views/GestureOverlay.scss
+++ b/src/client/views/GestureOverlay.scss
@@ -1,7 +1,7 @@
 .gestureOverlay-cont {
     width: 100vw;
     height: 100vh;
-    position: absolute;
+    position: fixed;
     top: 0;
     left: 0;
     touch-action: none;
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 714ff46a9..98efdfd23 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -428,11 +428,9 @@
 
     .collectionStackingView .collectionStackingView-columnDragger,
     .collectionMasonryView .collectionStackingView-columnDragger {
-        width: 30;
-        transform: translate(0, -40px);
-        height: 30;
-        font-size: 40;
-        position: absolute;
-        margin-left: -5;
+        width: 0.1;
+        height: 0.1;
+        opacity: 0;
+        font-size: 0;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
index 5a27f74e5..9f5e217bf 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
@@ -101,7 +101,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
                 title={`Draw ${btn}`}
                 key={btn}
                 onPointerDown={action(e => GestureOverlay.Instance.InkShape = btn)}
-                style={{ backgroundColor: btn === GestureOverlay.Instance.InkShape ? "121212" : "" }}>
+                style={{ backgroundColor: btn === GestureOverlay.Instance?.InkShape ? "121212" : "" }}>
                 {this._icons[i]}
             </button>)},
         </>;
@@ -113,7 +113,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
             title="Bezier changer"
             key="bezier"
             onPointerDown={e => this.changeBezier(e)}
-            style={ { backgroundColor:ActiveInkBezierApprox() ? "121212":"" } }>
+            style={{ backgroundColor: ActiveInkBezierApprox() ? "121212" : "" }}>
             B
         </button>;
     }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 1fab54d7e..e034e07a0 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1213,7 +1213,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
         const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground;
         if (this.props.isSelected()) {
-            this._editorView && RichTextMenu.Instance.updateFromDash(this._editorView, undefined, this.props);
+            this._editorView && RichTextMenu.Instance?.updateFromDash(this._editorView, undefined, this.props);
         } else if (FormattedTextBoxComment.textBox === this) {
             FormattedTextBoxComment.Hide();
         }
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index caee06d8f..793d4068f 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -49,7 +49,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
 
     componentDidMount() {
         this._heightDisposer = reaction(() => [this.rootDoc.presExpandInlineButton, this.collapsedHeight],
-            params => this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 100 : 0), { fireImmediately: true });
+            params => this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 200 : 0), { fireImmediately: true });
     }
     componentWillUnmount() {
         this._heightDisposer?.();
diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss
index d5ab31469..95c0c2680 100644
--- a/src/mobile/ImageUpload.scss
+++ b/src/mobile/ImageUpload.scss
@@ -6,6 +6,7 @@
     flex-direction: column;
     align-items: center;
     max-width: 400px;
+    min-width: 400px;
 
     .upload_label {
         font-size: 3em;
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 8f050aedd..3b4008e3f 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -14,6 +14,7 @@ import { listSpec } from '../fields/Schema';
 import { List } from '../fields/List';
 import { Scripting } from '../client/util/Scripting';
 import MainViewModal from '../client/views/MainViewModal';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 
 export interface ImageUploadProps {
     Document: Doc;
@@ -35,83 +36,80 @@ export class Uploader extends React.Component {
     @observable process: string = "";
 
     onClick = async () => {
-        console.log("uploader click");
         try {
-            this.status = "initializing protos";
+            await Docs.Prototypes.initialize();
+            const imgPrev = document.getElementById("img_preview");
             const slab1 = document.getElementById("slab1");
             if (slab1) {
                 slab1.style.opacity = "1";
             }
-            await Docs.Prototypes.initialize();
-            const imgPrev = document.getElementById("img_preview");
-            console.log("buddy");
             if (imgPrev) {
-                console.log("hi");
                 const files: FileList | null = inputRef.current!.files;
+                const slab2 = document.getElementById("slab2");
+                if (slab2) {
+                    slab2.style.opacity = "1";
+                }
                 if (files && files.length !== 0) {
-                    this.process = "Uploading Image"
-                    console.log(files[0]);
-                    const name = files[0].name;
-                    const res = await Networking.UploadFilesToServer(files[0]);
-                    this.status = "uploading image";
-                    const slab2 = document.getElementById("slab2");
-                    if (slab2) {
-                        slab2.style.opacity = "1";
-                    }
-                    this.status = "upload image, getting json";
-                    const slab3 = document.getElementById("slab3");
-                    if (slab3) {
-                        slab3.style.opacity = "1";
-                    }
-                    res.map(async ({ result }) => {
-                        if (result instanceof Error) {
-                            return;
-                        }
-                        const path = Utils.prepend(result.accessPaths.agnostic.client);
-                        const doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name });
-
-                        this.status = "getting user document";
-                        const slab4 = document.getElementById("slab4");
-                        if (slab4) {
-                            slab4.style.opacity = "1";
-                        }
-                        this.status = "upload image, getting json";
-                        const slab5 = document.getElementById("slab5");
-                        if (slab5) {
-                            slab5.style.opacity = "1";
+                    this.process = "Uploading Files";
+                    for (let index = 0; index < files.length; ++index) {
+                        const file = files[index];
+                        const res = await Networking.UploadFilesToServer(file);
+                        const slab3 = document.getElementById("slab3");
+                        if (slab3) {
+                            slab3.style.opacity = "1";
                         }
-                        const res = await rp.get(Utils.prepend("/getUserDocumentId"));
-                        if (!res) {
-                            throw new Error("No user id returned");
-                        }
-                        const field = await DocServer.GetRefField(res);
-                        let pending: Opt<Doc>;
-                        if (field instanceof Doc) {
-                            pending = await Cast(field.rightSidebarCollection, Doc);
-                        }
-                        if (pending) {
-                            this.status = "has pending docs";
-                            const slab6 = document.getElementById("slab6");
-                            if (slab6) {
-                                slab6.style.opacity = "1";
+                        res.map(async ({ result }) => {
+                            const name = file.name;
+                            if (result instanceof Error) {
+                                return;
                             }
-                            const data = await Cast(pending.data, listSpec(Doc));
-                            if (data) {
-                                data.push(doc);
+                            const path = Utils.prepend(result.accessPaths.agnostic.client);
+                            let doc = null;
+                            if (file.type === "video/mp4") {
+                                doc = Docs.Create.VideoDocument(path, { _nativeWidth: 200, _width: 200, title: name });
                             } else {
-                                pending.data = new List([doc]);
+                                doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name });
                             }
-                            this.status = "finished";
-
-                            console.log("hi");
-                            const slab7 = document.getElementById("slab7");
-                            if (slab7) {
-                                slab7.style.opacity = "1";
+                            const slab4 = document.getElementById("slab4");
+                            if (slab4) {
+                                slab4.style.opacity = "1";
+                            }
+                            const res = await rp.get(Utils.prepend("/getUserDocumentId"));
+                            if (!res) {
+                                throw new Error("No user id returned");
+                            }
+                            const field = await DocServer.GetRefField(res);
+                            let pending: Opt<Doc>;
+                            if (field instanceof Doc) {
+                                pending = await Cast(field.rightSidebarCollection, Doc);
                             }
-                            this.process = "Image Uploaded";
+                            if (pending) {
+                                const data = await Cast(pending.data, listSpec(Doc));
+                                if (data) {
+                                    data.push(doc);
+                                } else {
+                                    pending.data = new List([doc]);
+                                }
+                                this.status = "finished";
+                                const slab5 = document.getElementById("slab5");
+                                if (slab5) {
+                                    slab5.style.opacity = "1";
+                                }
+                                this.process = "File " + (index + 1).toString() + " Uploaded";
+                                if (index === files.length) {
+                                    const slab6 = document.getElementById("slab6");
+                                    if (slab6) {
+                                        slab6.style.opacity = "1";
+                                    }
+                                }
+                            }
+                        });
+                        this.process = "All Files Uploaded";
+                        const slab7 = document.getElementById("slab7");
+                        if (slab7) {
+                            slab7.style.opacity = "1";
                         }
-
-                    });
+                    }
                 } else {
                     this.process = "No file selected";
                 }
@@ -120,16 +118,18 @@ export class Uploader extends React.Component {
         } catch (error) {
             this.error = JSON.stringify(error);
         }
-
     }
 
     // Updates label after a files is selected (so user knows a file is uploaded)
     inputLabel = async () => {
         const files: FileList | null = inputRef.current!.files;
         await files;
-        if (files && files.length !== 0) {
+        if (files && files.length === 1) {
             console.log(files);
             this.nm = files[0].name;
+        } else if (files && files.length > 1) {
+            console.log(files.length);
+            this.nm = files.length.toString() + " files selected";
         }
     }
 
@@ -163,7 +163,7 @@ export class Uploader extends React.Component {
         if (slab7) {
             slab7.style.opacity = "0.4";
         }
-        this.nm = "Choose an image";
+        this.nm = "Choose files";
 
         if (inputRef.current) {
             inputRef.current.value = "";
@@ -177,9 +177,12 @@ export class Uploader extends React.Component {
     private get uploadInterface() {
         return (
             <div className="imgupload_cont">
-                <input type="file" accept="image/*" className="inputFile" id="input_image_file" ref={inputRef} onChange={this.inputLabel}></input>
+                <input type="file" accept="video/*,image/*" className="inputFile" id="input_image_file" ref={inputRef} onChange={this.inputLabel} multiple></input>
                 <label className="file" id="label" htmlFor="input_image_file">{this.nm}</label>
-                <div className="upload_label" onClick={this.onClick}>Upload Image</div>
+                <div className="upload_label" onClick={this.onClick}>
+                    <FontAwesomeIcon icon="upload" size="lg" />
+                    Upload
+                </div>
                 {/* <div onClick={this.onClick} className="upload_button">Upload</div> */}
                 <img id="img_preview" src=""></img>
                 {/* <p>{this.status}</p>
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index f2914eaae..211cc7a1a 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -52,10 +52,7 @@ export class MobileInterface extends React.Component {
     @observable static Instance: MobileInterface;
     @computed private get userDoc() { return Doc.UserDoc(); }
     @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
-    // @computed private get activeContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
-    // Sets up new mobile menu only if activeMobile already exists
-    // @observable private mainDoc: any = this.userDoc.activeMobile === undefined ? CurrentUserUtils.setupMobileMenu() : this.userDoc.activeMobile;
-    @observable private mainDoc: any = CurrentUserUtils.setupMobileMenu();
+    @observable private mainDoc: any = CurrentUserUtils.setupActiveMobile(this.userDoc);
     @observable private renderView?: () => JSX.Element;
     @observable private audioState: any;
     @observable private activeToolbar: boolean = false;
@@ -86,13 +83,7 @@ export class MobileInterface extends React.Component {
 
     @action
     componentDidMount = () => {
-        library.add(...[faPenNib, faHighlighter, faEraser, faMousePointer, faThumbtack]);
-        if (this.userDoc.activeMobile) {
-            console.log(Doc.UserDoc().activeMobile);
-        }
-        if (this.userDoc && !this.mainContainer) {
-            this.userDoc.activeMobile = this._homeDoc;
-        }
+        Doc.UserDoc().activeMobile = this._homeDoc;
         this._homeDoc._viewType === "stacking" ? this.menuListView = true : this.menuListView = false;
         Doc.SetSelectedTool(InkTool.None);
         this.switchCurrentView((userDoc: Doc) => this._homeDoc);
@@ -353,26 +344,6 @@ export class MobileInterface extends React.Component {
                 <div className="hidePath" />
             </div>);
         }
-        //     }
-        // } else {
-
-        //     return (
-        //         <div className="pathbar">
-        //             <div className="scrollmenu">
-        //                 <div className="pathbarItem">
-        //                     <div className="pathbarText"
-        //                         style={{ backgroundColor: "rgb(119, 37, 37)" }}
-        //                         key={0}
-        //                         onClick={() => this.returnHome()}>Home
-        //                     </div>
-        //                 </div>
-        //             </div>
-        //             <div className="hidePath" />
-        //         </div>
-        //     );
-        // }
-
-        // }
     }
 
     // Handles when user clicks on document in the pathbar
@@ -393,16 +364,6 @@ export class MobileInterface extends React.Component {
     }
 
     renderDefaultContent = () => {
-        let menuButtons = DocListCast(this._homeDoc.data).map((doc: Doc, index: any) => {
-            if (doc.type !== "ink") {
-                return (
-                    <div
-                        className="item"
-                        key={index}
-                        onClick={() => doc.onClick}>{doc.title}
-                    </div>);
-            }
-        });
 
         if (this._homeMenu === true) {
             return (
@@ -420,7 +381,10 @@ export class MobileInterface extends React.Component {
                     {this.renderPathbar()}
                     <div className="sidebar" id="sidebar">
                         <div className="sidebarButtons">
-                            {menuButtons}
+                            <div
+                                className="item"
+                                onClick={() => ScriptField.MakeScript("createNewWorkspace()")}>Create New Workspace
+                            </div>
                         </div>
                     </div>
                 </div>
@@ -429,7 +393,7 @@ export class MobileInterface extends React.Component {
 
         let workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
         if (this._child) {
-            workspaces = this._child
+            workspaces = this._child;
         }
 
         let buttons = DocListCast(workspaces.data).map((doc: Doc, index: any) => {
@@ -468,6 +432,10 @@ export class MobileInterface extends React.Component {
                             </> :
                             <>
                                 {buttons}
+                                <div
+                                    className="item"
+                                    onClick={() => ScriptField.MakeScript("createNewWorkspace()")}>Create New Workspace
+                                </div>
                             </>
                         }
                     </div>
@@ -627,100 +595,12 @@ export class MobileInterface extends React.Component {
         // this.recordAudio();
     }
 
-    // renderActiveCollection = (userDoc: Doc) => {
-    //     if (this.activeContainer) {
-    //         const active = Cast(this.activeContainer.data, listSpec(Doc));
-    //         if (active) {
-    //             return (
-    //                 <div className="mobileInterface-background">HELLO!</div>
-    //             );
-    //         }
-    //     }
-    // }
-
-    onBack = (e: React.MouseEvent) => {
-        this.switchCurrentView((userDoc: Doc) => this.mainDoc);
-        Doc.SetSelectedTool(InkTool.None); // TODO: switch to previous tool
-
-        DocServer.Mobile.dispatchOverlayTrigger({
-            enableOverlay: false,
-            width: window.innerWidth,
-            height: window.innerHeight
-        });
-
-        // this.inkDoc = undefined;
-        this.drawingInk = false;
-    }
-
-    shiftLeft = (e: React.MouseEvent) => {
-        DocServer.Mobile.dispatchOverlayPositionUpdate({
-            dx: -10
-        });
-        e.preventDefault();
-        e.stopPropagation();
-    }
-
-    shiftRight = (e: React.MouseEvent) => {
-        DocServer.Mobile.dispatchOverlayPositionUpdate({
-            dx: 10
-        });
-        e.preventDefault();
-        e.stopPropagation();
-    }
-
     panelHeight = () => window.innerHeight;
     panelWidth = () => window.innerWidth;
     //WAS 3
 
     //WAS 1
 
-    upload = async (e: React.MouseEvent) => {
-        if (this.mainContainer) {
-            const data = Cast(this.mainContainer.data, listSpec(Doc));
-            if (data) {
-                const collectionDoc = await data[1]; //this should be the collection doc since the positions should be locked
-                const children = DocListCast(collectionDoc.data);
-                const uploadDoc = children.length === 1 ? children[0] : Docs.Create.StackingDocument(children, {
-                    title: "Mobile Upload Collection", backgroundColor: "white", lockedPosition: true, _width: 300, _height: 300
-                });
-                if (uploadDoc) {
-                    DocServer.Mobile.dispatchMobileDocumentUpload({
-                        docId: uploadDoc[Id],
-                    });
-                }
-            }
-        }
-        e.stopPropagation();
-        e.preventDefault();
-    }
-
-    addWebToCollection = async () => {
-        let url = "https://en.wikipedia.org/wiki/Hedgehog";
-        if (this.mainContainer) {
-            const data = Cast(this.mainContainer.data, listSpec(Doc));
-            if (data) {
-                const webDoc = await data[0];
-                const urlField: FieldResult<WebField> = Cast(webDoc.data, WebField);
-                url = urlField ? urlField.url.toString() : "https://en.wikipedia.org/wiki/Hedgehog";
-
-            }
-        }
-        Docs.Create.WebDocument(url, { _width: 300, _height: 300, title: "Mobile Upload Web Doc" });
-    }
-
-    clearUpload = async () => {
-        if (this.mainContainer) {
-            const data = Cast(this.mainContainer.data, listSpec(Doc));
-            if (data) {
-                const collectionDoc = await data[1];
-                const children = DocListCast(collectionDoc.data);
-                children.forEach(doc => {
-                });
-                // collectionDoc[data] = new List<Doc>();
-            }
-        }
-    }
-
     pinToPresentation = () => {
         // Only making button available if it is an image
         if (this._activeDoc.type === "image") {
@@ -845,7 +725,6 @@ export class MobileInterface extends React.Component {
                     {this.uploadAudioButton()}
                     {/* {this.colorTool()} */}
                     {this.inkMenu()}
-                    <InkOptionsMenu />
                 </div>
                 <GestureOverlay>
                     {this.displayWorkspaces()}
@@ -879,14 +758,6 @@ export class MobileInterface extends React.Component {
         this.imageUploadActive = false;
     }
 
-    // toggleUpload = () => {
-    //     if (this.imageUploadActive === true) {
-    //         this.imageUploadActive = false;
-    //     } else {
-    //         this.imageUploadActive = true;
-    //     }
-    // }
-
     uploadImage = () => {
         if (this.imageUploadActive) {
             console.log("active");
@@ -905,11 +776,6 @@ export class MobileInterface extends React.Component {
     }
 }
 
-
-
-const inputRef = React.createRef<HTMLInputElement>();
-
-
 Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); });
 Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); });
 Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); });
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index da1e9d951..44d3acb6f 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -96,7 +96,7 @@ body {
 }
 
 .sidebar {
-    position: absolute;
+    position: fixed;
     top: 120px;
     opacity: 0;
     right: -100%;
@@ -212,7 +212,7 @@ body {
 }
 
 .pathbar {
-    position: absolute;
+    position: fixed;
     top: 118px;
     left: 0px;
     background: #1a1a1a;
@@ -373,7 +373,7 @@ body {
 }
 
 .homeSwitch {
-    position: absolute;
+    position: fixed;
     top: 212;
     right: 36px;
     display: inline-flex;
@@ -401,4 +401,4 @@ body {
 .list.active {
     color: darkred;
     border-color: darkred;
-}
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 4b1dc65c9e0bb917c1f1f780f8a63fc0c91b4ad6 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Tue, 16 Jun 2020 23:53:16 +0800
Subject: mobile menu bug fixes + doc button fix

---
 deploy/mobile/image.html                           |  1 +
 src/client/util/CurrentUserUtils.ts                | 73 ++++++++++++----------
 .../views/collections/CollectionStackingView.tsx   |  2 +-
 src/client/views/nodes/AudioBox.tsx                |  2 +-
 src/client/views/nodes/PresBox.scss                |  5 ++
 src/client/views/nodes/RadialMenu.tsx              |  6 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |  3 +-
 .../views/presentationview/PresElementBox.scss     |  2 +-
 src/mobile/MobileInterface.tsx                     | 69 +++++++-------------
 src/mobile/MobileMenu.scss                         |  4 +-
 10 files changed, 77 insertions(+), 90 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/deploy/mobile/image.html b/deploy/mobile/image.html
index d30ad6ac2..718550f02 100644
--- a/deploy/mobile/image.html
+++ b/deploy/mobile/image.html
@@ -3,6 +3,7 @@
 <head>
     <title>Dash Mobile</title>
     <link href="https://fonts.googleapis.com/css?family=Fjalla+One|Hind+Siliguri:300" rel="stylesheet">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=0" />
 </head>
 
 <body>
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 323e398be..9ce162897 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -55,6 +55,15 @@ export class CurrentUserUtils {
             });
         }
 
+        if (doc["template-mobile-button"] === undefined) {
+            const queryTemplate = this.mobileButton({ title: "NEW MOBILE BUTTON", onClick: undefined, _backgroundColor: "lightgrey" }, [this.ficon({ ignoreClick: true, icon: "mobile", backgroundColor: "rgba(0,0,0,0)" }), this.mobileTextContainer({}, [this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])]);
+            doc["template-mobile-button"] = CurrentUserUtils.ficon({
+                onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'),
+                dragFactory: new PrefetchProxy(queryTemplate) as any as Doc,
+                removeDropProperties: new List<string>(["dropAction"]), title: "mobile button", icon: "mobile"
+            });
+        }
+
         if (doc["template-button-slides"] === undefined) {
             const slideTemplate = Docs.Create.MultirowDocument(
                 [
@@ -165,16 +174,6 @@ export class CurrentUserUtils {
             });
         }
 
-        // if (doc["mobile-button"] === undefined) {
-        //     const mobileTemplate = this.mobileButton({ title: "mobile button", _backgroundColor: "lightgrey" }, [this.ficon({ ignoreClick: true, icon: "mobile", backgroundColor: "rgba(0,0,0,0)" }), this.mobileTextContainer({}, [this.mobileButtonText({}, "text"), this.mobileButtonInfo({}, "This is a default mobile button for use in the mobile menu")])]);
-        //     mobileTemplate.isTemplateDoc = makeTemplate(mobileTemplate);
-        //     doc["mobile-button"] = CurrentUserUtils.ficon({
-        //         onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'),
-        //         dragFactory: new PrefetchProxy(mobileTemplate) as any as Doc,
-        //         removeDropProperties: new List<string>(["dropAction"]), title: "mobile button view", icon: "mobile"
-        //     });
-        // }
-
         if (doc["template-button-detail"] === undefined) {
             const { TextDocument, MasonryDocument, CarouselDocument } = Docs.Create;
 
@@ -229,6 +228,7 @@ export class CurrentUserUtils {
             doc["template-button-slides"] as Doc,
             doc["template-button-description"] as Doc,
             doc["template-button-query"] as Doc,
+            doc["template-mobile-button"] as Doc,
             doc["template-button-detail"] as Doc,
             doc["template-button-link"] as Doc,
             doc["template-button-switch"] as Doc];
@@ -378,9 +378,8 @@ export class CurrentUserUtils {
         if (doc.emptyWebpage === undefined) {
             doc.emptyWebpage = Docs.Create.WebDocument("", { title: "New Webpage", _nativeWidth: 850, _nativeHeight: 962, _width: 600, UseCors: true });
         }
-        if (doc.activeMobile === undefined) {
-            console.log("phone setup");
-            this.setupActiveMobile(doc);
+        if (doc.activeMobileMenu === undefined) {
+            this.setupActiveMobileMenu(doc);
         }
         return [
             { title: "Drag a comparison box", label: "Comp", icon: "columns", ignoreClick: true, drag: 'Docs.Create.ComparisonDocument()' },
@@ -395,7 +394,7 @@ export class CurrentUserUtils {
             { title: "Drag a search box", label: "Query", icon: "search", ignoreClick: true, drag: 'Docs.Create.QueryDocument({ _width: 200, title: "an image of a cat" })' },
             { title: "Drag a scripting box", label: "Script", icon: "terminal", ignoreClick: true, drag: 'Docs.Create.ScriptingDocument(undefined, { _width: 200, _height: 250 title: "untitled script" })' },
             { title: "Drag an import folder", label: "Load", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' },
-            { title: "Drag a mobile view", label: "Phone", icon: "mobile", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory,true)', dragFactory: doc.activeMobile as Doc },
+            { title: "Drag a mobile view", label: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc },
             { title: "Drag an instance of the device collection", label: "Buxton", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.Buxton()' },
             // { title: "use pen", icon: "pen-nib", click: 'activatePen(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this)', backgroundColor: "blue", ischecked: `sameDocs(this.activeInkPen,  this)`, activeInkPen: doc },
             // { title: "use highlighter", icon: "highlighter", click: 'activateBrush(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this,20,this.backgroundColor)', backgroundColor: "yellow", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc },
@@ -449,12 +448,12 @@ export class CurrentUserUtils {
         return doc.myItemCreators as Doc;
     }
 
-    static setupActiveMobile(doc: Doc) {
-        if (doc.activeMobile === undefined) {
+    static setupActiveMobileMenu(doc: Doc) {
+        if (doc.activeMobileMenu === undefined) {
             console.log("undefined");
-            doc.activeMobile = this.setupMobileMenu();
+            doc.activeMobileMenu = this.setupMobileMenu();
         }
-        return doc.activeMobile as Doc;
+        return doc.activeMobileMenu as Doc;
     }
 
     static setupMobileMenu() {
@@ -466,37 +465,45 @@ export class CurrentUserUtils {
 
     static setupMobileButtons(doc?: Doc, buttons?: string[]) {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
-            { title: "LIBRARY", icon: "bars", click: 'switchToLibrary()', backgroundColor: "#ffd6d6", info: "Navigate and access all of your documents within their respective collections" },
-            { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your mobile to record audio and access it on Dash Web." },
-            { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "#ff9e9e", info: "Upload an image from your mobile device so it can be accessed on Dash Web" },
+            { title: "LIBRARY", icon: "bars", click: 'switchToLibrary()', backgroundColor: "#ffd6d6", info: "Navigate and access all of your documents within their respective collections." },
+            { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your phone to record and upload audio onto Dash Web." },
+            { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "#ff9e9e", info: "Upload images or videos from your mobile device so they can be accessed on Dash Web." },
             { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "#ff8080", info: "Use your phone as a remote for you presentation." },
-            { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "#ff5e5e", info: "Change your password, log out, or manage your account security" }
+            { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "#ff5e5e", info: "Change your password, log out, or manage your account security." }
         ];
-        return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => this.mobileButton({ title: data.title, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined, _backgroundColor: data.backgroundColor }, [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)" }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])]));
+        return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data =>
+            this.mobileButton({
+                title: data.title,
+                lockedPosition: true,
+                onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
+                _backgroundColor: data.backgroundColor
+            },
+                [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)" }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])])
+        );
     }
 
-    static mobileButton = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.MulticolumnDocument(docs, {
+    static mobileButton = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.MulticolumnDocument(docs, {
         ...opts,
         dropAction: undefined, removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 900, _nativeHeight: 250, _width: 900, _height: 250, _yMargin: 15,
-        borderRounding: "5px", boxShadow: "0 0", _chromeStatus: "disabled",
-    })) as any as Doc
+        borderRounding: "5px", boxShadow: "0 0", _chromeStatus: "disabled"
+    }) as any as Doc
 
-    static mobileTextContainer = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.MultirowDocument(docs, {
+    static mobileTextContainer = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.MultirowDocument(docs, {
         ...opts,
         dropAction: undefined, removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 450, _nativeHeight: 250, _width: 450, _height: 250, _yMargin: 25,
         backgroundColor: "rgba(0,0,0,0)", borderRounding: "0", boxShadow: "0 0", _chromeStatus: "disabled", ignoreClick: true
-    })) as any as Doc
+    }) as any as Doc
 
 
-    static mobileButtonText = (opts: DocumentOptions, buttonTitle: string) => new PrefetchProxy(Docs.Create.TextDocument(buttonTitle, {
+    static mobileButtonText = (opts: DocumentOptions, buttonTitle: string) => Docs.Create.TextDocument(buttonTitle, {
         ...opts,
         dropAction: undefined, title: buttonTitle, _fontSize: 37, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)"
-    })) as any as Doc
+    }) as any as Doc
 
-    static mobileButtonInfo = (opts: DocumentOptions, buttonInfo: string) => new PrefetchProxy(Docs.Create.TextDocument(buttonInfo, {
+    static mobileButtonInfo = (opts: DocumentOptions, buttonInfo: string) => Docs.Create.TextDocument(buttonInfo, {
         ...opts,
         dropAction: undefined, title: "info", _fontSize: 25, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)", _dimMagnitude: 2,
-    })) as any as Doc
+    }) as any as Doc
 
 
     static setupThumbButtons(doc: Doc) {
@@ -795,7 +802,7 @@ export class CurrentUserUtils {
         this.setupDefaultIconTemplates(doc);  // creates a set of icon templates triggered by the document deoration icon
         this.setupDocTemplates(doc); // sets up the template menu of templates
         this.setupRightSidebar(doc);  // sets up the right sidebar collection for mobile upload documents and sharing
-        this.setupActiveMobile(doc);
+        this.setupActiveMobileMenu(doc);
         this.setupOverlays(doc);  // documents in overlay layer
         this.setupDockedButtons(doc);  // the bottom bar of font icons
         this.setupDefaultPresentation(doc); // presentation that's initially triggered
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 0a1b03522..bd0b69da8 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -476,7 +476,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
                         transformOrigin: "top left",
                     }}
                     onScroll={action(e => {
-                        if (!this.props.isSelected()) e.currentTarget.scrollTop = this._scroll;
+                        if (!this.props.isSelected() && window.innerWidth > 1000) e.currentTarget.scrollTop = this._scroll;
                         else this._scroll = e.currentTarget.scrollTop;
                     })}
                     onDrop={this.onExternalDrop.bind(this)}
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 1a935d9b0..2e0be1c6a 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -228,7 +228,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
             {!this.path ?
                 <div className="audiobox-buttons">
                     <div className="audiobox-dictation" onClick={this.onFile}>
-                        <FontAwesomeIcon style={{ width: "30px", background: this.layoutDoc.playOnSelect ? "yellow" : "dimGray" }} icon="file-alt" size={this.props.PanelHeight() < 36 ? "1x" : "2x"} />
+                        <FontAwesomeIcon style={{ width: "30px", background: this.layoutDoc.playOnSelect ? "yellow" : "rgba(0,0,0,0)" }} icon="file-alt" size={this.props.PanelHeight() < 36 ? "1x" : "2x"} />
                     </div>
                     <button className={`audiobox-record${interactive}`} style={{ backgroundColor: this.audioState === "recording" ? "red" : "black" }}>
                         {this.audioState === "recording" ? "STOP" : "RECORD"}
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 2bb249ee4..ccce6e627 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -126,4 +126,9 @@
         position: absolute;
         min-width: 50px;
     }
+
+    .input,
+    .select {
+        font-size: 100%;
+    }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/RadialMenu.tsx b/src/client/views/nodes/RadialMenu.tsx
index ddfdb67b4..2bbb80b2a 100644
--- a/src/client/views/nodes/RadialMenu.tsx
+++ b/src/client/views/nodes/RadialMenu.tsx
@@ -1,9 +1,9 @@
 import React = require("react");
 import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import MobileInterface from "../../../mobile/MobileInterface";
 import "./RadialMenu.scss";
 import { RadialMenuItem, RadialMenuProps } from "./RadialMenuItem";
+import { MobileInterface } from "../../../mobile/MobileInterface";
 
 @observer
 export class RadialMenu extends React.Component {
@@ -38,7 +38,6 @@ export class RadialMenu extends React.Component {
         this._mouseY = e.clientY;
         this.used = false;
         document.addEventListener("pointermove", this.onPointerMove);
-
     }
 
     @observable
@@ -176,7 +175,6 @@ export class RadialMenu extends React.Component {
 
     @action
     openMenu = (x: number, y: number) => {
-
         this._pageX = x;
         this._pageY = y;
         this._shouldDisplay;
@@ -216,7 +214,7 @@ export class RadialMenu extends React.Component {
 
 
     render() {
-        if (!this._display || MobileInterface.Instance) {
+        if (!this._display) {
             return null;
         }
         const style = this._yRelativeToTop ? { left: this._pageX - 130, top: this._pageY - 130 } :
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 1db50a5cc..912bafc46 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -262,7 +262,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
 
     public unhighlightSearchTerms = () => {
-        if (this._editorView && (this._editorView as any).docView) {
+        if (window.innerWidth < 1000) null;
+        else if (this._editorView && (this._editorView as any).docView) {
             const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
             const activeMark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight, { selected: true });
             const end = this._editorView.state.doc.nodeSize - 2;
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index ec82b0c51..bf268eb8d 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -79,7 +79,7 @@
 }
 
 .presElementBox-name {
-    font-size: 12pxππ;
+    font-size: 12px;
     position: absolute;
     display: inline-block;
     width: calc(100% - 45px);
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 25dc9fd55..7af11a9c4 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -35,6 +35,7 @@ import { nullAudio } from '../fields/URLField';
 import GestureOverlay from "../client/views/GestureOverlay";
 import { ScriptField } from "../fields/ScriptField";
 import InkOptionsMenu from "../client/views/collections/collectionFreeForm/InkOptionsMenu";
+import { RadialMenu } from "../client/views/nodes/RadialMenu";
 
 library.add(faTasks, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
@@ -48,7 +49,7 @@ export class MobileInterface extends React.Component {
     @observable static Instance: MobileInterface;
     @computed private get userDoc() { return Doc.UserDoc(); }
     @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
-    @observable private mainDoc: any = CurrentUserUtils.setupActiveMobile(this.userDoc);
+    @observable private mainDoc: any = CurrentUserUtils.setupActiveMobileMenu(this.userDoc);
     @observable private renderView?: () => JSX.Element;
     @observable private sidebarActive: boolean = false;
     @observable private imageUploadActive: boolean = false;
@@ -94,31 +95,6 @@ export class MobileInterface extends React.Component {
         this.renderView = renderView;
     }
 
-    onSwitchUpload = async () => {
-        let width = 300;
-        let height = 300;
-        const res = await rp.get(Utils.prepend("/getUserDocumentId"));
-
-        // get width and height of the collection doc
-        if (this.mainContainer) {
-            const data = Cast(this.mainContainer.data, listSpec(Doc));
-            if (data) {
-                const collectionDoc = await data[1]; // this should be the collection doc since the positions should be locked
-                const docView = DocumentManager.Instance.getDocumentView(collectionDoc);
-                if (docView) {
-                    width = docView.nativeWidth ? docView.nativeWidth : 300;
-                    height = docView.nativeHeight ? docView.nativeHeight : 300;
-                }
-            }
-        }
-        DocServer.Mobile.dispatchOverlayTrigger({
-            enableOverlay: true,
-            width: width,
-            height: height,
-            text: "Documents uploaded from mobile will show here",
-        });
-    }
-
     // For toggling the hamburger menu
     @action
     toggleSidebar = () => this.sidebarActive = !this.sidebarActive
@@ -138,8 +114,8 @@ export class MobileInterface extends React.Component {
      * Back method for navigating
      */
     back = () => {
-        let header = document.getElementById("header") as HTMLElement;
-        let doc = Cast(this._parents.pop(), Doc) as Doc;
+        const header = document.getElementById("header") as HTMLElement;
+        const doc = Cast(this._parents.pop(), Doc) as Doc;
 
         if (doc === Cast(this._library, Doc) as Doc) {
             this._child = null;
@@ -198,7 +174,7 @@ export class MobileInterface extends React.Component {
         if (this.mainContainer) {
             const backgroundColor = () => "white";
             return (
-                <div style={{ position: "relative", top: '200px', height: `calc(100% - 200px)`, width: "100%", overflow: "hidden", left: "0%" }}>
+                <div style={{ position: "relative", top: '200px', height: `calc(100% - 350px)`, width: "100%", left: "0%" }}>
                     <DocumentView
                         Document={this.mainContainer}
                         DataDoc={undefined}
@@ -238,16 +214,15 @@ export class MobileInterface extends React.Component {
      * @param doc: doc for which the method is called
      */
     handleClick = async (doc: Doc) => {
-        let children = DocListCast(doc.data);
+        const children = DocListCast(doc.data);
         if (doc.type !== "collection") {
             this._parents.push(this._activeDoc);
             this._activeDoc = doc;
             this.switchCurrentView((userDoc: Doc) => doc);
             this._homeMenu = false;
             this.toggleSidebar();
-        } else if (doc.type === "collection" && children.length === 0) {
-            console.log("This collection has no children");
-        } else {
+        } else if (doc.type === "collection" && children.length === 0) console.log("This collection has no children");
+        else {
             this._parents.push(this._activeDoc);
             this._activeDoc = doc;
             this.switchCurrentView((userDoc: Doc) => doc);
@@ -260,7 +235,7 @@ export class MobileInterface extends React.Component {
      * Handles creation of array which is then rendered in renderPathbar()
      */
     createPathname = () => {
-        let docArray = [];
+        const docArray = [];
         this._parents.map((doc: Doc, index: any) => {
             docArray.push(doc);
         });
@@ -270,8 +245,8 @@ export class MobileInterface extends React.Component {
 
     // Renders the graphical pathbar
     renderPathbar = () => {
-        let docArray = this.createPathname();
-        let items = docArray.map((doc: Doc, index: any) => {
+        const docArray = this.createPathname();
+        const items = docArray.map((doc: Doc, index: any) => {
             if (index === 0) {
                 return (
                     <>
@@ -341,9 +316,8 @@ export class MobileInterface extends React.Component {
             this._child = null;
             this.switchCurrentView((userDoc: Doc) => doc);
             this._parents.length = index;
-        } else if (doc === this._homeDoc) {
-            this.returnHome();
-        } else {
+        } else if (doc === this._homeDoc) this.returnHome();
+        else {
             this._activeDoc = doc;
             this._child = doc;
             this.switchCurrentView((userDoc: Doc) => doc);
@@ -384,7 +358,7 @@ export class MobileInterface extends React.Component {
             workspaces = this._child;
         }
 
-        let buttons = DocListCast(workspaces.data).map((doc: Doc, index: any) => {
+        const buttons = DocListCast(workspaces.data).map((doc: Doc, index: any) => {
             if (doc.type !== "ink") {
                 return (
                     <div
@@ -473,7 +447,7 @@ export class MobileInterface extends React.Component {
                 console.log("here");
                 return <div className="colorSelector">
                     <InkOptionsMenu />
-                </div>
+                </div>;
 
             }
         }
@@ -677,17 +651,18 @@ export class MobileInterface extends React.Component {
                     {this.uploadImage()}
                 </div>
                 {this.switchMenuView()}
-                <div className="docButtonContainer">
-                    {this.pinToPresentation()}
-                    {this.downloadDocument()}
-                    {this.drawInk()}
-                    {this.uploadAudioButton()}
-                </div>
                 {this.inkMenu()}
                 <GestureOverlay>
+                    <div className="docButtonContainer">
+                        {this.pinToPresentation()}
+                        {this.downloadDocument()}
+                        {this.drawInk()}
+                        {this.uploadAudioButton()}
+                    </div>
                     {this.displayWorkspaces()}
                     {this.renderDefaultContent()}
                 </GestureOverlay>
+                <RadialMenu />
             </div>
         );
     }
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 8d996f779..3126a7d0e 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -256,7 +256,7 @@ body {
 }
 
 .docButtonContainer {
-    top: 90%;
+    top: 80%;
     position: absolute;
     display: flex;
     transform: translate(-50%, 0);
@@ -306,7 +306,7 @@ body {
     width: 200px;
     left: 0px;
     top: 0px;
-    background-image: linear-gradient(to right, #1a1a1a, rgba(255, 0, 0, 0));
+    background-image: linear-gradient(to right, #1a1a1a, rgba(0, 0, 0, 0));
     text-align: center;
     user-select: none;
     z-index: 99;
-- 
cgit v1.2.3-70-g09d2


From 6d68abf588f7b6182a62b74882d1fdc09b2b0230 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Tue, 16 Jun 2020 09:50:22 -0700
Subject: bug fixes

---
 .../collectionFreeForm/InkOptionsMenu.tsx          |  2 +-
 src/mobile/MobileInterface.tsx                     | 30 ++++------------------
 src/mobile/MobileMenu.scss                         |  3 +++
 3 files changed, 9 insertions(+), 26 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
index 8bebcd047..e7ef4cbd2 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
@@ -107,7 +107,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
                 onPointerDown={action(e => GestureOverlay.Instance.InkShape = btn)}
                 style={{ backgroundColor: btn === GestureOverlay.Instance?.InkShape ? "121212" : "" }}>
                 {this._icons[i]}
-            </button>)},
+            </button>)}
         </>;
     }
 
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 25dc9fd55..5d361f3ab 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -78,6 +78,11 @@ export class MobileInterface extends React.Component {
         document.addEventListener("dblclick", this.onReactDoubleClick);
     }
 
+    @action
+    componentWillUnmount = () => {
+        document.removeEventListener('dblclick', this.onReactDoubleClick);
+    }
+
     // Prevent zooming in when double tapping the screen
     onReactDoubleClick = (e: MouseEvent) => {
         e.stopPropagation();
@@ -94,31 +99,6 @@ export class MobileInterface extends React.Component {
         this.renderView = renderView;
     }
 
-    onSwitchUpload = async () => {
-        let width = 300;
-        let height = 300;
-        const res = await rp.get(Utils.prepend("/getUserDocumentId"));
-
-        // get width and height of the collection doc
-        if (this.mainContainer) {
-            const data = Cast(this.mainContainer.data, listSpec(Doc));
-            if (data) {
-                const collectionDoc = await data[1]; // this should be the collection doc since the positions should be locked
-                const docView = DocumentManager.Instance.getDocumentView(collectionDoc);
-                if (docView) {
-                    width = docView.nativeWidth ? docView.nativeWidth : 300;
-                    height = docView.nativeHeight ? docView.nativeHeight : 300;
-                }
-            }
-        }
-        DocServer.Mobile.dispatchOverlayTrigger({
-            enableOverlay: true,
-            width: width,
-            height: height,
-            text: "Documents uploaded from mobile will show here",
-        });
-    }
-
     // For toggling the hamburger menu
     @action
     toggleSidebar = () => this.sidebarActive = !this.sidebarActive
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 8d996f779..cd531056e 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -20,6 +20,7 @@ body {
     height: $navbar-height;
     background-color: whitesmoke;
     border-bottom: 5px solid black;
+    z-index: 150;
 }
 
 .navbar .cover {
@@ -192,8 +193,10 @@ body {
 
 
 .sidebar.active {
+    position: absolute;
     right: 0%;
     opacity: 1;
+    z-index: 101;
 }
 
 .back {
-- 
cgit v1.2.3-70-g09d2


From 5b7b2a3e083d532758409474b8549b7bc16e7a4e Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Tue, 16 Jun 2020 21:01:05 -0700
Subject: fix css

---
 deploy/mobile/image.html        | 1 -
 src/mobile/MobileInterface.scss | 2 +-
 src/mobile/MobileInterface.tsx  | 5 +++--
 src/mobile/MobileMenu.scss      | 5 +++++
 4 files changed, 9 insertions(+), 4 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/deploy/mobile/image.html b/deploy/mobile/image.html
index 718550f02..d30ad6ac2 100644
--- a/deploy/mobile/image.html
+++ b/deploy/mobile/image.html
@@ -3,7 +3,6 @@
 <head>
     <title>Dash Mobile</title>
     <link href="https://fonts.googleapis.com/css?family=Fjalla+One|Hind+Siliguri:300" rel="stylesheet">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=0" />
 </head>
 
 <body>
diff --git a/src/mobile/MobileInterface.scss b/src/mobile/MobileInterface.scss
index 215ce02e5..86b043590 100644
--- a/src/mobile/MobileInterface.scss
+++ b/src/mobile/MobileInterface.scss
@@ -33,4 +33,4 @@
     position: relative;
     touch-action: none;
     background-color: pink;
-}
\ No newline at end of file
+}
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 5054dd560..68fb8b28f 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -321,8 +321,9 @@ export class MobileInterface extends React.Component {
             this._child = null;
             this.switchCurrentView((userDoc: Doc) => doc);
             this._parents.length = index;
-        } else if (doc === this._homeDoc) this.returnHome();
-        else {
+        } else if (doc === this._homeDoc) {
+            this.returnHome();
+        } else {
             this._activeDoc = doc;
             this._child = doc;
             this.switchCurrentView((userDoc: Doc) => doc);
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index e5703c5fb..55c62f458 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -56,6 +56,11 @@ body {
     user-select: none;
     text-transform: uppercase;
     font-family: Arial, Helvetica, sans-serif;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    direction: ltr;
+    width: 600px;
 }
 
 .navbar .toggle-btn span {
-- 
cgit v1.2.3-70-g09d2


From 3ccc8e92682bfa257ef2052513b1826b811f6881 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Wed, 17 Jun 2020 19:04:45 +0800
Subject: long sidebar menu item fixes

---
 src/mobile/MobileInterface.tsx |  5 +++--
 src/mobile/MobileMenu.scss     | 12 +++++++++++-
 2 files changed, 14 insertions(+), 3 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 68fb8b28f..5acdc1dea 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -370,8 +370,9 @@ export class MobileInterface extends React.Component {
                     <div
                         className="item"
                         key={index}
-                        onClick={() => this.handleClick(doc)}>{doc.title}
-                        <div className="type">{doc.type}</div>
+                        onClick={() => this.handleClick(doc)}>
+                        <div className="item-title"> {doc.title} </div>
+                        <div className="item-type">{doc.type}</div>
                         <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
                     </div>);
             }
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 55c62f458..6304ff5e4 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -53,6 +53,8 @@ body {
     right: 50%;
     transform: translate(50%, -50%);
     font-size: 40;
+    font-weight: 700;
+    text-align: center;
     user-select: none;
     text-transform: uppercase;
     font-family: Arial, Helvetica, sans-serif;
@@ -125,6 +127,7 @@ body {
     font-style: normal;
     font-weight: normal;
     user-select: none;
+    display: inline-flex;
     font-size: 35px;
     text-transform: uppercase;
     color: black;
@@ -151,7 +154,7 @@ body {
     z-index: 200;
 }
 
-.type {
+.item-type {
     display: inline;
     text-transform: lowercase;
     margin-left: 20px;
@@ -160,6 +163,13 @@ body {
     color: rgb(28, 28, 28);
 }
 
+.item-title {
+    max-width: 70%;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
 .right {
     margin-left: 20px;
     z-index: 200;
-- 
cgit v1.2.3-70-g09d2


From 57d4c562b6f0ef39dcd68f2985a56c4a683fcf49 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Thu, 18 Jun 2020 04:38:08 +0800
Subject: pdf changes + radial menu + create new workspaces

(bug with ink)
---
 src/client/views/GestureOverlay.tsx                |  8 ---
 .../views/collections/CollectionStackingView.tsx   |  2 +-
 .../collectionFreeForm/InkOptionsMenu.tsx          |  4 +-
 src/client/views/nodes/DocumentView.tsx            | 12 ++--
 src/client/views/nodes/PDFBox.scss                 |  2 +-
 src/client/views/nodes/PDFBox.tsx                  |  7 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |  2 +-
 src/client/views/pdf/PDFViewer.tsx                 |  4 +-
 src/mobile/ImageUpload.tsx                         |  6 +-
 src/mobile/MobileInterface.tsx                     | 80 +++++++++++++++++++---
 src/server/ApiManagers/PDFManager.ts               |  3 +-
 11 files changed, 94 insertions(+), 36 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index e51e2d4e1..1c305ebeb 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -575,14 +575,6 @@ export default class GestureOverlay extends Touchable {
             const points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top }));
             //push first points to so interactionUtil knows pointer is up
             this._points.push({ X: this._points[0].X, Y: this._points[0].Y });
-            if (MobileInterface.Instance && MobileInterface.Instance.drawingInk) {
-                DocServer.Mobile.dispatchGesturePoints({
-                    points: this._points,
-                    bounds: B,
-                    color: ActiveInkColor(),
-                    width: ActiveInkWidth()
-                });
-            }
 
             const initialPoint = this._points[0.];
             const xInGlass = initialPoint.X > (this._thumbX ?? Number.MAX_SAFE_INTEGER) && initialPoint.X < (this._thumbX ?? Number.MAX_SAFE_INTEGER) + (this.height);
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 797aabf18..9f1b5d63c 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -476,7 +476,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
                         transformOrigin: "top left",
                     }}
                     onScroll={action(e => {
-                        if (!this.props.isSelected() && this.props.renderDepth && window.innerWidth > 1000) e.currentTarget.scrollTop = this._scroll;
+                        if (!this.props.isSelected() && this.props.renderDepth && window.screen.width > 600) e.currentTarget.scrollTop = this._scroll;
                         else this._scroll = e.currentTarget.scrollTop;
                     })}
                     onDrop={this.onExternalDrop.bind(this)}
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
index 647847b68..676dc10f4 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
@@ -130,13 +130,13 @@ export default class InkOptionsMenu extends AntimodeMenu {
         ];
 
         const mobileButtons = [
-            this.shapeButtons,
+            ...this.shapeButtons,
             this.bezierButton,
             this.widthPicker,
             this.colorPicker,
         ];
 
-        return (window.innerWidth < 1000 ? this.getElement(mobileButtons) : this.getElement(buttons));
+        return (window.screen.width < 600 ? this.getElement(mobileButtons) : this.getElement(buttons));
     }
 }
 Scripting.addGlobal(function activatePen(penBtn: any) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 75627607b..e027b6a0f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -31,7 +31,7 @@ import { SelectionManager } from "../../util/SelectionManager";
 import SharingManager from '../../util/SharingManager';
 import { Transform } from "../../util/Transform";
 import { undoBatch, UndoManager } from "../../util/UndoManager";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
+import { CollectionDockingView, DockedFrameRenderer } from "../collections/CollectionDockingView";
 import { CollectionView, CollectionViewType } from '../collections/CollectionView';
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from '../ContextMenuItem';
@@ -43,6 +43,7 @@ import "./DocumentView.scss";
 import { LinkAnchorBox } from './LinkAnchorBox';
 import { RadialMenu } from './RadialMenu';
 import React = require("react");
+import { MobileInterface } from '../../../mobile/MobileInterface';
 
 library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
     fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
@@ -181,10 +182,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const pt = me.touchEvent.touches[me.touchEvent.touches.length - 1];
         RadialMenu.Instance.openMenu(pt.pageX - 15, pt.pageY - 15);
 
-        RadialMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "map-pin", selected: -1 });
-        RadialMenu.Instance.addItem({ description: "Delete this document", event: () => { this.props.ContainingCollectionView?.removeDocument(this.props.Document), RadialMenu.Instance.closeMenu(); }, icon: "layer-group", selected: -1 });
-        RadialMenu.Instance.addItem({ description: "Open in a new tab", event: () => this.props.addDocTab(this.props.Document, "onRight"), icon: "trash", selected: -1 });
-        RadialMenu.Instance.addItem({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.Document), icon: "folder", selected: -1 });
+        // RadialMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "map-pin", selected: -1 });
+        RadialMenu.Instance.addItem({ description: "Delete", event: () => { this.props.ContainingCollectionView?.removeDocument(this.props.Document), RadialMenu.Instance.closeMenu(); }, icon: "external-link-square-alt", selected: -1 });
+        // RadialMenu.Instance.addItem({ description: "Open in a new tab", event: () => this.props.addDocTab(this.props.Document, "onRight"), icon: "trash", selected: -1 });
+        RadialMenu.Instance.addItem({ description: "Pin", event: () => DockedFrameRenderer.PinDoc(this.props.Document), icon: "map-pin", selected: -1 });
+        RadialMenu.Instance.addItem({ description: "Open", event: () => MobileInterface.Instance.handleClick(this.props.Document), icon: "trash", selected: -1 });
 
         SelectionManager.DeselectAll();
     }
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 474587159..1a31d2916 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -224,7 +224,7 @@
     }
 }
 
-@media only screen and (max-width: 1000px) {
+@media only screen and (max-width: 600px) {
 
     .pdfBox .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton,
     .pdfBox-interactive .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 78b7faeee..4b4348d3c 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -215,13 +215,14 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
 
     @computed get contentScaling() { return this.props.ContentScaling(); }
     @computed get renderTitleBox() {
-        console.log("fitWidth ?: " + !(this.props.Document._fitWidth) && (window.innerWidth > 1000));
+        console.log("fitWidth ?: " + !(this.props.Document._fitWidth) && (window.screen.width > 600));
         console.log("_nativeHeight: " + this.Document._nativeHeight);
         console.log("%: " + `${100 / this.contentScaling}%`);
         const classname = "pdfBox" + (this.active() ? "-interactive" : "");
         return <div className={classname} style={{
             width: !this.props.Document._fitWidth ? this.Document._nativeWidth || 0 : `${100 / this.contentScaling}%`,
-            height: !this.props.Document._fitWidth && (window.innerWidth > 1000) ? this.Document._nativeHeight || 0 : `${100 / this.contentScaling}%`, //Adjusted for mobile (!window.innerWidth < 1000)
+            //height adjusted for mobile (window.screen.width > 600)
+            height: !this.props.Document._fitWidth && (window.screen.width > 600) ? this.Document._nativeHeight || 0 : `${100 / this.contentScaling}%`,
             transform: `scale(${this.contentScaling})`
         }}  >
             <div className="pdfBox-title-outer">
@@ -233,7 +234,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     isChildActive = (outsideReaction?: boolean) => this._isChildActive;
     @computed get renderPdfView() {
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
-        return <div className={"pdfBox"} onContextMenu={this.specificContextMenu} style={{ height: this.props.Document._scrollTop && !this.Document._fitWidth && (window.innerWidth > 1000) ? NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined }}>
+        return <div className={"pdfBox"} onContextMenu={this.specificContextMenu} style={{ height: this.props.Document._scrollTop && !this.Document._fitWidth && (window.screen.width > 600) ? NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined }}>
             <PDFViewer {...this.props} pdf={this._pdf!} url={pdfUrl!.url.pathname} active={this.props.active} loaded={this.loaded}
                 setPdfViewer={this.setPdfViewer} ContainingCollectionView={this.props.ContainingCollectionView}
                 renderDepth={this.props.renderDepth} PanelHeight={this.props.PanelHeight} PanelWidth={this.props.PanelWidth}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index f3d0d135c..ae508cd67 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -261,7 +261,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
 
     public unhighlightSearchTerms = () => {
-        if (window.innerWidth < 1000) null;
+        if (window.screen.width < 600) null;
         else if (this._editorView && (this._editorView as any).docView) {
             const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
             const activeMark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight, { selected: true });
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 9cdbea2da..57b7bceca 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -709,8 +709,8 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
             onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick}
             style={{
                 overflowX: this._zoomed !== 1 ? "scroll" : undefined,
-                width: !this.props.Document._fitWidth && (window.innerWidth > 1000) ? NumCast(this.props.Document._nativeWidth) : `${100 / this.contentScaling}%`,
-                height: !this.props.Document._fitWidth && (window.innerWidth > 1000) ? NumCast(this.props.Document._nativeHeight) : `${100 / this.contentScaling}%`,
+                width: !this.props.Document._fitWidth && (window.screen.width > 600) ? NumCast(this.props.Document._nativeWidth) : `${100 / this.contentScaling}%`,
+                height: !this.props.Document._fitWidth && (window.screen.width > 600) ? NumCast(this.props.Document._nativeHeight) : `${100 / this.contentScaling}%`,
                 transform: `scale(${this.props.ContentScaling()})`
             }}  >
             {this.pdfViewerDiv}
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index d8b1913ee..b66f0461d 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -65,8 +65,11 @@ export class Uploader extends React.Component {
                             }
                             const path = Utils.prepend(result.accessPaths.agnostic.client);
                             let doc = null;
+                            console.log("type: " + file.type);
                             if (file.type === "video/mp4") {
                                 doc = Docs.Create.VideoDocument(path, { _nativeWidth: 200, _width: 200, title: name });
+                            } else if (file.type === "application/pdf") {
+                                doc = Docs.Create.PdfDocument(path, { _width: 200, title: name });
                             } else {
                                 doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name });
                             }
@@ -175,7 +178,7 @@ export class Uploader extends React.Component {
     private get uploadInterface() {
         return (
             <div className="imgupload_cont">
-                <input type="file" accept="video/*,image/*" className="inputFile" id="input_image_file" ref={inputRef} onChange={this.inputLabel} multiple></input>
+                <input type="file" accept="application/pdf, video/*,image/*" className="inputFile" id="input_image_file" ref={inputRef} onChange={this.inputLabel} multiple></input>
                 <label className="file" id="label" htmlFor="input_image_file">{this.nm}</label>
                 <div className="upload_label" onClick={this.onClick}>
                     <FontAwesomeIcon icon="upload" size="sm" />
@@ -217,4 +220,3 @@ export class Uploader extends React.Component {
 }
 
 
-// DocServer.init(window.location.protocol, window.location.hostname, 4321, "image upload");
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 5acdc1dea..644535179 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1,7 +1,7 @@
 import * as React from "react";
 import { library } from '@fortawesome/fontawesome-svg-core';
 import {
-    faTasks, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+    faTasks, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -17,7 +17,7 @@ import { FieldValue, Cast } from '../fields/Types';
 import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
 import { emptyPath, emptyFunction, returnFalse, returnOne, returnTrue, returnZero, Utils } from '../Utils';
 import { DocServer } from '../client/DocServer';
-import { Docs } from '../client/documents/Documents';
+import { Docs, DocumentOptions } from '../client/documents/Documents';
 import { Scripting } from '../client/util/Scripting';
 import { DocumentView } from '../client/views/nodes/DocumentView';
 import { Transform } from '../client/util/Transform';
@@ -36,8 +36,11 @@ import GestureOverlay from "../client/views/GestureOverlay";
 import { ScriptField } from "../fields/ScriptField";
 import InkOptionsMenu from "../client/views/collections/collectionFreeForm/InkOptionsMenu";
 import { RadialMenu } from "../client/views/nodes/RadialMenu";
+import { UndoManager } from "../client/util/UndoManager";
+import { MainView } from "../client/views/MainView";
+import { List } from "../fields/List";
 
-library.add(faTasks, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+library.add(faTasks, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -149,7 +152,7 @@ export class MobileInterface extends React.Component {
      * Return 'Home", which implies returning to 'Home' buttons
      */
     returnHome = () => {
-        if (this._homeMenu === false || this.sidebarActive === true) {
+        if (this._homeMenu || this.sidebarActive) {
             this._homeMenu = true;
             this._parents = [];
             this._activeDoc = this._homeDoc;
@@ -220,7 +223,7 @@ export class MobileInterface extends React.Component {
      */
     handleClick = async (doc: Doc) => {
         const children = DocListCast(doc.data);
-        if (doc.type !== "collection") {
+        if (doc.type !== "collection" && this.sidebarActive) {
             this._parents.push(this._activeDoc);
             this._activeDoc = doc;
             this.switchCurrentView((userDoc: Doc) => doc);
@@ -333,7 +336,7 @@ export class MobileInterface extends React.Component {
 
     // Renders the contents of the menu and sidebar
     renderDefaultContent = () => {
-        if (this._homeMenu === true) {
+        if (this._homeMenu) {
             return (
                 <div>
                     <div className="navbar">
@@ -351,7 +354,7 @@ export class MobileInterface extends React.Component {
                         <div className="sidebarButtons">
                             <div
                                 className="item"
-                                onClick={() => ScriptField.MakeScript("createNewWorkspace()")}>Create New Workspace
+                                onClick={() => MainView.Instance?.createNewWorkspace()}>Create New Workspace
                             </div>
                         </div>
                     </div>
@@ -403,7 +406,10 @@ export class MobileInterface extends React.Component {
                                 {buttons}
                                 <div
                                     className="item"
-                                    onClick={() => ScriptField.MakeScript("createNewWorkspace()")}>Create New Workspace
+                                    style={{ opacity: 0.7 }}
+                                    onClick={() => this.createNewWorkspace()}>
+                                    <FontAwesomeIcon className="right" icon="plus" size="lg" />
+                                    <div className="item-type">Create New Workspace</div>
                                 </div>
                             </>
                         }
@@ -413,6 +419,32 @@ export class MobileInterface extends React.Component {
         );
     }
 
+    /**
+     * Handles the Create New Workspace button in the menu
+     */
+    @action
+    createNewWorkspace = async (id?: string) => {
+        const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+        const workspaceCount = DocListCast(workspaces.data).length + 1;
+        const freeformOptions: DocumentOptions = {
+            x: 0,
+            y: 400,
+            title: "Collection " + workspaceCount,
+            _LODdisable: true
+        };
+        const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
+        const workspaceDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [Doc.UserDoc().myCatalog as Doc] }], { title: `Workspace ${workspaceCount}` }, id, "row");
+
+        const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`);
+        const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
+        const cloneWorkspace = ScriptField.MakeScript(`cloneWorkspace()`);
+        workspaceDoc.contextMenuScripts = new List<ScriptField>([toggleTheme!, toggleComic!, cloneWorkspace!]);
+        workspaceDoc.contextMenuLabels = new List<string>(["Toggle Theme Colors", "Toggle Comic Mode", "New Workspace Layout"]);
+
+        Doc.AddDocToList(workspaces, "data", workspaceDoc);
+        // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
+    }
+
     stop = (e: React.MouseEvent) => {
         e.stopPropagation();
     }
@@ -431,7 +463,7 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    // Button for switching between pan and ink mode
+    // Button for switching between pen and ink mode
     @action
     onSwitchInking = () => {
         const button = document.getElementById("inkButton") as HTMLElement;
@@ -465,6 +497,16 @@ export class MobileInterface extends React.Component {
         if (this._activeDoc._viewType === "docking") {
             return (
                 <>
+                    {/* <div className="docButton"
+                        id="undoButton"
+                        title="undo"
+                        onClick={(e: React.MouseEvent) => {
+                            UndoManager.Undo();
+                            e.stopPropagation();
+                        }}>
+                        <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="undo-alt"
+                        />
+                    </div> */}
                     <div className="docButton"
                         id="inkButton"
                         title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
@@ -472,6 +514,16 @@ export class MobileInterface extends React.Component {
                         <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="pen-nib"
                         />
                     </div>
+                    {/* <div className="docButton"
+                        id="redoButton"
+                        title="redo"
+                        onClick={(e: React.MouseEvent) => {
+                            UndoManager.Redo();
+                            e.stopPropagation();
+                        }}>
+                        <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="redo-alt"
+                        />
+                    </div> */}
                 </>);
         }
     }
@@ -645,6 +697,12 @@ export class MobileInterface extends React.Component {
         );
     }
 
+    displayRadialMenu = () => {
+        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) {
+            return <RadialMenu />;
+        }
+    }
+
     onDragOver = (e: React.DragEvent) => {
         e.preventDefault();
         e.stopPropagation();
@@ -669,12 +727,14 @@ export class MobileInterface extends React.Component {
                     {this.displayWorkspaces()}
                     {this.renderDefaultContent()}
                 </GestureOverlay>
-                <RadialMenu />
+                {this.displayRadialMenu()}
             </div>
         );
     }
 }
 
+
+
 Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); });
 Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); });
 Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); });
diff --git a/src/server/ApiManagers/PDFManager.ts b/src/server/ApiManagers/PDFManager.ts
index d2a9e9cce..b0b5a484a 100644
--- a/src/server/ApiManagers/PDFManager.ts
+++ b/src/server/ApiManagers/PDFManager.ts
@@ -55,7 +55,8 @@ async function CreateThumbnail(coreFilename: string, pageNum: number, res: expre
     const documentProxy = await Pdfjs.getDocument(sourcePath).promise;
     const factory = new NodeCanvasFactory();
     const page = await documentProxy.getPage(pageNum);
-    const viewport = page.getViewport(1 as any);
+    const scale = 1;
+    const viewport = page.getViewport(scale as any);
     const { canvas, context } = factory.create(viewport.width, viewport.height);
     const renderContext = {
         canvasContext: context,
-- 
cgit v1.2.3-70-g09d2


From cb5fa90bb580c2d618e279275c1e2cb49ce3d90c Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Thu, 18 Jun 2020 05:03:47 +0800
Subject: menu button bug fix

---
 src/mobile/MobileInterface.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 644535179..4000bee85 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -152,7 +152,7 @@ export class MobileInterface extends React.Component {
      * Return 'Home", which implies returning to 'Home' buttons
      */
     returnHome = () => {
-        if (this._homeMenu || this.sidebarActive) {
+        if (!this._homeMenu || this.sidebarActive) {
             this._homeMenu = true;
             this._parents = [];
             this._activeDoc = this._homeDoc;
-- 
cgit v1.2.3-70-g09d2


From 738a56b3c18c06d8290346373eb60a125120caaf Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Thu, 18 Jun 2020 15:02:50 -0700
Subject: hopefully fixed new ink

---
 src/client/util/InteractionUtils.tsx               |  4 +-
 src/client/views/InkingStroke.tsx                  |  4 +-
 .../views/collections/CollectionDockingView.tsx    |  2 +-
 src/client/views/collections/CollectionView.tsx    |  4 +-
 .../views/collections/CollectionViewChromes.tsx    |  2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  6 +--
 src/client/views/nodes/DocumentView.tsx            | 44 +++++++++++-----------
 src/mobile/MobileInterface.tsx                     | 16 +++++---
 src/pen-gestures/ndollar.ts                        |  2 +-
 9 files changed, 44 insertions(+), 40 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index aeb0f670d..3b42fcaee 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -96,9 +96,9 @@ export namespace InteractionUtils {
         }
         else if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y === points[0].Y) {
             //pointer is up (first and last points are the same)
-            points.pop();
+            //points.pop();
             const newPoints = points.reduce((p, pts) => { p.push([pts.X, pts.Y]); return p; }, [] as number[][]);
-
+            newPoints.pop();
             const bezierCurves = fitCurve(newPoints, parseInt(bezier));
             for (var i = 0; i < bezierCurves.length; i++) {
                 for (var t = 0; t < 1; t += 0.01) {
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 7e3bd1c17..5129ef65d 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -68,8 +68,8 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
                     mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? "multiply" : "unset"
                 }}
                 onContextMenu={() => {
-                    ContextMenu.Instance.addItem({ description: "Analyze Stroke", event: this.analyzeStrokes, icon: "paint-brush" });
-                    ContextMenu.Instance.addItem({ description: "Make Mask", event: this.makeMask, icon: "paint-brush" });
+                    ContextMenu.Instance?.addItem({ description: "Analyze Stroke", event: this.analyzeStrokes, icon: "paint-brush" });
+                    ContextMenu.Instance?.addItem({ description: "Make Mask", event: this.makeMask, icon: "paint-brush" });
                 }}
             ><defs>
                     <filter id="dangerShine">
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index c2e297f61..657e2a08b 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -790,7 +790,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         if (this._mainCont && this._mainCont.children) {
             const { translateX, translateY } = Utils.GetScreenTransform(this._mainCont.children[0].firstChild as HTMLElement);
             const scale = Utils.GetScreenTransform(this._mainCont).scale;
-            return CollectionDockingView.Instance.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.contentScaling() / scale);
+            return CollectionDockingView.Instance?.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.contentScaling() / scale);
         }
         return Transform.Identity();
     }
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index a700d0dfb..0a84e6f72 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -283,10 +283,10 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
             !existingOnClick && ContextMenu.Instance?.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
 
             if (!Doc.UserDoc().noviceMode) {
-                const more = ContextMenu.Instance.findByDescription("More...");
+                const more = ContextMenu.Instance?.findByDescription("More...");
                 const moreItems = more && "subitems" in more ? more.subitems : [];
                 moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) });
-                !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
+                !more && ContextMenu.Instance?.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
             }
         }
     }
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 48810f1e9..ec908f034 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -300,7 +300,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
 
     render() {
         const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled";
-        const scale = Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform().Scale);
+        const scale = Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform()?.Scale);
         return (
             <div className="collectionViewChrome-cont" style={{
                 top: collapsed ? -70 : 0, height: collapsed ? 0 : undefined,
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 82d6dee73..bed871f8d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1199,13 +1199,13 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     onContextMenu = (e: React.MouseEvent) => {
         if (this.props.annotationsKey) return;
 
-        ContextMenu.Instance.addItem({
+        ContextMenu.Instance?.addItem({
             description: (this._timelineVisible ? "Close" : "Open") + " Animation Timeline", event: action(() => {
                 this._timelineVisible = !this._timelineVisible;
             }), icon: this._timelineVisible ? faEyeSlash : faEye
         });
 
-        const options = ContextMenu.Instance.findByDescription("Options...");
+        const options = ContextMenu.Instance?.findByDescription("Options...");
         const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
 
         optionItems.push({ description: "reset view", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" });
@@ -1246,7 +1246,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             }
         });
         optionItems.push({ description: `${this.Document._LODdisable ? "Enable LOD" : "Disable LOD"}`, event: () => this.Document._LODdisable = !this.Document._LODdisable, icon: "table" });
-        ContextMenu.Instance.addItem({ description: "Options...", subitems: optionItems, icon: "eye" });
+        ContextMenu.Instance?.addItem({ description: "Options...", subitems: optionItems, icon: "eye" });
 
     }
     @observable _timelineVisible = false;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index e027b6a0f..2f868d558 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -708,40 +708,40 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     onContextMenu = async (e: React.MouseEvent | Touch): Promise<void> => {
         // the touch onContextMenu is button 0, the pointer onContextMenu is button 2
         if (!(e instanceof Touch)) {
-            if (e.button === 0 && !e.ctrlKey) {
-                e.preventDefault();
+            if (e?.button === 0 && !e.ctrlKey) {
+                e?.preventDefault();
                 return;
             }
-            e.persist();
+            e?.persist();
             e?.stopPropagation();
 
-            if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3 ||
-                e.isDefaultPrevented()) {
-                e.preventDefault();
+            if (Math.abs(this._downX - e?.clientX) > 3 || Math.abs(this._downY - e?.clientY) > 3 ||
+                e?.isDefaultPrevented()) {
+                e?.preventDefault();
                 return;
             }
-            e.preventDefault();
+            e?.preventDefault();
         }
 
         const cm = ContextMenu.Instance;
 
         const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []);
         Cast(this.props.Document.contextMenuLabels, listSpec("string"), []).forEach((label, i) =>
-            cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" }));
+            cm?.addItem({ description: label, event: () => customScripts[i]?.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" }));
         this.props.contextMenuItems?.().forEach(item =>
-            cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" }));
+            cm?.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" }));
 
-        let options = cm.findByDescription("Options...");
+        let options = cm?.findByDescription("Options...");
         const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
         const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null);
         optionItems.push({ description: "Open Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" });
         templateDoc && optionItems.push({ description: "Open Template   ", event: () => this.props.addDocTab(templateDoc, "onRight"), icon: "eye" });
         if (!options) {
             options = { description: "Options...", subitems: optionItems, icon: "compass" };
-            cm.addItem(options);
+            cm?.addItem(options);
         }
 
-        const existingOnClick = cm.findByDescription("OnClick...");
+        const existingOnClick = cm?.findByDescription("OnClick...");
         const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
         onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" });
         onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.props.Document.layoutKey}")`), icon: "window-restore" });
@@ -750,17 +750,17 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link on Right", event: this.toggleFollowOnRight, icon: "concierge-bell" });
         onClicks.push({ description: this.Document.isLinkButton || this.Document.onClick ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" });
         onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" });
-        !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
+        !existingOnClick && cm?.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
 
         const funcs: ContextMenuProps[] = [];
         if (this.Document.onDragStart) {
             funcs.push({ description: "Drag an Alias", icon: "edit", event: () => this.Document.dragFactory && (this.Document.onDragStart = ScriptField.MakeFunction('getAlias(this.dragFactory)')) });
             funcs.push({ description: "Drag a Copy", icon: "edit", event: () => this.Document.dragFactory && (this.Document.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) });
             funcs.push({ description: "Drag Document", icon: "edit", event: () => this.Document.onDragStart = undefined });
-            cm.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" });
+            cm?.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" });
         }
 
-        const more = cm.findByDescription("More...");
+        const more = cm?.findByDescription("More...");
         const moreItems = more && "subitems" in more ? more.subitems : [];
         if (!Doc.UserDoc().noviceMode) {
             moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" });
@@ -789,26 +789,26 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" });
         moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" });
         moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this), icon: "external-link-alt" });
-        !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
-        cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!);
+        !more && cm?.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
+        cm?.moveAfter(cm?.findByDescription("More...")!, cm?.findByDescription("OnClick...")!);
 
-        const help = cm.findByDescription("Help...");
+        const help = cm?.findByDescription("Help...");
         const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : [];
         helpItems.push({
             description: "Keyboard Shortcuts       Ctrl+/",
             event: () => this.props.addDocTab(Docs.Create.PdfDocument("http://localhost:1050/assets/cheat-sheet.pdf", { _width: 300, _height: 300 }), "onRight"),
             icon: "keyboard"
         });
-        cm.addItem({ description: "Help...", subitems: helpItems, icon: "question" });
+        cm?.addItem({ description: "Help...", subitems: helpItems, icon: "question" });
 
-        const existingAcls = cm.findByDescription("Privacy...");
+        const existingAcls = cm?.findByDescription("Privacy...");
         const aclItems: ContextMenuProps[] = existingAcls && "subitems" in existingAcls ? existingAcls.subitems : [];
         aclItems.push({ description: "Make Add Only", event: () => this.setAcl("addOnly"), icon: "concierge-bell" });
         aclItems.push({ description: "Make Read Only", event: () => this.setAcl("readOnly"), icon: "concierge-bell" });
         aclItems.push({ description: "Make Private", event: () => this.setAcl("ownerOnly"), icon: "concierge-bell" });
         aclItems.push({ description: "Test Private", event: () => this.testAcl("ownerOnly"), icon: "concierge-bell" });
         aclItems.push({ description: "Test Readonly", event: () => this.testAcl("readOnly"), icon: "concierge-bell" });
-        !existingAcls && cm.addItem({ description: "Privacy...", subitems: aclItems, icon: "question" });
+        !existingAcls && cm?.addItem({ description: "Privacy...", subitems: aclItems, icon: "question" });
 
         // const recommender_subitems: ContextMenuProps[] = [];
 
@@ -869,7 +869,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 // DocumentViews should stop propagation of this event
                 e.stopPropagation();
             }
-            ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
+            ContextMenu.Instance?.displayMenu(e.pageX - 15, e.pageY - 15);
             !SelectionManager.IsSelected(this, true) && SelectionManager.SelectDoc(this, false);
         });
         const path = this.props.LibraryPath.reduce((p: string, d: Doc) => p + "/" + (Doc.AreProtosEqual(d, (Doc.UserDoc()["tabs-button-library"] as Doc).sourcePanel as Doc) ? "" : d.title), "");
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 4000bee85..3a81e5de1 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -708,6 +708,10 @@ export class MobileInterface extends React.Component {
         e.stopPropagation();
     }
 
+    uploadToCurrentCollection = (doc: Doc) => {
+
+    }
+
     render() {
         return (
             <div className="mobileInterface-container" onDragOver={this.onDragOver}>
@@ -717,13 +721,13 @@ export class MobileInterface extends React.Component {
                 </div>
                 {this.switchMenuView()}
                 {this.inkMenu()}
+                <div className="docButtonContainer">
+                    {this.pinToPresentation()}
+                    {this.downloadDocument()}
+                    {this.drawInk()}
+                    {this.uploadAudioButton()}
+                </div>
                 <GestureOverlay>
-                    <div className="docButtonContainer">
-                        {this.pinToPresentation()}
-                        {this.downloadDocument()}
-                        {this.drawInk()}
-                        {this.uploadAudioButton()}
-                    </div>
                     {this.displayWorkspaces()}
                     {this.renderDefaultContent()}
                 </GestureOverlay>
diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts
index 9d42035d1..ecd8df3e7 100644
--- a/src/pen-gestures/ndollar.ts
+++ b/src/pen-gestures/ndollar.ts
@@ -552,7 +552,7 @@ function Distance(p1: any, p2: any) // distance between two points
 }
 function CalcStartUnitVector(points: any, index: any) // start angle from points[0] to points[index] normalized as a unit vector
 {
-    const v = new Point(points[index].X - points[0].X, points[index].Y - points[0].Y);
+    const v = new Point(points[index]?.X - points[0]?.X, points[index]?.Y - points[0]?.Y);
     const len = Math.sqrt(v.X * v.X + v.Y * v.Y);
     return new Point(v.X / len, v.Y / len);
 }
-- 
cgit v1.2.3-70-g09d2


From a19d891f386816f127ea1ee3970c6ec48adb0d74 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Thu, 18 Jun 2020 22:01:02 -0700
Subject: added mobile collection to menu and added image upload to current
 collection

---
 src/client/util/CurrentUserUtils.ts |  1 +
 src/mobile/ImageUpload.tsx          |  9 +++++--
 src/mobile/MobileInterface.tsx      | 48 ++++++++++++++++++++++++++++++++++---
 3 files changed, 53 insertions(+), 5 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 7b867ed02..b7da4ae2f 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -469,6 +469,7 @@ export class CurrentUserUtils {
             { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your phone to record and upload audio onto Dash Web." },
             { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "#ff9e9e", info: "Upload images or videos from your mobile device so they can be accessed on Dash Web." },
             { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "#ff8080", info: "Use your phone as a remote for you presentation." },
+            { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploads()', backgroundColor: "#ff7373", info: "Access the collection of your mobile uploads." },
             { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "#ff5e5e", info: "Change your password, log out, or manage your account security." }
         ];
         return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data =>
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index b66f0461d..0b63c42be 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -29,7 +29,7 @@ export interface ImageUploadProps {
 const inputRef = React.createRef<HTMLInputElement>();
 
 @observer
-export class Uploader extends React.Component {
+export class Uploader extends React.Component<ImageUploadProps> {
     @observable error: string = "";
     @observable status: string = "";
     @observable nm: string = "Choose files";
@@ -37,6 +37,7 @@ export class Uploader extends React.Component {
 
     onClick = async () => {
         try {
+            const col = this.props.Document;
             await Docs.Prototypes.initialize();
             const imgPrev = document.getElementById("img_preview");
             const slab1 = document.getElementById("slab1");
@@ -84,7 +85,11 @@ export class Uploader extends React.Component {
                             const field = await DocServer.GetRefField(res);
                             let pending: Opt<Doc>;
                             if (field instanceof Doc) {
-                                pending = await Cast(field.rightSidebarCollection, Doc);
+                                // if (col === Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc) {
+                                //     pending = await Cast(field.rightSidebarCollection, Doc);
+                                // }
+                                pending = col;
+                                //pending = await Cast(field.col, Doc);
                             }
                             if (pending) {
                                 const data = await Cast(pending.data, listSpec(Doc));
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 3a81e5de1..2fde359aa 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -674,6 +674,15 @@ export class MobileInterface extends React.Component {
     @action
     toggleUpload = () => this.imageUploadActive = !this.imageUploadActive
 
+    @action
+    toggleUploadInCollection = () => {
+        const button = document.getElementById("imageButton") as HTMLElement;
+        button.style.backgroundColor = this.imageUploadActive ? "white" : "black";
+        button.style.color = this.imageUploadActive ? "black" : "white";
+
+        this.imageUploadActive = !this.imageUploadActive;
+    }
+
     // For closing the image upload pop up
     @action
     closeUpload = () => {
@@ -687,12 +696,22 @@ export class MobileInterface extends React.Component {
         } else if (!this.imageUploadActive) {
 
         }
+
+        let doc;
+        let toggle;
+        if (this._homeMenu === false) {
+            doc = this._activeDoc;
+            toggle = this.toggleUploadInCollection;
+        } else {
+            doc = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc
+            toggle = this.toggleUpload;
+        }
         return (
             <div>
-                <div className="closeUpload" onClick={this.toggleUpload}>
+                <div className="closeUpload" onClick={toggle}>
                     <FontAwesomeIcon icon="window-close" size={"lg"} />
                 </div>
-                <Uploader />
+                <Uploader Document={doc} />
             </div>
         );
     }
@@ -708,8 +727,27 @@ export class MobileInterface extends React.Component {
         e.stopPropagation();
     }
 
-    uploadToCurrentCollection = (doc: Doc) => {
+    uploadImageButton = () => {
+        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc._viewType !== "docking" && this._activeDoc.title !== "WORKSPACES") {
+            return <div className="docButton"
+                id="imageButton"
+                title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
+                onClick={this.toggleUpload}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
+                />
+            </div>
+        }
+    }
 
+    switchToMobileUploads = () => {
+        if (this._activeDoc.title !== "Presentation") {
+            this._parents.push(this._activeDoc);
+        }
+        const mobileUpload = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
+        console.log(mobileUpload.title);
+        this._activeDoc = mobileUpload;
+        this.switchCurrentView((userDoc: Doc) => mobileUpload);
+        this._homeMenu = false;
     }
 
     render() {
@@ -718,14 +756,17 @@ export class MobileInterface extends React.Component {
                 <SettingsManager />
                 <div className={`image-upload ${this.imageUploadActive ? "active" : ""}`}>
                     {this.uploadImage()}
+
                 </div>
                 {this.switchMenuView()}
                 {this.inkMenu()}
                 <div className="docButtonContainer">
+                    {this.uploadImageButton()}
                     {this.pinToPresentation()}
                     {this.downloadDocument()}
                     {this.drawInk()}
                     {this.uploadAudioButton()}
+
                 </div>
                 <GestureOverlay>
                     {this.displayWorkspaces()}
@@ -746,3 +787,4 @@ Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance
 Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); });
 Scripting.addGlobal(function switchToLibrary() { return MobileInterface.Instance.switchToLibrary(); });
 Scripting.addGlobal(function uploadImageMobile() { return MobileInterface.Instance.toggleUpload(); });
+Scripting.addGlobal(function switchToMobileUploads() { return MobileInterface.Instance.switchToMobileUploads(); });
-- 
cgit v1.2.3-70-g09d2


From 10754a14c8d0dda68f2484e523f6901b3e7daee3 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Fri, 19 Jun 2020 14:14:28 +0800
Subject: css changes and bug fixes

Presentation
Undo / Redo
Image upload
Record Audio
---
 src/client/views/collections/CollectionView.tsx    |   2 +-
 .../views/collections/CollectionViewChromes.scss   |   6 +
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   2 +-
 src/client/views/nodes/AudioBox.tsx                |   2 +-
 src/client/views/nodes/PresBox.scss                |  10 +-
 src/mobile/AudioUpload.scss                        | 119 +++++++++++
 src/mobile/AudioUpload.tsx                         | 237 +++++++++++++++++++++
 src/mobile/ImageUpload.scss                        |  15 +-
 src/mobile/ImageUpload.tsx                         |  58 +++--
 src/mobile/MobileInterface.tsx                     | 205 ++++++++++--------
 src/mobile/MobileMenu.scss                         |  15 +-
 11 files changed, 531 insertions(+), 140 deletions(-)
 create mode 100644 src/mobile/AudioUpload.scss
 create mode 100644 src/mobile/AudioUpload.tsx

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index a700d0dfb..7c5c87e3e 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -283,7 +283,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
             !existingOnClick && ContextMenu.Instance?.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
 
             if (!Doc.UserDoc().noviceMode) {
-                const more = ContextMenu.Instance.findByDescription("More...");
+                const more = ContextMenu.Instance?.findByDescription("More...");
                 const moreItems = more && "subitems" in more ? more.subitems : [];
                 moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) });
                 !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index f85cbfee2..54ee4ab3b 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -80,6 +80,12 @@
                 // margin-top: 10px;
             }
 
+            @media only screen and (max-width: 1000) {
+                .collectionViewBaseChrome-collapse {
+                    display: none;
+                }
+            }
+
             .collectionViewBaseChrome-template,
             .collectionViewBaseChrome-viewModes {
                 display: grid;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 82d6dee73..327e172bb 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1199,7 +1199,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     onContextMenu = (e: React.MouseEvent) => {
         if (this.props.annotationsKey) return;
 
-        ContextMenu.Instance.addItem({
+        ContextMenu.Instance?.addItem({
             description: (this._timelineVisible ? "Close" : "Open") + " Animation Timeline", event: action(() => {
                 this._timelineVisible = !this._timelineVisible;
             }), icon: this._timelineVisible ? faEyeSlash : faEye
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 2e0be1c6a..cb0582d87 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -161,7 +161,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         const funcs: ContextMenuProps[] = [];
         funcs.push({ description: (this.layoutDoc.playOnSelect ? "Don't play" : "Play") + " when document selected", event: () => this.layoutDoc.playOnSelect = !this.layoutDoc.playOnSelect, icon: "expand-arrows-alt" });
 
-        ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
+        ContextMenu.Instance?.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
     }
 
     stopRecording = action(() => {
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index ccce6e627..e62aa48fb 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -105,15 +105,13 @@
     }
 
     .presBox-cont .presBox-buttons .presBox-button {
-        margin-right: 10px;
-        margin-left: 10px;
+        margin-top: 5%;
         height: 250;
-        width: 250;
-        font-size: 70;
-        border-radius: 25px;
+        width: 300;
+        font-size: 100;
         display: flex;
         align-items: center;
-        background: #323232;
+        background: 323232;
         color: white;
     }
 
diff --git a/src/mobile/AudioUpload.scss b/src/mobile/AudioUpload.scss
new file mode 100644
index 000000000..5f0ba465a
--- /dev/null
+++ b/src/mobile/AudioUpload.scss
@@ -0,0 +1,119 @@
+@import "../client/views/globalCssVariables.scss";
+
+.audioUpload_cont {
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
+    align-items: center;
+    max-width: 400px;
+    min-width: 400px;
+
+    .upload_label {
+        font-size: 3em;
+        font-weight: 700;
+        color: white;
+        background-color: black;
+        display: inline-block;
+        margin: 10;
+        width: 100%;
+        border-radius: 10px;
+    }
+
+    .file {
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        direction: ltr;
+    }
+
+    .upload_label:hover {
+        background-color: darkred;
+    }
+
+    .button_file {
+        text-align: center;
+        height: 50%;
+        width: 50%;
+        background-color: paleturquoise;
+        color: grey;
+        font-size: 3em;
+    }
+
+    .inputfile {
+        width: 0.1px;
+        height: 0.1px;
+        opacity: 0;
+        overflow: hidden;
+        position: absolute;
+        z-index: -1;
+    }
+
+    .inputfile+label {
+        font-size: 3em;
+        font-weight: 700;
+        color: white;
+        background-color: black;
+        display: inline-block;
+        margin: 10px;
+        width: 100%;
+        border-radius: 10px;
+    }
+
+    .inputfile:focus+label,
+    .inputfile+label:hover {
+        background-color: darkred;
+    }
+
+    .status {
+        font-size: 2em;
+    }
+
+}
+
+.backgroundUpload {
+    height: 100vh;
+    top: 0;
+    z-index: 999;
+    width: 100vw;
+    position: absolute;
+    background-color: lightgrey;
+    opacity: 0.4;
+}
+
+.audio-upload {
+    top: 100%;
+    opacity: 0;
+}
+
+.audio-upload.active {
+    top: 0;
+    position: absolute;
+    z-index: 999;
+    height: 100vh;
+    width: 100vw;
+    opacity: 1;
+}
+
+.uploadContainer {
+    top: 40;
+    position: absolute;
+    z-index: 1000;
+    height: 20vh;
+    width: 80vw;
+    opacity: 1;
+}
+
+.loadingImage {
+    display: inline-flex;
+    width: max-content;
+}
+
+.loadingSlab {
+    position: relative;
+    width: 30px;
+    height: 30px;
+    margin: 10;
+    border-radius: 20px;
+    opacity: 0.3;
+    background-color: black;
+}
\ No newline at end of file
diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx
new file mode 100644
index 000000000..7ea11ee84
--- /dev/null
+++ b/src/mobile/AudioUpload.tsx
@@ -0,0 +1,237 @@
+import * as ReactDOM from 'react-dom';
+import * as rp from 'request-promise';
+import { Docs } from '../client/documents/Documents';
+import "./ImageUpload.scss";
+import React = require('react');
+import { DocServer } from '../client/DocServer';
+import { observer } from 'mobx-react';
+import { observable, action } from 'mobx';
+import { Utils, emptyPath, returnFalse, emptyFunction, returnOne, returnZero, returnTrue } from '../Utils';
+import { Networking } from '../client/Network';
+import { Doc, Opt } from '../fields/Doc';
+import { Cast } from '../fields/Types';
+import { listSpec } from '../fields/Schema';
+import { List } from '../fields/List';
+import { Scripting } from '../client/util/Scripting';
+import MainViewModal from '../client/views/MainViewModal';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { nullAudio } from '../fields/URLField';
+import { Transform } from '../client/util/Transform';
+import { DocumentView } from '../client/views/nodes/DocumentView';
+import { MobileInterface } from './MobileInterface';
+
+export interface ImageUploadProps {
+    Document: Doc;
+}
+
+// const onPointerDown = (e: React.TouchEvent) => {
+//     let imgInput = document.getElementById("input_image_file");
+//     if (imgInput) {
+//         imgInput.click();
+//     }
+// }
+const inputRef = React.createRef<HTMLInputElement>();
+
+@observer
+export class AudioUpload extends React.Component {
+    @observable error: string = "";
+    @observable status: string = "";
+    @observable nm: string = "Choose files";
+    @observable process: string = "";
+
+    onClick = async () => {
+        try {
+            await Docs.Prototypes.initialize();
+            const imgPrev = document.getElementById("img_preview");
+            const slab1 = document.getElementById("slab1");
+            if (slab1) {
+                slab1.style.opacity = "1";
+            }
+            if (imgPrev) {
+                const files: FileList | null = inputRef.current!.files;
+                const slab2 = document.getElementById("slab2");
+                if (slab2) {
+                    slab2.style.opacity = "1";
+                }
+                if (files && files.length !== 0) {
+                    this.process = "Uploading Files";
+                    for (let index = 0; index < files.length; ++index) {
+                        const file = files[index];
+                        const res = await Networking.UploadFilesToServer(file);
+                        const slab3 = document.getElementById("slab3");
+                        if (slab3) {
+                            slab3.style.opacity = "1";
+                        }
+                        res.map(async ({ result }) => {
+                            const name = file.name;
+                            if (result instanceof Error) {
+                                return;
+                            }
+                            const path = Utils.prepend(result.accessPaths.agnostic.client);
+                            let doc = null;
+                            console.log("type: " + file.type);
+                            if (file.type === "video/mp4") {
+                                doc = Docs.Create.VideoDocument(path, { _nativeWidth: 200, _width: 200, title: name });
+                            } else if (file.type === "application/pdf") {
+                                doc = Docs.Create.PdfDocument(path, { _width: 200, title: name });
+                            } else {
+                                doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name });
+                            }
+                            const slab4 = document.getElementById("slab4");
+                            if (slab4) {
+                                slab4.style.opacity = "1";
+                            }
+                            const res = await rp.get(Utils.prepend("/getUserDocumentId"));
+                            if (!res) {
+                                throw new Error("No user id returned");
+                            }
+                            const field = await DocServer.GetRefField(res);
+                            let pending: Opt<Doc>;
+                            if (field instanceof Doc) {
+                                pending = await Cast(field.mobileUpload, Doc);
+                            }
+                            if (pending) {
+                                const data = await Cast(pending.data, listSpec(Doc));
+                                if (data) {
+                                    data.push(doc);
+                                } else {
+                                    pending.data = new List([doc]);
+                                }
+                                this.status = "finished";
+                                const slab5 = document.getElementById("slab5");
+                                if (slab5) {
+                                    slab5.style.opacity = "1";
+                                }
+                                this.process = "File " + (index + 1).toString() + " Uploaded";
+                                const slab6 = document.getElementById("slab6");
+                                if (slab6) {
+                                    slab6.style.opacity = "1";
+                                }
+                                const slab7 = document.getElementById("slab7");
+                                if (slab7) {
+                                    slab7.style.opacity = "1";
+                                }
+
+                            }
+                        });
+                    }
+                } else {
+                    this.process = "No file selected";
+                }
+                setTimeout(this.clearUpload, 3000);
+            }
+        } catch (error) {
+            this.error = JSON.stringify(error);
+        }
+    }
+
+    // Updates label after a files is selected (so user knows a file is uploaded)
+    inputLabel = async () => {
+        const files: FileList | null = inputRef.current!.files;
+        await files;
+        if (files && files.length === 1) {
+            console.log(files);
+            this.nm = files[0].name;
+        } else if (files && files.length > 1) {
+            console.log(files.length);
+            this.nm = files.length.toString() + " files selected";
+        }
+    }
+
+    @action
+    clearUpload = () => {
+        const slab1 = document.getElementById("slab1");
+        if (slab1) {
+            slab1.style.opacity = "0.4";
+        }
+        const slab2 = document.getElementById("slab2");
+        if (slab2) {
+            slab2.style.opacity = "0.4";
+        }
+        const slab3 = document.getElementById("slab3");
+        if (slab3) {
+            slab3.style.opacity = "0.4";
+        }
+        const slab4 = document.getElementById("slab4");
+        if (slab4) {
+            slab4.style.opacity = "0.4";
+        }
+        const slab5 = document.getElementById("slab5");
+        if (slab5) {
+            slab5.style.opacity = "0.4";
+        }
+        const slab6 = document.getElementById("slab6");
+        if (slab6) {
+            slab6.style.opacity = "0.4";
+        }
+        const slab7 = document.getElementById("slab7");
+        if (slab7) {
+            slab7.style.
+                opacity = "0.4";
+        }
+        this.nm = "Choose files";
+
+        if (inputRef.current) {
+            inputRef.current.value = "";
+        }
+        this.process = "";
+        console.log(inputRef.current!.files);
+    }
+
+
+
+    private get uploadInterface() {
+        const audioDoc = Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio" }), Doc) as Doc;
+
+        return (
+            <div className="imgupload_cont">
+                <div className="closeUpload" onClick={MobileInterface.Instance.toggleAudio}>
+                    <FontAwesomeIcon icon="window-close" size={"lg"} />
+                </div>
+                <DocumentView
+                    Document={audioDoc}
+                    DataDoc={undefined}
+                    LibraryPath={emptyPath}
+                    addDocument={returnFalse}
+                    addDocTab={returnFalse}
+                    pinToPres={emptyFunction}
+                    rootSelected={returnFalse}
+                    removeDocument={undefined}
+                    onClick={undefined}
+                    ScreenToLocalTransform={Transform.Identity}
+                    ContentScaling={returnOne}
+                    PanelWidth={() => 1000}
+                    PanelHeight={() => 1000}
+                    NativeHeight={returnZero}
+                    NativeWidth={returnZero}
+                    renderDepth={0}
+                    focus={emptyFunction}
+                    backgroundColor={() => "white"}
+                    parentActive={returnTrue}
+                    whenActiveChanged={emptyFunction}
+                    bringToFront={emptyFunction}
+                    ContainingCollectionView={undefined}
+                    ContainingCollectionDoc={undefined}
+                />
+            </div>
+        );
+    }
+
+    @observable private dialogueBoxOpacity = 1;
+    @observable private overlayOpacity = 0.4;
+
+    render() {
+        return (
+            <MainViewModal
+                contents={this.uploadInterface}
+                isDisplayed={true}
+                interactive={true}
+                dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
+                overlayDisplayedOpacity={this.overlayOpacity}
+            />
+        );
+    }
+
+}
+
+
diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss
index 95c0c2680..b64aac338 100644
--- a/src/mobile/ImageUpload.scss
+++ b/src/mobile/ImageUpload.scss
@@ -55,6 +55,7 @@
         background-color: black;
         display: inline-block;
         margin: 10px;
+        margin-top: 30px;
         width: 100%;
         border-radius: 10px;
     }
@@ -106,16 +107,15 @@
 .closeUpload {
     position: absolute;
     border-radius: 10px;
-    top: 39.7%;
-    color: grey;
-    font-size: 40;
-    left: 65.8%;
+    top: 3;
+    color: black;
+    font-size: 30;
+    right: 3;
     z-index: 1002;
     padding: 0px 3px;
-    background: aliceblue;
+    background: rgba(0, 0, 0, 0);
     transition: 0.5s ease all;
-    border: 3px solid;
-    border-color: black;
+    border: 0px solid;
 }
 
 .loadingImage {
@@ -131,4 +131,5 @@
     border-radius: 20px;
     opacity: 0.3;
     background-color: black;
+    transition: all 2s, opacity 1.5s;
 }
\ No newline at end of file
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index b66f0461d..744a45507 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -15,6 +15,8 @@ import { List } from '../fields/List';
 import { Scripting } from '../client/util/Scripting';
 import MainViewModal from '../client/views/MainViewModal';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { MobileInterface } from './MobileInterface';
+import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
 
 export interface ImageUploadProps {
     Document: Doc;
@@ -29,7 +31,7 @@ export interface ImageUploadProps {
 const inputRef = React.createRef<HTMLInputElement>();
 
 @observer
-export class Uploader extends React.Component {
+export class Uploader extends React.Component<ImageUploadProps> {
     @observable error: string = "";
     @observable status: string = "";
     @observable nm: string = "Choose files";
@@ -39,25 +41,22 @@ export class Uploader extends React.Component {
         try {
             await Docs.Prototypes.initialize();
             const imgPrev = document.getElementById("img_preview");
+            // Slab 1
             const slab1 = document.getElementById("slab1");
-            if (slab1) {
-                slab1.style.opacity = "1";
-            }
+            if (slab1) slab1.style.opacity = "1";
             if (imgPrev) {
                 const files: FileList | null = inputRef.current!.files;
+                // Slab 2
                 const slab2 = document.getElementById("slab2");
-                if (slab2) {
-                    slab2.style.opacity = "1";
-                }
+                if (slab2) slab2.style.opacity = "1";
                 if (files && files.length !== 0) {
                     this.process = "Uploading Files";
                     for (let index = 0; index < files.length; ++index) {
                         const file = files[index];
                         const res = await Networking.UploadFilesToServer(file);
+                        // Slab 3
                         const slab3 = document.getElementById("slab3");
-                        if (slab3) {
-                            slab3.style.opacity = "1";
-                        }
+                        if (slab3) slab3.style.opacity = "1";
                         res.map(async ({ result }) => {
                             const name = file.name;
                             if (result instanceof Error) {
@@ -67,16 +66,15 @@ export class Uploader extends React.Component {
                             let doc = null;
                             console.log("type: " + file.type);
                             if (file.type === "video/mp4") {
-                                doc = Docs.Create.VideoDocument(path, { _nativeWidth: 200, _width: 200, title: name });
+                                doc = Docs.Create.VideoDocument(path, { _nativeWidth: 400, _width: 400, title: name });
                             } else if (file.type === "application/pdf") {
-                                doc = Docs.Create.PdfDocument(path, { _width: 200, title: name });
+                                doc = Docs.Create.PdfDocument(path, { _nativeWidth: 400, _width: 400, title: name });
                             } else {
-                                doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name });
+                                doc = Docs.Create.ImageDocument(path, { _nativeWidth: 400, _width: 400, title: name });
                             }
+                            // Slab 4
                             const slab4 = document.getElementById("slab4");
-                            if (slab4) {
-                                slab4.style.opacity = "1";
-                            }
+                            if (slab4) slab4.style.opacity = "1";
                             const res = await rp.get(Utils.prepend("/getUserDocumentId"));
                             if (!res) {
                                 throw new Error("No user id returned");
@@ -84,30 +82,23 @@ export class Uploader extends React.Component {
                             const field = await DocServer.GetRefField(res);
                             let pending: Opt<Doc>;
                             if (field instanceof Doc) {
-                                pending = await Cast(field.rightSidebarCollection, Doc);
+                                const parent = await Cast(this.props.Document.data, listSpec(Doc));
+                                const u = CurrentUserUtils.setupMobileUpload(this.props.Document);
+                                if (parent && !parent.includes(u)) parent.push(u);
+                                pending = await Cast(u, Doc);
                             }
                             if (pending) {
                                 const data = await Cast(pending.data, listSpec(Doc));
-                                if (data) {
-                                    data.push(doc);
-                                } else {
-                                    pending.data = new List([doc]);
-                                }
+                                if (data) data.push(doc);
+                                else pending.data = new List([doc]);
                                 this.status = "finished";
                                 const slab5 = document.getElementById("slab5");
-                                if (slab5) {
-                                    slab5.style.opacity = "1";
-                                }
+                                if (slab5) slab5.style.opacity = "1";
                                 this.process = "File " + (index + 1).toString() + " Uploaded";
                                 const slab6 = document.getElementById("slab6");
-                                if (slab6) {
-                                    slab6.style.opacity = "1";
-                                }
+                                if (slab6) slab6.style.opacity = "1";
                                 const slab7 = document.getElementById("slab7");
-                                if (slab7) {
-                                    slab7.style.opacity = "1";
-                                }
-
+                                if (slab7) slab7.style.opacity = "1";
                             }
                         });
                     }
@@ -178,6 +169,9 @@ export class Uploader extends React.Component {
     private get uploadInterface() {
         return (
             <div className="imgupload_cont">
+                <div className="closeUpload" onClick={MobileInterface.Instance.toggleUpload}>
+                    <FontAwesomeIcon icon="window-close" size={"lg"} />
+                </div>
                 <input type="file" accept="application/pdf, video/*,image/*" className="inputFile" id="input_image_file" ref={inputRef} onChange={this.inputLabel} multiple></input>
                 <label className="file" id="label" htmlFor="input_image_file">{this.nm}</label>
                 <div className="upload_label" onClick={this.onClick}>
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 4000bee85..612b112e6 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1,7 +1,7 @@
 import * as React from "react";
 import { library } from '@fortawesome/fontawesome-svg-core';
 import {
-    faTasks, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+    faTasks, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -25,6 +25,7 @@ import "./MobileInterface.scss";
 import "./MobileMenu.scss";
 import "./MobileHome.scss";
 import "./ImageUpload.scss";
+import "./AudioUpload.scss";
 import { DocumentManager } from '../client/util/DocumentManager';
 import SettingsManager from '../client/util/SettingsManager';
 import { Uploader } from "./ImageUpload";
@@ -39,8 +40,9 @@ import { RadialMenu } from "../client/views/nodes/RadialMenu";
 import { UndoManager } from "../client/util/UndoManager";
 import { MainView } from "../client/views/MainView";
 import { List } from "../fields/List";
+import { AudioUpload } from "./AudioUpload";
 
-library.add(faTasks, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+library.add(faTasks, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -54,17 +56,18 @@ export class MobileInterface extends React.Component {
     @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
     @observable private mainDoc: any = CurrentUserUtils.setupActiveMobileMenu(this.userDoc);
     @observable private renderView?: () => JSX.Element;
-    @observable private sidebarActive: boolean = false;
-    @observable private imageUploadActive: boolean = false;
-    @observable private menuListView: boolean = false;
-    @observable private _ink: boolean = false;
-
-    public _activeDoc: Doc = this.mainDoc;
-    public _homeDoc: Doc = this.mainDoc;
-    private _homeMenu: boolean = true;
-    private _child: Doc | null = null;
-    private _parents: Array<Doc> = [];
-    private _library: Doc = CurrentUserUtils.setupLibrary(this.userDoc);
+    @observable private sidebarActive: boolean = false; //to toggle sidebar display
+    @observable private imageUploadActive: boolean = false; //to toggle image upload
+    @observable private audioUploadActive: boolean = false;
+    @observable private menuListView: boolean = false; //to switch between menu view (list / icon)
+    @observable private _ink: boolean = false; //toggle whether ink is being dispalyed
+
+    public _activeDoc: Doc = this.mainDoc; // doc updated as the active mobile page is updated (initially home menu)
+    public _homeDoc: Doc = this.mainDoc; // home menu as a document
+    private _homeMenu: boolean = true; // to determine whether currently at home menu
+    private _child: Doc | null = null; // currently selected document
+    private _parents: Array<Doc> = []; // array of parent docs (for pathbar)
+    private _library: Doc = CurrentUserUtils.setupLibrary(this.userDoc); // to access documents in Dash Web
 
     constructor(props: Readonly<{}>) {
         super(props);
@@ -119,7 +122,7 @@ export class MobileInterface extends React.Component {
     }
 
     /**
-     * Back method for navigating
+     * Back method for navigating through items
      */
     back = () => {
         const header = document.getElementById("header") as HTMLElement;
@@ -182,7 +185,7 @@ export class MobileInterface extends React.Component {
         if (this.mainContainer) {
             const backgroundColor = () => "white";
             return (
-                <div style={{ position: "relative", top: '200px', height: `calc(100% - 350px)`, width: "100%", left: "0%" }}>
+                <div style={{ position: "relative", top: '198px', height: `calc(100% - 350px)`, width: "100%", left: "0%" }}>
                     <DocumentView
                         Document={this.mainContainer}
                         DataDoc={undefined}
@@ -213,6 +216,11 @@ export class MobileInterface extends React.Component {
         }
     }
 
+    /**
+     * Note: window.innerWidth and window.screen.width compute different values. 
+     * window.screen.width is the display size, however window.innerWidth is the
+     * display resolution which computes differently. 
+     */
     returnWidth = () => window.innerWidth; //The windows width
     returnHeight = () => (window.innerHeight - 300); //Calculating the windows height (-300 to account for topbar)
 
@@ -224,11 +232,7 @@ export class MobileInterface extends React.Component {
     handleClick = async (doc: Doc) => {
         const children = DocListCast(doc.data);
         if (doc.type !== "collection" && this.sidebarActive) {
-            this._parents.push(this._activeDoc);
-            this._activeDoc = doc;
-            this.switchCurrentView((userDoc: Doc) => doc);
-            this._homeMenu = false;
-            this.toggleSidebar();
+            this.openFromSidebar(doc);
         } else if (doc.type === "collection" && children.length === 0) console.log("This collection has no children");
         else {
             this._parents.push(this._activeDoc);
@@ -239,6 +243,14 @@ export class MobileInterface extends React.Component {
         }
     }
 
+    openFromSidebar = (doc: Doc) => {
+        this._parents.push(this._activeDoc);
+        this._activeDoc = doc;
+        this.switchCurrentView((userDoc: Doc) => doc);
+        this._homeMenu = false;
+        this.toggleSidebar();
+    }
+
     /**
      * Handles creation of array which is then rendered in renderPathbar()
      */
@@ -350,14 +362,6 @@ export class MobileInterface extends React.Component {
                         </div>
                     </div>
                     {this.renderPathbar()}
-                    <div className="sidebar" id="sidebar">
-                        <div className="sidebarButtons">
-                            <div
-                                className="item"
-                                onClick={() => MainView.Instance?.createNewWorkspace()}>Create New Workspace
-                            </div>
-                        </div>
-                    </div>
                 </div>
             );
         }
@@ -377,6 +381,7 @@ export class MobileInterface extends React.Component {
                         <div className="item-title"> {doc.title} </div>
                         <div className="item-type">{doc.type}</div>
                         <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
+                        <FontAwesomeIcon className="open" onClick={() => this.openFromSidebar(doc)} icon="external-link-alt" size="lg" />
                     </div>);
             }
         });
@@ -398,9 +403,13 @@ export class MobileInterface extends React.Component {
                         {this._child ?
                             <>
                                 {buttons}
-                                <div className="item" key="home" onClick={this.returnMain}>
-                                    Return to library
-                            </div>
+                                <div
+                                    className="item" key="home"
+                                    onClick={this.returnMain}
+                                    style={{ opacity: 0.7 }}>
+                                    <FontAwesomeIcon className="right" icon="angle-double-left" size="lg" />
+                                    <div className="item-type">Return to library</div>
+                                </div>
                             </> :
                             <>
                                 {buttons}
@@ -455,7 +464,7 @@ export class MobileInterface extends React.Component {
             return <div className="docButton"
                 title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
                 style={{ backgroundColor: "black", color: "white" }}
-                onClick={this.uploadAudio}
+            // onClick={this.uploadAudio}
             >
                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
                 />
@@ -492,21 +501,45 @@ export class MobileInterface extends React.Component {
         }
     }
 
+    undo = () => {
+        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) {
+            return (<>
+                <div className="docButton"
+                    style={{ backgroundColor: "black", color: "white" }}
+                    id="undoButton"
+                    title="undo"
+                    onClick={(e: React.MouseEvent) => {
+                        UndoManager.Undo();
+                        e.stopPropagation();
+                    }}>
+                    <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="undo-alt" />
+                </div>
+            </>);
+        }
+    }
+
+    redo = () => {
+        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) {
+            return (<>
+                <div className="docButton"
+                    style={{ backgroundColor: "black", color: "white" }}
+                    id="undoButton"
+                    title="redo"
+                    onClick={(e: React.MouseEvent) => {
+                        UndoManager.Redo();
+                        e.stopPropagation();
+                    }}>
+                    <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="redo-alt" />
+                </div>
+            </>);
+        }
+    }
+
     // Button for switching into ink mode
     drawInk = () => {
         if (this._activeDoc._viewType === "docking") {
             return (
                 <>
-                    {/* <div className="docButton"
-                        id="undoButton"
-                        title="undo"
-                        onClick={(e: React.MouseEvent) => {
-                            UndoManager.Undo();
-                            e.stopPropagation();
-                        }}>
-                        <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="undo-alt"
-                        />
-                    </div> */}
                     <div className="docButton"
                         id="inkButton"
                         title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
@@ -514,23 +547,29 @@ export class MobileInterface extends React.Component {
                         <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="pen-nib"
                         />
                     </div>
-                    {/* <div className="docButton"
-                        id="redoButton"
-                        title="redo"
-                        onClick={(e: React.MouseEvent) => {
-                            UndoManager.Redo();
-                            e.stopPropagation();
-                        }}>
-                        <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="redo-alt"
+                </>);
+        }
+    }
+
+    // Mobile doc button for uploading 
+    upload = () => {
+        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) {
+            return (
+                <>
+                    <div className="docButton"
+                        id="uploadButton"
+                        title={"uploadFile"}
+                        onClick={this.toggleUpload}>
+                        <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
                         />
-                    </div> */}
+                    </div>
                 </>);
         }
     }
 
     // Button to download images on the mobile
     downloadDocument = () => {
-        if (this._activeDoc.type === "image") {
+        if (this._activeDoc.type === "image" || this._activeDoc.type === "pdf" || this._activeDoc.type === "video") {
             const url = this._activeDoc["data-path"]?.toString();
             return <div className="docButton"
                 title={"Download Image"}
@@ -559,24 +598,21 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    // Pushing the audio doc onto Dash Web through the right side bar
-    uploadAudio = () => {
-        const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
-        const audioDoc = this._activeDoc;
-        const data = Cast(audioRightSidebar.data, listSpec(Doc));
-
-        if (data) {
-            data.push(audioDoc);
-        }
-    }
+    // // Pushing the audio doc onto Dash Web through the right side bar
+    // uploadAudio = () => {
+    //     const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
+    //     const audioDoc = this._activeDoc;
+    //     const data = Cast(audioRightSidebar.data, listSpec(Doc));
 
-    panelHeight = () => window.innerHeight;
-    panelWidth = () => window.innerWidth;
+    //     if (data) {
+    //         data.push(audioDoc);
+    //     }
+    // }
 
     // Button for pinning images to presentation
     pinToPresentation = () => {
         // Only making button available if it is an image
-        if (this._activeDoc.type === "image") {
+        if (!(this._activeDoc.type === "collection" || this._activeDoc.type === "presentation")) {
             const isPinned = this._activeDoc && Doc.isDocPinned(this._activeDoc);
             return <div className="docButton"
                 title={Doc.isDocPinned(this._activeDoc) ? "Unpin from presentation" : "Pin to presentation"}
@@ -611,7 +647,7 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    // Logics for switching the menu into the icons
+    // Logic for switching the menu into the icons
     @action
     changeToIconView = () => {
         if (this._homeDoc._viewType = "stacking") {
@@ -635,7 +671,7 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    // Logics for switching the menu into the stacking view
+    // Logic for switching the menu into the stacking view
     @action
     changeToListView = () => {
         if (this._homeDoc._viewType = "masonry") {
@@ -674,29 +710,16 @@ export class MobileInterface extends React.Component {
     @action
     toggleUpload = () => this.imageUploadActive = !this.imageUploadActive
 
+    // For toggling image upload pop up
+    @action
+    toggleAudio = () => this.audioUploadActive = !this.audioUploadActive
+
     // For closing the image upload pop up
     @action
     closeUpload = () => {
         this.imageUploadActive = false;
     }
 
-    // Returns the image upload pop up
-    uploadImage = () => {
-        if (this.imageUploadActive) {
-            console.log("active");
-        } else if (!this.imageUploadActive) {
-
-        }
-        return (
-            <div>
-                <div className="closeUpload" onClick={this.toggleUpload}>
-                    <FontAwesomeIcon icon="window-close" size={"lg"} />
-                </div>
-                <Uploader />
-            </div>
-        );
-    }
-
     displayRadialMenu = () => {
         if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) {
             return <RadialMenu />;
@@ -713,7 +736,10 @@ export class MobileInterface extends React.Component {
             <div className="mobileInterface-container" onDragOver={this.onDragOver}>
                 <SettingsManager />
                 <div className={`image-upload ${this.imageUploadActive ? "active" : ""}`}>
-                    {this.uploadImage()}
+                    <Uploader Document={this._homeMenu ? this._library : this._activeDoc} />
+                </div>
+                <div className={`audio-upload ${this.audioUploadActive ? "active" : ""}`}>
+                    <AudioUpload />
                 </div>
                 {this.switchMenuView()}
                 {this.inkMenu()}
@@ -721,8 +747,11 @@ export class MobileInterface extends React.Component {
                     <div className="docButtonContainer">
                         {this.pinToPresentation()}
                         {this.downloadDocument()}
-                        {this.drawInk()}
-                        {this.uploadAudioButton()}
+                        {this.undo()}
+                        {this.redo()}
+                        {this.upload()}
+                        {/* {this.drawInk()} */}
+                        {/* {this.uploadAudioButton()} */}
                     </div>
                     {this.displayWorkspaces()}
                     {this.renderDefaultContent()}
@@ -738,7 +767,7 @@ export class MobileInterface extends React.Component {
 Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); });
 Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); });
 Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); });
-Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.recordAudio(); });
+Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.toggleAudio(); });
 Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); });
 Scripting.addGlobal(function switchToLibrary() { return MobileInterface.Instance.switchToLibrary(); });
 Scripting.addGlobal(function uploadImageMobile() { return MobileInterface.Instance.toggleUpload(); });
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 6304ff5e4..87731655a 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -175,6 +175,11 @@ body {
     z-index: 200;
 }
 
+.open {
+    right: 20px;
+    position: absolute;
+}
+
 .left {
     width: 100%;
     height: 100%;
@@ -262,15 +267,17 @@ body {
 .docButton {
     position: relative;
     width: 100px;
+    display: flex;
     height: 100px;
     font-size: 70px;
-    padding: 5px;
     text-align: center;
-    border-style: solid;
-    border-radius: 50px;
-    border-width: 5px;
+    border: 3px solid black;
     margin: 20px;
     z-index: 100;
+    border-radius: 100%;
+    justify-content: center;
+    flex-direction: column;
+    align-items: center;
 }
 
 .docButtonContainer {
-- 
cgit v1.2.3-70-g09d2


From 790d41009a678f560cd3b78e86069251e494cfd1 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Mon, 22 Jun 2020 14:55:00 +0800
Subject: updated css width property for mobile

---
 src/client/util/CurrentUserUtils.ts                |  2 +-
 src/client/util/SettingsManager.scss               |  2 +-
 src/client/views/AntimodeMenu.scss                 | 16 ++--
 .../views/collections/CollectionStackingView.scss  |  2 +-
 .../views/collections/CollectionViewChromes.scss   |  2 +-
 .../collectionFreeForm/InkOptionsMenu.scss         | 18 ++--
 src/client/views/nodes/AudioBox.scss               |  2 +-
 src/client/views/nodes/PDFBox.scss                 |  2 +-
 src/client/views/nodes/PresBox.scss                |  2 +-
 .../views/presentationview/PresElementBox.scss     |  2 +-
 src/mobile/AudioUpload.scss                        | 95 ----------------------
 src/mobile/MobileInterface.tsx                     | 10 +--
 src/mobile/MobileMenu.scss                         | 24 ++++--
 13 files changed, 45 insertions(+), 134 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index b7da4ae2f..5edb2225f 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -465,7 +465,7 @@ export class CurrentUserUtils {
 
     static setupMobileButtons(doc?: Doc, buttons?: string[]) {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
-            { title: "LIBRARY", icon: "bars", click: 'switchToLibrary()', backgroundColor: "#ffd6d6", info: "Navigate and access all of your documents within their respective collections." },
+            { title: "WORKSPACES", icon: "folder-open", click: 'openWorkspaces()', backgroundColor: "#ffd6d6", info: "Access your Workspaces from your mobile, and navigate through all of your documents. " },
             { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your phone to record and upload audio onto Dash Web." },
             { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "#ff9e9e", info: "Upload images or videos from your mobile device so they can be accessed on Dash Web." },
             { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "#ff8080", info: "Use your phone as a remote for you presentation." },
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index 1eac9303b..0116c5294 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -135,7 +135,7 @@
     }
 }
 
-@media only screen and (max-width: 1000px) {
+@media only screen and (max-device-width: 480px) {
     .settings-interface {
         background-color: whitesmoke !important;
         color: grey;
diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss
index 170631422..43f45fb1c 100644
--- a/src/client/views/AntimodeMenu.scss
+++ b/src/client/views/AntimodeMenu.scss
@@ -41,7 +41,7 @@
     }
 }
 
-@media only screen and (max-width: 1000px) {
+@media only screen and (max-device-width: 480px) {
     .antimodeMenu-cont {
         position: absolute;
         z-index: 10000;
@@ -51,31 +51,31 @@
         border-radius: 0px 6px 6px 6px;
         // overflow: hidden;    
         display: flex;
-    
+
         &.with-rows {
             flex-direction: column-reverse;
         }
-    
+
         .antimodeMenu-row {
             display: flex;
             height: 100%;
-            width:100%;
+            width: 100%;
         }
-    
+
         .antimodeMenu-button {
             background-color: transparent;
             width: 100px;
             height: 100px;
-    
+
             &.active {
                 background-color: #121212;
             }
         }
-    
+
         .antimodeMenu-button:hover {
             background-color: #121212;
         }
-    
+
         .antimodeMenu-dragger {
             height: 100%;
             transition: width .2s;
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 98efdfd23..342773db8 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -424,7 +424,7 @@
     }
 }
 
-@media only screen and (max-width: 1000px) {
+@media only screen and (max-device-width: 480px) {
 
     .collectionStackingView .collectionStackingView-columnDragger,
     .collectionMasonryView .collectionStackingView-columnDragger {
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index 54ee4ab3b..ec2d78735 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -80,7 +80,7 @@
                 // margin-top: 10px;
             }
 
-            @media only screen and (max-width: 1000) {
+            @media only screen and (max-device-width: 480px) {
                 .collectionViewBaseChrome-collapse {
                     display: none;
                 }
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
index 72fdf5af9..4855dfea8 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
@@ -33,39 +33,39 @@
     }
 }
 
-@media only screen and (max-width: 1000px) {
+@media only screen and (max-device-width: 480px) {
     .antimodeMenu-button {
         .color-preview {
             width: 100%;
             height: 100%;
         }
-    
+
     }
-    
+
     .sketch-picker {
         background: #323232;
-    
+
         .flexbox-fit {
             background: #323232;
         }
     }
-    
+
     .btn-group {
         display: grid;
         grid-template-columns: auto auto;
         /* Make the buttons appear below each other */
     }
-    
+
     .btn2-group {
         display: block;
         background: #323232;
         grid-template-columns: auto;
-    
+
         /* Make the buttons appear below each other */
         .antimodeMenu-button {
             background: #323232;
             display: block;
-    
+
         }
     }
-}
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 61ce4bd13..43dd698ad 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -174,7 +174,7 @@
 }
 
 
-@media only screen and (max-width: 1000px) {
+@media only screen and (max-device-width: 480px) {
 
     .audiobox-container,
     .audiobox-container-interactive {
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 1a31d2916..b19ddf1f5 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -224,7 +224,7 @@
     }
 }
 
-@media only screen and (max-width: 600px) {
+@media only screen and (max-device-width: 480px) {
 
     .pdfBox .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton,
     .pdfBox-interactive .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton {
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index e62aa48fb..1261cbfdd 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -81,7 +81,7 @@
     }
 }
 
-@media only screen and (max-width: 1000px) {
+@media only screen and (max-device-width: 480px) {
     .presBox-cont .presBox-buttons {
         position: absolute;
         top: 70%;
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index 99fe2a3ba..79532995e 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -106,7 +106,7 @@
     z-index: 2;
 }
 
-@media only screen and (max-width: 1000px) {
+@media only screen and (max-device-width: 480px) {
     .presElementBox-buttons {
         display: inline-flex;
         position: relative;
diff --git a/src/mobile/AudioUpload.scss b/src/mobile/AudioUpload.scss
index 5f0ba465a..9fe442e55 100644
--- a/src/mobile/AudioUpload.scss
+++ b/src/mobile/AudioUpload.scss
@@ -7,77 +7,6 @@
     align-items: center;
     max-width: 400px;
     min-width: 400px;
-
-    .upload_label {
-        font-size: 3em;
-        font-weight: 700;
-        color: white;
-        background-color: black;
-        display: inline-block;
-        margin: 10;
-        width: 100%;
-        border-radius: 10px;
-    }
-
-    .file {
-        white-space: nowrap;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        direction: ltr;
-    }
-
-    .upload_label:hover {
-        background-color: darkred;
-    }
-
-    .button_file {
-        text-align: center;
-        height: 50%;
-        width: 50%;
-        background-color: paleturquoise;
-        color: grey;
-        font-size: 3em;
-    }
-
-    .inputfile {
-        width: 0.1px;
-        height: 0.1px;
-        opacity: 0;
-        overflow: hidden;
-        position: absolute;
-        z-index: -1;
-    }
-
-    .inputfile+label {
-        font-size: 3em;
-        font-weight: 700;
-        color: white;
-        background-color: black;
-        display: inline-block;
-        margin: 10px;
-        width: 100%;
-        border-radius: 10px;
-    }
-
-    .inputfile:focus+label,
-    .inputfile+label:hover {
-        background-color: darkred;
-    }
-
-    .status {
-        font-size: 2em;
-    }
-
-}
-
-.backgroundUpload {
-    height: 100vh;
-    top: 0;
-    z-index: 999;
-    width: 100vw;
-    position: absolute;
-    background-color: lightgrey;
-    opacity: 0.4;
 }
 
 .audio-upload {
@@ -92,28 +21,4 @@
     height: 100vh;
     width: 100vw;
     opacity: 1;
-}
-
-.uploadContainer {
-    top: 40;
-    position: absolute;
-    z-index: 1000;
-    height: 20vh;
-    width: 80vw;
-    opacity: 1;
-}
-
-.loadingImage {
-    display: inline-flex;
-    width: max-content;
-}
-
-.loadingSlab {
-    position: relative;
-    width: 30px;
-    height: 30px;
-    margin: 10;
-    border-radius: 20px;
-    opacity: 0.3;
-    background-color: black;
 }
\ No newline at end of file
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 84a5975cb..ceda74da2 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -415,7 +415,7 @@ export class MobileInterface extends React.Component {
                                     onClick={this.returnMain}
                                     style={{ opacity: 0.7 }}>
                                     <FontAwesomeIcon className="right" icon="angle-double-left" size="lg" />
-                                    <div className="item-type">Return to library</div>
+                                    <div className="item-type">Return to workspaces</div>
                                 </div>
                             </> :
                             <>
@@ -509,7 +509,7 @@ export class MobileInterface extends React.Component {
     }
 
     undo = () => {
-        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) {
+        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc.title !== "WORKSPACES") {
             return (<>
                 <div className="docButton"
                     style={{ backgroundColor: "black", color: "white" }}
@@ -526,7 +526,7 @@ export class MobileInterface extends React.Component {
     }
 
     redo = () => {
-        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) {
+        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc.title !== "WORKSPACES") {
             return (<>
                 <div className="docButton"
                     style={{ backgroundColor: "black", color: "white" }}
@@ -814,10 +814,10 @@ export class MobileInterface extends React.Component {
                         {this.pinToPresentation()}
                         {this.downloadDocument()}
                         {this.undo()}
+                        {this.drawInk()}
                         {this.redo()}
-                        {this.upload()}
+                        {/* {this.upload()} */}
                         {this.uploadImageButton()}
-                        {/* {this.drawInk()} */}
                         {/* {this.uploadAudioButton()} */}
                     </div>
                     {this.displayWorkspaces()}
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 87731655a..53bc48034 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -19,7 +19,6 @@ body {
     width: 100vw;
     height: $navbar-height;
     background-color: whitesmoke;
-    border-bottom: 5px solid black;
     z-index: 150;
 }
 
@@ -221,14 +220,17 @@ body {
 
 .back {
     position: absolute;
-    top: 44%;
     left: 42px;
-    background-color: black;
+    top: 0;
+    background: #1a1a1a;
     width: 50px;
-    height: 50px;
+    height: 100%;
+    display: flex;
+    justify-content: center;
     text-align: center;
+    flex-direction: column;
+    align-items: center;
     border-radius: 10px;
-    transform: translate(0, -50%);
     font-size: 25px;
     user-select: none;
     z-index: 100;
@@ -243,7 +245,7 @@ body {
     border-radius: 0px;
     width: 100%;
     height: 80px;
-    transition: all 400ms ease 50ms;
+    overflow: hidden;
 }
 
 .pathname {
@@ -291,14 +293,19 @@ body {
 
 .scrollmenu {
     overflow: auto;
+    width: 100%;
+    height: 100%;
     white-space: nowrap;
+    display: inline-flex;
 }
 
 .pathbarItem {
     position: relative;
-    display: inline-flex;
+    display: flex;
+    align-items: center;
     color: whitesmoke;
     text-align: center;
+    justify-content: center;
     user-select: none;
     transform: translate(100px, 0px);
     font-size: 30px;
@@ -311,7 +318,6 @@ body {
     text-align: center;
     height: 50px;
     padding: 10px;
-    background-color: rgb(48, 40, 40);
     font-size: 30px;
     border-radius: 10px;
     text-transform: uppercase;
@@ -321,7 +327,7 @@ body {
 
 
 .pathIcon {
-    transform: translate(0px, 8px);
+    transform: translate(0px, 0px);
     position: relative;
 }
 
-- 
cgit v1.2.3-70-g09d2


From db92851456f168affcdbd4053b38e7b9f6b7a97d Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Thu, 25 Jun 2020 12:00:43 -0700
Subject: fix image flikering (hopefully), changed sidebar UI, and changed
 handle click

---
 src/client/views/nodes/ImageBox.tsx |  1 +
 src/mobile/MobileInterface.tsx      | 20 ++++++++++++---
 src/mobile/MobileMenu.scss          | 50 +++++++++++++++++++++++++++++++------
 3 files changed, 60 insertions(+), 11 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 225d03104..d16aa528c 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -236,6 +236,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
         if (this._curSuffix === "_m") this._mediumRetryCount++;
         if (this._curSuffix === "_l") this._largeRetryCount++;
     }
+
     @action onError = (error: any) => {
         const timeout = this._curSuffix === "_s" ? this._smallRetryCount : this._curSuffix === "_m" ? this._mediumRetryCount : this._largeRetryCount;
         if (timeout < 5) {
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index a1719c015..0bc950a71 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -11,6 +11,7 @@ import {
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
+import { trace } from 'mobx';
 import * as rp from 'request-promise';
 import { Doc, DocListCast } from '../fields/Doc';
 import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
@@ -115,12 +116,14 @@ export class MobileInterface extends React.Component {
     /**
      * Method called when 'Library' button is pressed on the home screen
      */
-    switchToLibrary = () => {
+    switchToLibrary = async () => {
         this._parents.push(this._activeDoc);
         this.switchCurrentView((userDoc: Doc) => this._library);
         this._activeDoc = this._library;
         this._homeMenu = false;
-        this.sidebarActive = true;
+        this.toggleSidebar();
+        //setTimeout(this.toggleSidebar, 300);
+
     }
 
     openWorkspaces = () => {
@@ -128,6 +131,7 @@ export class MobileInterface extends React.Component {
         this.switchCurrentView((userDoc: Doc) => this._library);
         this._activeDoc = this._library;
         this._homeMenu = false;
+        this.sidebarActive = true;
     }
 
     /**
@@ -242,7 +246,13 @@ export class MobileInterface extends React.Component {
     @undoBatch
     handleClick = async (doc: Doc) => {
         const children = DocListCast(doc.data);
-        if (doc.type !== "collection" && this.sidebarActive) this.openFromSidebar(doc);
+        if (doc.type !== "collection" && this.sidebarActive) {
+            this._parents.push(this._activeDoc);
+            this._activeDoc = doc;
+            this.switchCurrentView((userDoc: Doc) => doc);
+            this._homeMenu = false;
+            this.toggleSidebar();
+        }
         else if (doc.type === "collection" && children.length === 0) this.openFromSidebar(doc);
         else {
             this._parents.push(this._activeDoc);
@@ -407,6 +417,7 @@ export class MobileInterface extends React.Component {
                         <span></span>
                         <span></span>
                     </div>
+                    <div className={`background ${this.sidebarActive ? "active" : ""}`} onClick={this.toggleSidebar}></div>
                 </div>
                 {this.renderPathbar()}
                 <div className={`sidebar ${this.sidebarActive ? "active" : ""}`}>
@@ -435,6 +446,8 @@ export class MobileInterface extends React.Component {
                         }
                     </div>
                 </div>
+                <div className={`blanket ${this.sidebarActive ? "active" : ""}`} onClick={this.toggleSidebar}>
+                </div>
             </div>
         );
     }
@@ -846,3 +859,4 @@ Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Insta
 Scripting.addGlobal(function openWorkspaces() { return MobileInterface.Instance.openWorkspaces(); });
 Scripting.addGlobal(function uploadImageMobile() { return MobileInterface.Instance.toggleUpload(); });
 Scripting.addGlobal(function switchToMobileUploads() { return MobileInterface.Instance.switchToMobileUploads(); });
+Scripting.addGlobal(function switchToLibrary() { return MobileInterface.Instance.switchToLibrary(); });
\ No newline at end of file
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 53bc48034..ec8946578 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -24,10 +24,10 @@ body {
 
 .navbar .cover {
     position: absolute;
-    right: 20px;
-    top: 30px;
-    height: 70px;
-    width: 70px;
+    right: 0px;
+    top: 0px;
+    height: 120px;
+    width: 120px;
     background-color: whitesmoke;
     z-index: 200;
 }
@@ -38,7 +38,21 @@ body {
     top: 30px;
     height: 70px;
     width: 70px;
-    transition: all 300ms ease-in-out 200ms;
+    transition: all 400ms ease-in-out 200ms;
+    z-index: 180;
+}
+
+.navbar .background {
+    position: absolute;
+    right: 0px;
+    top: 0px;
+    height: 120px;
+    width: 120px;
+    //border: 1px solid black;
+}
+
+.navbar .background.active {
+    background-color: lightgrey;
 }
 
 .navbar .toggle-btn-home {
@@ -73,6 +87,7 @@ body {
     height: 4px;
     background: black;
     transition: all 200ms ease;
+    z-index: 180;
 }
 
 .navbar .toggle-btn span:nth-child(1) {
@@ -107,8 +122,8 @@ body {
     top: 120px;
     opacity: 0;
     right: -100%;
-    width: 100%;
-    height: calc(100% - (120px));
+    width: 80%;
+    height: calc(80% - (120px));
     z-index: 101;
     background-color: whitesmoke;
     transition: all 400ms ease 50ms;
@@ -116,6 +131,7 @@ body {
     // overflow-y: auto;
     // -webkit-overflow-scrolling: touch;
     // border-right: 5px solid black;
+    box-shadow: 0 0 5px 5px grey;
 }
 
 .sidebar .item {
@@ -142,6 +158,24 @@ body {
     position: relative;
 }
 
+.blanket {
+    position: fixed;
+    top: 120px;
+    opacity: 0.5;
+    right: -100%;
+    width: 100%;
+    height: calc(100% - (120px));
+    z-index: 101;
+    background-color: grey;
+    padding: 20px;
+}
+
+.blanket.active {
+    position: absolute;
+    right: 0%;
+    z-index: 100;
+}
+
 .home {
     position: absolute;
     top: 30px;
@@ -213,7 +247,7 @@ body {
 
 .sidebar.active {
     position: absolute;
-    right: 0%;
+    right:0%;
     opacity: 1;
     z-index: 101;
 }
-- 
cgit v1.2.3-70-g09d2


From e7372931b9d28c141aaec9552041b5644c2f415a Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Fri, 26 Jun 2020 03:37:08 +0800
Subject: Merge branch 'master' into mobile_revision_direct

And changes to UI of record and image upload
---
 src/client/util/CurrentUserUtils.ts                |  12 +-
 src/client/util/DragManager.ts                     |   2 +-
 src/client/views/DocumentButtonBar.tsx             |  63 +-----
 src/client/views/DocumentDecorations.tsx           |   2 +-
 src/client/views/GlobalKeyHandler.ts               |   2 +
 src/client/views/MainView.tsx                      |  11 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   4 +-
 src/client/views/globalCssVariables.scss           |   1 +
 src/client/views/linking/LinkMenu.scss             |   4 +
 src/client/views/linking/LinkMenu.tsx              |  37 +--
 src/client/views/nodes/AudioBox.scss               |  71 +-----
 src/client/views/nodes/AudioBox.tsx                |   2 +-
 src/client/views/nodes/DocumentLinksButton.scss    |  38 ++++
 src/client/views/nodes/DocumentLinksButton.tsx     | 104 +++++++++
 src/client/views/nodes/DocumentView.tsx            |  28 ++-
 src/client/views/nodes/LinkAnchorBox.tsx           |   8 +
 src/client/views/nodes/LinkDocPreview.tsx          | 107 +++++++++
 .../views/nodes/formattedText/RichTextMenu.tsx     |   9 +-
 src/mobile/AudioUpload.scss                        |  41 +++-
 src/mobile/AudioUpload.tsx                         | 249 +++++++--------------
 src/mobile/ImageUpload.scss                        |  61 ++---
 src/mobile/ImageUpload.tsx                         |  66 +++---
 src/mobile/MobileInterface.tsx                     |  29 ++-
 src/mobile/MobileMenu.scss                         |   1 +
 24 files changed, 549 insertions(+), 403 deletions(-)
 create mode 100644 src/client/views/nodes/DocumentLinksButton.scss
 create mode 100644 src/client/views/nodes/DocumentLinksButton.tsx
 create mode 100644 src/client/views/nodes/LinkDocPreview.tsx

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index efdc943fa..823a99436 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -474,12 +474,12 @@ export class CurrentUserUtils {
 
     static setupMobileButtons(doc?: Doc, buttons?: string[]) {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
-            { title: "WORKSPACES", icon: "folder-open", click: 'openWorkspaces()', backgroundColor: "#ffd6d6", info: "Access your Workspaces from your mobile, and navigate through all of your documents. " },
-            { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your phone to record and upload audio onto Dash Web." },
-            { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "#ff9e9e", info: "Upload images or videos from your mobile device so they can be accessed on Dash Web." },
-            { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "#ff8080", info: "Use your phone as a remote for you presentation." },
-            { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploads()', backgroundColor: "#ff7373", info: "Access the collection of your mobile uploads." },
-            { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "#ff5e5e", info: "Change your password, log out, or manage your account security." }
+            { title: "WORKSPACES", icon: "bars", click: 'openMobileWorkspaces()', backgroundColor: "lightgrey", info: "Access your Workspaces from your mobile, and navigate through all of your documents. " },
+            { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "lightgrey", info: "Upload files from your mobile device so they can be accessed on Dash Web." },
+            { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploads()', backgroundColor: "lightgrey", info: "Access the collection of your mobile uploads." },
+            { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "lightgrey", info: "Use your phone to record, dictate and then upload audio onto Dash Web." },
+            { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "lightgrey", info: "Use your phone as a remote for you presentation." },
+            { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "lightgrey", info: "Change your password, log out, or manage your account security." }
         ];
         return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data =>
             this.mobileButton({
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 91bc51101..417ddf989 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -353,7 +353,7 @@ export namespace DragManager {
             const dragElement = ele.parentNode === dragDiv ? ele : ele.cloneNode(true) as HTMLElement;
             const rect = ele.getBoundingClientRect();
             const scaleX = rect.width / ele.offsetWidth,
-                scaleY = rect.height / ele.offsetHeight;
+                scaleY = ele.offsetHeight ? rect.height / ele.offsetHeight : scaleX;
             elesCont.left = Math.min(rect.left, elesCont.left);
             elesCont.top = Math.min(rect.top, elesCont.top);
             elesCont.right = Math.max(rect.right, elesCont.right);
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 62a95116f..fcaea0f0b 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -1,28 +1,28 @@
 import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
-import { faArrowAltCircleDown, faPhotoVideo, faArrowAltCircleUp, faArrowAltCircleRight, faCheckCircle, faCloudUploadAlt, faLink, faShare, faStopCircle, faSyncAlt, faTag, faTimes } from '@fortawesome/free-solid-svg-icons';
+import { faArrowAltCircleDown, faArrowAltCircleRight, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faPhotoVideo, faShare, faStopCircle, faSyncAlt, faTag, faTimes } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast } from "../../fields/Doc";
 import { RichTextField } from '../../fields/RichTextField';
-import { NumCast, StrCast, Cast } from "../../fields/Types";
+import { Cast, NumCast } from "../../fields/Types";
 import { emptyFunction, setupMoveUpEvents } from "../../Utils";
+import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
 import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
+import { Docs, DocUtils } from '../documents/Documents';
+import { DragManager } from '../util/DragManager';
 import { UndoManager } from "../util/UndoManager";
 import { CollectionDockingView, DockedFrameRenderer } from './collections/CollectionDockingView';
 import { ParentDocSelector } from './collections/ParentDocumentSelector';
 import './collections/ParentDocumentSelector.scss';
 import './DocumentButtonBar.scss';
-import { LinkMenu } from "./linking/LinkMenu";
+import { MetadataEntryMenu } from './MetadataEntryMenu';
 import { DocumentView } from './nodes/DocumentView';
 import { GoogleRef } from "./nodes/formattedText/FormattedTextBox";
 import { TemplateMenu } from "./TemplateMenu";
 import { Template, Templates } from "./Templates";
 import React = require("react");
-import { DragManager } from '../util/DragManager';
-import { MetadataEntryMenu } from './MetadataEntryMenu';
-import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
-import { Docs } from '../documents/Documents';
+import { DocumentLinksButton } from './nodes/DocumentLinksButton';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -113,39 +113,6 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
 
     get view0() { return this.props.views()?.[0]; }
 
-    @action
-    onLinkButtonMoved = (e: PointerEvent) => {
-        if (this._linkButton.current !== null) {
-            const linkDrag = UndoManager.StartBatch("Drag Link");
-            this.view0 && DragManager.StartLinkDrag(this._linkButton.current, this.view0.props.Document, e.pageX, e.pageY, {
-                dragComplete: dropEv => {
-                    const linkDoc = dropEv.linkDragData?.linkDocument as Doc; // equivalent to !dropEve.aborted since linkDocument is only assigned on a completed drop
-                    if (this.view0 && linkDoc) {
-                        !linkDoc.linkRelationship && (Doc.GetProto(linkDoc).linkRelationship = "hyperlink");
-
-                        // we want to allow specific views to handle the link creation in their own way (e.g., rich text makes text hyperlinks)
-                        // the dragged view can regiser a linkDropCallback to be notified that the link was made and to update their data structures
-                        // however, the dropped document isn't so accessible.  What we do is set the newly created link document on the documentView
-                        // The documentView passes a function prop returning this link doc to its descendants who can react to changes to it.
-                        dropEv.linkDragData?.linkDropCallback?.(dropEv.linkDragData);
-                        runInAction(() => this.view0!._link = linkDoc);
-                        setTimeout(action(() => this.view0!._link = undefined), 0);
-                    }
-                    linkDrag?.end();
-                },
-                hideSource: false
-            });
-            return true;
-        }
-        return false;
-    }
-
-
-    onLinkButtonDown = (e: React.PointerEvent): void => {
-        setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, emptyFunction);
-    }
-
-
     @computed
     get considerGoogleDocsPush() {
         const targetDoc = this.view0?.props.Document;
@@ -235,20 +202,6 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
         </div>;
     }
 
-    @computed
-    get linkButton() {
-        const view0 = this.view0;
-        const linkCount = view0 && DocListCast(view0.props.Document.links).length;
-        return !view0 ? (null) : <div title="Drag(create link) Tap(view links)" className="documentButtonBar-linkFlyout" ref={this._linkButton}>
-            <Flyout anchorPoint={anchorPoints.LEFT_TOP}
-                content={<LinkMenu docView={view0} addDocTab={view0.props.addDocTab} changeFlyout={emptyFunction} />}>
-                <div className={"documentButtonBar-linkButton-" + (linkCount ? "nonempty" : "empty")} onPointerDown={this.onLinkButtonDown} >
-                    {linkCount ? linkCount : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />}
-                </div>
-            </Flyout>
-        </div>;
-    }
-
     @computed
     get metadataButton() {
         const view0 = this.view0;
@@ -318,7 +271,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
         const considerPush = isText && this.considerGoogleDocsPush;
         return <div className="documentButtonBar">
             <div className="documentButtonBar-button">
-                {this.linkButton}
+                <DocumentLinksButton View={this.view0!} AlwaysOn={true} />
             </div>
             <div className="documentButtonBar-button">
                 {this.templateButton}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index beb6155ca..d7b0ab7a9 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -552,7 +552,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                     onPointerDown={this.onRadiusDown} onContextMenu={(e) => e.preventDefault()}></div>
 
             </div >
-            <div className="link-button-container" style={{ left: bounds.x - this._resizeBorderWidth / 2, top: bounds.b + this._resizeBorderWidth / 2 }}>
+            <div className="link-button-container" style={{ left: bounds.x - this._resizeBorderWidth / 2 + 10, top: bounds.b + this._resizeBorderWidth / 2 }}>
                 <DocumentButtonBar views={SelectionManager.SelectedDocuments} />
             </div>
         </div >
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 27755737e..7bc8cf6a7 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -19,6 +19,7 @@ import { MarqueeView } from "./collections/collectionFreeForm/MarqueeView";
 import { DocumentDecorations } from "./DocumentDecorations";
 import { MainView } from "./MainView";
 import { DocumentView } from "./nodes/DocumentView";
+import { DocumentLinksButton } from "./nodes/DocumentLinksButton";
 
 const modifiers = ["control", "meta", "shift", "alt"];
 type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo | Promise<KeyControlInfo>;
@@ -77,6 +78,7 @@ export default class KeyManager {
                 // MarqueeView.DragMarquee = !MarqueeView.DragMarquee; // bcz: this needs a better disclosure UI
                 break;
             case "escape":
+                DocumentLinksButton.StartLink = undefined;
                 const main = MainView.Instance;
                 Doc.SetSelectedTool(InkTool.None);
                 if (main.isPointerDown) {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 97953452d..4e2c067ac 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -5,7 +5,7 @@ import {
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
     faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote,
-    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faQuoteLeft
+    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faQuoteLeft, faSortAmountDown
 } from '@fortawesome/free-solid-svg-icons';
 import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -55,6 +55,9 @@ import { TimelineMenu } from './animationtimeline/TimelineMenu';
 import { SnappingManager } from '../util/SnappingManager';
 import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
 import { DocumentManager } from '../util/DocumentManager';
+import { DocumentLinksButton } from './nodes/DocumentLinksButton';
+import { LinkMenu } from './linking/LinkMenu';
+import { LinkDocPreview } from './nodes/LinkDocPreview';
 
 @observer
 export class MainView extends React.Component {
@@ -135,7 +138,7 @@ export class MainView extends React.Component {
             faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
             faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
             faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTrashAlt, faAngleRight, faBell,
-            faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faQuoteLeft);
+            faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faQuoteLeft, faSortAmountDown);
         this.initEventListeners();
         this.initAuthenticationRouters();
     }
@@ -578,6 +581,10 @@ export class MainView extends React.Component {
                 {this.mainContent}
             </GestureOverlay>
             <PreviewCursor />
+            {DocumentLinksButton.EditLink ? <LinkMenu location={DocumentLinksButton.EditLinkLoc} docView={DocumentLinksButton.EditLink} addDocTab={DocumentLinksButton.EditLink.props.addDocTab} changeFlyout={emptyFunction} /> : (null)}
+            {LinkDocPreview.LinkInfo ? <LinkDocPreview location={LinkDocPreview.LinkInfo.Location} backgroundColor={this.defaultBackgroundColors}
+                linkDoc={LinkDocPreview.LinkInfo.linkDoc} linkSrc={LinkDocPreview.LinkInfo.linkSrc} href={LinkDocPreview.LinkInfo.href}
+                addDocTab={LinkDocPreview.LinkInfo.addDocTab} /> : (null)}
             <ContextMenu />
             <RadialMenu />
             <PDFMenu />
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index dc62c48b7..42aa0f58e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -47,6 +47,7 @@ import { Timeline } from "../../animationtimeline/Timeline";
 import { SnappingManager } from "../../../util/SnappingManager";
 import { ActiveInkColor, ActiveInkWidth, ActiveInkBezierApprox } from "../../InkingStroke";
 import { DocumentType } from "../../../documents/DocumentTypes";
+import { DocumentLinksButton } from "../../nodes/DocumentLinksButton";
 
 library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
 
@@ -245,7 +246,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             // const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, x: xp, y: yp, title: "dropped annotation" });
             // this.props.addDocument(source);
             // linkDragData.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: linkDragData.linkSourceDocument }, "doc annotation"); // TODODO this is where in text links get passed
-           return false;
+            return false;
         } else {
             const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, x: xp, y: yp, title: "dropped annotation" });
             this.props.addDocument(source);
@@ -589,6 +590,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     onClick = (e: React.MouseEvent) => {
         if (this.layoutDoc.targetScale && (Math.abs(e.pageX - this._downX) < 3 && Math.abs(e.pageY - this._downY) < 3)) {
             if (Date.now() - this._lastTap < 300) {
+                runInAction(() => DocumentLinksButton.StartLink = undefined);
                 const docpt = this.getTransform().transformPoint(e.clientX, e.clientY);
                 this.scaleAtPt(docpt, 1);
                 e.stopPropagation();
diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss
index 4e85fe0ca..3e54d001b 100644
--- a/src/client/views/globalCssVariables.scss
+++ b/src/client/views/globalCssVariables.scss
@@ -12,6 +12,7 @@ $lighter-alt-accent: rgb(207, 220, 240);
 $darker-alt-accent: rgb(178, 206, 248);
 $intermediate-color: #9c9396;
 $dark-color: #121721;
+$link-color: lightBlue;
 $antimodemenu-height: 35px;
 // fonts
 $sans-serif: "Noto Sans",
diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss
index 7dee22f66..c372e7098 100644
--- a/src/client/views/linking/LinkMenu.scss
+++ b/src/client/views/linking/LinkMenu.scss
@@ -8,6 +8,10 @@
 .linkMenu-list {
     max-height: 200px;
     overflow-y: scroll;
+    position: absolute;
+    z-index: 10;
+    background: $link-color;
+    min-width: 150px
 }
 
 .linkMenu-group {
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index 56f40ad69..0fcc0f0b9 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -4,11 +4,12 @@ import { DocumentView } from "../nodes/DocumentView";
 import { LinkEditor } from "./LinkEditor";
 import './LinkMenu.scss';
 import React = require("react");
-import { Doc } from "../../../fields/Doc";
+import { Doc, Opt } from "../../../fields/Doc";
 import { LinkManager } from "../../util/LinkManager";
 import { LinkMenuGroup } from "./LinkMenuGroup";
 import { faTrash } from '@fortawesome/free-solid-svg-icons';
 import { library } from "@fortawesome/fontawesome-svg-core";
+import { DocumentLinksButton } from "../nodes/DocumentLinksButton";
 
 library.add(faTrash);
 
@@ -16,16 +17,29 @@ interface Props {
     docView: DocumentView;
     changeFlyout: () => void;
     addDocTab: (document: Doc, where: string) => boolean;
+    location: number[];
 }
 
 @observer
 export class LinkMenu extends React.Component<Props> {
 
     @observable private _editingLink?: Doc;
+    @observable private _linkMenuRef: Opt<HTMLDivElement | null>;
 
+    @action
+    onClick = (e: PointerEvent) => {
+        if (!Array.from(this._linkMenuRef?.getElementsByTagName((e.target as HTMLElement).tagName) || []).includes(e.target as any)) {
+            DocumentLinksButton.EditLink = undefined;
+        }
+    }
     @action
     componentDidMount() {
         this._editingLink = undefined;
+        document.addEventListener("pointerdown", this.onClick);
+    }
+
+    componentWillUnmount() {
+        document.removeEventListener("pointerdown", this.onClick);
     }
 
     clearAllLinks = () => {
@@ -56,20 +70,11 @@ export class LinkMenu extends React.Component<Props> {
     render() {
         const sourceDoc = this.props.docView.props.Document;
         const groups: Map<string, Doc[]> = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc);
-        if (this._editingLink === undefined) {
-            return (
-                <div className="linkMenu">
-                    {/* <button className="linkEditor-button linkEditor-clearButton" onClick={() => this.clearAllLinks()} title="Clear all links"><FontAwesomeIcon icon="trash" size="sm" /></button> */}
-                    {/* <input id="linkMenu-searchBar" type="text" placeholder="Search..."></input> */}
-                    <div className="linkMenu-list">
-                        {this.renderAllGroups(groups)}
-                    </div>
-                </div>
-            );
-        } else {
-            return (
-                <LinkEditor sourceDoc={this.props.docView.props.Document} linkDoc={this._editingLink} showLinks={action(() => this._editingLink = undefined)}></LinkEditor>
-            );
-        }
+        return <div className="linkMenu-list" ref={(r) => this._linkMenuRef = r} style={{ left: this.props.location[0], top: this.props.location[1] }}>
+            {!this._editingLink ?
+                this.renderAllGroups(groups) :
+                <LinkEditor sourceDoc={this.props.docView.props.Document} linkDoc={this._editingLink} showLinks={action(() => this._editingLink = undefined)} />
+            }
+        </div>;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 43dd698ad..b5d113ca0 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -175,76 +175,29 @@
 
 
 @media only screen and (max-device-width: 480px) {
-
-    .audiobox-container,
-    .audiobox-container-interactive {
-        width: max-content;
-        /* align-self: center; */
-        left: 50%;
-        top: 40%;
-        transform: translate(-50%, 0);
-        height: 100px;
-        position: absolute;
-        display: flex;
-        pointer-events: all;
-        /* cursor: default; */
-    }
-
-    .audiobox-container .audiobox-buttons,
-    .audiobox-container-interactive .audiobox-buttons {
-        display: flex;
-        width: 500px;
-        /* left: 50%; */
-        /* transform: translate(-50%,0); */
-        align-items: center;
-    }
-
     .audiobox-dictation {
+        font-size: 5em;
+        display: flex;
         width: 100;
-        height: 100;
-        font-size: 50;
-        /* background-color: white; */
+        justify-content: center;
+        flex-direction: column;
+        align-items: center;
     }
 
-    .audiobox-container .audiobox-record-interactive,
-    .audiobox-container-interactive .audiobox-record-interactive {
-        width: 95%;
-        user-select: none;
-        font-size: 50px;
-        font-weight: 100;
-        left: 5%;
+    .audiobox-container .audiobox-record,
+    .audiobox-container-interactive .audiobox-record {
+        pointer-events: all;
+        font-size: 3em;
+        width: 100%;
         height: 100%;
         position: relative;
+        pointer-events: none;
     }
 
     .audiobox-container .audiobox-controls .audiobox-player .audiobox-playhead,
     .audiobox-container .audiobox-controls .audiobox-player .audiobox-dictation,
     .audiobox-container-interactive .audiobox-controls .audiobox-player .audiobox-playhead,
     .audiobox-container-interactive .audiobox-controls .audiobox-player .audiobox-dictation {
-        position: relative;
-        align-self: center;
-        width: 50px;
-        height: max-content;
-        padding: 0;
-    }
-
-    .audiobox-container .audiobox-controls .audiobox-player,
-    .audiobox-container-interactive .audiobox-controls .audiobox-player {
-        margin-top: auto;
-        margin-bottom: auto;
-        width: 100%;
-        height: 100%;
-        position: relative;
-        padding-right: 5px;
-        display: flex;
-    }
-
-    .audiobox-container .audiobox-controls,
-    .audiobox-container-interactive .audiobox-controls {
-        width: 500px;
-        height: 100%;
-        position: relative;
-        display: flex;
-        padding-left: 2px;
+        width: 70px;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index cb0582d87..d5288fff6 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -193,7 +193,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         const newDoc = Docs.Create.TextDocument("", {
             title: "", _chromeStatus: "disabled",
             x: NumCast(this.props.Document.x), y: NumCast(this.props.Document.y) + NumCast(this.props.Document._height) + 10,
-            _width: NumCast(this.props.Document._width), _height: 3 * NumCast(this.props.Document._height)
+            _width: NumCast(this.props.Document._width), _height: 2 * NumCast(this.props.Document._height)
         });
         Doc.GetProto(newDoc).recordingSource = this.dataDoc;
         Doc.GetProto(newDoc).recordingStart = ComputedField.MakeFunction(`self.recordingSource["${this.props.fieldKey}-recordingStart"]`);
diff --git a/src/client/views/nodes/DocumentLinksButton.scss b/src/client/views/nodes/DocumentLinksButton.scss
new file mode 100644
index 000000000..484f8c469
--- /dev/null
+++ b/src/client/views/nodes/DocumentLinksButton.scss
@@ -0,0 +1,38 @@
+@import "../globalCssVariables.scss";
+
+
+.documentLinksButton,
+.documentLinksButton-endLink,
+.documentLinksButton-startLink {
+    height: 20px;
+    width: 20px;
+    position: absolute;
+    border-radius: 50%;
+    opacity: 0.9;
+    pointer-events: auto;
+    color: black;
+    text-transform: uppercase;
+    letter-spacing: 2px;
+    font-size: 75%;
+    transition: transform 0.2s;
+    text-align: center;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    &:hover {
+        background: deepskyblue;
+        transform: scale(1.05);
+        cursor: default;
+    }
+}
+.documentLinksButton {
+    background-color: $link-color;
+}
+.documentLinksButton-endLink {
+    border: red solid 2px;
+}
+.documentLinksButton-startLink {
+    border: red solid 2px;
+    background-color: rgba(255, 192, 203, 0.5);
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
new file mode 100644
index 000000000..f35b48ce4
--- /dev/null
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -0,0 +1,104 @@
+import { action, computed, observable, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { Doc, DocListCast } from "../../../fields/Doc";
+import { emptyFunction, setupMoveUpEvents, returnFalse } from "../../../Utils";
+import { DragManager } from "../../util/DragManager";
+import { UndoManager } from "../../util/UndoManager";
+import './DocumentLinksButton.scss';
+import { DocumentView } from "./DocumentView";
+import React = require("react");
+import { DocUtils } from "../../documents/Documents";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { LinkDocPreview } from "./LinkDocPreview";
+const higflyout = require("@hig/flyout");
+export const { anchorPoints } = higflyout;
+export const Flyout = higflyout.default;
+
+interface DocumentLinksButtonProps {
+    View: DocumentView;
+    Offset?: number[];
+    AlwaysOn?: boolean;
+}
+@observer
+export class DocumentLinksButton extends React.Component<DocumentLinksButtonProps, {}> {
+    private _linkButton = React.createRef<HTMLDivElement>();
+
+    @action
+    onLinkButtonMoved = (e: PointerEvent) => {
+        if (this._linkButton.current !== null) {
+            const linkDrag = UndoManager.StartBatch("Drag Link");
+            this.props.View && DragManager.StartLinkDrag(this._linkButton.current, this.props.View.props.Document, e.pageX, e.pageY, {
+                dragComplete: dropEv => {
+                    const linkDoc = dropEv.linkDragData?.linkDocument as Doc; // equivalent to !dropEve.aborted since linkDocument is only assigned on a completed drop
+                    if (this.props.View && linkDoc) {
+                        !linkDoc.linkRelationship && (Doc.GetProto(linkDoc).linkRelationship = "hyperlink");
+
+                        // we want to allow specific views to handle the link creation in their own way (e.g., rich text makes text hyperlinks)
+                        // the dragged view can regiser a linkDropCallback to be notified that the link was made and to update their data structures
+                        // however, the dropped document isn't so accessible.  What we do is set the newly created link document on the documentView
+                        // The documentView passes a function prop returning this link doc to its descendants who can react to changes to it.
+                        dropEv.linkDragData?.linkDropCallback?.(dropEv.linkDragData);
+                        runInAction(() => this.props.View._link = linkDoc);
+                        setTimeout(action(() => this.props.View._link = undefined), 0);
+                    }
+                    linkDrag?.end();
+                },
+                hideSource: false
+            });
+            return true;
+        }
+        return false;
+    }
+
+    @observable static StartLink: DocumentView | undefined;
+    onLinkButtonDown = (e: React.PointerEvent): void => {
+        setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => {
+            if (doubleTap) {
+                DocumentLinksButton.StartLink = this.props.View;
+            } else {
+                DocumentLinksButton.EditLink = this.props.View;
+                DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY];
+            }
+        }));
+    }
+    completeLink = (e: React.PointerEvent): void => {
+        setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e, doubleTap) => {
+            if (doubleTap) {
+                if (DocumentLinksButton.StartLink === this.props.View) {
+                    DocumentLinksButton.StartLink = undefined;
+                } else {
+                    DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
+                        DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
+                }
+            }
+        }));
+    }
+
+    @observable
+    public static EditLink: DocumentView | undefined;
+    public static EditLinkLoc: number[] = [0, 0];
+
+    @computed
+    get linkButton() {
+        const links = DocListCast(this.props.View.props.Document.links);
+        return (!links.length || links[0].hidden) && !this.props.AlwaysOn ? (null) :
+            <div title="Drag(create link) Tap(view links)" ref={this._linkButton} style={{ position: "absolute", left: this.props.Offset?.[0] }}>
+                <div className={"documentLinksButton"} style={{ backgroundColor: DocumentLinksButton.StartLink ? "transparent" : "" }}
+                    onPointerDown={this.onLinkButtonDown}
+                    onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
+                    onPointerEnter={action(e => LinkDocPreview.LinkInfo = {
+                        addDocTab: this.props.View.props.addDocTab,
+                        linkSrc: this.props.View.props.Document,
+                        linkDoc: links[0],
+                        Location: [e.clientX, e.clientY + 20]
+                    })} >
+                    {links.length ? links.length : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />}
+                </div>
+                {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"} onPointerDown={this.completeLink} /> : (null)}
+                {DocumentLinksButton.StartLink === this.props.View ? <div className={"documentLinksButton-startLink"} /> : (null)}
+            </div>;
+    }
+    render() {
+        return this.linkButton;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index d31ec8c1a..afd28534e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -42,6 +42,7 @@ import { LinkAnchorBox } from './LinkAnchorBox';
 import { RadialMenu } from './RadialMenu';
 import React = require("react");
 import { MobileInterface } from '../../../mobile/MobileInterface';
+import { DocumentLinksButton } from './DocumentLinksButton';
 
 library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
     fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
@@ -585,10 +586,14 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     toggleLinkButtonBehavior = (): void => {
         if (this.Document.isLinkButton || this.layoutDoc.onClick || this.Document.ignoreClick) {
             this.Document.isLinkButton = false;
+            const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
+            first && (first.hidden = false);
             this.Document.ignoreClick = false;
             this.layoutDoc.onClick = undefined;
         } else {
             this.Document.isLinkButton = true;
+            const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
+            first && (first.hidden = true);
             this.Document.followLinkZoom = false;
             this.Document.followLinkLocation = undefined;
         }
@@ -598,8 +603,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     toggleFollowInPlace = (): void => {
         if (this.Document.isLinkButton) {
             this.Document.isLinkButton = false;
+            const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
+            first && (first.hidden = false);
         } else {
             this.Document.isLinkButton = true;
+            const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
+            first && (first.hidden = true);
             this.Document.followLinkZoom = true;
             this.Document.followLinkLocation = "inPlace";
         }
@@ -609,6 +618,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     toggleFollowOnRight = (): void => {
         if (this.Document.isLinkButton) {
             this.Document.isLinkButton = false;
+            const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
+            first && (first.hidden = false);
         } else {
             this.Document.isLinkButton = true;
             this.Document.followLinkZoom = false;
@@ -737,10 +748,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
         const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null);
         templateDoc && optionItems.push({ description: "Open Template   ", event: () => this.props.addDocTab(templateDoc, "onRight"), icon: "eye" });
-        if (!options) {
-            options = { description: "Options...", subitems: optionItems, icon: "compass" };
-            cm?.addItem(options);
-        }
+        optionItems.push({ description: "Toggle Show Each Link Dot", event: () => this.layoutDoc.showLinks = !this.layoutDoc.showLinks, icon: "eye" });
+        !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" });
 
         const existingOnClick = cm?.findByDescription("OnClick...");
         const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
@@ -1039,7 +1048,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 select={this.select}
                 onClick={this.onClickHandler}
                 layoutKey={this.finalLayoutKey} />
-            {this.anchors}
+            {this.layoutDoc.showLinks ? this.anchors : (null)}
+            {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.props.dontRegisterView ? (null) : <DocumentLinksButton View={this} Offset={[-15, 0]} />}
         </div>
         );
     }
@@ -1063,7 +1073,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     anchorPanelHeight = () => this.props.PanelHeight() || 1;
     @computed get anchors() {
         TraceMobx();
-        return this.layoutDoc.presBox ? (null) : DocListCast(this.Document.links).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) =>
+        return this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.layoutDoc.presBox || this.props.dontRegisterView ? (null) : DocListCast(this.Document.links).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) =>
             <DocumentView {...this.props} key={i + 1}
                 Document={d}
                 ContainingCollectionView={this.props.ContainingCollectionView}
@@ -1071,6 +1081,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 PanelWidth={this.anchorPanelWidth}
                 PanelHeight={this.anchorPanelHeight}
                 ContentScaling={returnOne}
+                dontRegisterView={false}
                 forcedBackgroundColor={returnTransparent}
                 removeDocument={this.hideLinkAnchor}
                 pointerEvents={false}
@@ -1194,7 +1205,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 color: StrCast(this.layoutDoc.color, "inherit"),
                 outline: highlighting && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px",
                 border: highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined,
-                boxShadow: this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined,
+                boxShadow: this.Document.isLinkButton && !this.props.dontRegisterView && this.props.forcedBackgroundColor?.(this.Document) !== "transparent" ?
+                    StrCast(this.props.Document._linkButtonShadow, "lightblue 0em 0em 1em") :
+                    this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" :
+                        undefined,
                 background: finalColor,
                 opacity: finalOpacity,
                 fontFamily: StrCast(this.Document._fontFamily, "inherit"),
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index 2b64cdab6..2bcc6168b 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -18,6 +18,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { SelectionManager } from "../../util/SelectionManager";
 import { TraceMobx } from "../../../fields/util";
 import { Id } from "../../../fields/FieldSymbols";
+import { LinkDocPreview } from "./LinkDocPreview";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -132,6 +133,13 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps, LinkAnch
         );
         const small = this.props.PanelWidth() <= 1;
         return <div className={`linkAnchorBox-cont${small ? "-small" : ""} ${this.rootDoc[Id]}`}
+            onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
+            onPointerEnter={action(e => LinkDocPreview.LinkInfo = {
+                addDocTab: this.props.addDocTab,
+                linkSrc: this.props.ContainingCollectionDoc!,
+                linkDoc: this.rootDoc,
+                Location: [e.clientX, e.clientY + 20]
+            })}
             onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle} onContextMenu={this.specificContextMenu}
             ref={this._ref} style={{
                 background: c,
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
new file mode 100644
index 000000000..126dc240a
--- /dev/null
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -0,0 +1,107 @@
+import { action, computed, observable, runInAction } from 'mobx';
+import { observer } from "mobx-react";
+import wiki from "wikijs";
+import { Doc, DocCastAsync, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { Cast, FieldValue, NumCast } from "../../../fields/Types";
+import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnZero } from "../../../Utils";
+import { Docs } from "../../documents/Documents";
+import { DocumentManager } from "../../util/DocumentManager";
+import { Transform } from "../../util/Transform";
+import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
+import React = require("react");
+import { DocumentView } from './DocumentView';
+
+interface Props {
+    linkDoc?: Doc;
+    linkSrc?: Doc;
+    href?: string;
+    backgroundColor: (doc: Doc) => string;
+    addDocTab: (document: Doc, where: string) => boolean;
+    location: number[];
+}
+@observer
+export class LinkDocPreview extends React.Component<Props> {
+    @observable public static LinkInfo: Opt<{ linkDoc?: Doc; addDocTab: (document: Doc, where: string) => boolean, linkSrc: Doc; href?: string; Location: number[] }>;
+    @observable _targetDoc: Opt<Doc>;
+    @observable _toolTipText = "";
+
+    componentDidUpdate() { this.updatePreview() }
+    componentDidMount() { this.updatePreview() }
+    async updatePreview() {
+        const linkDoc = this.props.linkDoc;
+        const linkSrc = this.props.linkSrc;
+        if (this.props.href) {
+            if (this.props.href.startsWith("https://en.wikipedia.org/wiki/")) {
+                wiki().page(this.props.href.replace("https://en.wikipedia.org/wiki/", "")).then(page => page.summary().then(action(summary => this._toolTipText = summary.substring(0, 500))));
+            } else {
+                runInAction(() => this._toolTipText = "external => " + this.props.href);
+            }
+        } else if (linkDoc && linkSrc) {
+            const anchor = FieldValue(Doc.AreProtosEqual(FieldValue(Cast(linkDoc.anchor1, Doc)), linkSrc) ? Cast(linkDoc.anchor2, Doc) : (Cast(linkDoc.anchor1, Doc)) || linkDoc);
+            const target = anchor?.annotationOn ? await DocCastAsync(anchor.annotationOn) : anchor;
+            runInAction(() => {
+                this._toolTipText = "";
+                this._targetDoc = target;
+                if (anchor !== this._targetDoc && anchor && this._targetDoc) {
+                    this._targetDoc._scrollY = NumCast(anchor?.y);
+                }
+            });
+        }
+    }
+    pointerDown = (e: React.PointerEvent) => {
+        if (this.props.linkDoc && this.props.linkSrc) {
+            DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.linkSrc,
+                (doc: Doc, followLinkLocation: string) => this.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+        } else if (this.props.href) {
+            this.props.addDocTab(Docs.Create.WebDocument(this.props.href, { title: this.props.href, _width: 200, _height: 400, UseCors: true }), "onRight");
+        }
+    }
+    width = () => Math.min(350, NumCast(this._targetDoc?.[WidthSym](), 350));
+    height = () => Math.min(350, NumCast(this._targetDoc?.[HeightSym](), 350));
+    @computed get targetDocView() {
+        return !this._targetDoc ?
+            <div style={{ pointerEvents: "all", maxWidth: 350, maxHeight: 250, width: "100%", height: "100%", overflow: "hidden" }}>
+                <div style={{ width: "100%", height: "100%", textOverflow: "ellipsis", }} onPointerDown={this.pointerDown}>
+                    {this._toolTipText}
+                </div>
+            </div> :
+            <ContentFittingDocumentView
+                Document={this._targetDoc}
+                LibraryPath={emptyPath}
+                fitToBox={true}
+                backgroundColor={this.props.backgroundColor}
+                moveDocument={returnFalse}
+                rootSelected={returnFalse}
+                ScreenToLocalTransform={Transform.Identity}
+                parentActive={returnFalse}
+                addDocument={returnFalse}
+                removeDocument={returnFalse}
+                addDocTab={returnFalse}
+                pinToPres={returnFalse}
+                dontRegisterView={true}
+                docFilters={returnEmptyFilter}
+                ContainingCollectionDoc={undefined}
+                ContainingCollectionView={undefined}
+                renderDepth={0}
+                PanelWidth={this.width}
+                PanelHeight={this.height}
+                focus={emptyFunction}
+                whenActiveChanged={returnFalse}
+                bringToFront={returnFalse}
+                ContentScaling={returnOne}
+                NativeWidth={returnZero}
+                NativeHeight={returnZero}
+            />;
+    }
+
+    render() {
+        return <div className="linkDocPreview"
+            style={{
+                position: "absolute", left: this.props.location[0],
+                top: this.props.location[1], width: this.width(), height: this.height(),
+                boxShadow: "black 2px 2px 1em"
+            }}>
+            {this.targetDocView}
+        </div>;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 5e32b3ef8..839943aac 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -11,7 +11,7 @@ import { EditorState, NodeSelection, TextSelection } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { Doc } from "../../../../fields/Doc";
 import { DarkPastelSchemaPalette, PastelSchemaPalette } from '../../../../fields/SchemaHeaderField';
-import { Cast, StrCast } from "../../../../fields/Types";
+import { Cast, StrCast, BoolCast } from "../../../../fields/Types";
 import { unimplementedFunction, Utils } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 import { LinkManager } from "../../../util/LinkManager";
@@ -72,7 +72,7 @@ export default class RichTextMenu extends AntimodeMenu {
         super(props);
         RichTextMenu.Instance = this;
         this._canFade = false;
-        this.Pinned = true;
+        this.Pinned = BoolCast(Doc.UserDoc()["menuRichText-pinned"]);
 
         this.fontSizeOptions = [
             { mark: schema.marks.pFontSize.create({ fontSize: 7 }), title: "Set font size", label: "7pt", command: this.changeFontSize },
@@ -147,7 +147,6 @@ export default class RichTextMenu extends AntimodeMenu {
         this.updateFromDash(view, lastState, this.editorProps);
     }
 
-
     public MakeLinkToSelection = (linkDocId: string, title: string, location: string, targetDocId: string): string => {
         if (this.view) {
             const link = this.view.state.schema.marks.link.create({ href: Utils.prepend("/doc/" + linkDocId), title: title, location: location, linkId: linkDocId, targetId: targetDocId });
@@ -750,7 +749,7 @@ export default class RichTextMenu extends AntimodeMenu {
 
     @action
     toggleMenuPin = (e: React.MouseEvent) => {
-        this.Pinned = !this.Pinned;
+        Doc.UserDoc()["menuRichText-pinned"] = this.Pinned = !this.Pinned;
         if (!this.Pinned) {
             this.fadeOut(true);
         }
@@ -779,7 +778,7 @@ export default class RichTextMenu extends AntimodeMenu {
             this.createHighlighterButton(),
             this.createLinkButton(),
             this.createBrushButton(),
-            this.createButton("indent", "Summarize", undefined, this.insertSummarizer),
+            this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer),
             this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote),
         ]}</div>;
 
diff --git a/src/mobile/AudioUpload.scss b/src/mobile/AudioUpload.scss
index 9fe442e55..6e64d9e2e 100644
--- a/src/mobile/AudioUpload.scss
+++ b/src/mobile/AudioUpload.scss
@@ -5,8 +5,45 @@
     justify-content: center;
     flex-direction: column;
     align-items: center;
-    max-width: 400px;
-    min-width: 400px;
+    margin-top: 10px;
+    height: 400px;
+    width: 600px;
+}
+
+.upload_label {
+    position: relative;
+    font-weight: 700;
+    color: black;
+    background-color: rgba(0, 0, 0, 0);
+    border: solid 3px black;
+    margin: 10px;
+    font-size: 30;
+    height: 70px;
+    width: 60%;
+    display: inline-flex;
+    font-family: sans-serif;
+    text-transform: uppercase;
+    justify-content: center;
+    flex-direction: column;
+    border-radius: 10px;
+}
+
+.restart_label {
+    position: relative;
+    font-weight: 700;
+    color: black;
+    background-color: rgba(0, 0, 0, 0);
+    border: solid 3px black;
+    margin: 10px;
+    font-size: 30;
+    height: 70px;
+    width: 60%;
+    display: inline-flex;
+    font-family: sans-serif;
+    text-transform: uppercase;
+    justify-content: center;
+    flex-direction: column;
+    border-radius: 10px;
 }
 
 .audio-upload {
diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx
index 7ea11ee84..f859b0ba3 100644
--- a/src/mobile/AudioUpload.tsx
+++ b/src/mobile/AudioUpload.tsx
@@ -5,11 +5,11 @@ import "./ImageUpload.scss";
 import React = require('react');
 import { DocServer } from '../client/DocServer';
 import { observer } from 'mobx-react';
-import { observable, action } from 'mobx';
-import { Utils, emptyPath, returnFalse, emptyFunction, returnOne, returnZero, returnTrue } from '../Utils';
+import { observable, action, computed } from 'mobx';
+import { Utils, emptyPath, returnFalse, emptyFunction, returnOne, returnZero, returnTrue, returnEmptyFilter } from '../Utils';
 import { Networking } from '../client/Network';
 import { Doc, Opt } from '../fields/Doc';
-import { Cast } from '../fields/Types';
+import { Cast, FieldValue } from '../fields/Types';
 import { listSpec } from '../fields/Schema';
 import { List } from '../fields/List';
 import { Scripting } from '../client/util/Scripting';
@@ -38,185 +38,100 @@ export class AudioUpload extends React.Component {
     @observable status: string = "";
     @observable nm: string = "Choose files";
     @observable process: string = "";
+    @observable public _audioCol: Doc = FieldValue(Cast(Docs.Create.FreeformDocument([Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio", _width: 500, _height: 100 }), Doc) as Doc], { title: "mobile audio", _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc;
 
-    onClick = async () => {
-        try {
-            await Docs.Prototypes.initialize();
-            const imgPrev = document.getElementById("img_preview");
-            const slab1 = document.getElementById("slab1");
-            if (slab1) {
-                slab1.style.opacity = "1";
-            }
-            if (imgPrev) {
-                const files: FileList | null = inputRef.current!.files;
-                const slab2 = document.getElementById("slab2");
-                if (slab2) {
-                    slab2.style.opacity = "1";
-                }
-                if (files && files.length !== 0) {
-                    this.process = "Uploading Files";
-                    for (let index = 0; index < files.length; ++index) {
-                        const file = files[index];
-                        const res = await Networking.UploadFilesToServer(file);
-                        const slab3 = document.getElementById("slab3");
-                        if (slab3) {
-                            slab3.style.opacity = "1";
-                        }
-                        res.map(async ({ result }) => {
-                            const name = file.name;
-                            if (result instanceof Error) {
-                                return;
-                            }
-                            const path = Utils.prepend(result.accessPaths.agnostic.client);
-                            let doc = null;
-                            console.log("type: " + file.type);
-                            if (file.type === "video/mp4") {
-                                doc = Docs.Create.VideoDocument(path, { _nativeWidth: 200, _width: 200, title: name });
-                            } else if (file.type === "application/pdf") {
-                                doc = Docs.Create.PdfDocument(path, { _width: 200, title: name });
-                            } else {
-                                doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name });
-                            }
-                            const slab4 = document.getElementById("slab4");
-                            if (slab4) {
-                                slab4.style.opacity = "1";
-                            }
-                            const res = await rp.get(Utils.prepend("/getUserDocumentId"));
-                            if (!res) {
-                                throw new Error("No user id returned");
-                            }
-                            const field = await DocServer.GetRefField(res);
-                            let pending: Opt<Doc>;
-                            if (field instanceof Doc) {
-                                pending = await Cast(field.mobileUpload, Doc);
-                            }
-                            if (pending) {
-                                const data = await Cast(pending.data, listSpec(Doc));
-                                if (data) {
-                                    data.push(doc);
-                                } else {
-                                    pending.data = new List([doc]);
-                                }
-                                this.status = "finished";
-                                const slab5 = document.getElementById("slab5");
-                                if (slab5) {
-                                    slab5.style.opacity = "1";
-                                }
-                                this.process = "File " + (index + 1).toString() + " Uploaded";
-                                const slab6 = document.getElementById("slab6");
-                                if (slab6) {
-                                    slab6.style.opacity = "1";
-                                }
-                                const slab7 = document.getElementById("slab7");
-                                if (slab7) {
-                                    slab7.style.opacity = "1";
-                                }
-
-                            }
-                        });
-                    }
-                } else {
-                    this.process = "No file selected";
-                }
-                setTimeout(this.clearUpload, 3000);
-            }
-        } catch (error) {
-            this.error = JSON.stringify(error);
-        }
-    }
-
-    // Updates label after a files is selected (so user knows a file is uploaded)
-    inputLabel = async () => {
-        const files: FileList | null = inputRef.current!.files;
-        await files;
-        if (files && files.length === 1) {
-            console.log(files);
-            this.nm = files[0].name;
-        } else if (files && files.length > 1) {
-            console.log(files.length);
-            this.nm = files.length.toString() + " files selected";
-        }
-    }
 
     @action
     clearUpload = () => {
-        const slab1 = document.getElementById("slab1");
-        if (slab1) {
-            slab1.style.opacity = "0.4";
-        }
-        const slab2 = document.getElementById("slab2");
-        if (slab2) {
-            slab2.style.opacity = "0.4";
-        }
-        const slab3 = document.getElementById("slab3");
-        if (slab3) {
-            slab3.style.opacity = "0.4";
+        for (let i = 1; i < 8; i++) {
+            this.setOpacity(i, "0.2");
         }
-        const slab4 = document.getElementById("slab4");
-        if (slab4) {
-            slab4.style.opacity = "0.4";
-        }
-        const slab5 = document.getElementById("slab5");
-        if (slab5) {
-            slab5.style.opacity = "0.4";
-        }
-        const slab6 = document.getElementById("slab6");
-        if (slab6) {
-            slab6.style.opacity = "0.4";
-        }
-        const slab7 = document.getElementById("slab7");
-        if (slab7) {
-            slab7.style.
-                opacity = "0.4";
-        }
-        this.nm = "Choose files";
-
-        if (inputRef.current) {
-            inputRef.current.value = "";
-        }
-        this.process = "";
-        console.log(inputRef.current!.files);
+        this._audioCol = FieldValue(Cast(Docs.Create.FreeformDocument([Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio", _width: 500, _height: 100 }), Doc) as Doc], { title: "mobile audio", _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc;
     }
 
-
+    closeUpload = () => {
+        this.clearUpload();
+        MobileInterface.Instance.toggleAudio();
+    }
 
     private get uploadInterface() {
-        const audioDoc = Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio" }), Doc) as Doc;
-
         return (
-            <div className="imgupload_cont">
-                <div className="closeUpload" onClick={MobileInterface.Instance.toggleAudio}>
+            <>
+                <div className="closeUpload" onClick={() => this.closeUpload()}>
                     <FontAwesomeIcon icon="window-close" size={"lg"} />
                 </div>
-                <DocumentView
-                    Document={audioDoc}
-                    DataDoc={undefined}
-                    LibraryPath={emptyPath}
-                    addDocument={returnFalse}
-                    addDocTab={returnFalse}
-                    pinToPres={emptyFunction}
-                    rootSelected={returnFalse}
-                    removeDocument={undefined}
-                    onClick={undefined}
-                    ScreenToLocalTransform={Transform.Identity}
-                    ContentScaling={returnOne}
-                    PanelWidth={() => 1000}
-                    PanelHeight={() => 1000}
-                    NativeHeight={returnZero}
-                    NativeWidth={returnZero}
-                    renderDepth={0}
-                    focus={emptyFunction}
-                    backgroundColor={() => "white"}
-                    parentActive={returnTrue}
-                    whenActiveChanged={emptyFunction}
-                    bringToFront={emptyFunction}
-                    ContainingCollectionView={undefined}
-                    ContainingCollectionDoc={undefined}
-                />
-            </div>
+                <FontAwesomeIcon icon="microphone" size="lg" style={{ fontSize: "130" }} />
+                <div className="audioUpload_cont">
+                    <DocumentView
+                        Document={this._audioCol}
+                        DataDoc={undefined}
+                        LibraryPath={emptyPath}
+                        addDocument={returnFalse}
+                        addDocTab={returnFalse}
+                        pinToPres={emptyFunction}
+                        rootSelected={returnFalse}
+                        removeDocument={undefined}
+                        docFilters={returnEmptyFilter}
+                        onClick={undefined}
+                        ScreenToLocalTransform={Transform.Identity}
+                        ContentScaling={returnOne}
+                        PanelWidth={() => 600}
+                        PanelHeight={() => 400}
+                        NativeHeight={returnZero}
+                        NativeWidth={returnZero}
+                        renderDepth={0}
+                        focus={emptyFunction}
+                        backgroundColor={() => "rgba(0,0,0,0)"}
+                        parentActive={returnTrue}
+                        whenActiveChanged={emptyFunction}
+                        bringToFront={emptyFunction}
+                        ContainingCollectionView={undefined}
+                        ContainingCollectionDoc={undefined}
+                    />
+                </div>
+                <div className="restart_label" onClick={this.clearUpload}>
+                    Restart
+                </div>
+                <div className="upload_label" onClick={this.uploadAudio}>
+                    Upload
+                </div>
+                <div className="loadingImage">
+                    <div className="loadingSlab" id="slab01" />
+                    <div className="loadingSlab" id="slab02" />
+                    <div className="loadingSlab" id="slab03" />
+                    <div className="loadingSlab" id="slab04" />
+                    <div className="loadingSlab" id="slab05" />
+                    <div className="loadingSlab" id="slab06" />
+                    <div className="loadingSlab" id="slab07" />
+                </div>
+            </>
         );
     }
 
+    setOpacity = (i: number, o: string) => {
+        const slab = document.getElementById("slab0" + i);
+        if (slab) {
+            console.log(slab?.id);
+            slab.style.opacity = o;
+        }
+    }
+
+    // Pushing the audio doc onto Dash Web through the right side bar
+    uploadAudio = () => {
+        console.log("uploading");
+        const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
+        const audioDoc = this._audioCol;
+        const data = Cast(audioRightSidebar.data, listSpec(Doc));
+        for (let i = 1; i < 8; i++) {
+            setTimeout(() => this.setOpacity(i, "1"), i * 200);
+        }
+        if (data) {
+            data.push(audioDoc);
+        }
+
+        setTimeout(this.clearUpload, 3000);
+    }
+
     @observable private dialogueBoxOpacity = 1;
     @observable private overlayOpacity = 0.4;
 
diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss
index b64aac338..890258918 100644
--- a/src/mobile/ImageUpload.scss
+++ b/src/mobile/ImageUpload.scss
@@ -9,13 +9,19 @@
     min-width: 400px;
 
     .upload_label {
-        font-size: 3em;
         font-weight: 700;
-        color: white;
-        background-color: black;
-        display: inline-block;
-        margin: 10;
-        width: 100%;
+        color: black;
+        background-color: rgba(0, 0, 0, 0);
+        border: solid 3px black;
+        margin: 10px;
+        font-size: 30;
+        height: 70px;
+        width: 80%;
+        display: flex;
+        font-family: sans-serif;
+        text-transform: uppercase;
+        justify-content: center;
+        flex-direction: column;
         border-radius: 10px;
     }
 
@@ -26,10 +32,6 @@
         direction: ltr;
     }
 
-    .upload_label:hover {
-        background-color: darkred;
-    }
-
     .button_file {
         text-align: center;
         height: 50%;
@@ -49,20 +51,31 @@
     }
 
     .inputfile+label {
-        font-size: 3em;
         font-weight: 700;
-        color: white;
-        background-color: black;
-        display: inline-block;
+        color: black;
+        background-color: rgba(0, 0, 0, 0);
+        border: solid 3px black;
         margin: 10px;
+        font-size: 30;
+        height: 70px;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
         margin-top: 30px;
-        width: 100%;
+        width: 80%;
+        display: flex;
+        font-family: sans-serif;
+        text-transform: uppercase;
+        justify-content: center;
+        flex-direction: column;
         border-radius: 10px;
     }
 
-    .inputfile:focus+label,
-    .inputfile+label:hover {
-        background-color: darkred;
+    .inputfile.active+label {
+        font-style: italic;
+        color: black;
+        background-color: lightgreen;
+        border: solid 3px darkgreen;
     }
 
     .status {
@@ -71,16 +84,6 @@
 
 }
 
-.backgroundUpload {
-    height: 100vh;
-    top: 0;
-    z-index: 999;
-    width: 100vw;
-    position: absolute;
-    background-color: lightgrey;
-    opacity: 0.4;
-}
-
 .image-upload {
     top: 100%;
     opacity: 0;
@@ -129,7 +132,7 @@
     height: 30px;
     margin: 10;
     border-radius: 20px;
-    opacity: 0.3;
+    opacity: 0.2;
     background-color: black;
     transition: all 2s, opacity 1.5s;
 }
\ No newline at end of file
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index b712d52cc..6a5a2dd5b 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -43,21 +43,18 @@ export class Uploader extends React.Component<ImageUploadProps> {
             await Docs.Prototypes.initialize();
             const imgPrev = document.getElementById("img_preview");
             // Slab 1
-            const slab1 = document.getElementById("slab1");
-            if (slab1) slab1.style.opacity = "1";
+            this.setOpacity(1, "1");
             if (imgPrev) {
                 const files: FileList | null = inputRef.current!.files;
                 // Slab 2
-                const slab2 = document.getElementById("slab2");
-                if (slab2) slab2.style.opacity = "1";
+                this.setOpacity(2, "1");
                 if (files && files.length !== 0) {
                     this.process = "Uploading Files";
                     for (let index = 0; index < files.length; ++index) {
                         const file = files[index];
                         const res = await Networking.UploadFilesToServer(file);
                         // Slab 3
-                        const slab3 = document.getElementById("slab3");
-                        if (slab3) slab3.style.opacity = "1";
+                        this.setOpacity(3, "1");
                         res.map(async ({ result }) => {
                             const name = file.name;
                             if (result instanceof Error) {
@@ -74,8 +71,7 @@ export class Uploader extends React.Component<ImageUploadProps> {
                                 doc = Docs.Create.ImageDocument(path, { _nativeWidth: 400, _width: 400, title: name });
                             }
                             // Slab 4
-                            const slab4 = document.getElementById("slab4");
-                            if (slab4) slab4.style.opacity = "1";
+                            this.setOpacity(4, "1");
                             const res = await rp.get(Utils.prepend("/getUserDocumentId"));
                             if (!res) {
                                 throw new Error("No user id returned");
@@ -94,13 +90,15 @@ export class Uploader extends React.Component<ImageUploadProps> {
                                 if (data) data.push(doc);
                                 else pending.data = new List([doc]);
                                 this.status = "finished";
-                                const slab5 = document.getElementById("slab5");
-                                if (slab5) slab5.style.opacity = "1";
+                                this.setOpacity(5, "1"); // Slab 5
                                 this.process = "File " + (index + 1).toString() + " Uploaded";
-                                const slab6 = document.getElementById("slab6");
-                                if (slab6) slab6.style.opacity = "1";
-                                const slab7 = document.getElementById("slab7");
-                                if (slab7) slab7.style.opacity = "1";
+                                this.setOpacity(6, "1"); // Slab 6
+                                this.setOpacity(7, "1"); // Slab 7
+                            }
+                            console.log("i: " + index + 1);
+                            console.log("l: " + files.length);
+                            if ((index + 1) === files.length) {
+                                this.process = "Uploads Completed";
                             }
                         });
                     }
@@ -129,20 +127,9 @@ export class Uploader extends React.Component<ImageUploadProps> {
 
     @action
     clearUpload = () => {
-        const slab1 = document.getElementById("slab1");
-        if (slab1) slab1.style.opacity = "0.4";
-        const slab2 = document.getElementById("slab2");
-        if (slab2) slab2.style.opacity = "0.4";
-        const slab3 = document.getElementById("slab3");
-        if (slab3) slab3.style.opacity = "0.4";
-        const slab4 = document.getElementById("slab4");
-        if (slab4) slab4.style.opacity = "0.4";
-        const slab5 = document.getElementById("slab5");
-        if (slab5) slab5.style.opacity = "0.4";
-        const slab6 = document.getElementById("slab6");
-        if (slab6) slab6.style.opacity = "0.4";
-        const slab7 = document.getElementById("slab7");
-        if (slab7) slab7.style.opacity = "0.4";
+        for (let i = 1; i < 8; i++) {
+            this.setOpacity(i, "0.2");
+        }
         this.nm = "Choose files";
 
         if (inputRef.current) {
@@ -152,24 +139,33 @@ export class Uploader extends React.Component<ImageUploadProps> {
         console.log(inputRef.current!.files);
     }
 
+    closeUpload = () => {
+        this.clearUpload();
+        MobileInterface.Instance.toggleUpload();
+    }
+
+    setOpacity = (i: number, o: string) => {
+        const slab = document.getElementById("slab" + i);
+        if (slab) {
+            console.log(slab?.id);
+            slab.style.opacity = o;
+        }
+    }
 
 
     private get uploadInterface() {
         return (
             <div className="imgupload_cont">
-                <div className="closeUpload" onClick={MobileInterface.Instance.toggleUpload}>
+                <div className="closeUpload" onClick={() => this.closeUpload()}>
                     <FontAwesomeIcon icon="window-close" size={"lg"} />
                 </div>
-                <input type="file" accept="application/pdf, video/*,image/*" className="inputFile" id="input_image_file" ref={inputRef} onChange={this.inputLabel} multiple></input>
+                <FontAwesomeIcon icon="upload" size="lg" style={{ fontSize: "130" }} />
+                <input type="file" accept="application/pdf, video/*,image/*" className={`inputFile ${this.nm !== "Choose files" ? "active" : ""}`} id="input_image_file" ref={inputRef} onChange={this.inputLabel} multiple></input>
                 <label className="file" id="label" htmlFor="input_image_file">{this.nm}</label>
                 <div className="upload_label" onClick={this.onClick}>
-                    <FontAwesomeIcon icon="upload" size="sm" />
-                    &nbsp; &nbsp; Upload
+                    Upload
                 </div>
-                {/* <div onClick={this.onClick} className="upload_button">Upload</div> */}
                 <img id="img_preview" src=""></img>
-                {/* <p>{this.status}</p>
-                <p>{this.error}</p> */}
                 <div className="loadingImage">
                     <div className="loadingSlab" id="slab1" />
                     <div className="loadingSlab" id="slab2" />
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index a1719c015..5894326ab 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1,7 +1,7 @@
 import * as React from "react";
 import { library } from '@fortawesome/fontawesome-svg-core';
 import {
-    faTasks, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+    faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -43,8 +43,9 @@ import { AudioUpload } from "./AudioUpload";
 import { Cast, FieldValue } from '../fields/Types';
 import { CollectionView } from '../client/views/collections/CollectionView';
 import { InkingStroke } from '../client/views/InkingStroke';
+import RichTextMenu from "../client/views/nodes/formattedText/RichTextMenu";
 
-library.add(faTasks, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+library.add(faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -387,13 +388,13 @@ export class MobileInterface extends React.Component {
                 return (
                     <div
                         className="item"
-                        key={index}
-                        onClick={() => this.handleClick(doc)}>
-                        <div className="item-title"> {doc.title} </div>
-                        <div className="item-type">{doc.type}</div>
-                        <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
+                        key={index}>
+                        <div className="item-title" onClick={() => this.handleClick(doc)}> {doc.title} </div>
+                        <div className="item-type" onClick={() => this.handleClick(doc)}>{doc.type}</div>
+                        <FontAwesomeIcon onClick={() => this.handleClick(doc)} className="right" icon="angle-right" size="lg" style={{ display: `${doc.type === "collection" ? "block" : "none"}` }} />
                         <FontAwesomeIcon className="open" onClick={() => this.openFromSidebar(doc)} icon="external-link-alt" size="lg" />
-                    </div>);
+                    </div>
+                );
             }
         });
 
@@ -440,7 +441,7 @@ export class MobileInterface extends React.Component {
     }
 
     /**
-     * Handles the Create New Workspace button in the menu
+     * Handles the Create New Workspace button in the menu (taken from MainView.tsx)
      */
     @action
     createNewWorkspace = async (id?: string) => {
@@ -759,12 +760,7 @@ export class MobileInterface extends React.Component {
             toggle = this.toggleUpload;
         }
         return (
-            <div>
-                <div className="closeUpload" onClick={toggle}>
-                    <FontAwesomeIcon icon="window-close" size={"lg"} />
-                </div>
-                <Uploader Document={doc} />
-            </div>
+            <Uploader Document={doc} />
         );
     }
 
@@ -815,6 +811,7 @@ export class MobileInterface extends React.Component {
                 {this.switchMenuView()}
                 {this.inkMenu()}
                 <GestureOverlay>
+                    <div style={{ display: "none" }}><RichTextMenu key="rich" /></div>
                     <div className="docButtonContainer">
                         {this.pinToPresentation()}
                         {this.downloadDocument()}
@@ -843,6 +840,6 @@ Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.I
 Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); });
 Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.toggleAudio(); });
 Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); });
-Scripting.addGlobal(function openWorkspaces() { return MobileInterface.Instance.openWorkspaces(); });
+Scripting.addGlobal(function openMobileWorkspaces() { return MobileInterface.Instance.openWorkspaces(); });
 Scripting.addGlobal(function uploadImageMobile() { return MobileInterface.Instance.toggleUpload(); });
 Scripting.addGlobal(function switchToMobileUploads() { return MobileInterface.Instance.switchToMobileUploads(); });
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index 53bc48034..c499e6d1e 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -176,6 +176,7 @@ body {
 
 .open {
     right: 20px;
+    font-size: 35;
     position: absolute;
 }
 
-- 
cgit v1.2.3-70-g09d2


From 48e841282b896a0961d595281211b276b7a9d345 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Fri, 26 Jun 2020 22:06:33 +0800
Subject: audio dictation

---
 src/client/util/CurrentUserUtils.ts                |   2 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |   4 +
 src/mobile/AudioUpload.tsx                         |  10 +-
 src/mobile/MobileInterface.tsx                     | 116 +++++++--------------
 4 files changed, 48 insertions(+), 84 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 823a99436..e402718bf 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -474,7 +474,7 @@ export class CurrentUserUtils {
 
     static setupMobileButtons(doc?: Doc, buttons?: string[]) {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
-            { title: "WORKSPACES", icon: "bars", click: 'openMobileWorkspaces()', backgroundColor: "lightgrey", info: "Access your Workspaces from your mobile, and navigate through all of your documents. " },
+            { title: "WORKSPACES", icon: "bars", click: 'switchToMobileLibrary()', backgroundColor: "lightgrey", info: "Access your Workspaces from your mobile, and navigate through all of your documents. " },
             { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "lightgrey", info: "Upload files from your mobile device so they can be accessed on Dash Web." },
             { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploads()', backgroundColor: "lightgrey", info: "Access the collection of your mobile uploads." },
             { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "lightgrey", info: "Use your phone to record, dictate and then upload audio onto Dash Web." },
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 3eecc98a4..b5591ca02 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -505,6 +505,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
 
     recordDictation = () => {
+        console.log("recording dictation");
+        console.log(this._editorView);
         DictationManager.Controls.listen({
             interimHandler: this.setCurrentBulletContent,
             continuous: { indefinite: false },
@@ -523,6 +525,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
 
     recordBullet = async () => {
+        console.log("recording bullet");
         const completedCue = "end session";
         const results = await DictationManager.Controls.listen({
             interimHandler: this.setCurrentBulletContent,
@@ -539,6 +542,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     setCurrentBulletContent = (value: string) => {
         if (this._editorView) {
+            console.log("this._editorView");
             const state = this._editorView.state;
             const now = Date.now();
             let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(now / 1000) });
diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx
index f859b0ba3..83da41d90 100644
--- a/src/mobile/AudioUpload.tsx
+++ b/src/mobile/AudioUpload.tsx
@@ -19,6 +19,9 @@ import { nullAudio } from '../fields/URLField';
 import { Transform } from '../client/util/Transform';
 import { DocumentView } from '../client/views/nodes/DocumentView';
 import { MobileInterface } from './MobileInterface';
+import { DictationOverlay } from '../client/views/DictationOverlay';
+import RichTextMenu from '../client/views/nodes/formattedText/RichTextMenu';
+import { ContextMenu } from '../client/views/ContextMenu';
 
 export interface ImageUploadProps {
     Document: Doc;
@@ -57,6 +60,9 @@ export class AudioUpload extends React.Component {
     private get uploadInterface() {
         return (
             <>
+                <ContextMenu />
+                <DictationOverlay />
+                <div style={{ display: "none" }}><RichTextMenu key="rich" /></div>
                 <div className="closeUpload" onClick={() => this.closeUpload()}>
                     <FontAwesomeIcon icon="window-close" size={"lg"} />
                 </div>
@@ -66,10 +72,10 @@ export class AudioUpload extends React.Component {
                         Document={this._audioCol}
                         DataDoc={undefined}
                         LibraryPath={emptyPath}
-                        addDocument={returnFalse}
+                        addDocument={undefined}
                         addDocTab={returnFalse}
                         pinToPres={emptyFunction}
-                        rootSelected={returnFalse}
+                        rootSelected={returnTrue}
                         removeDocument={undefined}
                         docFilters={returnEmptyFilter}
                         onClick={undefined}
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index ed5076402..90672e19f 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -45,6 +45,8 @@ import { Cast, FieldValue } from '../fields/Types';
 import { CollectionView } from '../client/views/collections/CollectionView';
 import { InkingStroke } from '../client/views/InkingStroke';
 import RichTextMenu from "../client/views/nodes/formattedText/RichTextMenu";
+import { AudioBox } from "../client/views/nodes/AudioBox";
+import { FormattedTextBox } from "../client/views/nodes/formattedText/FormattedTextBox";
 
 library.add(faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
@@ -80,13 +82,22 @@ export class MobileInterface extends React.Component {
 
     @action
     componentDidMount = () => {
-        Doc.UserDoc().activeMobile = this._homeDoc;
+        // Doc.UserDoc().activeMobile = this._homeDoc;
         this._homeDoc._viewType === "stacking" ? this.menuListView = true : this.menuListView = false;
         Doc.SetSelectedTool(InkTool.None);
-        this.switchCurrentView((userDoc: Doc) => this._homeDoc);
+        Doc.UserDoc().activeMobile = this._homeDoc;
+        AudioBox.Enabled = true;
 
         document.removeEventListener("dblclick", this.onReactDoubleClick);
         document.addEventListener("dblclick", this.onReactDoubleClick);
+        document.addEventListener("dash", (e: any) => {  // event used by chrome plugin to tell Dash which document to focus on 
+            const id = FormattedTextBox.GetDocFromUrl(e.detail);
+            DocServer.GetRefField(id).then(doc => {
+                if (doc instanceof Doc) {
+                    DocumentManager.Instance.jumpToDocument(doc, false, undefined);
+                }
+            });
+        });
     }
 
     @action
@@ -101,10 +112,14 @@ export class MobileInterface extends React.Component {
 
     // Switch the mobile view to the given doc
     @action
-    switchCurrentView = (doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) => {
+    switchCurrentView = (doc: Doc, renderView?: () => JSX.Element, onSwitch?: () => void) => {
         if (!this.userDoc) return;
-
-        Doc.UserDoc().activeMobile = doc(this.userDoc);
+        if (this._activeDoc === this._homeDoc) {
+            this._parents.push(this._activeDoc);
+            this._homeMenu = false;
+        }
+        this._activeDoc = doc;
+        Doc.UserDoc().activeMobile = doc;
         onSwitch && onSwitch();
 
         this.renderView = renderView;
@@ -118,21 +133,10 @@ export class MobileInterface extends React.Component {
      * Method called when 'Library' button is pressed on the home screen
      */
     switchToLibrary = async () => {
-        this._parents.push(this._activeDoc);
-        this.switchCurrentView((userDoc: Doc) => this._library);
-        this._activeDoc = this._library;
+        this.switchCurrentView(this._library);
         this._homeMenu = false;
         this.toggleSidebar();
         //setTimeout(this.toggleSidebar, 300);
-
-    }
-
-    openWorkspaces = () => {
-        this._parents.push(this._activeDoc);
-        this.switchCurrentView((userDoc: Doc) => this._library);
-        this._activeDoc = this._library;
-        this._homeMenu = false;
-        this.sidebarActive = true;
     }
 
     /**
@@ -144,24 +148,20 @@ export class MobileInterface extends React.Component {
 
         if (doc === Cast(this._library, Doc) as Doc) {
             this._child = null;
-            this.userDoc.activeMobile = this._library;
+            this.switchCurrentView(this._library);
         } else if (doc === Cast(this._homeDoc, Doc) as Doc) {
             this._homeMenu = true;
             this._parents = [];
-            this._activeDoc = this._homeDoc;
             this._child = null;
-            this.switchCurrentView((userDoc: Doc) => this._homeDoc);
+            this.switchCurrentView(this._homeDoc);
         } else {
             if (doc) {
                 this._child = doc;
-                this.switchCurrentView((userDoc: Doc) => doc);
+                this.switchCurrentView(doc);
                 this._homeMenu = false;
                 header.textContent = String(doc.title);
             }
         }
-        if (doc) {
-            this._activeDoc = doc;
-        }
         this._ink = false;
     }
 
@@ -172,9 +172,8 @@ export class MobileInterface extends React.Component {
         if (!this._homeMenu || this.sidebarActive) {
             this._homeMenu = true;
             this._parents = [];
-            this._activeDoc = this._homeDoc;
             this._child = null;
-            this.switchCurrentView((userDoc: Doc) => this._homeDoc);
+            this.switchCurrentView(this._homeDoc);
         }
         if (this.sidebarActive) {
             this.toggleSidebar();
@@ -186,8 +185,7 @@ export class MobileInterface extends React.Component {
      */
     returnMain = () => {
         this._parents = [this._homeDoc];
-        this._activeDoc = this._library;
-        this.switchCurrentView((userDoc: Doc) => this._library);
+        this.switchCurrentView(this._library);
         this._homeMenu = false;
         this._child = null;
     }
@@ -244,21 +242,17 @@ export class MobileInterface extends React.Component {
      * Navigates to the given doc and updates the sidebar.
      * @param doc: doc for which the method is called
      */
-    @undoBatch
     handleClick = async (doc: Doc) => {
         const children = DocListCast(doc.data);
         if (doc.type !== "collection" && this.sidebarActive) {
             this._parents.push(this._activeDoc);
-            this._activeDoc = doc;
-            this.switchCurrentView((userDoc: Doc) => doc);
+            this.switchCurrentView(doc);
             this._homeMenu = false;
             this.toggleSidebar();
         }
-        else if (doc.type === "collection" && children.length === 0) this.openFromSidebar(doc);
         else {
             this._parents.push(this._activeDoc);
-            this._activeDoc = doc;
-            this.switchCurrentView((userDoc: Doc) => doc);
+            this.switchCurrentView(doc);
             this._homeMenu = false;
             this._child = doc;
         }
@@ -266,8 +260,7 @@ export class MobileInterface extends React.Component {
 
     openFromSidebar = (doc: Doc) => {
         this._parents.push(this._activeDoc);
-        this._activeDoc = doc;
-        this.switchCurrentView((userDoc: Doc) => doc);
+        this.switchCurrentView(doc);
         this._homeMenu = false;
         this._child = doc; //?
         this.toggleSidebar();
@@ -354,16 +347,14 @@ export class MobileInterface extends React.Component {
     // Handles when user clicks on a document in the pathbar
     handlePathClick = (doc: Doc, index: number) => {
         if (doc === this._library) {
-            this._activeDoc = doc;
             this._child = null;
-            this.switchCurrentView((userDoc: Doc) => doc);
+            this.switchCurrentView(doc);
             this._parents.length = index;
         } else if (doc === this._homeDoc) {
             this.returnHome();
         } else {
-            this._activeDoc = doc;
             this._child = doc;
-            this.switchCurrentView((userDoc: Doc) => doc);
+            this.switchCurrentView(doc);
             this._parents.length = index;
         }
     }
@@ -610,31 +601,6 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    // Mobile audio doc
-    recordAudio = async () => {
-        // upload to server with known URL
-        if (this._activeDoc.title !== "mobile audio") {
-            this._parents.push(this._activeDoc);
-        }
-        const audioDoc = Cast(Docs.Create.AudioDocument(nullAudio, { _width: 200, _height: 100, title: "mobile audio" }), Doc) as Doc;
-        if (audioDoc) {
-            this._activeDoc = audioDoc;
-            this.switchCurrentView((userDoc: Doc) => audioDoc);
-            this._homeMenu = false;
-        }
-    }
-
-    // // Pushing the audio doc onto Dash Web through the right side bar
-    // uploadAudio = () => {
-    //     const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
-    //     const audioDoc = this._activeDoc;
-    //     const data = Cast(audioRightSidebar.data, listSpec(Doc));
-
-    //     if (data) {
-    //         data.push(audioDoc);
-    //     }
-    // }
-
     // Button for pinning images to presentation
     pinToPresentation = () => {
         // Only making button available if it is an image
@@ -719,15 +685,11 @@ export class MobileInterface extends React.Component {
 
     // For setting up the presentation document for the home menu
     setupDefaultPresentation = () => {
-        if (this._activeDoc.title !== "Presentation") {
-            this._parents.push(this._activeDoc);
-        }
 
         const presentation = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
 
         if (presentation) {
-            this._activeDoc = presentation;
-            this.switchCurrentView((userDoc: Doc) => presentation);
+            this.switchCurrentView(presentation);
             this._homeMenu = false;
         }
     }
@@ -801,13 +763,8 @@ export class MobileInterface extends React.Component {
     }
 
     switchToMobileUploads = () => {
-        if (this._activeDoc.title !== "Presentation") {
-            this._parents.push(this._activeDoc);
-        }
         const mobileUpload = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
-        console.log(mobileUpload.title);
-        this._activeDoc = mobileUpload;
-        this.switchCurrentView((userDoc: Doc) => mobileUpload);
+        this.switchCurrentView(mobileUpload);
         this._homeMenu = false;
     }
 
@@ -831,9 +788,7 @@ export class MobileInterface extends React.Component {
                         {this.undo()}
                         {this.drawInk()}
                         {this.redo()}
-                        {/* {this.upload()} */}
                         {this.uploadImageButton()}
-                        {/* {this.uploadAudioButton()} */}
                     </div>
                     {this.displayWorkspaces()}
                     {this.renderDefaultContent()}
@@ -846,14 +801,13 @@ export class MobileInterface extends React.Component {
 
 
 
-Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); },
+Scripting.addGlobal(function switchMobileView(doc: Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); },
     "changes the active document displayed on the mobile, (doc: any)");
 Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); },
     "opens the presentation on mobile");
 Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); });
 Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.toggleAudio(); });
 Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); });
-Scripting.addGlobal(function openMobileWorkspaces() { return MobileInterface.Instance.openWorkspaces(); });
 Scripting.addGlobal(function uploadImageMobile() { return MobileInterface.Instance.toggleUpload(); });
 Scripting.addGlobal(function switchToMobileUploads() { return MobileInterface.Instance.switchToMobileUploads(); });
-Scripting.addGlobal(function switchToLibrary() { return MobileInterface.Instance.switchToLibrary(); });
\ No newline at end of file
+Scripting.addGlobal(function switchToMobileLibrary() { return MobileInterface.Instance.switchToLibrary(); });
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From ecd3c3b0a713a594d4d0f4295bad017af1ba47ba Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Sat, 27 Jun 2020 21:46:17 -0700
Subject: some changes

---
 src/client/views/GestureOverlay.tsx | 2 +-
 src/mobile/MobileInterface.tsx      | 4 ++++
 src/mobile/MobileMenu.scss          | 2 +-
 3 files changed, 6 insertions(+), 2 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 98777a92c..e82609e7e 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -260,7 +260,7 @@ export default class GestureOverlay extends Touchable {
     handleHandDown = async (e: React.TouchEvent) => {
         this._holdTimer && clearTimeout(this._holdTimer);
 
-        // this chunk of code helps us keep track of which touch events are associated with a hand event
+        // this chunk of code helps us keep track of which touch events ar e associated with a hand event
         // so that if a hand is held down, but a second hand is interacting with dash, the second hand's events
         // won't interfere with the first hand's events.
         const fingers = new Array<React.Touch>();
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 0bc950a71..d0848aea2 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -12,6 +12,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import { trace } from 'mobx';
+import { TraceMobx } from "../fields/util";
 import * as rp from 'request-promise';
 import { Doc, DocListCast } from '../fields/Doc';
 import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
@@ -788,6 +789,7 @@ export class MobileInterface extends React.Component {
     }
 
     onDragOver = (e: React.DragEvent) => {
+        console.log("drag!");
         e.preventDefault();
         e.stopPropagation();
     }
@@ -816,6 +818,8 @@ export class MobileInterface extends React.Component {
     }
 
     render() {
+        // trace();
+        // TraceMobx();
         return (
             <div className="mobileInterface-container" onDragOver={this.onDragOver}>
                 <SettingsManager />
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index ec8946578..24d72dec6 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -248,7 +248,7 @@ body {
 .sidebar.active {
     position: absolute;
     right:0%;
-    opacity: 1;
+    opacity: 0.8;
     z-index: 101;
 }
 
-- 
cgit v1.2.3-70-g09d2


From 78cd082c5e0ba82a479433e60a3e76d1ba21bdca Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 29 Jun 2020 10:29:23 -0400
Subject: started to fix the way subviews are created in MobileInterface to
 avoid unnecessary re-renders

---
 src/mobile/MobileInterface.tsx | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index ed5076402..4c566a571 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -45,6 +45,7 @@ import { Cast, FieldValue } from '../fields/Types';
 import { CollectionView } from '../client/views/collections/CollectionView';
 import { InkingStroke } from '../client/views/InkingStroke';
 import RichTextMenu from "../client/views/nodes/formattedText/RichTextMenu";
+import { Compute } from "google-auth-library";
 
 library.add(faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
@@ -195,7 +196,7 @@ export class MobileInterface extends React.Component {
     /**
      * DocumentView for graphic display of all documents
      */
-    displayWorkspaces = () => {
+    @computed get displayWorkspaces() {
         if (this.mainContainer) {
             const backgroundColor = () => "white";
             return (
@@ -527,7 +528,7 @@ export class MobileInterface extends React.Component {
     }
 
 
-    undo = () => {
+    @computed get undo() {
         if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc.title !== "WORKSPACES") {
             return (<>
                 <div className="docButton"
@@ -544,7 +545,7 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    redo = () => {
+    @computed get redo() {
         if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc.title !== "WORKSPACES") {
             return (<>
                 <div className="docButton"
@@ -562,7 +563,7 @@ export class MobileInterface extends React.Component {
     }
 
     // Button for switching into ink mode
-    drawInk = () => {
+    @computed get drawInk() {
         if (this._activeDoc._viewType === "docking") {
             return (
                 <>
@@ -812,6 +813,7 @@ export class MobileInterface extends React.Component {
     }
 
     render() {
+        trace();
         return (
             <div className="mobileInterface-container" onDragOver={this.onDragOver}>
                 <SettingsManager />
@@ -828,14 +830,14 @@ export class MobileInterface extends React.Component {
                     <div className="docButtonContainer">
                         {this.pinToPresentation()}
                         {this.downloadDocument()}
-                        {this.undo()}
-                        {this.drawInk()}
-                        {this.redo()}
+                        {this.undo}
+                        {this.drawInk}
+                        {this.redo}
                         {/* {this.upload()} */}
                         {this.uploadImageButton()}
                         {/* {this.uploadAudioButton()} */}
                     </div>
-                    {this.displayWorkspaces()}
+                    {this.displayWorkspaces}
                     {this.renderDefaultContent()}
                 </GestureOverlay>
                 {this.displayRadialMenu()}
-- 
cgit v1.2.3-70-g09d2


From 991376428130bd80e1e80b5cca52477e45caf679 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Tue, 30 Jun 2020 02:34:08 +0800
Subject: css comment fixes + commenting

---
 src/client/util/CurrentUserUtils.ts                |  54 ++-
 src/client/util/SettingsManager.scss               |  10 -
 src/client/views/AntimodeMenu.scss                 |  16 -
 src/client/views/nodes/AudioBox.scss               |   8 +-
 src/client/views/nodes/PDFBox.scss                 | 188 +++-----
 src/client/views/nodes/PresBox.scss                |  47 +-
 .../views/presentationview/PresElementBox.scss     |  78 +---
 src/mobile/AudioUpload.tsx                         |  84 ++--
 src/mobile/ImageUpload.tsx                         |  61 +--
 src/mobile/MobileHome.scss                         | 101 -----
 src/mobile/MobileInterface.scss                    | 448 ++++++++++++++++++-
 src/mobile/MobileInterface.tsx                     | 116 +++--
 src/mobile/MobileMenu.scss                         | 475 ---------------------
 13 files changed, 665 insertions(+), 1021 deletions(-)
 delete mode 100644 src/mobile/MobileHome.scss

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index e402718bf..8e53c7a3c 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -55,9 +55,20 @@ export class CurrentUserUtils {
                 removeDropProperties: new List<string>(["dropAction"]), title: "query view", icon: "question-circle"
             });
         }
-
+        // Prototype for mobile button (not sure if 'Advanced Item Prototypes' is ideal location)
         if (doc["template-mobile-button"] === undefined) {
-            const queryTemplate = this.mobileButton({ title: "NEW MOBILE BUTTON", onClick: undefined, _backgroundColor: "lightgrey" }, [this.ficon({ ignoreClick: true, icon: "mobile", backgroundColor: "rgba(0,0,0,0)" }), this.mobileTextContainer({}, [this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])]);
+            const queryTemplate = this.mobileButton({
+                title: "NEW MOBILE BUTTON",
+                onClick: undefined,
+                _backgroundColor: "lightgrey"
+            },
+                [this.ficon({
+                    ignoreClick: true,
+                    icon: "mobile",
+                    backgroundColor: "rgba(0,0,0,0)"
+                }),
+                this.mobileTextContainer({},
+                    [this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])]);
             doc["template-mobile-button"] = CurrentUserUtils.ficon({
                 onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'),
                 dragFactory: new PrefetchProxy(queryTemplate) as any as Doc,
@@ -457,6 +468,7 @@ export class CurrentUserUtils {
         return doc.myItemCreators as Doc;
     }
 
+    // Sets up mobile menu if it is undefined creates a new one, otherwise returns existing menu
     static setupActiveMobileMenu(doc: Doc) {
         if (doc.activeMobileMenu === undefined) {
             console.log("undefined");
@@ -465,6 +477,7 @@ export class CurrentUserUtils {
         return doc.activeMobileMenu as Doc;
     }
 
+    // Sets up mobileMenu stacking document
     static setupMobileMenu() {
         const menu = new PrefetchProxy(Docs.Create.StackingDocument(this.setupMobileButtons(), {
             _width: 980, ignoreClick: true, lockedPosition: false, _chromeStatus: "disabled", title: "home", _yMargin: 100
@@ -472,15 +485,17 @@ export class CurrentUserUtils {
         return menu;
     }
 
+    // SEts up mobile buttons for inside mobile menu
     static setupMobileButtons(doc?: Doc, buttons?: string[]) {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
             { title: "WORKSPACES", icon: "bars", click: 'switchToMobileLibrary()', backgroundColor: "lightgrey", info: "Access your Workspaces from your mobile, and navigate through all of your documents. " },
-            { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "lightgrey", info: "Upload files from your mobile device so they can be accessed on Dash Web." },
-            { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploads()', backgroundColor: "lightgrey", info: "Access the collection of your mobile uploads." },
+            { title: "UPLOAD", icon: "upload", click: 'openMobileUploads()', backgroundColor: "lightgrey", info: "Upload files from your mobile device so they can be accessed on Dash Web." },
+            { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploadCollection()', backgroundColor: "lightgrey", info: "Access the collection of your mobile uploads." },
             { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "lightgrey", info: "Use your phone to record, dictate and then upload audio onto Dash Web." },
-            { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "lightgrey", info: "Use your phone as a remote for you presentation." },
+            { title: "PRESENTATION", icon: "desktop", click: 'switchToMobilePresentation()', backgroundColor: "lightgrey", info: "Use your phone as a remote for you presentation." },
             { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "lightgrey", info: "Change your password, log out, or manage your account security." }
         ];
+        // returns a list of mobile buttons
         return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data =>
             this.mobileButton({
                 title: data.title,
@@ -492,24 +507,27 @@ export class CurrentUserUtils {
         );
     }
 
+    // sets up the main document for the mobile button
     static mobileButton = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.MulticolumnDocument(docs, {
         ...opts,
         dropAction: undefined, removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 900, _nativeHeight: 250, _width: 900, _height: 250, _yMargin: 15,
         borderRounding: "5px", boxShadow: "0 0", _chromeStatus: "disabled"
     }) as any as Doc
 
+    // sets up the text container for the information contained within the mobile button
     static mobileTextContainer = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.MultirowDocument(docs, {
         ...opts,
         dropAction: undefined, removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 450, _nativeHeight: 250, _width: 450, _height: 250, _yMargin: 25,
         backgroundColor: "rgba(0,0,0,0)", borderRounding: "0", boxShadow: "0 0", _chromeStatus: "disabled", ignoreClick: true
     }) as any as Doc
 
-
+    // Sets up the title of the button
     static mobileButtonText = (opts: DocumentOptions, buttonTitle: string) => Docs.Create.TextDocument(buttonTitle, {
         ...opts,
         dropAction: undefined, title: buttonTitle, _fontSize: 37, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)"
     }) as any as Doc
 
+    // Sets up the description of the button
     static mobileButtonInfo = (opts: DocumentOptions, buttonInfo: string) => Docs.Create.TextDocument(buttonInfo, {
         ...opts,
         dropAction: undefined, title: "info", _fontSize: 25, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)", _dimMagnitude: 2,
@@ -553,23 +571,6 @@ export class CurrentUserUtils {
         return CurrentUserUtils.setupWorkspaces(userDoc);
     }
 
-    static setupMobileInkingDoc(userDoc: Doc) {
-        return Docs.Create.FreeformDocument([], { title: "Mobile Inking", backgroundColor: "white" });
-    }
-
-    static setupMobileUploadDoc(userDoc: Doc) {
-        // const addButton = Docs.Create.FontIconDocument({ onDragStart: ScriptField.MakeScript('addWebToMobileUpload()'), title: "Add Web Doc to Upload Collection", icon: "plus", backgroundColor: "black" })
-        const webDoc = Docs.Create.WebDocument("https://www.britannica.com/biography/Miles-Davis", {
-            title: "Upload Images From the Web", _chromeStatus: "enabled", lockedPosition: true
-        });
-        const uploadDoc = Docs.Create.StackingDocument([], {
-            title: "Mobile Upload Collection", backgroundColor: "white", lockedPosition: true
-        });
-        return Docs.Create.StackingDocument([webDoc, uploadDoc], {
-            _width: screen.width, lockedPosition: true, _chromeStatus: "disabled", title: "Upload", _autoHeight: true, _yMargin: 80, backgroundColor: "lightgray"
-        });
-    }
-
     // setup the Creator button which will display the creator panel.  This panel will include the drag creators and the color picker.
     // when clicked, this panel will be displayed in the target container (ie, sidebarContainer)
     static async setupToolsBtnPanel(doc: Doc, sidebarContainer: Doc) {
@@ -764,6 +765,7 @@ export class CurrentUserUtils {
         }
     }
 
+    // Right sidebar is where mobile uploads are contained
     static setupRightSidebar(doc: Doc) {
         if (doc.rightSidebarCollection === undefined) {
             doc.rightSidebarCollection = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "Mobile Uploads" }));
@@ -823,7 +825,7 @@ export class CurrentUserUtils {
         this.setupDefaultIconTemplates(doc);  // creates a set of icon templates triggered by the document deoration icon
         this.setupDocTemplates(doc); // sets up the template menu of templates
         this.setupRightSidebar(doc);  // sets up the right sidebar collection for mobile upload documents and sharing
-        this.setupActiveMobileMenu(doc);
+        this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
         this.setupOverlays(doc);  // documents in overlay layer
         this.setupDockedButtons(doc);  // the bottom bar of font icons
         this.setupDefaultPresentation(doc); // presentation that's initially triggered
@@ -862,9 +864,5 @@ export class CurrentUserUtils {
     }
 }
 
-Scripting.addGlobal(function setupMobileInkingDoc(userDoc: Doc) { return CurrentUserUtils.setupMobileInkingDoc(userDoc); },
-    "initializes the Mobile inking document", "(userDoc: Doc)");
-Scripting.addGlobal(function setupMobileUploadDoc(userDoc: Doc) { return CurrentUserUtils.setupMobileUploadDoc(userDoc); },
-    "initializes the Mobile upload document", "(userDoc: Doc)");
 Scripting.addGlobal(function createNewWorkspace() { return MainView.Instance.createNewWorkspace(); },
     "creates a new workspace when called");
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index 0116c5294..1c2a2ce05 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -137,31 +137,21 @@
 
 @media only screen and (max-device-width: 480px) {
     .settings-interface {
-        background-color: whitesmoke !important;
-        color: grey;
         width: 80vw;
         height: 400px;
     }
 
     .settings-interface .settings-body .settings-content input {
-        border-radius: 5px;
-        border: none;
         font-size: 30;
-        padding: 4px;
-        min-width: 100%;
-        margin: 2px 0;
     }
 
     .settings-interface button {
         width: 100%;
         font-size: 30px;
-        align-self: center;
         background: #b2cef8;
-        margin-top: 4px;
     }
 
     .settings-interface .settings-heading {
-        letter-spacing: .5em;
         font-size: 25;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss
index 17506b3dc..be21cec12 100644
--- a/src/client/views/AntimodeMenu.scss
+++ b/src/client/views/AntimodeMenu.scss
@@ -46,15 +46,8 @@
 
 @media only screen and (max-device-width: 480px) {
     .antimodeMenu-cont {
-        position: absolute;
-        z-index: 10000;
         height: 100px;
         width: 100vw;
-        background: #323232;
-        box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
-        border-radius: 0px 6px 6px 6px;
-        // overflow: hidden;    
-        display: flex;
 
         &.with-rows {
             flex-direction: column-reverse;
@@ -79,14 +72,5 @@
         .antimodeMenu-button:hover {
             background-color: #121212;
         }
-
-        .antimodeMenu-dragger {
-            height: 100%;
-            transition: width .2s;
-            background-image: url("https://logodix.com/logo/1020374.png");
-            background-size: 90% 100%;
-            background-repeat: no-repeat;
-            background-position: left center;
-        }
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index b5d113ca0..c959b79f5 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -186,18 +186,12 @@
 
     .audiobox-container .audiobox-record,
     .audiobox-container-interactive .audiobox-record {
-        pointer-events: all;
         font-size: 3em;
-        width: 100%;
-        height: 100%;
-        position: relative;
-        pointer-events: none;
     }
 
     .audiobox-container .audiobox-controls .audiobox-player .audiobox-playhead,
     .audiobox-container .audiobox-controls .audiobox-player .audiobox-dictation,
-    .audiobox-container-interactive .audiobox-controls .audiobox-player .audiobox-playhead,
-    .audiobox-container-interactive .audiobox-controls .audiobox-player .audiobox-dictation {
+    .audiobox-container-interactive .audiobox-controls .audiobox-player .audiobox-playhead {
         width: 70px;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 974ddecdf..fbbd49a2f 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -11,18 +11,19 @@
 
     .pdfBox-ui {
         position: absolute;
-         width: 100%;
-         height: 100%;
-         z-index: 1;
-         pointer-events: none;
+        width: 100%;
+        height: 100%;
+        z-index: 1;
+        pointer-events: none;
 
-         .pdfBox-pageNums {
+        .pdfBox-pageNums {
             display: flex;
             flex-direction: row;
             height: 25px;
             position: absolute;
             left: 5px;
             top: 5px;
+
             .pdfBox-overlayButton-fwd,
             .pdfBox-overlayButton-back {
                 background: #121721;
@@ -35,29 +36,29 @@
                 border-radius: 3px;
                 pointer-events: all;
             }
-         }
-
-         .pdfBox-overlayButton {
-             border-bottom-left-radius: 50%;
-             display: flex;
-             justify-content: space-evenly;
-             align-items: center;
-             height: 20px;
-             background: none;
-             padding: 0;
-             position: absolute;
-             pointer-events: all;
-
-             .pdfBox-overlayButton-arrow {
-                 width: 0;
-                 height: 0;
-                 border-top: 10px solid transparent;
-                 border-bottom: 10px solid transparent;
-                 border-right: 15px solid #121721;
-                 transition: all 0.5s;
-             }
-
-             .pdfBox-overlayButton-iconCont {
+        }
+
+        .pdfBox-overlayButton {
+            border-bottom-left-radius: 50%;
+            display: flex;
+            justify-content: space-evenly;
+            align-items: center;
+            height: 20px;
+            background: none;
+            padding: 0;
+            position: absolute;
+            pointer-events: all;
+
+            .pdfBox-overlayButton-arrow {
+                width: 0;
+                height: 0;
+                border-top: 10px solid transparent;
+                border-bottom: 10px solid transparent;
+                border-right: 15px solid #121721;
+                transition: all 0.5s;
+            }
+
+            .pdfBox-overlayButton-iconCont {
                 background: #121721;
                 height: 20px;
                 width: 25px;
@@ -222,120 +223,60 @@
     }
 }
 
+// CSS adjusted for mobile devices
 @media only screen and (max-device-width: 480px) {
 
     .pdfBox .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton,
     .pdfBox-interactive .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton {
-        border-bottom-left-radius: 50%;
-        display: flex;
-        justify-content: space-evenly;
-        align-items: center;
         height: 60px;
-        background: none;
-        padding: 0;
-    }
 
-    .pdfBox .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton .pdfBox-settingsButton-iconCont,
-    .pdfBox-interactive .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton .pdfBox-settingsButton-iconCont {
-        background: #121721;
-        height: 60px;
-        width: 75px;
-        font-size: 30px;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        margin-left: -2px;
-        border-radius: 3px;
+        .pdfBox-settingsButton-iconCont {
+            height: 60px;
+            width: 75px;
+            font-size: 30px;
+        }
+
+        .pdfBox-settingsButton-arrow {
+            height: 60;
+            border-top: 30px solid transparent;
+            border-bottom: 30px solid transparent;
+            border-right: 30px solid #121721;
+        }
     }
 
+
+
     .pdfBox .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsFlyout,
     .pdfBox-interactive .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsFlyout {
-        position: absolute;
-        background: #323232;
-        box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
-        right: 20px;
-        border-radius: 7px;
-        padding: 20px;
-        display: flex;
-        flex-direction: column;
         font-size: 30px;
-        transition: all 0.5s;
     }
 
-    .pdfBox .pdfBox-ui .pdfBox-settingsCont,
-    .pdfBox-interactive .pdfBox-ui .pdfBox-settingsCont {
-        position: absolute;
-        right: 0;
-        top: 3;
-        pointer-events: all;
-    }
 
-    .pdfBox .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton .pdfBox-settingsButton-arrow,
-    .pdfBox-interactive .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton .pdfBox-settingsButton-arrow {
-        width: 0;
-        height: 60;
-        border-top: 30px solid transparent;
-        border-bottom: 30px solid transparent;
-        border-right: 30px solid #121721;
-        transition: all 0.5s;
-    }
-
-    .pdfBox .pdfBox-ui .pdfBox-overlayButton .pdfBox-overlayButton-iconCont,
-    .pdfBox-interactive .pdfBox-ui .pdfBox-overlayButton .pdfBox-overlayButton-iconCont {
-        background: #121721;
-        height: 60px;
-        width: 75px;
-        display: flex;
-        font-size: 30;
-        position: relative;
-        align-items: center;
-        justify-content: center;
-        border-radius: 3px;
-        pointer-events: all;
-    }
-
-    .pdfBox .pdfBox-ui .pdfBox-overlayButton .pdfBox-overlayButton-arrow,
-    .pdfBox-interactive .pdfBox-ui .pdfBox-overlayButton .pdfBox-overlayButton-arrow {
-        width: 0;
-        height: 0;
-        border-top: 30px solid transparent;
-        border-bottom: 30px solid transparent;
-        border-right: 30px solid #121721;
-        transition: all 0.5s;
-    }
 
     .pdfBox .pdfBox-ui .pdfBox-overlayCont,
     .pdfBox-interactive .pdfBox-ui .pdfBox-overlayCont {
-        position: absolute;
-        width: calc(100% - 40px);
         height: 60px;
-        background: #121721;
-        bottom: 0;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        overflow: hidden;
-        transition: left .5s;
-        pointer-events: all;
+
+        .pdfBox-searchBar {
+            font-size: 40px;
+        }
     }
 
     .pdfBox .pdfBox-ui .pdfBox-overlayButton,
     .pdfBox-interactive .pdfBox-ui .pdfBox-overlayButton {
-        border-bottom-left-radius: 50%;
-        display: flex;
-        justify-content: space-evenly;
-        align-items: center;
         height: 60px;
-        background: none;
-        padding: 0;
-        position: absolute;
-        pointer-events: all;
-    }
 
-    .pdfBox .pdfBox-ui .pdfBox-overlayCont .pdfBox-searchBar,
-    .pdfBox-interactive .pdfBox-ui .pdfBox-overlayCont .pdfBox-searchBar {
-        width: 70%;
-        font-size: 40px;
+        .pdfBox-overlayButton-iconCont {
+            height: 60px;
+            width: 75px;
+            font-size: 30;
+        }
+
+        .pdfBox-overlayButton-arrow {
+            border-top: 30px solid transparent;
+            border-bottom: 30px solid transparent;
+            border-right: 30px solid #121721;
+        }
     }
 
     button.pdfBox-search {
@@ -348,17 +289,8 @@
     .pdfBox .pdfBox-ui .pdfBox-prevIcon,
     .pdfBox-interactive .pdfBox-ui .pdfBox-nextIcon,
     .pdfBox-interactive .pdfBox-ui .pdfBox-prevIcon {
-        background: #121721;
         height: 50px;
         width: 50px;
         font-size: 30px;
-        display: flex;
-        position: relative;
-        align-items: center;
-        justify-content: center;
-        border-radius: 3px;
-        pointer-events: all;
-        padding: 0px;
     }
-
-}
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 1261cbfdd..9f6af1bde 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -81,6 +81,7 @@
     }
 }
 
+// CSS adjusted for mobile devices
 @media only screen and (max-device-width: 480px) {
     .presBox-cont .presBox-buttons {
         position: absolute;
@@ -92,37 +93,33 @@
         z-index: 2;
         align-items: center;
         background: rgba(0, 0, 0, 0);
-        padding-top: 5px;
-        padding-bottom: 5px;
         display: inline-flex;
+
+        .presBox-button {
+            margin-top: 5%;
+            height: 250;
+            width: 300;
+            font-size: 100;
+            display: flex;
+            align-items: center;
+            background: #323232;
+            color: white;
+        }
+
+        .presBox-viewPicker {
+            top: -70;
+            left: 2.5%;
+            height: 50;
+            width: 95%;
+            font-size: 30px;
+            position: absolute;
+            min-width: 50px;
+        }
     }
 
     .presBox-cont .presBox-listCont {
-        position: absolute;
         top: 50;
         height: calc(100% - 80px);
-        width: 100%;
-    }
-
-    .presBox-cont .presBox-buttons .presBox-button {
-        margin-top: 5%;
-        height: 250;
-        width: 300;
-        font-size: 100;
-        display: flex;
-        align-items: center;
-        background: 323232;
-        color: white;
-    }
-
-    .presBox-cont .presBox-buttons .presBox-viewPicker {
-        top: -70;
-        left: 2.5%;
-        height: 50;
-        width: 95%;
-        font-size: 30px;
-        position: absolute;
-        min-width: 50px;
     }
 
     .input,
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index 79532995e..0632f6a8b 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -109,89 +109,43 @@
 @media only screen and (max-device-width: 480px) {
     .presElementBox-buttons {
         display: inline-flex;
-        position: relative;
-        width: 100%;
+        position: absolute;
+        top: 0;
+        right: 0;
+        z-index: 3;
+        width: 50%;
+
+        .presElementBox-interaction {
+            width: 50;
+            height: 50;
+        }
+
+        .presElementBox-interaction-selected {
+            width: 50;
+            height: 50;
+        }
     }
 
     .presElementBox-item {
         display: inline-flex;
+        height: max-content;
         overflow: hidden;
     }
 
-    .presElementBox-buttons .presElementBox-interaction {
-        color: gray;
-        float: left;
-        padding: 0px;
-        width: 50;
-        height: 50;
-    }
-
-    .presElementBox-buttons .presElementBox-interaction-selected {
-        color: white;
-        float: left;
-        padding: 0px;
-        width: 50;
-        height: 50;
-        border: solid 1px darkgray;
-    }
-
     .presElementBox-closeIcon {
-        border-radius: 20px;
         transform: scale(1.5);
-        position: absolute;
         right: 10;
         top: 10;
-        padding: 8px;
-    }
-
-    .presElementBox-buttons {
-        display: inline-flex;
-        position: absolute;
-        top: 0;
-        right: 0;
-        z-index: 3;
-        width: 50%;
     }
 
     .presElementBox-name {
         font-size: 30px;
-        position: absolute;
-        display: inline-block;
         top: 10px;
         z-index: 3;
         width: 50%;
-        text-overflow: ellipsis;
-        overflow: hidden;
-        white-space: pre;
-    }
-
-    .presElementBox-item {
-        display: inline-block;
-        background-color: #eeeeee;
-        pointer-events: all;
-        width: 100%;
-        min-height: 100%;
-        height: max-content;
-        outline-color: maroon;
-        outline-style: dashed;
-        border-radius: 6px;
-        -webkit-touch-callout: none;
-        -webkit-user-select: none;
-        -khtml-user-select: none;
-        -moz-user-select: none;
-        -ms-user-select: none;
-        user-select: none;
-        transition: all .1s;
-        padding: 0px;
-        padding-bottom: 3px;
     }
 
     .presElementBox-embedded {
-        position: relative;
-        display: flex;
         transform: translate(0, 90px) scale(1.5);
-        width: auto;
-        justify-content: center;
-        margin: auto;
     }
 }
\ No newline at end of file
diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx
index 83da41d90..590bf8f9d 100644
--- a/src/mobile/AudioUpload.tsx
+++ b/src/mobile/AudioUpload.tsx
@@ -1,18 +1,12 @@
-import * as ReactDOM from 'react-dom';
-import * as rp from 'request-promise';
 import { Docs } from '../client/documents/Documents';
 import "./ImageUpload.scss";
 import React = require('react');
-import { DocServer } from '../client/DocServer';
 import { observer } from 'mobx-react';
 import { observable, action, computed } from 'mobx';
 import { Utils, emptyPath, returnFalse, emptyFunction, returnOne, returnZero, returnTrue, returnEmptyFilter } from '../Utils';
-import { Networking } from '../client/Network';
 import { Doc, Opt } from '../fields/Doc';
 import { Cast, FieldValue } from '../fields/Types';
 import { listSpec } from '../fields/Schema';
-import { List } from '../fields/List';
-import { Scripting } from '../client/util/Scripting';
 import MainViewModal from '../client/views/MainViewModal';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { nullAudio } from '../fields/URLField';
@@ -23,40 +17,56 @@ import { DictationOverlay } from '../client/views/DictationOverlay';
 import RichTextMenu from '../client/views/nodes/formattedText/RichTextMenu';
 import { ContextMenu } from '../client/views/ContextMenu';
 
-export interface ImageUploadProps {
-    Document: Doc;
-}
-
-// const onPointerDown = (e: React.TouchEvent) => {
-//     let imgInput = document.getElementById("input_image_file");
-//     if (imgInput) {
-//         imgInput.click();
-//     }
-// }
-const inputRef = React.createRef<HTMLInputElement>();
-
 @observer
 export class AudioUpload extends React.Component {
-    @observable error: string = "";
-    @observable status: string = "";
-    @observable nm: string = "Choose files";
-    @observable process: string = "";
-    @observable public _audioCol: Doc = FieldValue(Cast(Docs.Create.FreeformDocument([Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio", _width: 500, _height: 100 }), Doc) as Doc], { title: "mobile audio", _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc;
-
+    @observable public _audioCol: Doc = FieldValue(Cast(Docs.Create.FreeformDocument([Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio", _width: 500, _height: 100 }), Doc) as Doc], { title: "mobile audio", _width: 300, _height: 300, _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc;
 
+    /**
+     * Handles the onclick functionality for the 'Restart' button
+     * Resets the document to its default view
+     */
     @action
     clearUpload = () => {
         for (let i = 1; i < 8; i++) {
             this.setOpacity(i, "0.2");
         }
-        this._audioCol = FieldValue(Cast(Docs.Create.FreeformDocument([Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio", _width: 500, _height: 100 }), Doc) as Doc], { title: "mobile audio", _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc;
+        this._audioCol = FieldValue(Cast(
+            Docs.Create.FreeformDocument(
+                [Cast(Docs.Create.AudioDocument(nullAudio, {
+                    title: "mobile audio",
+                    _width: 500,
+                    _height: 100
+                }), Doc) as Doc], { title: "mobile audio", _width: 300, _height: 300, _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc;
     }
 
+    /** 
+     * Handles the onClick of the 'Close' button
+     * Reset upload interface and toggle audio
+     */
     closeUpload = () => {
         this.clearUpload();
         MobileInterface.Instance.toggleAudio();
     }
 
+    /**
+     * Handles the on click of the 'Upload' button.
+     * Pushing the audio doc onto Dash Web through the right side bar
+     */
+    uploadAudio = () => {
+        const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
+        const audioDoc = this._audioCol;
+        const data = Cast(audioRightSidebar.data, listSpec(Doc));
+        for (let i = 1; i < 8; i++) {
+            setTimeout(() => this.setOpacity(i, "1"), i * 200);
+        }
+        if (data) {
+            data.push(audioDoc);
+        }
+        // Resets uploader after 3 seconds
+        setTimeout(this.clearUpload, 3000);
+    }
+
+    // Returns the upload audio menu
     private get uploadInterface() {
         return (
             <>
@@ -114,30 +124,14 @@ export class AudioUpload extends React.Component {
         );
     }
 
-    setOpacity = (i: number, o: string) => {
-        const slab = document.getElementById("slab0" + i);
+    // Handles the setting of the loading bar
+    setOpacity = (index: number, opacity: string) => {
+        const slab = document.getElementById("slab0" + index);
         if (slab) {
-            console.log(slab?.id);
-            slab.style.opacity = o;
+            slab.style.opacity = opacity;
         }
     }
 
-    // Pushing the audio doc onto Dash Web through the right side bar
-    uploadAudio = () => {
-        console.log("uploading");
-        const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
-        const audioDoc = this._audioCol;
-        const data = Cast(audioRightSidebar.data, listSpec(Doc));
-        for (let i = 1; i < 8; i++) {
-            setTimeout(() => this.setOpacity(i, "1"), i * 200);
-        }
-        if (data) {
-            data.push(audioDoc);
-        }
-
-        setTimeout(this.clearUpload, 3000);
-    }
-
     @observable private dialogueBoxOpacity = 1;
     @observable private overlayOpacity = 0.4;
 
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 6a5a2dd5b..5ea626d52 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -1,4 +1,3 @@
-import * as ReactDOM from 'react-dom';
 import * as rp from 'request-promise';
 import { Docs } from '../client/documents/Documents';
 import "./ImageUpload.scss";
@@ -12,49 +11,38 @@ import { Doc, Opt } from '../fields/Doc';
 import { Cast } from '../fields/Types';
 import { listSpec } from '../fields/Schema';
 import { List } from '../fields/List';
-import { Scripting } from '../client/util/Scripting';
 import MainViewModal from '../client/views/MainViewModal';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { MobileInterface } from './MobileInterface';
-import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
 
 export interface ImageUploadProps {
-    Document: Doc;
+    Document: Doc; // Target document for upload (upload location)
 }
 
-// const onPointerDown = (e: React.TouchEvent) => {
-//     let imgInput = document.getElementById("input_image_file");
-//     if (imgInput) {
-//         imgInput.click();
-//     }
-// }
 const inputRef = React.createRef<HTMLInputElement>();
 
 @observer
 export class Uploader extends React.Component<ImageUploadProps> {
     @observable error: string = "";
-    @observable status: string = "";
-    @observable nm: string = "Choose files";
-    @observable process: string = "";
+    @observable nm: string = "Choose files"; // Text of 'Choose Files' button
+    @observable process: string = ""; // Current status of upload
 
     onClick = async () => {
         try {
             const col = this.props.Document;
             await Docs.Prototypes.initialize();
             const imgPrev = document.getElementById("img_preview");
-            // Slab 1
-            this.setOpacity(1, "1");
+            this.setOpacity(1, "1"); // Slab 1
             if (imgPrev) {
                 const files: FileList | null = inputRef.current!.files;
-                // Slab 2
-                this.setOpacity(2, "1");
+                this.setOpacity(2, "1"); // Slab 2
                 if (files && files.length !== 0) {
                     this.process = "Uploading Files";
                     for (let index = 0; index < files.length; ++index) {
                         const file = files[index];
                         const res = await Networking.UploadFilesToServer(file);
-                        // Slab 3
-                        this.setOpacity(3, "1");
+                        this.setOpacity(3, "1"); // Slab 3
+                        // For each item that the user has selected
                         res.map(async ({ result }) => {
                             const name = file.name;
                             if (result instanceof Error) {
@@ -62,16 +50,17 @@ export class Uploader extends React.Component<ImageUploadProps> {
                             }
                             const path = Utils.prepend(result.accessPaths.agnostic.client);
                             let doc = null;
-                            console.log("type: " + file.type);
+                            // Case 1: File is a video
                             if (file.type === "video/mp4") {
                                 doc = Docs.Create.VideoDocument(path, { _nativeWidth: 400, _width: 400, title: name });
+                                // Case 2: File is a PDF document
                             } else if (file.type === "application/pdf") {
                                 doc = Docs.Create.PdfDocument(path, { _nativeWidth: 400, _width: 400, title: name });
+                                // Case 3: File is another document type (most likely Image)
                             } else {
                                 doc = Docs.Create.ImageDocument(path, { _nativeWidth: 400, _width: 400, title: name });
                             }
-                            // Slab 4
-                            this.setOpacity(4, "1");
+                            this.setOpacity(4, "1"); // Slab 4
                             const res = await rp.get(Utils.prepend("/getUserDocumentId"));
                             if (!res) {
                                 throw new Error("No user id returned");
@@ -79,32 +68,27 @@ export class Uploader extends React.Component<ImageUploadProps> {
                             const field = await DocServer.GetRefField(res);
                             let pending: Opt<Doc>;
                             if (field instanceof Doc) {
-                                // if (col === Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc) {
-                                //     pending = await Cast(field.rightSidebarCollection, Doc);
-                                // }
                                 pending = col;
-                                //pending = await Cast(field.col, Doc);
                             }
                             if (pending) {
                                 const data = await Cast(pending.data, listSpec(Doc));
                                 if (data) data.push(doc);
                                 else pending.data = new List([doc]);
-                                this.status = "finished";
                                 this.setOpacity(5, "1"); // Slab 5
                                 this.process = "File " + (index + 1).toString() + " Uploaded";
                                 this.setOpacity(6, "1"); // Slab 6
-                                this.setOpacity(7, "1"); // Slab 7
                             }
-                            console.log("i: " + index + 1);
-                            console.log("l: " + files.length);
                             if ((index + 1) === files.length) {
                                 this.process = "Uploads Completed";
+                                this.setOpacity(7, "1"); // Slab 7
                             }
                         });
                     }
+                    // Case in which the user pressed upload and no files were selected
                 } else {
                     this.process = "No file selected";
                 }
+                // Three seconds after upload the menu will reset
                 setTimeout(this.clearUpload, 3000);
             }
         } catch (error) {
@@ -117,14 +101,13 @@ export class Uploader extends React.Component<ImageUploadProps> {
         const files: FileList | null = inputRef.current!.files;
         await files;
         if (files && files.length === 1) {
-            console.log(files);
             this.nm = files[0].name;
         } else if (files && files.length > 1) {
-            console.log(files.length);
             this.nm = files.length.toString() + " files selected";
         }
     }
 
+    // Loops through load icons, and resets buttons
     @action
     clearUpload = () => {
         for (let i = 1; i < 8; i++) {
@@ -136,23 +119,21 @@ export class Uploader extends React.Component<ImageUploadProps> {
             inputRef.current.value = "";
         }
         this.process = "";
-        console.log(inputRef.current!.files);
     }
 
+    // Clears the upload and closes the upload menu
     closeUpload = () => {
         this.clearUpload();
         MobileInterface.Instance.toggleUpload();
     }
 
-    setOpacity = (i: number, o: string) => {
-        const slab = document.getElementById("slab" + i);
-        if (slab) {
-            console.log(slab?.id);
-            slab.style.opacity = o;
-        }
+    // Handles the setting of the loading bar
+    setOpacity = (index: number, opacity: string) => {
+        const slab = document.getElementById("slab" + index);
+        if (slab) slab.style.opacity = opacity;
     }
 
-
+    // Returns the upload interface for mobile
     private get uploadInterface() {
         return (
             <div className="imgupload_cont">
diff --git a/src/mobile/MobileHome.scss b/src/mobile/MobileHome.scss
deleted file mode 100644
index e1566b622..000000000
--- a/src/mobile/MobileHome.scss
+++ /dev/null
@@ -1,101 +0,0 @@
-$navbar-height: 120px;
-$pathbar-height: 50px;
-
-* {
-    margin: 0px;
-    padding: 0px;
-    box-sizing: border-box;
-    font-family: "Open Sans";
-}
-
-.homeContainer {
-    position: relative;
-    top: 200px;
-    overflow: scroll;
-    width: 100%;
-    left: 0;
-    height: calc(100% - 120px);
-    overflow-y: scroll;
-}
-
-.homeButton {
-    width: 96%;
-    margin-left: 2.5%;
-    height: 250px;
-    border-radius: 30px;
-    margin-top: 15px;
-    margin-bottom: 15px;
-}
-
-.iconRight {
-    position: absolute;
-    width: 50%;
-    height: 80px;
-    transform: translate(0, 50%);
-    right: 0px;
-    text-align: center;
-    font-size: 80;
-}
-
-.iconLeft {
-    position: absolute;
-    width: 50%;
-    height: 80px;
-    transform: translate(0%, 50%);
-    left: 0px;
-    text-align: center;
-    font-size: 80;
-}
-
-.textLeft {
-    position: absolute;
-    width: 50%;
-    left: 0px;
-    font-size: 40px;
-    text-align: left;
-    margin-left: 110px;
-    margin-top: 40px;
-    font-family: sans-serif;
-    font-weight: bold;
-}
-
-.textRight {
-    position: absolute;
-    width: 50%;
-    right: 0px;
-    font-size: 40px;
-    text-align: right;
-    margin-right: 110px;
-    margin-top: 40px;
-    font-family: sans-serif;
-    font-weight: bold;
-}
-
-.menuView {
-    position: absolute;
-    top: 135px;
-    left: 50%;
-    transform: translate(-50%, 0%);
-    display: flex;
-}
-
-.iconView {
-    height: 60px;
-    width: 60px;
-    background-color: darkgray;
-    border-radius: 5px;
-    border-style: solid;
-    border-width: 2px;
-    border-color: black;
-}
-
-.listView {
-    height: 60px;
-    width: 60px;
-    margin-left: 20;
-    background-color: darkgray;
-    border-radius: 5px;
-    border-style: solid;
-    border-width: 2px;
-    border-color: black;
-}
\ No newline at end of file
diff --git a/src/mobile/MobileInterface.scss b/src/mobile/MobileInterface.scss
index 86b043590..ee39d4f50 100644
--- a/src/mobile/MobileInterface.scss
+++ b/src/mobile/MobileInterface.scss
@@ -1,36 +1,444 @@
-.mobileInterface-inkInterfaceButtons {
-    position: absolute;
-    top: 0px;
-    display: flex;
-    justify-content: space-between;
-    width: 100%;
-    z-index: 9999;
-    height: 50px;
+$navbar-height: 120px;
+$pathbar-height: 50px;
 
-    .mobileInterface-button {
-        height: 100%;
+@media only screen and (max-device-width: 480px) {
+    * {
+        margin: 0px;
+        padding: 0px;
+        box-sizing: border-box;
+        font-family: sans-serif;
     }
 }
 
+body {
+    overflow: hidden;
+}
+
 .mobileInterface-container {
     height: 100%;
     position: relative;
     touch-action: none;
     width: 100%;
 
-    -webkit-touch-callout:none;
-    -webkit-user-select:none;
-    -khtml-user-select:none;
-    -moz-user-select:none;
-    -ms-user-select:none;
-    user-select:none;
-    -webkit-tap-highlight-color:rgba(0,0,0,0);
+    -webkit-touch-callout: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+// Topbar of Dash Mobile
+.navbar {
+    position: fixed;
+    top: 0px;
+    left: 0px;
+    width: 100vw;
+    height: $navbar-height;
+    background-color: whitesmoke;
+    z-index: 150;
+
+    .cover {
+        position: absolute;
+        right: 0px;
+        top: 0px;
+        height: 120px;
+        width: 120px;
+        background-color: whitesmoke;
+        z-index: 200;
+    }
+
+    .toggle-btn {
+        position: absolute;
+        right: 20px;
+        top: 30px;
+        height: 70px;
+        width: 70px;
+        transition: all 400ms ease-in-out 200ms;
+        z-index: 180;
+    }
+
+    .background {
+        position: absolute;
+        right: 0px;
+        top: 0px;
+        height: 120px;
+        width: 120px;
+        //border: 1px solid black;
+    }
+
+    .background.active {
+        background-color: lightgrey;
+    }
+
+    .toggle-btn-home {
+        right: -200px;
+    }
+
+    .header {
+        position: absolute;
+        top: 50%;
+        top: calc(9px + 50%);
+        right: 50%;
+        transform: translate(50%, -50%);
+        font-size: 40;
+        font-weight: 700;
+        text-align: center;
+        user-select: none;
+        text-transform: uppercase;
+        font-family: Arial, Helvetica, sans-serif;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        direction: ltr;
+        width: 600px;
+    }
+
+    .toggle-btn span {
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+        width: 70%;
+        height: 4px;
+        background: black;
+        transition: all 200ms ease;
+        z-index: 180;
+    }
+
+    .toggle-btn span:nth-child(1) {
+        transition: top 200ms ease-in-out;
+        top: 30%;
+    }
+
+    .toggle-btn span:nth-child(3) {
+        transition: top 200ms ease-in-out;
+        top: 70%;
+    }
+
+    .toggle-btn.active {
+        transition: transform 200ms ease-in-out 200ms;
+        transform: rotate(135deg);
+    }
+
+    .toggle-btn.active span:nth-child(1) {
+        top: 50%;
+    }
+
+    .toggle-btn.active span:nth-child(2) {
+        transform: translate(-50%, -50%) rotate(90deg);
+    }
+
+    .toggle-btn.active span:nth-child(3) {
+        top: 50%;
+    }
+}
+
+.sidebar {
+    position: fixed;
+    top: 120px;
+    opacity: 0;
+    right: -100%;
+    width: 80%;
+    height: calc(80% - (120px));
+    z-index: 101;
+    background-color: whitesmoke;
+    transition: all 400ms ease 50ms;
+    padding: 20px;
+    box-shadow: 0 0 5px 5px grey;
+
+    .item {
+        width: 100%;
+        padding: 13px 12px;
+        border-bottom: 1px solid rgba(200, 200, 200, 0.7);
+        font-family: Arial, Helvetica, sans-serif;
+        font-style: normal;
+        font-weight: normal;
+        user-select: none;
+        display: inline-flex;
+        font-size: 35px;
+        text-transform: uppercase;
+        color: black;
+    }
+
+    .ink:focus {
+        outline: 1px solid blue;
+    }
+
+    .sidebarButtons {
+        top: 80px;
+        position: relative;
+    }
+}
+
+
+
+
+
+
+.blanket {
+    position: fixed;
+    top: 120px;
+    opacity: 0.5;
+    right: -100%;
+    width: 100%;
+    height: calc(100% - (120px));
+    z-index: 101;
+    background-color: grey;
+    padding: 20px;
+}
+
+.blanket.active {
+    position: absolute;
+    right: 0%;
+    z-index: 100;
+}
+
+.home {
+    position: absolute;
+    top: 30px;
+    left: 30px;
+    font-size: 60;
+    user-select: none;
+    text-transform: uppercase;
+    font-family: Arial, Helvetica, sans-serif;
+    z-index: 200;
 }
 
-.mobileInterface-background {
+.item-type {
+    display: inline;
+    text-transform: lowercase;
+    margin-left: 20px;
+    font-size: 35px;
+    font-style: italic;
+    color: rgb(28, 28, 28);
+}
+
+.item-title {
+    max-width: 70%;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.right {
+    margin-left: 20px;
+    z-index: 200;
+}
+
+.open {
+    right: 20px;
+    font-size: 35;
+    position: absolute;
+}
+
+.left {
+    width: 100%;
     height: 100%;
+}
+
+
+
+.sidebar.active {
+    position: absolute;
+    right: 0%;
+    opacity: 1;
+    z-index: 101;
+}
+
+.back {
+    position: absolute;
+    left: 42px;
+    top: 0;
+    background: #1a1a1a;
+    width: 50px;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    text-align: center;
+    flex-direction: column;
+    align-items: center;
+    border-radius: 10px;
+    font-size: 25px;
+    user-select: none;
+    z-index: 100;
+}
+
+.pathbar {
+    position: fixed;
+    top: 118px;
+    left: 0px;
+    background: #1a1a1a;
+    z-index: 120;
+    border-radius: 0px;
     width: 100%;
+    height: 80px;
+    overflow: hidden;
+
+    .pathname {
+        position: relative;
+        font-size: 25;
+        top: 50%;
+        width: 86%;
+        left: 12%;
+        color: whitesmoke;
+        transform: translate(0%, -50%);
+        z-index: 20;
+        font-family: sans-serif;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        direction: rtl;
+        text-align: left;
+        text-transform: uppercase;
+    }
+
+    .scrollmenu {
+        overflow: auto;
+        width: 100%;
+        height: 100%;
+        white-space: nowrap;
+        display: inline-flex;
+    }
+
+    .hidePath {
+        position: absolute;
+        height: 100%;
+        width: 200px;
+        left: 0px;
+        top: 0px;
+        background-image: linear-gradient(to right, #1a1a1a, rgba(0, 0, 0, 0));
+        text-align: center;
+        user-select: none;
+        z-index: 99;
+        pointer-events: none;
+    }
+
+    .pathbarItem {
+        position: relative;
+        display: flex;
+        align-items: center;
+        color: whitesmoke;
+        text-align: center;
+        justify-content: center;
+        user-select: none;
+        transform: translate(100px, 0px);
+        font-size: 30px;
+        padding: 10px;
+        text-transform: uppercase;
+
+        .pathbarText {
+            font-family: sans-serif;
+            text-align: center;
+            height: 50px;
+            padding: 10px;
+            font-size: 30px;
+            border-radius: 10px;
+            text-transform: uppercase;
+            margin-left: 20px;
+            position: relative;
+        }
+
+        .pathIcon {
+            transform: translate(0px, 0px);
+            position: relative;
+        }
+    }
+}
+
+
+/**
+* docButton appears at the bottom of mobile document
+* Buttons include: pin to presentation, download, upload, reload
+*/
+.docButton {
     position: relative;
-    touch-action: none;
-    background-color: pink;
+    width: 100px;
+    display: flex;
+    height: 100px;
+    font-size: 70px;
+    text-align: center;
+    border: 3px solid black;
+    margin: 20px;
+    z-index: 100;
+    border-radius: 100%;
+    justify-content: center;
+    flex-direction: column;
+    align-items: center;
+}
+
+.docButtonContainer {
+    top: 80%;
+    position: absolute;
+    display: flex;
+    transform: translate(-50%, 0);
+    left: 50%;
+    z-index: 100;
 }
+
+.toolbar {
+    left: 50%;
+    transform: translate(-50%);
+    position: absolute;
+    height: max-content;
+    top: 0px;
+    border-radius: 20px;
+    background-color: lightgrey;
+    opacity: 0;
+    transition: all 400ms ease 50ms;
+}
+
+.toolbar.active {
+    display: inline-block;
+    width: 300px;
+    padding: 5px;
+    opacity: 1;
+    height: max-content;
+    top: -450px;
+}
+
+.colorSelector {
+    position: absolute;
+    top: 550px;
+    left: 300px;
+    transform: translate(-50%, 0);
+    z-index: 100;
+    display: inline-flex;
+    width: max-content;
+    height: max-content;
+    pointer-events: all;
+    font-size: 90px;
+}
+
+// Menu buttons for toggling between list and icon view
+.homeSwitch {
+    position: fixed;
+    top: 212;
+    right: 36px;
+    display: inline-flex;
+    width: max-content;
+    z-index: 99;
+    height: 70px;
+
+    .list {
+        width: 70px;
+        height: 70px;
+        margin: 5;
+        padding: 10;
+        align-items: center;
+        text-align: center;
+        font-size: 50;
+        border-style: solid;
+        border-width: 3;
+        border-color: black;
+        background: whitesmoke;
+        align-self: center;
+        border-radius: 10px;
+    }
+
+    .list.active {
+        color: darkred;
+        border-color: darkred;
+    }
+}
\ No newline at end of file
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 90672e19f..38705898b 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -11,42 +11,30 @@ import {
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
-import { trace } from 'mobx';
-import * as rp from 'request-promise';
 import { Doc, DocListCast } from '../fields/Doc';
 import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
 import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero, returnEmptyFilter } from '../Utils';
-import { DocServer } from '../client/DocServer';
 import { Docs, DocumentOptions } from '../client/documents/Documents';
 import { Scripting } from '../client/util/Scripting';
 import { DocumentView } from '../client/views/nodes/DocumentView';
 import { Transform } from '../client/util/Transform';
 import "./MobileInterface.scss";
-import "./MobileMenu.scss";
-import "./MobileHome.scss";
 import "./ImageUpload.scss";
 import "./AudioUpload.scss";
-import { DocumentManager } from '../client/util/DocumentManager';
 import SettingsManager from '../client/util/SettingsManager';
 import { Uploader } from "./ImageUpload";
 import { DockedFrameRenderer } from '../client/views/collections/CollectionDockingView';
 import { InkTool } from '../fields/InkField';
-import { listSpec } from '../fields/Schema';
-import { nullAudio } from '../fields/URLField';
 import GestureOverlay from "../client/views/GestureOverlay";
 import { ScriptField } from "../fields/ScriptField";
 import InkOptionsMenu from "../client/views/collections/collectionFreeForm/InkOptionsMenu";
 import { RadialMenu } from "../client/views/nodes/RadialMenu";
-import { UndoManager, undoBatch } from "../client/util/UndoManager";
-import { MainView } from "../client/views/MainView";
+import { UndoManager } from "../client/util/UndoManager";
 import { List } from "../fields/List";
 import { AudioUpload } from "./AudioUpload";
 import { Cast, FieldValue } from '../fields/Types';
-import { CollectionView } from '../client/views/collections/CollectionView';
-import { InkingStroke } from '../client/views/InkingStroke';
 import RichTextMenu from "../client/views/nodes/formattedText/RichTextMenu";
 import { AudioBox } from "../client/views/nodes/AudioBox";
-import { FormattedTextBox } from "../client/views/nodes/formattedText/FormattedTextBox";
 
 library.add(faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
@@ -82,22 +70,15 @@ export class MobileInterface extends React.Component {
 
     @action
     componentDidMount = () => {
-        // Doc.UserDoc().activeMobile = this._homeDoc;
+        // if the home menu is in list view -> adjust the menu toggle appropriately
         this._homeDoc._viewType === "stacking" ? this.menuListView = true : this.menuListView = false;
-        Doc.SetSelectedTool(InkTool.None);
-        Doc.UserDoc().activeMobile = this._homeDoc;
+        Doc.SetSelectedTool(InkTool.None); // ink should intially be set to none
+        Doc.UserDoc().activeMobile = this._homeDoc; // active mobile set to home
         AudioBox.Enabled = true;
 
+        // remove double click to avoid mobile zoom in
         document.removeEventListener("dblclick", this.onReactDoubleClick);
         document.addEventListener("dblclick", this.onReactDoubleClick);
-        document.addEventListener("dash", (e: any) => {  // event used by chrome plugin to tell Dash which document to focus on 
-            const id = FormattedTextBox.GetDocFromUrl(e.detail);
-            DocServer.GetRefField(id).then(doc => {
-                if (doc instanceof Doc) {
-                    DocumentManager.Instance.jumpToDocument(doc, false, undefined);
-                }
-            });
-        });
     }
 
     @action
@@ -123,6 +104,8 @@ export class MobileInterface extends React.Component {
         onSwitch && onSwitch();
 
         this.renderView = renderView;
+        // Ensures that switching to home is not registed
+        UndoManager.undoStack.length = 0;
     }
 
     // For toggling the hamburger menu
@@ -144,16 +127,18 @@ export class MobileInterface extends React.Component {
      */
     back = () => {
         const header = document.getElementById("header") as HTMLElement;
-        const doc = Cast(this._parents.pop(), Doc) as Doc;
-
+        const doc = Cast(this._parents.pop(), Doc) as Doc; // Parent document
+        // Case 1: Parent document is 'workspaces'
         if (doc === Cast(this._library, Doc) as Doc) {
             this._child = null;
             this.switchCurrentView(this._library);
+            // Case 2: Parent document is the 'home' menu (root node)
         } else if (doc === Cast(this._homeDoc, Doc) as Doc) {
             this._homeMenu = true;
             this._parents = [];
             this._child = null;
             this.switchCurrentView(this._homeDoc);
+            // Case 3: Parent document is any document
         } else {
             if (doc) {
                 this._child = doc;
@@ -162,11 +147,11 @@ export class MobileInterface extends React.Component {
                 header.textContent = String(doc.title);
             }
         }
-        this._ink = false;
+        this._ink = false; // turns ink off
     }
 
     /**
-     * Return 'Home", which implies returning to 'Home' buttons
+     * Return 'Home", which implies returning to 'Home' menu buttons
      */
     returnHome = () => {
         if (!this._homeMenu || this.sidebarActive) {
@@ -258,11 +243,16 @@ export class MobileInterface extends React.Component {
         }
     }
 
+    /**
+     * Called when an item in the library is clicked and should 
+     * be opened (open icon on RHS of all menu items)
+     * @param doc doc to be opened
+     */
     openFromSidebar = (doc: Doc) => {
         this._parents.push(this._activeDoc);
         this.switchCurrentView(doc);
         this._homeMenu = false;
-        this._child = doc; //?
+        this._child = doc;
         this.toggleSidebar();
     }
 
@@ -378,12 +368,12 @@ export class MobileInterface extends React.Component {
                 </div>
             );
         }
-
+        // stores workspace documents as 'workspaces' variable
         let workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
         if (this._child) {
             workspaces = this._child;
         }
-
+        // returns a list of navbar buttons as 'buttons'
         const buttons = DocListCast(workspaces.data).map((doc: Doc, index: any) => {
             if (doc.type !== "ink") {
                 return (
@@ -445,7 +435,7 @@ export class MobileInterface extends React.Component {
     }
 
     /**
-     * Handles the Create New Workspace button in the menu (taken from MainView.tsx)
+     * Handles the 'Create New Workspace' button in the menu (taken from MainView.tsx)
      */
     @action
     createNewWorkspace = async (id?: string) => {
@@ -467,7 +457,6 @@ export class MobileInterface extends React.Component {
         workspaceDoc.contextMenuLabels = new List<string>(["Toggle Theme Colors", "Toggle Comic Mode", "New Workspace Layout"]);
 
         Doc.AddDocToList(workspaces, "data", workspaceDoc);
-        // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
     }
 
     stop = (e: React.MouseEvent) => {
@@ -508,7 +497,6 @@ export class MobileInterface extends React.Component {
     inkMenu = () => {
         if (this._activeDoc._viewType === "docking") {
             if (this._ink) {
-                console.log("here");
                 return <div className="colorSelector">
                     <InkOptionsMenu />
                 </div>;
@@ -517,9 +505,9 @@ export class MobileInterface extends React.Component {
         }
     }
 
-
+    // uses UndoManager and handles the color change opacity change if CanUndo is true
     undo = () => {
-        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc.title !== "WORKSPACES") {
+        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
             return (<>
                 <div className="docButton"
                     style={{ backgroundColor: "black", color: "white", fontSize: "60", opacity: UndoManager.CanUndo() ? "1" : "0.4", }}
@@ -535,8 +523,9 @@ export class MobileInterface extends React.Component {
         }
     }
 
+    // uses UndoManager and handles the color change opacity change if CanRedo is true
     redo = () => {
-        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc.title !== "WORKSPACES") {
+        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
             return (<>
                 <div className="docButton"
                     style={{ backgroundColor: "black", color: "white", fontSize: "60", opacity: UndoManager.CanRedo() ? "1" : "0.4", }}
@@ -576,6 +565,7 @@ export class MobileInterface extends React.Component {
                     <div className="docButton"
                         id="uploadButton"
                         title={"uploadFile"}
+                        style={{ backgroundColor: "white", color: "black" }}
                         onClick={this.toggleUpload}>
                         <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
                         />
@@ -593,7 +583,6 @@ export class MobileInterface extends React.Component {
                 style={{ backgroundColor: "white", color: "black" }}
                 onClick={e => {
                     window.open(url);
-                    console.log(url);
                 }}>
                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="download"
                 />
@@ -647,18 +636,13 @@ export class MobileInterface extends React.Component {
             this._homeDoc._viewType = "masonry";
             this._homeDoc.columnWidth = 300;
             const menuButtons = DocListCast(this._homeDoc.data);
-            console.log('hello');
             menuButtons.map((doc: Doc, index: any) => {
-                console.log(index);
                 const buttonData = DocListCast(doc.data);
                 buttonData[1]._nativeWidth = 0.1;
                 buttonData[1]._width = 0.1;
                 buttonData[1]._dimMagnitude = 0;
                 buttonData[1]._opacity = 0;
-                console.log(buttonData);
-                console.log(doc._nativeWidth);
                 doc._nativeWidth = 400;
-                console.log(doc._nativeWidth);
             });
         }
     }
@@ -670,22 +654,18 @@ export class MobileInterface extends React.Component {
             this._homeDoc._viewType = "stacking";
             this.menuListView = true;
             const menuButtons = DocListCast(this._homeDoc.data);
-            console.log('hello');
             menuButtons.map((doc: Doc, index: any) => {
                 const buttonData = DocListCast(doc.data);
                 buttonData[1]._nativeWidth = 450;
                 buttonData[1]._dimMagnitude = 2;
                 buttonData[1]._opacity = 1;
-                console.log(doc._nativeWidth);
                 doc._nativeWidth = 900;
-                console.log(doc._nativeWidth);
             });
         }
     }
 
     // For setting up the presentation document for the home menu
     setupDefaultPresentation = () => {
-
         const presentation = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
 
         if (presentation) {
@@ -698,10 +678,11 @@ export class MobileInterface extends React.Component {
     @action
     toggleUpload = () => this.imageUploadActive = !this.imageUploadActive
 
-    // For toggling image upload pop up
+    // For toggling audio record and dictate pop up
     @action
     toggleAudio = () => this.audioUploadActive = !this.audioUploadActive
 
+    // Button for toggling the upload pop up in a collection
     @action
     toggleUploadInCollection = () => {
         const button = document.getElementById("imageButton") as HTMLElement;
@@ -719,12 +700,6 @@ export class MobileInterface extends React.Component {
 
     // Returns the image upload pop up
     uploadImage = () => {
-        if (this.imageUploadActive) {
-            console.log("active");
-        } else if (!this.imageUploadActive) {
-
-        }
-
         let doc;
         let toggle;
         if (this._homeMenu === false) {
@@ -739,6 +714,7 @@ export class MobileInterface extends React.Component {
         );
     }
 
+    // Radial menu can only be used if it is a colleciton and it is not a homeDoc
     displayRadialMenu = () => {
         if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) {
             return <RadialMenu />;
@@ -750,6 +726,7 @@ export class MobileInterface extends React.Component {
         e.stopPropagation();
     }
 
+    // Button that appears on the bottom of the screen to initiate image upload
     uploadImageButton = () => {
         if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc._viewType !== "docking" && this._activeDoc.title !== "WORKSPACES") {
             return <div className="docButton"
@@ -762,6 +739,11 @@ export class MobileInterface extends React.Component {
         }
     }
 
+    /**
+     * MENU BUTTON
+     * Switch view from mobile menu to access the mobile uploads
+     * Global function name: openMobileUploads()
+     */
     switchToMobileUploads = () => {
         const mobileUpload = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
         this.switchCurrentView(mobileUpload);
@@ -800,14 +782,20 @@ export class MobileInterface extends React.Component {
 }
 
 
-
+//Global functions for mobile menu
+Scripting.addGlobal(function switchToMobileLibrary() { return MobileInterface.Instance.switchToLibrary(); },
+    "opens the library to navigate through workspaces on Dash Mobile");
+Scripting.addGlobal(function openMobileUploads() { return MobileInterface.Instance.toggleUpload(); },
+    "opens the upload files menu for Dash Mobile");
+Scripting.addGlobal(function switchToMobileUploadCollection() { return MobileInterface.Instance.switchToMobileUploads(); },
+    "opens the mobile uploads collection on Dash Mobile");
+Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.toggleAudio(); },
+    "opens the record and dictate menu on Dash Mobile");
+Scripting.addGlobal(function switchToMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); },
+    "opens the presentation on Dash Mobile");
+Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); },
+    "opens settings on Dash Mobile");
+
+// Other global functions for mobile
 Scripting.addGlobal(function switchMobileView(doc: Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); },
-    "changes the active document displayed on the mobile, (doc: any)");
-Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); },
-    "opens the presentation on mobile");
-Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); });
-Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.toggleAudio(); });
-Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); });
-Scripting.addGlobal(function uploadImageMobile() { return MobileInterface.Instance.toggleUpload(); });
-Scripting.addGlobal(function switchToMobileUploads() { return MobileInterface.Instance.switchToMobileUploads(); });
-Scripting.addGlobal(function switchToMobileLibrary() { return MobileInterface.Instance.switchToLibrary(); });
\ No newline at end of file
+    "changes the active document displayed on the Dash Mobile", "(doc: any)");
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
index b60aa308f..e69de29bb 100644
--- a/src/mobile/MobileMenu.scss
+++ b/src/mobile/MobileMenu.scss
@@ -1,475 +0,0 @@
-$navbar-height: 120px;
-$pathbar-height: 50px;
-
-* {
-    margin: 0px;
-    padding: 0px;
-    box-sizing: border-box;
-    font-family: "Open Sans";
-}
-
-body {
-    overflow: hidden;
-}
-
-.navbar {
-    position: fixed;
-    top: 0px;
-    left: 0px;
-    width: 100vw;
-    height: $navbar-height;
-    background-color: whitesmoke;
-    z-index: 150;
-}
-
-.navbar .cover {
-    position: absolute;
-    right: 0px;
-    top: 0px;
-    height: 120px;
-    width: 120px;
-    background-color: whitesmoke;
-    z-index: 200;
-}
-
-.navbar .toggle-btn {
-    position: absolute;
-    right: 20px;
-    top: 30px;
-    height: 70px;
-    width: 70px;
-    transition: all 400ms ease-in-out 200ms;
-    z-index: 180;
-}
-
-.navbar .background {
-    position: absolute;
-    right: 0px;
-    top: 0px;
-    height: 120px;
-    width: 120px;
-    //border: 1px solid black;
-}
-
-.navbar .background.active {
-    background-color: lightgrey;
-}
-
-.navbar .toggle-btn-home {
-    right: -200px;
-}
-
-.navbar .header {
-    position: absolute;
-    top: 50%;
-    top: calc(9px + 50%);
-    right: 50%;
-    transform: translate(50%, -50%);
-    font-size: 40;
-    font-weight: 700;
-    text-align: center;
-    user-select: none;
-    text-transform: uppercase;
-    font-family: Arial, Helvetica, sans-serif;
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    direction: ltr;
-    width: 600px;
-}
-
-.navbar .toggle-btn span {
-    position: absolute;
-    top: 50%;
-    left: 50%;
-    transform: translate(-50%, -50%);
-    width: 70%;
-    height: 4px;
-    background: black;
-    transition: all 200ms ease;
-    z-index: 180;
-}
-
-.navbar .toggle-btn span:nth-child(1) {
-    transition: top 200ms ease-in-out;
-    top: 30%;
-}
-
-.navbar .toggle-btn span:nth-child(3) {
-    transition: top 200ms ease-in-out;
-    top: 70%;
-}
-
-.navbar .toggle-btn.active {
-    transition: transform 200ms ease-in-out 200ms;
-    transform: rotate(135deg);
-}
-
-.navbar .toggle-btn.active span:nth-child(1) {
-    top: 50%;
-}
-
-.navbar .toggle-btn.active span:nth-child(2) {
-    transform: translate(-50%, -50%) rotate(90deg);
-}
-
-.navbar .toggle-btn.active span:nth-child(3) {
-    top: 50%;
-}
-
-.sidebar {
-    position: fixed;
-    top: 120px;
-    opacity: 0;
-    right: -100%;
-    width: 80%;
-    height: calc(80% - (120px));
-    z-index: 101;
-    background-color: whitesmoke;
-    transition: all 400ms ease 50ms;
-    padding: 20px;
-    // overflow-y: auto;
-    // -webkit-overflow-scrolling: touch;
-    // border-right: 5px solid black;
-    box-shadow: 0 0 5px 5px grey;
-}
-
-.sidebar .item {
-    width: 100%;
-    padding: 13px 12px;
-    border-bottom: 1px solid rgba(200, 200, 200, 0.7);
-    font-family: Arial, Helvetica, sans-serif;
-    font-style: normal;
-    font-weight: normal;
-    user-select: none;
-    display: inline-flex;
-    font-size: 35px;
-    text-transform: uppercase;
-    color: black;
-
-}
-
-.sidebar .ink:focus {
-    outline: 1px solid blue;
-}
-
-.sidebarButtons {
-    top: 80px;
-    position: relative;
-}
-
-.blanket {
-    position: fixed;
-    top: 120px;
-    opacity: 0.5;
-    right: -100%;
-    width: 100%;
-    height: calc(100% - (120px));
-    z-index: 101;
-    background-color: grey;
-    padding: 20px;
-}
-
-.blanket.active {
-    position: absolute;
-    right: 0%;
-    z-index: 100;
-}
-
-.home {
-    position: absolute;
-    top: 30px;
-    left: 30px;
-    font-size: 60;
-    user-select: none;
-    text-transform: uppercase;
-    font-family: Arial, Helvetica, sans-serif;
-    z-index: 200;
-}
-
-.item-type {
-    display: inline;
-    text-transform: lowercase;
-    margin-left: 20px;
-    font-size: 35px;
-    font-style: italic;
-    color: rgb(28, 28, 28);
-}
-
-.item-title {
-    max-width: 70%;
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.right {
-    margin-left: 20px;
-    z-index: 200;
-}
-
-.open {
-    right: 20px;
-    font-size: 35;
-    position: absolute;
-}
-
-.left {
-    width: 100%;
-    height: 100%;
-}
-
-.sidebar .logout {
-    width: 100%;
-    padding: 13px 12px;
-    border-bottom: 1px solid rgba(200, 200, 200, 0.7);
-    font-family: Arial, Helvetica, sans-serif;
-    font-style: normal;
-    font-weight: normal;
-    user-select: none;
-    font-size: 30px;
-    text-transform: uppercase;
-    color: black;
-}
-
-.sidebar .settings {
-    width: 100%;
-    padding: 13px 12px;
-    border-bottom: 1px solid rgba(200, 200, 200, 0.7);
-    font-family: Arial, Helvetica, sans-serif;
-    font-style: normal;
-    font-weight: normal;
-    user-select: none;
-    font-size: 30px;
-    text-transform: uppercase;
-    color: black;
-}
-
-
-.sidebar.active {
-    position: absolute;
-    right:0%;
-    opacity: 1;
-    z-index: 101;
-}
-
-.back {
-    position: absolute;
-    left: 42px;
-    top: 0;
-    background: #1a1a1a;
-    width: 50px;
-    height: 100%;
-    display: flex;
-    justify-content: center;
-    text-align: center;
-    flex-direction: column;
-    align-items: center;
-    border-radius: 10px;
-    font-size: 25px;
-    user-select: none;
-    z-index: 100;
-}
-
-.pathbar {
-    position: fixed;
-    top: 118px;
-    left: 0px;
-    background: #1a1a1a;
-    z-index: 120;
-    border-radius: 0px;
-    width: 100%;
-    height: 80px;
-    overflow: hidden;
-}
-
-.pathname {
-    position: relative;
-    font-size: 25;
-    top: 50%;
-    width: 86%;
-    left: 12%;
-    color: whitesmoke;
-    transform: translate(0%, -50%);
-    z-index: 20;
-    font-family: sans-serif;
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    direction: rtl;
-    text-align: left;
-    text-transform: uppercase;
-}
-
-.docButton {
-    position: relative;
-    width: 100px;
-    display: flex;
-    height: 100px;
-    font-size: 70px;
-    text-align: center;
-    border: 3px solid black;
-    margin: 20px;
-    z-index: 100;
-    border-radius: 100%;
-    justify-content: center;
-    flex-direction: column;
-    align-items: center;
-}
-
-.docButtonContainer {
-    top: 80%;
-    position: absolute;
-    display: flex;
-    transform: translate(-50%, 0);
-    left: 50%;
-    z-index: 100;
-}
-
-.scrollmenu {
-    overflow: auto;
-    width: 100%;
-    height: 100%;
-    white-space: nowrap;
-    display: inline-flex;
-}
-
-.pathbarItem {
-    position: relative;
-    display: flex;
-    align-items: center;
-    color: whitesmoke;
-    text-align: center;
-    justify-content: center;
-    user-select: none;
-    transform: translate(100px, 0px);
-    font-size: 30px;
-    padding: 10px;
-    text-transform: uppercase;
-}
-
-.pathbarText {
-    font-family: sans-serif;
-    text-align: center;
-    height: 50px;
-    padding: 10px;
-    font-size: 30px;
-    border-radius: 10px;
-    text-transform: uppercase;
-    margin-left: 20px;
-    position: relative;
-}
-
-
-.pathIcon {
-    transform: translate(0px, 0px);
-    position: relative;
-}
-
-.hidePath {
-    position: absolute;
-    height: 100%;
-    width: 200px;
-    left: 0px;
-    top: 0px;
-    background-image: linear-gradient(to right, #1a1a1a, rgba(0, 0, 0, 0));
-    text-align: center;
-    user-select: none;
-    z-index: 99;
-    pointer-events: none;
-}
-
-.toolbar {
-    left: 50%;
-    transform: translate(-50%);
-    position: absolute;
-    height: max-content;
-    top: 0px;
-    border-radius: 20px;
-    background-color: lightgrey;
-    opacity: 0;
-    transition: all 400ms ease 50ms;
-}
-
-.toolbar.active {
-    display: inline-block;
-    width: 300px;
-    padding: 5px;
-    opacity: 1;
-    height: max-content;
-    top: -450px;
-}
-
-.colorSelector {
-    position: absolute;
-    top: 550px;
-    left: 300px;
-    transform: translate(-50%, 0);
-    z-index: 100;
-    display: inline-flex;
-    width: max-content;
-    height: max-content;
-    pointer-events: all;
-    font-size: 90px;
-}
-
-.widthSelector {
-    display: inline-flex;
-    width: max-content;
-    height: 100px;
-    padding: 10px;
-}
-
-.slider {
-    -webkit-appearance: none;
-    /* Override default CSS styles */
-    appearance: none;
-    width: 100%;
-    /* Full-width */
-    height: 25px;
-    /* Specified height */
-    background: #d3d3d3;
-    /* Grey background */
-    outline: none;
-    /* Remove outline */
-}
-
-.colorButton {
-    width: 70px;
-    margin: 10px;
-    height: 70px;
-    border-style: solid;
-    border-width: 3px;
-    border-radius: 100%;
-}
-
-.homeSwitch {
-    position: fixed;
-    top: 212;
-    right: 36px;
-    display: inline-flex;
-    width: max-content;
-    z-index: 99;
-    height: 70px;
-}
-
-.list {
-    width: 70px;
-    height: 70px;
-    margin: 5;
-    padding: 10;
-    align-items: center;
-    text-align: center;
-    font-size: 50;
-    border-style: solid;
-    border-width: 3;
-    border-color: black;
-    background: whitesmoke;
-    align-self: center;
-    border-radius: 10px;
-}
-
-.list.active {
-    color: darkred;
-    border-color: darkred;
-}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 14c35574abc3c0f0b8fd86c5537b28828646f520 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Tue, 30 Jun 2020 03:04:17 +0800
Subject: oops

small bug fixes
---
 src/mobile/MobileInterface.tsx | 67 ++++++++++++------------------------------
 1 file changed, 18 insertions(+), 49 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index bac18d975..dc36b2c09 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -9,7 +9,7 @@ import {
     faThumbtack, faTree, faTv, faBook, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft, faBars, faTh, faChevronLeft
 } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable, reaction } from 'mobx';
+import { action, computed, observable, reaction, trace } from 'mobx';
 import { observer } from 'mobx-react';
 import { Doc, DocListCast } from '../fields/Doc';
 import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
@@ -464,20 +464,6 @@ export class MobileInterface extends React.Component {
         e.stopPropagation();
     }
 
-    // Button for uploading mobile audio
-    uploadAudioButton = () => {
-        if (this._activeDoc.type === "audio") {
-            return <div className="docButton"
-                title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
-                style={{ backgroundColor: "black", color: "white" }}
-            // onClick={this.uploadAudio}
-            >
-                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
-                />
-            </div>;
-        }
-    }
-
     // Button for switching between pen and ink mode
     @action
     onSwitchInking = () => {
@@ -506,8 +492,8 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    // uses UndoManager and handles the color change opacity change if CanUndo is true
-    @computed get undo = () => {
+    // DocButton that uses UndoManager and handles the opacity change if CanUndo is true
+    @computed get undo() {
         if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
             return (<>
                 <div className="docButton"
@@ -524,8 +510,8 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    // uses UndoManager and handles the color change opacity change if CanRedo is true
-    @computed get redo = () => {
+    // DocButton that uses UndoManager and handles the opacity change if CanRedo is true
+    @computed get redo() {
         if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
             return (<>
                 <div className="docButton"
@@ -542,7 +528,7 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    // Button for switching into ink mode
+    // DocButton for switching into ink mode
     @computed get drawInk() {
         if (this._activeDoc._viewType === "docking") {
             return (
@@ -558,24 +544,20 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    // Mobile doc button for uploading
-    upload = () => {
-        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) {
-            return (
-                <>
-                    <div className="docButton"
-                        id="uploadButton"
-                        title={"uploadFile"}
-                        style={{ backgroundColor: "white", color: "black" }}
-                        onClick={this.toggleUpload}>
-                        <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
-                        />
-                    </div>
-                </>);
+    // DocButton: Button that appears on the bottom of the screen to initiate image upload
+    uploadImageButton = () => {
+        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc._viewType !== "docking" && this._activeDoc.title !== "WORKSPACES") {
+            return <div className="docButton"
+                id="imageButton"
+                title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
+                onClick={this.toggleUpload}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
+                />
+            </div>;
         }
     }
 
-    // Button to download images on the mobile
+    // DocButton to download images on the mobile
     downloadDocument = () => {
         if (this._activeDoc.type === "image" || this._activeDoc.type === "pdf" || this._activeDoc.type === "video") {
             const url = this._activeDoc["data-path"]?.toString();
@@ -591,7 +573,7 @@ export class MobileInterface extends React.Component {
         }
     }
 
-    // Button for pinning images to presentation
+    // DocButton for pinning images to presentation
     pinToPresentation = () => {
         // Only making button available if it is an image
         if (!(this._activeDoc.type === "collection" || this._activeDoc.type === "presentation")) {
@@ -727,19 +709,6 @@ export class MobileInterface extends React.Component {
         e.stopPropagation();
     }
 
-    // Button that appears on the bottom of the screen to initiate image upload
-    uploadImageButton = () => {
-        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc._viewType !== "docking" && this._activeDoc.title !== "WORKSPACES") {
-            return <div className="docButton"
-                id="imageButton"
-                title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
-                onClick={this.toggleUpload}>
-                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
-                />
-            </div>;
-        }
-    }
-
     /**
      * MENU BUTTON
      * Switch view from mobile menu to access the mobile uploads
-- 
cgit v1.2.3-70-g09d2


From 992a65ec6f828dda0adcd3cd121896f07f64af87 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Mon, 29 Jun 2020 14:21:57 -0700
Subject: minor fixes

---
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +-
 src/client/views/nodes/DocumentView.tsx                             | 6 +++---
 src/mobile/MobileInterface.tsx                                      | 1 -
 3 files changed, 4 insertions(+), 5 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 42aa0f58e..a068e391e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1214,7 +1214,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         appearanceItems.push({ description: `${this.fitToContent ? "Unset" : "Set"} Fit To Container`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
         appearanceItems.push({ description: `${this.Document.useClusters ? "Uncluster" : "Use Clusters"}`, event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" });
         appearanceItems.push({ description: "Use Background Color as Default", event: () => Cast(Doc.UserDoc().emptyCollection, Doc, null)._backgroundColor = StrCast(this.layoutDoc._backgroundColor), icon: "palette" });
-        !appearance && ContextMenu.Instance.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" });
+        !appearance && ContextMenu.Instance?.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" });
 
         const options = ContextMenu.Instance?.findByDescription("Options...");
         const optionItems = options && "subitems" in options ? options.subitems : [];
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index afd28534e..0f46be345 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -749,7 +749,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null);
         templateDoc && optionItems.push({ description: "Open Template   ", event: () => this.props.addDocTab(templateDoc, "onRight"), icon: "eye" });
         optionItems.push({ description: "Toggle Show Each Link Dot", event: () => this.layoutDoc.showLinks = !this.layoutDoc.showLinks, icon: "eye" });
-        !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" });
+        !options && cm?.addItem({ description: "Options...", subitems: optionItems, icon: "compass" });
 
         const existingOnClick = cm?.findByDescription("OnClick...");
         const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
@@ -767,7 +767,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             funcs.push({ description: "Drag an Alias", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getAlias(this.dragFactory)')) });
             funcs.push({ description: "Drag a Copy", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) });
             funcs.push({ description: "Drag Document", icon: "edit", event: () => this.layoutDoc.onDragStart = undefined });
-            cm.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" });
+            cm?.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" });
         }
 
         const more = cm?.findByDescription("More...");
@@ -806,7 +806,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : [];
         helpItems.push({ description: "Text Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument("http://localhost:1050/assets/cheat-sheet.pdf", { _width: 300, _height: 300 }), "onRight"), icon: "keyboard" });
         helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" });
-        cm.addItem({ description: "Help...", subitems: helpItems, icon: "question" });
+        cm?.addItem({ description: "Help...", subitems: helpItems, icon: "question" });
 
         const existingAcls = cm?.findByDescription("Privacy...");
         const aclItems: ContextMenuProps[] = existingAcls && "subitems" in existingAcls ? existingAcls.subitems : [];
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index e39349ff2..8cec03897 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -518,7 +518,6 @@ export class MobileInterface extends React.Component {
     inkMenu = () => {
         if (this._activeDoc._viewType === "docking") {
             if (this._ink) {
-                console.log("here");
                 return <div className="colorSelector">
                     <InkOptionsMenu />
                 </div>;
-- 
cgit v1.2.3-70-g09d2


From 56da30314c4d434c4b7bb8be94f3bcb5923790d8 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Mon, 29 Jun 2020 18:05:46 -0700
Subject: minor changes

---
 .../collectionFreeForm/InkOptionsMenu.tsx          |  5 ++-
 src/mobile/MobileInterface.tsx                     | 37 +++++++++++++---------
 2 files changed, 26 insertions(+), 16 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
index e5b7023a1..218cef183 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
@@ -320,10 +320,13 @@ export default class InkOptionsMenu extends AntimodeMenu {
         ];
 
         const mobileButtons = [
-            ...this.shapeButtons,
+            this.shapePicker,
             this.bezierButton,
             this.widthPicker,
             this.colorPicker,
+            this.fillPicker,
+            this.arrowPicker,
+            this.dashButton,
         ];
 
         return (window.screen.width < 600 ? this.getElement(mobileButtons) : this.getElement(buttons));
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index a49bfb9b1..cb7319e03 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -56,6 +56,8 @@ export class MobileInterface extends React.Component {
     @observable private audioUploadActive: boolean = false;
     @observable private menuListView: boolean = false; //to switch between menu view (list / icon)
     @observable private _ink: boolean = false; //toggle whether ink is being dispalyed
+    @observable private inkButton: boolean = false;
+    @observable private undoButton: boolean = false;
 
     public _activeDoc: Doc = this.mainDoc; // doc updated as the active mobile page is updated (initially home menu)
     public _homeDoc: Doc = this.mainDoc; // home menu as a document
@@ -107,6 +109,10 @@ export class MobileInterface extends React.Component {
         this.renderView = renderView;
         // Ensures that switching to home is not registed
         UndoManager.undoStack.length = 0;
+
+        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
+            this.undoButton = true;
+        }
     }
 
     // For toggling the hamburger menu
@@ -445,7 +451,7 @@ export class MobileInterface extends React.Component {
         const freeformOptions: DocumentOptions = {
             x: 0,
             y: 400,
-            title: "Collection " + workspaceCount
+            title: "Collection " + workspaceCount,
         };
         const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
         const workspaceDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [Doc.UserDoc().myCatalog as Doc] }], { title: `Workspace ${workspaceCount}` }, id, "row");
@@ -493,19 +499,21 @@ export class MobileInterface extends React.Component {
 
     // DocButton that uses UndoManager and handles the opacity change if CanUndo is true
     @computed get undo() {
-        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
-            return (<>
-                <div className="docButton"
-                    style={{ backgroundColor: "black", color: "white", fontSize: "60", opacity: UndoManager.CanUndo() ? "1" : "0.4", }}
-                    id="undoButton"
-                    title="undo"
-                    onClick={(e: React.MouseEvent) => {
-                        UndoManager.Undo();
-                        e.stopPropagation();
-                    }}>
-                    <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="undo-alt" />
-                </div>
-            </>);
+        if (this.mainContainer) {
+            if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
+                return (<>
+                    <div className="docButton"
+                        style={{ backgroundColor: "black", color: "white", fontSize: "60", opacity: UndoManager.CanUndo() ? "1" : "0.4", }}
+                        id="undoButton"
+                        title="undo"
+                        onClick={(e: React.MouseEvent) => {
+                            UndoManager.Undo();
+                            e.stopPropagation();
+                        }}>
+                        <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="undo-alt" />
+                    </div>
+                </>);
+            }
         }
     }
 
@@ -704,7 +712,6 @@ export class MobileInterface extends React.Component {
     }
 
     onDragOver = (e: React.DragEvent) => {
-        console.log("drag!");
         e.preventDefault();
         e.stopPropagation();
     }
-- 
cgit v1.2.3-70-g09d2


From b9f4d13ffa8cd20ed89be16f471a1fab760ba2c0 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Mon, 29 Jun 2020 22:14:09 -0700
Subject: fix buttons

---
 src/mobile/MobileInterface.tsx | 60 ++++++++++++++++++++----------------------
 1 file changed, 29 insertions(+), 31 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index cb7319e03..7ff82ccc4 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -56,8 +56,6 @@ export class MobileInterface extends React.Component {
     @observable private audioUploadActive: boolean = false;
     @observable private menuListView: boolean = false; //to switch between menu view (list / icon)
     @observable private _ink: boolean = false; //toggle whether ink is being dispalyed
-    @observable private inkButton: boolean = false;
-    @observable private undoButton: boolean = false;
 
     public _activeDoc: Doc = this.mainDoc; // doc updated as the active mobile page is updated (initially home menu)
     public _homeDoc: Doc = this.mainDoc; // home menu as a document
@@ -109,10 +107,6 @@ export class MobileInterface extends React.Component {
         this.renderView = renderView;
         // Ensures that switching to home is not registed
         UndoManager.undoStack.length = 0;
-
-        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
-            this.undoButton = true;
-        }
     }
 
     // For toggling the hamburger menu
@@ -519,35 +513,39 @@ export class MobileInterface extends React.Component {
 
     // DocButton that uses UndoManager and handles the opacity change if CanRedo is true
     @computed get redo() {
-        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
-            return (<>
-                <div className="docButton"
-                    style={{ backgroundColor: "black", color: "white", fontSize: "60", opacity: UndoManager.CanRedo() ? "1" : "0.4", }}
-                    id="undoButton"
-                    title="redo"
-                    onClick={(e: React.MouseEvent) => {
-                        UndoManager.Redo();
-                        e.stopPropagation();
-                    }}>
-                    <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="redo-alt" />
-                </div>
-            </>);
+        if (this.mainContainer) {
+            if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
+                return (<>
+                    <div className="docButton"
+                        style={{ backgroundColor: "black", color: "white", fontSize: "60", opacity: UndoManager.CanRedo() ? "1" : "0.4", }}
+                        id="undoButton"
+                        title="redo"
+                        onClick={(e: React.MouseEvent) => {
+                            UndoManager.Redo();
+                            e.stopPropagation();
+                        }}>
+                        <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="redo-alt" />
+                    </div>
+                </>);
+            }
         }
     }
 
     // DocButton for switching into ink mode
     @computed get drawInk() {
-        if (this._activeDoc._viewType === "docking") {
-            return (
-                <>
-                    <div className="docButton"
-                        id="inkButton"
-                        title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
-                        onClick={this.onSwitchInking}>
-                        <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="pen-nib"
-                        />
-                    </div>
-                </>);
+        if (this.mainContainer) {
+            if (this._activeDoc._viewType === "docking") {
+                return (
+                    <>
+                        <div className="docButton"
+                            id="inkButton"
+                            title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
+                            onClick={this.onSwitchInking}>
+                            <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="pen-nib"
+                            />
+                        </div>
+                    </>);
+            }
         }
     }
 
@@ -746,8 +744,8 @@ export class MobileInterface extends React.Component {
                         {this.pinToPresentation()}
                         {this.downloadDocument()}
                         {this.undo}
-                        {this.drawInk}
                         {this.redo}
+                        {this.drawInk}
                         {this.uploadImageButton()}
                     </div>
                     {this.displayWorkspaces}
-- 
cgit v1.2.3-70-g09d2


From 5af1cbd51c06ff875e225aafe35eda438bf997d3 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Tue, 30 Jun 2020 13:57:37 +0800
Subject: menu update bug

added _columnWidth
---
 src/mobile/MobileInterface.tsx | 1 +
 1 file changed, 1 insertion(+)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 7ff82ccc4..194c8eb66 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -623,6 +623,7 @@ export class MobileInterface extends React.Component {
             this.menuListView = false;
             this._homeDoc._viewType = "masonry";
             this._homeDoc.columnWidth = 300;
+            this._homeDoc._columnWidth = 300;
             const menuButtons = DocListCast(this._homeDoc.data);
             menuButtons.map((doc: Doc, index: any) => {
                 const buttonData = DocListCast(doc.data);
-- 
cgit v1.2.3-70-g09d2


From 917098c107052f825e0f9b96bdb0706371862b90 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Mon, 29 Jun 2020 23:14:41 -0700
Subject: ink fixes

---
 .../views/collections/collectionFreeForm/InkOptionsMenu.tsx | 13 +------------
 src/client/views/nodes/DocumentView.tsx                     |  1 +
 src/mobile/MobileInterface.scss                             |  5 +++--
 src/mobile/MobileInterface.tsx                              |  8 +++++++-
 4 files changed, 12 insertions(+), 15 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
index 218cef183..f47fca6ac 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
@@ -318,18 +318,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
             this.arrowPicker,
             this.dashButton,
         ];
-
-        const mobileButtons = [
-            this.shapePicker,
-            this.bezierButton,
-            this.widthPicker,
-            this.colorPicker,
-            this.fillPicker,
-            this.arrowPicker,
-            this.dashButton,
-        ];
-
-        return (window.screen.width < 600 ? this.getElement(mobileButtons) : this.getElement(buttons));
+        return this.getElement(buttons);
     }
 }
 Scripting.addGlobal(function activatePen(penBtn: any) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 3b785a200..0ec676379 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -42,6 +42,7 @@ import { LinkAnchorBox } from './LinkAnchorBox';
 import { RadialMenu } from './RadialMenu';
 import React = require("react");
 import { DocumentLinksButton } from './DocumentLinksButton';
+import { MobileInterface } from '../../../mobile/MobileInterface';
 
 library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
     fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
diff --git a/src/mobile/MobileInterface.scss b/src/mobile/MobileInterface.scss
index ee39d4f50..4b32c3da0 100644
--- a/src/mobile/MobileInterface.scss
+++ b/src/mobile/MobileInterface.scss
@@ -401,14 +401,15 @@ body {
 .colorSelector {
     position: absolute;
     top: 550px;
-    left: 300px;
+    left: 280px;
     transform: translate(-50%, 0);
     z-index: 100;
     display: inline-flex;
     width: max-content;
     height: max-content;
     pointer-events: all;
-    font-size: 90px;
+    font-size: 80px;
+    user-select: none;
 }
 
 // Menu buttons for toggling between list and icon view
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 7ff82ccc4..54461c4cc 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -107,12 +107,18 @@ export class MobileInterface extends React.Component {
         this.renderView = renderView;
         // Ensures that switching to home is not registed
         UndoManager.undoStack.length = 0;
+        UndoManager.redoStack.length = 0;
     }
 
     // For toggling the hamburger menu
     @action
-    toggleSidebar = () => this.sidebarActive = !this.sidebarActive
+    toggleSidebar = () => {
+        this.sidebarActive = !this.sidebarActive;
 
+        if (this._ink) {
+            this.onSwitchInking();
+        }
+    }
     /**
      * Method called when 'Library' button is pressed on the home screen
      */
-- 
cgit v1.2.3-70-g09d2


From 713b200804fa84d654aeb0051e086641d55d95d9 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 2 Jul 2020 10:17:26 -0400
Subject: started some cleanup for Mobile  ..  lookslike workspaces view is
 broken now

---
 src/client/util/CurrentUserUtils.ts                |   3 +-
 src/client/views/AntimodeMenu.tsx                  |   2 +-
 src/client/views/nodes/DocumentView.tsx            |   7 +-
 src/client/views/nodes/PDFBox.tsx                  |   3 -
 src/client/views/nodes/RadialMenu.tsx              |   2 -
 .../views/nodes/formattedText/FormattedTextBox.tsx |   6 +-
 src/mobile/MobileInterface.tsx                     | 393 +++++++++------------
 7 files changed, 170 insertions(+), 246 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index e86f72684..6906c0bb3 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -32,7 +32,6 @@ export class CurrentUserUtils {
     public static get MainDocId() { return this.mainDocId; }
     public static set MainDocId(id: string | undefined) { this.mainDocId = id; }
     @computed public static get UserDocument() { return Doc.UserDoc(); }
-    @computed public static get ActivePen() { return Doc.UserDoc().activePen instanceof Doc && (Doc.UserDoc().activePen as Doc).inkPen as Doc; }
 
     @observable public static GuestTarget: Doc | undefined;
     @observable public static GuestWorkspace: Doc | undefined;
@@ -365,7 +364,7 @@ export class CurrentUserUtils {
         } else {
             const templateIconsDoc = Cast(doc["template-icons"], Doc, null);
             const requiredTypes = [doc["template-icon-view"] as Doc, doc["template-icon-view-img"] as Doc,
-            doc["template-icon-view-col"] as Doc, doc["template-icon-view-rtf"] as Doc, doc["template-icon-view-pdf"] as Doc];
+            doc["template-icon-view-col"] as Doc, doc["template-icon-view-rtf"] as Doc];
             DocListCastAsync(templateIconsDoc.data).then(async curIcons => {
                 await Promise.all(curIcons!);
                 requiredTypes.map(ntype => Doc.AddDocToList(templateIconsDoc, "data", ntype));
diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx
index 3e4d20fea..b8f77932d 100644
--- a/src/client/views/AntimodeMenu.tsx
+++ b/src/client/views/AntimodeMenu.tsx
@@ -131,7 +131,7 @@ export default abstract class AntimodeMenu extends React.Component {
     }
 
     protected getDragger = () => {
-        return <div className="antimodeMenu-dragger" onPointerDown={this.dragStart} style={{ width: "20px" }} />;
+        return <div className="antimodeMenu-dragger" key="dragger" onPointerDown={this.dragStart} style={{ width: "20px" }} />;
     }
 
     protected getElement(buttons: JSX.Element[]) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 0ec676379..8d122baeb 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -29,7 +29,6 @@ import { SelectionManager } from "../../util/SelectionManager";
 import SharingManager from '../../util/SharingManager';
 import { Transform } from "../../util/Transform";
 import { undoBatch, UndoManager } from "../../util/UndoManager";
-import { CollectionDockingView, DockedFrameRenderer } from "../collections/CollectionDockingView";
 import { CollectionView, CollectionViewType } from '../collections/CollectionView';
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from '../ContextMenuItem';
@@ -185,7 +184,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         // RadialMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "map-pin", selected: -1 });
         RadialMenu.Instance.addItem({ description: "Delete", event: () => { this.props.ContainingCollectionView?.removeDocument(this.props.Document), RadialMenu.Instance.closeMenu(); }, icon: "external-link-square-alt", selected: -1 });
         // RadialMenu.Instance.addItem({ description: "Open in a new tab", event: () => this.props.addDocTab(this.props.Document, "onRight"), icon: "trash", selected: -1 });
-        RadialMenu.Instance.addItem({ description: "Pin", event: () => DockedFrameRenderer.PinDoc(this.props.Document), icon: "map-pin", selected: -1 });
+        RadialMenu.Instance.addItem({ description: "Pin", event: () => this.props.pinToPres(this.props.Document), icon: "map-pin", selected: -1 });
         RadialMenu.Instance.addItem({ description: "Open", event: () => MobileInterface.Instance.handleClick(this.props.Document), icon: "trash", selected: -1 });
 
         SelectionManager.DeselectAll();
@@ -945,7 +944,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         recommendations.documentIconHeight = 150;
         recommendations.sourceDoc = this.props.Document;
         recommendations.sourceDocContext = this.props.ContainingCollectionView!.props.Document;
-        CollectionDockingView.AddRightSplit(recommendations, undefined);
+        this.props.addDocTab(recommendations, "onRight");
 
         // RecommendationsBox.Instance.displayRecommendations(e.pageX + 100, e.pageY);
     }
@@ -977,7 +976,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             body.href = urls[i];
             bodies.push(body);
         }
-        CollectionDockingView.AddRightSplit(Docs.Create.SchemaDocument(headers, bodies, { title: `Showing External Recommendations for "${StrCast(doc.title)}"` }), undefined);
+        this.props.addDocTab(Docs.Create.SchemaDocument(headers, bodies, { title: `Showing External Recommendations for "${StrCast(doc.title)}"` }), "onRight");
         this._showKPQuery = true;
         this._queries = kps.toString();
     }
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 54f44a0f9..1c5825a8f 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -226,9 +226,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
 
     @computed get contentScaling() { return this.props.ContentScaling(); }
     @computed get renderTitleBox() {
-        console.log("fitWidth ?: " + !(this.props.Document._fitWidth) && (window.screen.width > 600));
-        console.log("_nativeHeight: " + this.Document._nativeHeight);
-        console.log("%: " + `${100 / this.contentScaling}%`);
         const classname = "pdfBox" + (this.active() ? "-interactive" : "");
         return <div className={classname} style={{
             width: !this.props.Document._fitWidth ? this.Document._nativeWidth || 0 : `${100 / this.contentScaling}%`,
diff --git a/src/client/views/nodes/RadialMenu.tsx b/src/client/views/nodes/RadialMenu.tsx
index 2bbb80b2a..a3ac09a11 100644
--- a/src/client/views/nodes/RadialMenu.tsx
+++ b/src/client/views/nodes/RadialMenu.tsx
@@ -3,7 +3,6 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction
 import { observer } from "mobx-react";
 import "./RadialMenu.scss";
 import { RadialMenuItem, RadialMenuProps } from "./RadialMenuItem";
-import { MobileInterface } from "../../../mobile/MobileInterface";
 
 @observer
 export class RadialMenu extends React.Component {
@@ -26,7 +25,6 @@ export class RadialMenu extends React.Component {
 
 
     catchTouch = (te: React.TouchEvent) => {
-        console.log("caught");
         te.stopPropagation();
         te.preventDefault();
     }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index ae1db76de..270fcb01c 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -190,7 +190,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 }
             }
             const state = this._editorView.state.apply(tx);
-            this?._editorView?.updateState(state);
+            this._editorView?.updateState(state);
             (tx.storedMarks && !this._editorView.state.storedMarks) && (this._editorView.state.storedMarks = tx.storedMarks);
 
             const tsel = this._editorView.state.selection.$from;
@@ -512,8 +512,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
 
     recordDictation = () => {
-        console.log("recording dictation");
-        console.log(this._editorView);
         DictationManager.Controls.listen({
             interimHandler: this.setCurrentBulletContent,
             continuous: { indefinite: false },
@@ -532,7 +530,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
 
     recordBullet = async () => {
-        console.log("recording bullet");
         const completedCue = "end session";
         const results = await DictationManager.Controls.listen({
             interimHandler: this.setCurrentBulletContent,
@@ -549,7 +546,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     setCurrentBulletContent = (value: string) => {
         if (this._editorView) {
-            console.log("this._editorView");
             const state = this._editorView.state;
             const now = Date.now();
             let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(now / 1000) });
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 1b934df93..34894250a 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -13,7 +13,7 @@ import { action, computed, observable, reaction, trace } from 'mobx';
 import { observer } from 'mobx-react';
 import { Doc, DocListCast } from '../fields/Doc';
 import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
-import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero, returnEmptyFilter } from '../Utils';
+import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, returnZero, returnEmptyFilter } from '../Utils';
 import { Docs, DocumentOptions } from '../client/documents/Documents';
 import { Scripting } from '../client/util/Scripting';
 import { DocumentView } from '../client/views/nodes/DocumentView';
@@ -35,7 +35,6 @@ import { AudioUpload } from "./AudioUpload";
 import { Cast, FieldValue } from '../fields/Types';
 import RichTextMenu from "../client/views/nodes/formattedText/RichTextMenu";
 import { AudioBox } from "../client/views/nodes/AudioBox";
-import { Compute } from "google-auth-library";
 
 library.add(faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
@@ -47,22 +46,22 @@ library.add(faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngl
 @observer
 export class MobileInterface extends React.Component {
     @observable static Instance: MobileInterface;
-    @computed private get userDoc() { return Doc.UserDoc(); }
-    @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
-    @observable private mainDoc: any = CurrentUserUtils.setupActiveMobileMenu(this.userDoc);
-    @observable private renderView?: () => JSX.Element;
-    @observable private sidebarActive: boolean = false; //to toggle sidebar display
-    @observable private imageUploadActive: boolean = false; //to toggle image upload
-    @observable private audioUploadActive: boolean = false;
-    @observable private menuListView: boolean = false; //to switch between menu view (list / icon)
+    @observable private _mainDoc: any = CurrentUserUtils.setupActiveMobileMenu(Doc.UserDoc());
+    @observable private _sidebarActive: boolean = false; //to toggle sidebar display
+    @observable private _imageUploadActive: boolean = false; //to toggle image upload
+    @observable private _audioUploadActive: boolean = false;
+    @observable private _menuListView: boolean = false; //to switch between menu view (list / icon)
     @observable private _ink: boolean = false; //toggle whether ink is being dispalyed
+    @observable private renderView?: () => JSX.Element;
 
-    public _activeDoc: Doc = this.mainDoc; // doc updated as the active mobile page is updated (initially home menu)
-    public _homeDoc: Doc = this.mainDoc; // home menu as a document
+    private _activeDoc: Doc = this._mainDoc; // doc updated as the active mobile page is updated (initially home menu)
+    private _homeDoc: Doc = this._mainDoc; // home menu as a document
     private _homeMenu: boolean = true; // to determine whether currently at home menu
     private _child: Doc | null = null; // currently selected document
     private _parents: Array<Doc> = []; // array of parent docs (for pathbar)
-    private _library: Doc = CurrentUserUtils.setupLibrary(this.userDoc); // to access documents in Dash Web
+    private _library: Doc = CurrentUserUtils.setupLibrary(Doc.UserDoc()); // to access documents in Dash Web
+
+    @computed private get mainContainer() { return Doc.UserDoc() ? FieldValue(Cast(Doc.UserDoc().activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
 
     constructor(props: Readonly<{}>) {
         super(props);
@@ -72,7 +71,7 @@ export class MobileInterface extends React.Component {
     @action
     componentDidMount = () => {
         // if the home menu is in list view -> adjust the menu toggle appropriately
-        this._homeDoc._viewType === "stacking" ? this.menuListView = true : this.menuListView = false;
+        this._menuListView = this._homeDoc._viewType === "stacking" ? true : false;
         Doc.SetSelectedTool(InkTool.None); // ink should intially be set to none
         Doc.UserDoc().activeMobile = this._homeDoc; // active mobile set to home
         AudioBox.Enabled = true;
@@ -95,14 +94,14 @@ export class MobileInterface extends React.Component {
     // Switch the mobile view to the given doc
     @action
     switchCurrentView = (doc: Doc, renderView?: () => JSX.Element, onSwitch?: () => void) => {
-        if (!this.userDoc) return;
+        if (!Doc.UserDoc()) return;
         if (this._activeDoc === this._homeDoc) {
             this._parents.push(this._activeDoc);
             this._homeMenu = false;
         }
         this._activeDoc = doc;
         Doc.UserDoc().activeMobile = doc;
-        onSwitch && onSwitch();
+        onSwitch?.();
 
         this.renderView = renderView;
         // Ensures that switching to home is not registed
@@ -113,7 +112,7 @@ export class MobileInterface extends React.Component {
     // For toggling the hamburger menu
     @action
     toggleSidebar = () => {
-        this.sidebarActive = !this.sidebarActive;
+        this._sidebarActive = !this._sidebarActive;
 
         if (this._ink) {
             this.onSwitchInking();
@@ -126,7 +125,6 @@ export class MobileInterface extends React.Component {
         this.switchCurrentView(this._library);
         this._homeMenu = false;
         this.toggleSidebar();
-        //setTimeout(this.toggleSidebar, 300);
     }
 
     /**
@@ -146,13 +144,11 @@ export class MobileInterface extends React.Component {
             this._child = null;
             this.switchCurrentView(this._homeDoc);
             // Case 3: Parent document is any document
-        } else {
-            if (doc) {
-                this._child = doc;
-                this.switchCurrentView(doc);
-                this._homeMenu = false;
-                header.textContent = String(doc.title);
-            }
+        } else if (doc) {
+            this._child = doc;
+            this.switchCurrentView(doc);
+            this._homeMenu = false;
+            header.textContent = String(doc.title);
         }
         this._ink = false; // turns ink off
     }
@@ -161,13 +157,13 @@ export class MobileInterface extends React.Component {
      * Return 'Home", which implies returning to 'Home' menu buttons
      */
     returnHome = () => {
-        if (!this._homeMenu || this.sidebarActive) {
+        if (!this._homeMenu || this._sidebarActive) {
             this._homeMenu = true;
             this._parents = [];
             this._child = null;
             this.switchCurrentView(this._homeDoc);
         }
-        if (this.sidebarActive) {
+        if (this._sidebarActive) {
             this.toggleSidebar();
         }
     }
@@ -185,42 +181,38 @@ export class MobileInterface extends React.Component {
     /**
      * DocumentView for graphic display of all documents
      */
+    whitebackground = () => "white";
     @computed get displayWorkspaces() {
-        if (this.mainContainer) {
-            const backgroundColor = () => "white";
-            return (
-                <div style={{ position: "relative", top: '198px', height: `calc(100% - 350px)`, width: "100%", left: "0%" }}>
-                    <DocumentView
-                        Document={this.mainContainer}
-                        DataDoc={undefined}
-                        LibraryPath={emptyPath}
-                        addDocument={returnFalse}
-                        addDocTab={returnFalse}
-                        pinToPres={emptyFunction}
-                        rootSelected={returnFalse}
-                        removeDocument={undefined}
-                        onClick={undefined}
-                        ScreenToLocalTransform={Transform.Identity}
-                        ContentScaling={returnOne}
-                        PanelWidth={this.returnWidth}
-                        PanelHeight={this.returnHeight}
-                        NativeHeight={returnZero}
-                        NativeWidth={returnZero}
-                        renderDepth={0}
-                        focus={emptyFunction}
-                        backgroundColor={backgroundColor}
-                        parentActive={returnTrue}
-                        whenActiveChanged={emptyFunction}
-                        bringToFront={emptyFunction}
-                        docFilters={returnEmptyFilter}
-                        ContainingCollectionView={undefined}
-                        ContainingCollectionDoc={undefined}
-                    />
-                </div>
-            );
-        }
+        return !this.mainContainer ? (null) :
+            <div style={{ position: "relative", top: '198px', height: `calc(100% - 350px)`, width: "100%", left: "0%" }}>
+                <DocumentView
+                    Document={this.mainContainer}
+                    DataDoc={undefined}
+                    LibraryPath={emptyPath}
+                    addDocument={returnFalse}
+                    addDocTab={returnFalse}
+                    pinToPres={emptyFunction}
+                    rootSelected={returnFalse}
+                    removeDocument={undefined}
+                    onClick={undefined}
+                    ScreenToLocalTransform={Transform.Identity}
+                    ContentScaling={returnOne}
+                    PanelWidth={this.returnWidth}
+                    PanelHeight={this.returnHeight}
+                    NativeHeight={returnZero}
+                    NativeWidth={returnZero}
+                    renderDepth={0}
+                    focus={emptyFunction}
+                    backgroundColor={this.whitebackground}
+                    parentActive={returnTrue}
+                    whenActiveChanged={emptyFunction}
+                    bringToFront={emptyFunction}
+                    docFilters={returnEmptyFilter}
+                    ContainingCollectionView={undefined}
+                    ContainingCollectionDoc={undefined}
+                />
+            </div>;
     }
-
     /**
      * Note: window.innerWidth and window.screen.width compute different values.
      * window.screen.width is the display size, however window.innerWidth is the
@@ -235,8 +227,7 @@ export class MobileInterface extends React.Component {
      * @param doc: doc for which the method is called
      */
     handleClick = async (doc: Doc) => {
-        const children = DocListCast(doc.data);
-        if (doc.type !== "collection" && this.sidebarActive) {
+        if (doc.type !== "collection" && this._sidebarActive) {
             this._parents.push(this._activeDoc);
             this.switchCurrentView(doc);
             this._homeMenu = false;
@@ -267,12 +258,7 @@ export class MobileInterface extends React.Component {
      * Handles creation of array which is then rendered in renderPathbar()
      */
     createPathname = () => {
-        const docArray = [];
-        this._parents.map((doc: Doc, index: any) => {
-            docArray.push(doc);
-        });
-        docArray.push(this._activeDoc);
-        return docArray;
+        return [...this._parents, this._activeDoc];
     }
 
     // Renders the graphical pathbar
@@ -280,24 +266,21 @@ export class MobileInterface extends React.Component {
         const docArray = this.createPathname();
         const items = docArray.map((doc: Doc, index: any) => {
             if (index === 0) {
-                return (
-                    <>
-                        {this._homeMenu ?
-                            <div className="pathbarItem">
-                                <div className="pathbarText"
-                                    style={{ backgroundColor: "rgb(119, 37, 37)" }}
-                                    key={index}
-                                    onClick={() => this.handlePathClick(doc, index)}>{doc.title}
-                                </div>
-                            </div>
-                            :
-                            <div className="pathbarItem">
-                                <div className="pathbarText"
-                                    key={index}
-                                    onClick={() => this.handlePathClick(doc, index)}>{doc.title}
-                                </div>
-                            </div>}
-                    </>);
+                return this._homeMenu ?
+                    <div className="pathbarItem" key={index}>
+                        <div className="pathbarText"
+                            style={{ backgroundColor: "rgb(119, 37, 37)" }}
+                            key={index}
+                            onClick={() => this.handlePathClick(doc, index)}>{doc.title}
+                        </div>
+                    </div>
+                    :
+                    <div className="pathbarItem" key={index}>
+                        <div className="pathbarText"
+                            key={index}
+                            onClick={() => this.handlePathClick(doc, index)}>{doc.title}
+                        </div>
+                    </div>;
 
             } else if (doc === this._activeDoc) {
                 return (
@@ -357,14 +340,14 @@ export class MobileInterface extends React.Component {
     }
 
     // Renders the contents of the menu and sidebar
-    renderDefaultContent = () => {
+    @computed get renderDefaultContent() {
         if (this._homeMenu) {
             return (
                 <div>
                     <div className="navbar">
                         <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
                         <div className="header" id="header">{this._homeDoc.title}</div>
-                        <div className="cover" id="cover" onClick={(e) => this.stop(e)}></div>
+                        <div className="cover" id="cover" onClick={e => e.stopPropagation()}></div>
                         <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
                             <span></span>
                             <span></span>
@@ -376,7 +359,7 @@ export class MobileInterface extends React.Component {
             );
         }
         // stores workspace documents as 'workspaces' variable
-        let workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+        let workspaces = Cast(Doc.UserDoc().myWorkspaces, Doc) as Doc;
         if (this._child) {
             workspaces = this._child;
         }
@@ -400,16 +383,16 @@ export class MobileInterface extends React.Component {
             <div>
                 <div className="navbar">
                     <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
-                    <div className="header" id="header">{this.sidebarActive ? "library" : this._activeDoc.title}</div>
-                    <div className={`toggle-btn ${this.sidebarActive ? "active" : ""}`} onClick={this.toggleSidebar}>
+                    <div className="header" id="header">{this._sidebarActive ? "library" : this._activeDoc.title}</div>
+                    <div className={`toggle-btn ${this._sidebarActive ? "active" : ""}`} onClick={this.toggleSidebar}>
                         <span></span>
                         <span></span>
                         <span></span>
                     </div>
-                    <div className={`background ${this.sidebarActive ? "active" : ""}`} onClick={this.toggleSidebar}></div>
+                    <div className={`background ${this._sidebarActive ? "active" : ""}`} onClick={this.toggleSidebar}></div>
                 </div>
                 {this.renderPathbar()}
-                <div className={`sidebar ${this.sidebarActive ? "active" : ""}`}>
+                <div className={`sidebar ${this._sidebarActive ? "active" : ""}`}>
                     <div className="sidebarButtons">
                         {this._child ?
                             <>
@@ -435,7 +418,7 @@ export class MobileInterface extends React.Component {
                         }
                     </div>
                 </div>
-                <div className={`blanket ${this.sidebarActive ? "active" : ""}`} onClick={this.toggleSidebar}>
+                <div className={`blanket ${this._sidebarActive ? "active" : ""}`} onClick={this.toggleSidebar}>
                 </div>
             </div>
         );
@@ -446,7 +429,7 @@ export class MobileInterface extends React.Component {
      */
     @action
     createNewWorkspace = async (id?: string) => {
-        const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+        const workspaces = Cast(Doc.UserDoc().myWorkspaces, Doc) as Doc;
         const workspaceCount = DocListCast(workspaces.data).length + 1;
         const freeformOptions: DocumentOptions = {
             x: 0,
@@ -465,10 +448,6 @@ export class MobileInterface extends React.Component {
         Doc.AddDocToList(workspaces, "data", workspaceDoc);
     }
 
-    stop = (e: React.MouseEvent) => {
-        e.stopPropagation();
-    }
-
     // Button for switching between pen and ink mode
     @action
     onSwitchInking = () => {
@@ -486,152 +465,121 @@ export class MobileInterface extends React.Component {
     }
 
     // The static ink menu that appears at the top
-    inkMenu = () => {
-        if (this._activeDoc._viewType === "docking") {
-            if (this._ink) {
-                return <div className="colorSelector">
-                    <InkOptionsMenu />
-                </div>;
-
-            }
-        }
+    @computed get inkMenu() {
+        return this._activeDoc._viewType !== "docking" || !this._ink ? (null) :
+            <div className="colorSelector">
+                <InkOptionsMenu />
+            </div>;
     }
 
     // DocButton that uses UndoManager and handles the opacity change if CanUndo is true
     @computed get undo() {
-        if (this.mainContainer) {
-            if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
-                return (<>
-                    <div className="docButton"
-                        style={{ backgroundColor: "black", color: "white", fontSize: "60", opacity: UndoManager.CanUndo() ? "1" : "0.4", }}
-                        id="undoButton"
-                        title="undo"
-                        onClick={(e: React.MouseEvent) => {
-                            UndoManager.Undo();
-                            e.stopPropagation();
-                        }}>
-                        <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="undo-alt" />
-                    </div>
-                </>);
-            }
-        }
+        if (this.mainContainer && this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc &&
+            this._activeDoc !== Doc.UserDoc().rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
+            return (
+                <div className="docButton"
+                    style={{ backgroundColor: "black", color: "white", fontSize: "60", opacity: UndoManager.CanUndo() ? "1" : "0.4", }}
+                    id="undoButton"
+                    title="undo"
+                    onClick={(e: React.MouseEvent) => {
+                        UndoManager.Undo();
+                        e.stopPropagation();
+                    }}>
+                    <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="undo-alt" />
+                </div>);
+        } else return (null);
     }
 
     // DocButton that uses UndoManager and handles the opacity change if CanRedo is true
     @computed get redo() {
-        if (this.mainContainer) {
-            if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
-                return (<>
-                    <div className="docButton"
-                        style={{ backgroundColor: "black", color: "white", fontSize: "60", opacity: UndoManager.CanRedo() ? "1" : "0.4", }}
-                        id="undoButton"
-                        title="redo"
-                        onClick={(e: React.MouseEvent) => {
-                            UndoManager.Redo();
-                            e.stopPropagation();
-                        }}>
-                        <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="redo-alt" />
-                    </div>
-                </>);
-            }
-        }
+        if (this.mainContainer && this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc &&
+            this._activeDoc !== Doc.UserDoc().rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") {
+            return (
+                <div className="docButton"
+                    style={{ backgroundColor: "black", color: "white", fontSize: "60", opacity: UndoManager.CanRedo() ? "1" : "0.4", }}
+                    id="undoButton"
+                    title="redo"
+                    onClick={(e: React.MouseEvent) => {
+                        UndoManager.Redo();
+                        e.stopPropagation();
+                    }}>
+                    <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="redo-alt" />
+                </div>);
+        } else return (null);
     }
 
     // DocButton for switching into ink mode
     @computed get drawInk() {
-        if (this.mainContainer) {
-            if (this._activeDoc._viewType === "docking") {
-                return (
-                    <>
-                        <div className="docButton"
-                            id="inkButton"
-                            title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
-                            onClick={this.onSwitchInking}>
-                            <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="pen-nib"
-                            />
-                        </div>
-                    </>);
-            }
-        }
+        return !this.mainContainer || this._activeDoc._viewType !== "docking" ? (null) :
+            <div className="docButton"
+                id="inkButton"
+                title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
+                onClick={this.onSwitchInking}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="pen-nib" />
+            </div>;
     }
 
     // DocButton: Button that appears on the bottom of the screen to initiate image upload
-    uploadImageButton = () => {
+    @computed get uploadImageButton() {
         if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc._viewType !== "docking" && this._activeDoc.title !== "WORKSPACES") {
             return <div className="docButton"
                 id="imageButton"
                 title={Doc.isDocPinned(this._activeDoc) ? "Pen on" : "Pen off"}
                 onClick={this.toggleUpload}>
-                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload"
-                />
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload" />
             </div>;
-        }
+        } else return (null);
     }
 
     // DocButton to download images on the mobile
-    downloadDocument = () => {
+    @computed get downloadDocument() {
         if (this._activeDoc.type === "image" || this._activeDoc.type === "pdf" || this._activeDoc.type === "video") {
-            const url = this._activeDoc["data-path"]?.toString();
             return <div className="docButton"
                 title={"Download Image"}
                 style={{ backgroundColor: "white", color: "black" }}
-                onClick={e => {
-                    window.open(url);
-                }}>
-                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="download"
-                />
+                onClick={e => window.open(this._activeDoc["data-path"]?.toString())}> // daa-path holds the url
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="download" />
             </div>;
-        }
+        } else return (null);
     }
 
     // DocButton for pinning images to presentation
-    pinToPresentation = () => {
+    @computed get pinToPresentation() {
         // Only making button available if it is an image
         if (!(this._activeDoc.type === "collection" || this._activeDoc.type === "presentation")) {
             const isPinned = this._activeDoc && Doc.isDocPinned(this._activeDoc);
             return <div className="docButton"
                 title={Doc.isDocPinned(this._activeDoc) ? "Unpin from presentation" : "Pin to presentation"}
                 style={{ backgroundColor: isPinned ? "black" : "white", color: isPinned ? "white" : "black" }}
-                onClick={e => {
-                    if (isPinned) {
-                        DockedFrameRenderer.UnpinDoc(this._activeDoc);
-                    }
-                    else {
-                        DockedFrameRenderer.PinDoc(this._activeDoc);
-                    }
-                }}>
-                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
-                />
+                onClick={e => DockedFrameRenderer.PinDoc(this._activeDoc, isPinned)}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
             </div>;
-        }
+        } else return (null);
     }
 
     // Buttons for switching the menu between large and small icons
-    switchMenuView = () => {
-        if (this._activeDoc.title === this._homeDoc.title) {
-            return (
-                <div className="homeSwitch">
-                    <div className={`list ${!this.menuListView ? "active" : ""}`} onClick={this.changeToIconView}>
-                        <FontAwesomeIcon size="sm" icon="th-large" />
-                    </div>
-                    <div className={`list ${this.menuListView ? "active" : ""}`} onClick={this.changeToListView}>
-                        <FontAwesomeIcon size="sm" icon="bars" />
-                    </div>
+    @computed get switchMenuView() {
+        return this._activeDoc.title !== this._homeDoc.title ? (null) :
+            <div className="homeSwitch">
+                <div className={`list ${!this._menuListView ? "active" : ""}`} onClick={this.changeToIconView}>
+                    <FontAwesomeIcon size="sm" icon="th-large" />
                 </div>
-            );
-        }
+                <div className={`list ${this._menuListView ? "active" : ""}`} onClick={this.changeToListView}>
+                    <FontAwesomeIcon size="sm" icon="bars" />
+                </div>
+            </div>;
     }
 
     // Logic for switching the menu into the icons
     @action
     changeToIconView = () => {
         if (this._homeDoc._viewType = "stacking") {
-            this.menuListView = false;
+            this._menuListView = false;
             this._homeDoc._viewType = "masonry";
             this._homeDoc.columnWidth = 300;
             this._homeDoc._columnWidth = 300;
             const menuButtons = DocListCast(this._homeDoc.data);
-            menuButtons.map((doc: Doc, index: any) => {
+            menuButtons.map(doc => {
                 const buttonData = DocListCast(doc.data);
                 buttonData[1]._nativeWidth = 0.1;
                 buttonData[1]._width = 0.1;
@@ -647,9 +595,9 @@ export class MobileInterface extends React.Component {
     changeToListView = () => {
         if (this._homeDoc._viewType = "masonry") {
             this._homeDoc._viewType = "stacking";
-            this.menuListView = true;
+            this._menuListView = true;
             const menuButtons = DocListCast(this._homeDoc.data);
-            menuButtons.map((doc: Doc, index: any) => {
+            menuButtons.map(doc => {
                 const buttonData = DocListCast(doc.data);
                 buttonData[1]._nativeWidth = 450;
                 buttonData[1]._dimMagnitude = 2;
@@ -671,49 +619,37 @@ export class MobileInterface extends React.Component {
 
     // For toggling image upload pop up
     @action
-    toggleUpload = () => this.imageUploadActive = !this.imageUploadActive
+    toggleUpload = () => this._imageUploadActive = !this._imageUploadActive
 
     // For toggling audio record and dictate pop up
     @action
-    toggleAudio = () => this.audioUploadActive = !this.audioUploadActive
+    toggleAudio = () => this._audioUploadActive = !this._audioUploadActive
 
     // Button for toggling the upload pop up in a collection
     @action
     toggleUploadInCollection = () => {
         const button = document.getElementById("imageButton") as HTMLElement;
-        button.style.backgroundColor = this.imageUploadActive ? "white" : "black";
-        button.style.color = this.imageUploadActive ? "black" : "white";
+        button.style.backgroundColor = this._imageUploadActive ? "white" : "black";
+        button.style.color = this._imageUploadActive ? "black" : "white";
 
-        this.imageUploadActive = !this.imageUploadActive;
+        this._imageUploadActive = !this._imageUploadActive;
     }
 
     // For closing the image upload pop up
     @action
     closeUpload = () => {
-        this.imageUploadActive = false;
+        this._imageUploadActive = false;
     }
 
     // Returns the image upload pop up
-    uploadImage = () => {
-        let doc;
-        let toggle;
-        if (this._homeMenu === false) {
-            doc = this._activeDoc;
-            toggle = this.toggleUploadInCollection;
-        } else {
-            doc = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
-            toggle = this.toggleUpload;
-        }
-        return (
-            <Uploader Document={doc} />
-        );
+    @computed get uploadImage() {
+        const doc = !this._homeMenu ? this._activeDoc : Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
+        return <Uploader Document={doc} />;
     }
 
     // Radial menu can only be used if it is a colleciton and it is not a homeDoc
-    displayRadialMenu = () => {
-        if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) {
-            return <RadialMenu />;
-        }
+    @computed get displayRadialMenu() {
+        return this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc ? <RadialMenu /> : (null);
     }
 
     onDragOver = (e: React.DragEvent) => {
@@ -733,32 +669,31 @@ export class MobileInterface extends React.Component {
     }
 
     render() {
-        trace();
         return (
             <div className="mobileInterface-container" onDragOver={this.onDragOver}>
                 <SettingsManager />
-                <div className={`image-upload ${this.imageUploadActive ? "active" : ""}`}>
-                    {this.uploadImage()}
+                <div className={`image-upload ${this._imageUploadActive ? "active" : ""}`}>
+                    {this.uploadImage}
                 </div>
-                <div className={`audio-upload ${this.audioUploadActive ? "active" : ""}`}>
+                <div className={`audio-upload ${this._audioUploadActive ? "active" : ""}`}>
                     <AudioUpload />
                 </div>
-                {this.switchMenuView()}
-                {this.inkMenu()}
+                {this.switchMenuView}
+                {this.inkMenu}
                 <GestureOverlay>
                     <div style={{ display: "none" }}><RichTextMenu key="rich" /></div>
                     <div className="docButtonContainer">
-                        {this.pinToPresentation()}
-                        {this.downloadDocument()}
+                        {this.pinToPresentation}
+                        {this.downloadDocument}
                         {this.undo}
                         {this.redo}
                         {this.drawInk}
-                        {this.uploadImageButton()}
+                        {this.uploadImageButton}
                     </div>
                     {this.displayWorkspaces}
-                    {this.renderDefaultContent()}
+                    {this.renderDefaultContent}
                 </GestureOverlay>
-                {this.displayRadialMenu()}
+                {this.displayRadialMenu}
             </div>
         );
     }
-- 
cgit v1.2.3-70-g09d2


From 9e5ff4fc51d3ae555a76979fb34c043bcd0712a1 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 2 Jul 2020 11:06:01 -0400
Subject: fixed reactions for Mobile

---
 src/mobile/MobileInterface.tsx | 151 +++++++++++++++--------------------------
 1 file changed, 55 insertions(+), 96 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 34894250a..1bf1fb022 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -9,7 +9,7 @@ import {
     faThumbtack, faTree, faTv, faBook, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft, faBars, faTh, faChevronLeft
 } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable, reaction, trace } from 'mobx';
+import { action, computed, observable, reaction, trace, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { Doc, DocListCast } from '../fields/Doc';
 import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
@@ -45,21 +45,19 @@ library.add(faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngl
 
 @observer
 export class MobileInterface extends React.Component {
-    @observable static Instance: MobileInterface;
-    @observable private _mainDoc: any = CurrentUserUtils.setupActiveMobileMenu(Doc.UserDoc());
+    static Instance: MobileInterface;
+    private _library: Doc = CurrentUserUtils.setupLibrary(Doc.UserDoc()); // to access documents in Dash Web
+    private _mainDoc: any = CurrentUserUtils.setupActiveMobileMenu(Doc.UserDoc());
     @observable private _sidebarActive: boolean = false; //to toggle sidebar display
     @observable private _imageUploadActive: boolean = false; //to toggle image upload
     @observable private _audioUploadActive: boolean = false;
     @observable private _menuListView: boolean = false; //to switch between menu view (list / icon)
     @observable private _ink: boolean = false; //toggle whether ink is being dispalyed
-    @observable private renderView?: () => JSX.Element;
-
-    private _activeDoc: Doc = this._mainDoc; // doc updated as the active mobile page is updated (initially home menu)
-    private _homeDoc: Doc = this._mainDoc; // home menu as a document
-    private _homeMenu: boolean = true; // to determine whether currently at home menu
-    private _child: Doc | null = null; // currently selected document
-    private _parents: Array<Doc> = []; // array of parent docs (for pathbar)
-    private _library: Doc = CurrentUserUtils.setupLibrary(Doc.UserDoc()); // to access documents in Dash Web
+    @observable private _homeMenu: boolean = true; // to determine whether currently at home menu
+    @observable private _child: Doc | null = null; // currently selected document
+    @observable private _activeDoc: Doc = this._mainDoc; // doc updated as the active mobile page is updated (initially home menu)
+    @observable private _homeDoc: Doc = this._mainDoc; // home menu as a document
+    @observable private _parents: Array<Doc> = []; // array of parent docs (for pathbar)
 
     @computed private get mainContainer() { return Doc.UserDoc() ? FieldValue(Cast(Doc.UserDoc().activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
 
@@ -103,7 +101,6 @@ export class MobileInterface extends React.Component {
         Doc.UserDoc().activeMobile = doc;
         onSwitch?.();
 
-        this.renderView = renderView;
         // Ensures that switching to home is not registed
         UndoManager.undoStack.length = 0;
         UndoManager.redoStack.length = 0;
@@ -123,13 +120,14 @@ export class MobileInterface extends React.Component {
      */
     switchToLibrary = async () => {
         this.switchCurrentView(this._library);
-        this._homeMenu = false;
+        runInAction(() => this._homeMenu = false);
         this.toggleSidebar();
     }
 
     /**
      * Back method for navigating through items
      */
+    @action
     back = () => {
         const header = document.getElementById("header") as HTMLElement;
         const doc = Cast(this._parents.pop(), Doc) as Doc; // Parent document
@@ -156,6 +154,7 @@ export class MobileInterface extends React.Component {
     /**
      * Return 'Home", which implies returning to 'Home' menu buttons
      */
+    @action
     returnHome = () => {
         if (!this._homeMenu || this._sidebarActive) {
             this._homeMenu = true;
@@ -171,6 +170,7 @@ export class MobileInterface extends React.Component {
     /**
      * Return to primary Workspace in library (Workspaces Doc)
      */
+    @action
     returnMain = () => {
         this._parents = [this._homeDoc];
         this.switchCurrentView(this._library);
@@ -179,9 +179,16 @@ export class MobileInterface extends React.Component {
     }
 
     /**
-     * DocumentView for graphic display of all documents
+     * Note: window.innerWidth and window.screen.width compute different values.
+     * window.screen.width is the display size, however window.innerWidth is the
+     * display resolution which computes differently.
      */
+    returnWidth = () => window.innerWidth; //The windows width
+    returnHeight = () => (window.innerHeight - 300); //Calculating the windows height (-300 to account for topbar)
     whitebackground = () => "white";
+    /**
+     * DocumentView for graphic display of all documents
+     */
     @computed get displayWorkspaces() {
         return !this.mainContainer ? (null) :
             <div style={{ position: "relative", top: '198px', height: `calc(100% - 350px)`, width: "100%", left: "0%" }}>
@@ -213,13 +220,6 @@ export class MobileInterface extends React.Component {
                 />
             </div>;
     }
-    /**
-     * Note: window.innerWidth and window.screen.width compute different values.
-     * window.screen.width is the display size, however window.innerWidth is the
-     * display resolution which computes differently.
-     */
-    returnWidth = () => window.innerWidth; //The windows width
-    returnHeight = () => (window.innerHeight - 300); //Calculating the windows height (-300 to account for topbar)
 
     /**
      * Handles the click functionality in the library panel.
@@ -227,18 +227,20 @@ export class MobileInterface extends React.Component {
      * @param doc: doc for which the method is called
      */
     handleClick = async (doc: Doc) => {
-        if (doc.type !== "collection" && this._sidebarActive) {
-            this._parents.push(this._activeDoc);
-            this.switchCurrentView(doc);
-            this._homeMenu = false;
-            this.toggleSidebar();
-        }
-        else {
-            this._parents.push(this._activeDoc);
-            this.switchCurrentView(doc);
-            this._homeMenu = false;
-            this._child = doc;
-        }
+        runInAction(() => {
+            if (doc.type !== "collection" && this._sidebarActive) {
+                this._parents.push(this._activeDoc);
+                this.switchCurrentView(doc);
+                this._homeMenu = false;
+                this.toggleSidebar();
+            }
+            else {
+                this._parents.push(this._activeDoc);
+                this.switchCurrentView(doc);
+                this._homeMenu = false;
+                this._child = doc;
+            }
+        });
     }
 
     /**
@@ -246,6 +248,7 @@ export class MobileInterface extends React.Component {
      * be opened (open icon on RHS of all menu items)
      * @param doc doc to be opened
      */
+    @action
     openFromSidebar = (doc: Doc) => {
         this._parents.push(this._activeDoc);
         this.switchCurrentView(doc);
@@ -254,77 +257,31 @@ export class MobileInterface extends React.Component {
         this.toggleSidebar();
     }
 
-    /**
-     * Handles creation of array which is then rendered in renderPathbar()
-     */
-    createPathname = () => {
-        return [...this._parents, this._activeDoc];
-    }
-
     // Renders the graphical pathbar
     renderPathbar = () => {
-        const docArray = this.createPathname();
-        const items = docArray.map((doc: Doc, index: any) => {
-            if (index === 0) {
-                return this._homeMenu ?
-                    <div className="pathbarItem" key={index}>
-                        <div className="pathbarText"
-                            style={{ backgroundColor: "rgb(119, 37, 37)" }}
-                            key={index}
-                            onClick={() => this.handlePathClick(doc, index)}>{doc.title}
-                        </div>
-                    </div>
-                    :
-                    <div className="pathbarItem" key={index}>
-                        <div className="pathbarText"
-                            key={index}
-                            onClick={() => this.handlePathClick(doc, index)}>{doc.title}
-                        </div>
-                    </div>;
-
-            } else if (doc === this._activeDoc) {
-                return (
-                    <div className="pathbarItem">
-                        <FontAwesomeIcon className="pathIcon" icon="angle-right" size="lg" />
-                        <div className="pathbarText"
-                            style={{ backgroundColor: "rgb(119, 37, 37)" }}
-                            key={index}
-                            onClick={() => this.handlePathClick(doc, index)}>{doc.title}
-                        </div>
-                    </div>);
-            } else {
-                return (
-                    <div className="pathbarItem">
-                        <FontAwesomeIcon className="pathIcon" icon="angle-right" size="lg" />
-                        <div className="pathbarText"
-                            key={index}
-                            onClick={() => this.handlePathClick(doc, index)}>{doc.title}
-                        </div>
-                    </div>);
-            }
-
-        });
-        if (this._parents.length !== 0) {
-            return (<div className="pathbar">
-                <div className="scrollmenu">
-                    {items}
+        const docPath = [...this._parents, this._activeDoc];
+        const items = docPath.map((doc: Doc, index: any) =>
+            <div className="pathbarItem" key={index}>
+                {index === 0 ? (null) : <FontAwesomeIcon key="icon" className="pathIcon" icon="angle-right" size="lg" />}
+                <div className="pathbarText"
+                    style={{ backgroundColor: this._homeMenu || doc === this._activeDoc ? "rgb(119,17,37)" : undefined }}
+                    onClick={() => this.handlePathClick(doc, index)}>{doc.title}
                 </div>
+            </div>);
+        return (<div className="pathbar">
+            <div className="scrollmenu">
+                {items}
+            </div>
+            {!this._parents.length ? (null) :
                 <div className="back" >
                     <FontAwesomeIcon onClick={this.back} icon={"chevron-left"} color="white" size={"2x"} />
-                </div>
-                <div className="hidePath" />
-            </div>);
-        } else {
-            return (<div className="pathbar">
-                <div className="scrollmenu">
-                    {items}
-                </div>
-                <div className="hidePath" />
-            </div>);
-        }
+                </div>}
+            <div className="hidePath" />
+        </div>);
     }
 
     // Handles when user clicks on a document in the pathbar
+    @action
     handlePathClick = (doc: Doc, index: number) => {
         if (doc === this._library) {
             this._child = null;
@@ -608,6 +565,7 @@ export class MobileInterface extends React.Component {
     }
 
     // For setting up the presentation document for the home menu
+    @action
     setupDefaultPresentation = () => {
         const presentation = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
 
@@ -662,6 +620,7 @@ export class MobileInterface extends React.Component {
      * Switch view from mobile menu to access the mobile uploads
      * Global function name: openMobileUploads()
      */
+    @action
     switchToMobileUploads = () => {
         const mobileUpload = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
         this.switchCurrentView(mobileUpload);
-- 
cgit v1.2.3-70-g09d2


From 59868be3182e049297f7f86da368cf2733870fb2 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 2 Jul 2020 14:41:56 -0400
Subject: final mobile tweaks before merge?

---
 src/client/views/nodes/DocumentView.tsx | 10 +++++-----
 src/mobile/MobileInterface.tsx          |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

(limited to 'src/mobile/MobileInterface.tsx')

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 732089068..37d8df47d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -720,19 +720,19 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     onContextMenu = async (e: React.MouseEvent | Touch): Promise<void> => {
         // the touch onContextMenu is button 0, the pointer onContextMenu is button 2
         if (!(e instanceof Touch)) {
-            if (e?.button === 0 && !e.ctrlKey) {
-                e?.preventDefault();
+            if (e.button === 0 && !e.ctrlKey) {
+                e.preventDefault();
                 return;
             }
-            e?.persist();
-            e?.stopPropagation();
+            e.persist();
+            e.stopPropagation();
 
             if (Math.abs(this._downX - e?.clientX) > 3 || Math.abs(this._downY - e?.clientY) > 3 ||
                 e?.isDefaultPrevented()) {
                 e?.preventDefault();
                 return;
             }
-            e?.preventDefault();
+            e.preventDefault();
         }
 
         const cm = ContextMenu.Instance;
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 1bf1fb022..47768fd09 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -494,7 +494,7 @@ export class MobileInterface extends React.Component {
             return <div className="docButton"
                 title={"Download Image"}
                 style={{ backgroundColor: "white", color: "black" }}
-                onClick={e => window.open(this._activeDoc["data-path"]?.toString())}> // daa-path holds the url
+                onClick={e => window.open(this._activeDoc["data-path"]?.toString())}> {/*  daa-path holds the url */}
                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="download" />
             </div>;
         } else return (null);
-- 
cgit v1.2.3-70-g09d2

