From 9a2221a65c56841a9d9cba57a1b260999a5f9f4d Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Sat, 8 Aug 2020 00:15:35 -0500
Subject: fixing multiple undo bugs

---
 .../collectionFreeForm/MarqueeOptionsMenu.tsx      | 62 ++++++++++++----------
 1 file changed, 34 insertions(+), 28 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index db4b674b5..d27ca7c3a 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -3,6 +3,8 @@ import AntimodeMenu from "../../AntimodeMenu";
 import { observer } from "mobx-react";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { unimplementedFunction } from "../../../../Utils";
+import { undoBatch } from "../../../util/UndoManager";
+import { Tooltip } from "@material-ui/core";
 
 @observer
 export default class MarqueeOptionsMenu extends AntimodeMenu {
@@ -23,34 +25,38 @@ export default class MarqueeOptionsMenu extends AntimodeMenu {
 
     render() {
         const buttons = [
-            <button
-                className="antimodeMenu-button"
-                title="Create a Collection"
-                key="group"
-                onPointerDown={this.createCollection}>
-                <FontAwesomeIcon icon="object-group" size="lg" />
-            </button>,
-            <button
-                className="antimodeMenu-button"
-                title="Summarize Documents"
-                key="summarize"
-                onPointerDown={this.summarize}>
-                <FontAwesomeIcon icon="compress-arrows-alt" size="lg" />
-            </button>,
-            <button
-                className="antimodeMenu-button"
-                title="Delete Documents"
-                key="delete"
-                onPointerDown={this.delete}>
-                <FontAwesomeIcon icon="trash-alt" size="lg" />
-            </button>,
-            <button
-                className="antimodeMenu-button"
-                title="Change to Text"
-                key="inkToText"
-                onPointerDown={this.inkToText}>
-                <FontAwesomeIcon icon="font" size="lg" />
-            </button>,
+            <Tooltip title={<><div className="dash-tooltip">Create a Collection</div></>} placement="bottom">
+                <button
+                    className="antimodeMenu-button"
+                    key="group"
+                    onPointerDown={this.createCollection}>
+                    <FontAwesomeIcon icon="object-group" size="lg" />
+                </button>
+            </Tooltip>,
+            <Tooltip title={<><div className="dash-tooltip">Summarize Documents</div></>} placement="bottom">
+                <button
+                    className="antimodeMenu-button"
+                    key="summarize"
+                    onPointerDown={this.summarize}>
+                    <FontAwesomeIcon icon="compress-arrows-alt" size="lg" />
+                </button>
+            </Tooltip>,
+            <Tooltip title={<><div className="dash-tooltip">Delete Documents</div></>} placement="bottom">
+                <button
+                    className="antimodeMenu-button"
+                    key="delete"
+                    onPointerDown={this.delete}>
+                    <FontAwesomeIcon icon="trash-alt" size="lg" />
+                </button>
+            </Tooltip>,
+            <Tooltip title={<><div className="dash-tooltip">Change to Text</div></>} placement="bottom">
+                <button
+                    className="antimodeMenu-button"
+                    key="inkToText"
+                    onPointerDown={this.inkToText}>
+                    <FontAwesomeIcon icon="font" size="lg" />
+                </button>
+            </Tooltip>,
         ];
         return this.getElement(buttons);
     }
-- 
cgit v1.2.3-70-g09d2


From 03ae3477dac354eff9178dac701ee40e394434c9 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 10 Aug 2020 10:37:07 -0400
Subject: fixed issues with presentationBox grabbing all keyboard events and
 preventing title edits among others. fixed runtime errors.  fixed
 groupManager to open again.

---
 src/client/util/SettingsManager.tsx                |  2 +-
 src/client/views/GlobalKeyHandler.ts               |  4 +++-
 .../views/collections/CollectionDockingView.tsx    | 12 +++++++----
 .../collectionFreeForm/MarqueeOptionsMenu.tsx      | 12 ++++-------
 src/client/views/nodes/PresBox.tsx                 | 24 ++++++++++++++++++----
 5 files changed, 36 insertions(+), 18 deletions(-)

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

diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 513cece40..e3b91925a 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -146,7 +146,7 @@ export default class SettingsManager extends React.Component<{}> {
     @computed get accountsContent() {
         return <div className="accounts-content">
             <button onClick={this.googleAuthorize} value="data">Link to Google</button>
-            <button onClick={GroupManager.Instance?.open}>Manage groups</button>
+            <button onClick={() => GroupManager.Instance?.open()}>Manage groups</button>
         </div>;
     }
 
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 0ea02e3cb..182f6397c 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -108,7 +108,9 @@ export default class KeyManager {
                 GoogleAuthenticationManager.Instance.cancel();
                 SharingManager.Instance.close();
                 GroupManager.Instance.close();
-                CollectionFreeFormViewChrome.Instance.clearKeep();
+                CollectionFreeFormViewChrome.Instance?.clearKeep();
+                window.getSelection()?.empty();
+                document.body.focus();
                 break;
             case "delete":
             case "backspace":
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 7e096fa37..0c93b4e63 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -513,7 +513,11 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
 
             const doc = await DocServer.GetRefField(tab.contentItem.config.props.documentId) as Doc;
             if (doc instanceof Doc) {
-                tab.titleElement[0].onclick = (e: any) => tab.titleElement[0].focus();
+                tab.titleElement[0].onclick = (e: any) => {
+                    if (Date.now() - tab.titleElement[0].lastClick < 1000) tab.titleElement[0].select();
+                    tab.titleElement[0].lastClick = Date.now();
+                    tab.titleElement[0].focus();
+                }
                 tab.titleElement[0].onchange = (e: any) => {
                     tab.titleElement[0].size = e.currentTarget.value.length + 1;
                     Doc.GetProto(doc).title = e.currentTarget.value, true;
@@ -691,8 +695,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         return (this.props as any).glContainer.parent.parent;
     }
     get _tab(): any {
-        const tab = (this.props as any).glContainer.tab.element[0] as HTMLElement;
-        return tab.getElementsByClassName("lm_title")?.[0];
+        const tab = (this.props as any).glContainer.tab?.element[0] as HTMLElement;
+        return tab?.getElementsByClassName("lm_title")?.[0];
     }
     constructor(props: any) {
         super(props);
@@ -757,7 +761,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         this._tabReaction = reaction(() => ({ views: SelectionManager.SelectedDocuments(), color: StrCast(this._document?._backgroundColor, "white") }),
             (data) => {
                 const selected = data.views.some(v => Doc.AreProtosEqual(v.props.Document, this._document));
-                this._tab.style.backgroundColor = selected ? data.color : "";
+                this._tab && (this._tab.style.backgroundColor = selected ? data.color : "");
             }
         );
     }
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index d27ca7c3a..f1df7998b 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -25,34 +25,30 @@ export default class MarqueeOptionsMenu extends AntimodeMenu {
 
     render() {
         const buttons = [
-            <Tooltip title={<><div className="dash-tooltip">Create a Collection</div></>} placement="bottom">
+            <Tooltip key="group" title={<><div className="dash-tooltip">Create a Collection</div></>} placement="bottom">
                 <button
                     className="antimodeMenu-button"
-                    key="group"
                     onPointerDown={this.createCollection}>
                     <FontAwesomeIcon icon="object-group" size="lg" />
                 </button>
             </Tooltip>,
-            <Tooltip title={<><div className="dash-tooltip">Summarize Documents</div></>} placement="bottom">
+            <Tooltip key="summarize" title={<><div className="dash-tooltip">Summarize Documents</div></>} placement="bottom">
                 <button
                     className="antimodeMenu-button"
-                    key="summarize"
                     onPointerDown={this.summarize}>
                     <FontAwesomeIcon icon="compress-arrows-alt" size="lg" />
                 </button>
             </Tooltip>,
-            <Tooltip title={<><div className="dash-tooltip">Delete Documents</div></>} placement="bottom">
+            <Tooltip key="delete" title={<><div className="dash-tooltip">Delete Documents</div></>} placement="bottom">
                 <button
                     className="antimodeMenu-button"
-                    key="delete"
                     onPointerDown={this.delete}>
                     <FontAwesomeIcon icon="trash-alt" size="lg" />
                 </button>
             </Tooltip>,
-            <Tooltip title={<><div className="dash-tooltip">Change to Text</div></>} placement="bottom">
+            <Tooltip key="inkToText" title={<><div className="dash-tooltip">Change to Text</div></>} placement="bottom">
                 <button
                     className="antimodeMenu-button"
-                    key="inkToText"
                     onPointerDown={this.inkToText}>
                     <FontAwesomeIcon icon="font" size="lg" />
                 </button>
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index b7af4683e..849fc4076 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -83,6 +83,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
     @computed get isPres(): boolean {
         if (this.selectedDoc?.type === DocumentType.PRES) {
+            document.removeEventListener("keydown", this.keyEvents, true);
             document.addEventListener("keydown", this.keyEvents, true);
             return true;
         } else {
@@ -91,6 +92,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
     @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
+    componentWillUnmount() {
+        document.removeEventListener("keydown", this.keyEvents, true);
+    }
 
     componentDidMount() {
         this.rootDoc.presBox = this.rootDoc;
@@ -517,29 +521,41 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     // Key for when the presentaiton is active (according to Selection Manager)
     @action
     keyEvents = (e: KeyboardEvent) => {
-        e.stopPropagation();
-        e.preventDefault();
-
+        let handled = false;
+        const anchorNode = document.activeElement as HTMLDivElement;
+        if (anchorNode && anchorNode.className?.includes("lm_title")) return;
         if (e.keyCode === 27) { // Escape key
             if (this.layoutDoc.presStatus === "edit") this._selectedArray = [];
             else this.layoutDoc.presStatus = "edit";
+            handled = true;
         } if ((e.metaKey || e.altKey) && e.keyCode === 65) { // Ctrl-A to select all
-            if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs;
+            if (this.layoutDoc.presStatus === "edit") {
+                this._selectedArray = this.childDocs;
+                handled = true;
+            }
         } if (e.keyCode === 37 || e.keyCode === 38) { // left(37) / a(65) / up(38) to go back
             this.back();
+            handled = true;
         } if (e.keyCode === 39 || e.keyCode === 40) { // right (39) / d(68) / down(40) to go to next
             this.next();
+            handled = true;
         } if (e.keyCode === 32) { // spacebar to 'present' or autoplay
             if (this.layoutDoc.presStatus !== "edit") this.startAutoPres(0);
             else this.layoutDoc.presStatus = "manual";
+            handled = true;
         }
         if (e.keyCode === 8) { // delete selected items
             if (this.layoutDoc.presStatus === "edit") {
                 this._selectedArray.forEach((doc, i) => {
                     this.removeDocument(doc);
                 });
+                handled = true;
             }
         }
+        if (handled) {
+            e.stopPropagation();
+            e.preventDefault();
+        }
     }
 
     /**
-- 
cgit v1.2.3-70-g09d2

