From 2583d4cd4b8a5f8b3acc3c0e0970adf295d4d8c5 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Thu, 13 Aug 2020 14:50:06 +0530
Subject: location of mainviewnotifs notification bubble should be fixed +
 Anika's defaultaclprivate fix

---
 src/client/views/MainViewNotifs.tsx | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

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

diff --git a/src/client/views/MainViewNotifs.tsx b/src/client/views/MainViewNotifs.tsx
index 89006ebc8..c0cd7b3a7 100644
--- a/src/client/views/MainViewNotifs.tsx
+++ b/src/client/views/MainViewNotifs.tsx
@@ -8,6 +8,7 @@ import { DragManager } from '../util/DragManager';
 import "./MainViewNotifs.scss";
 import { MainView } from './MainView';
 import { NumCast } from '../../fields/Types';
+import { Id } from '../../fields/FieldSymbols';
 
 
 @observer
@@ -28,7 +29,14 @@ export class MainViewNotifs extends React.Component {
 
     render() {
         const length = MainViewNotifs.NotifsCol ? DocListCast(MainViewNotifs.NotifsCol.data).length : 0;
-        return <div className="mainNotifs-container" style={{ width: 15, height: 15, top: 12 + NumCast(MainViewNotifs.NotifsCol?.position) * 60 }} ref={this._notifsRef}>
+        const menuStack = Doc.UserDoc().menuStack as Doc;
+        const menuButtons = DocListCast(menuStack.data);
+        let top = 12 - NumCast(menuStack._scrollTop);
+        for (const button of menuButtons) {
+            if (button[Id] !== menuStack.sharingButtonId) top += NumCast(button._height);
+            else break;
+        }
+        return <div className="mainNotifs-container" style={{ width: 15, height: 15, top }} ref={this._notifsRef}>
             <button className="mainNotifs-badge" style={length > 0 ? { "display": "initial" } : { "display": "none" }}
                 onPointerDown={this.onPointerDown} >
                 {length}
-- 
cgit v1.2.3-70-g09d2


From 7d4867438fa2aa55a58184649f4e5042a68a3fd9 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 13 Aug 2020 09:08:04 -0400
Subject: got rid of mainviewnotifs in favor of having badges for any
 fonticonbox

---
 src/client/documents/Documents.ts                  |  1 +
 src/client/util/CurrentUserUtils.ts                | 15 +++----
 src/client/views/MainView.tsx                      |  7 +---
 src/client/views/MainViewNotifs.scss               | 20 ----------
 src/client/views/MainViewNotifs.tsx                | 46 ----------------------
 .../views/collections/CollectionStackingView.tsx   |  3 --
 src/client/views/nodes/DocumentView.tsx            |  6 +--
 src/client/views/nodes/FontIconBox.scss            | 21 ++++++++++
 src/client/views/nodes/FontIconBox.tsx             | 39 ++++++++++++++++--
 9 files changed, 66 insertions(+), 92 deletions(-)
 delete mode 100644 src/client/views/MainViewNotifs.scss
 delete mode 100644 src/client/views/MainViewNotifs.tsx

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 5e83645ec..fe50ed0b3 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -112,6 +112,7 @@ export interface DocumentOptions {
     _columnsHideIfEmpty?: boolean; // whether stacking view column headings should be hidden
     isTemplateForField?: string; // the field key for which the containing document is a rendering template
     isTemplateDoc?: boolean;
+    watchedDocuments?: Doc; // list of documents to "watch" in an icon doc to display a badge
     targetScriptKey?: string; // where to write a template script (used by collections with click templates which need to target onClick, onDoubleClick, etc)
     templates?: List<string>;
     hero?: ImageField; // primary image that best represents a compound document (e.g., for a buxton device document that has multiple images)
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index f3c405a1a..605bec2e8 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -503,11 +503,12 @@ export class CurrentUserUtils {
         return doc.myItemCreators as Doc;
     }
 
-    static menuBtnDescriptions(): {
-        title: string, icon: string, click: string,
+    static menuBtnDescriptions(doc: Doc): {
+        title: string, icon: string, click: string, watchedDocuments?: Doc
     }[] {
+        this.setupSharingSidebar(doc);  // sets up the right sidebar collection for mobile upload documents and sharing
         return [
-            { title: "Sharing", icon: "users", click: 'scriptContext.selectMenu(self, "Sharing")' },
+            { title: "Sharing", icon: "users", click: 'scriptContext.selectMenu(self, "Sharing")', watchedDocuments: doc["sidebar-sharing"] as Doc },
             { title: "Workspace", icon: "desktop", click: 'scriptContext.selectMenu(self, "Workspace")' },
             { title: "Catalog", icon: "file", click: 'scriptContext.selectMenu(self, "Catalog")' },
             { title: "Archive", icon: "archive", click: 'scriptContext.selectMenu(self, "Archive")' },
@@ -529,7 +530,7 @@ export class CurrentUserUtils {
     }
     static setupMenuPanel(doc: Doc) {
         if (doc.menuStack === undefined) {
-            const menuBtns = CurrentUserUtils.menuBtnDescriptions().map(({ title, icon, click }) =>
+            const menuBtns = CurrentUserUtils.menuBtnDescriptions(doc).map(({ title, icon, click, watchedDocuments }) =>
                 Docs.Create.FontIconDocument({
                     icon,
                     iconShape: "square",
@@ -539,6 +540,7 @@ export class CurrentUserUtils {
                     childDropAction: "same",
                     _width: 60,
                     _height: 60,
+                    watchedDocuments,
                     onClick: ScriptField.MakeScript(click, { scriptContext: "any" }), system: true
                 }));
             const userDoc = menuBtns[menuBtns.length - 1];
@@ -553,10 +555,6 @@ export class CurrentUserUtils {
                 _yMargin: 0,
                 _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, lockedPosition: true, _chromeStatus: "disabled", system: true
             }));
-
-            PromiseValue(Cast(doc.menuStack, Doc)).then(stack => {
-                stack && !stack.sharingButtonId && (stack.sharingButtonId = menuBtns.find(button => button.title === "Sharing")![Id]);
-            });
         }
         // this resets all sidebar buttons to being deactivated
         PromiseValue(Cast(doc.menuStack, Doc)).then(stack => {
@@ -937,7 +935,6 @@ export class CurrentUserUtils {
         Utils.DRAG_THRESHOLD = NumCast(doc["constants-dragThreshold"]);
         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.setupSharingSidebar(doc);  // sets up the right sidebar collection for mobile upload documents and sharing
         this.setupImportSidebar(doc);
         this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
         this.setupMenuPanel(doc);
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index be8807336..9fae3996e 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -310,11 +310,7 @@ export class MainView extends React.Component {
                 DocServer.Control.makeEditable();
             }
         }
-        // if there is a pending doc, and it has new data, show it (syip: we use a timeout to prevent collection docking view from being uninitialized)
-        setTimeout(async () => {
-            const col = this.userDoc && await Cast(this.userDoc["sidebar-sharing"], Doc);
-            col && Cast(col.data, listSpec(Doc)) && runInAction(() => MainViewNotifs.NotifsCol = col);
-        }, 100);
+
         return true;
     }
 
@@ -612,7 +608,6 @@ export class MainView extends React.Component {
                     </div>
                 </div>
                 {this.dockingContent}
-                <MainViewNotifs />
                 {this.showProperties ? (null) :
                     <div className="mainView-propertiesDragger" title="Properties View Dragger" onPointerDown={this.onPropertiesPointerDown}
                         style={{ right: rightFlyout, top: "50%" }}>
diff --git a/src/client/views/MainViewNotifs.scss b/src/client/views/MainViewNotifs.scss
deleted file mode 100644
index 92d7d6ee3..000000000
--- a/src/client/views/MainViewNotifs.scss
+++ /dev/null
@@ -1,20 +0,0 @@
-.mainNotifs-container {
-    position:absolute;
-    z-index: 1000;
-    top: 12px;
-
-    .mainNotifs-badge {
-        position: absolute;
-        top: -10px;
-        right: -10px;
-        color: white;
-        background: #f44b42;
-        font-weight: 300;
-        border-radius: 100%;
-        width: 25px;
-        height: 25px;
-        text-align: center;
-        padding-top: 4px;
-        font-size: 12px;
-    }
-}
\ No newline at end of file
diff --git a/src/client/views/MainViewNotifs.tsx b/src/client/views/MainViewNotifs.tsx
deleted file mode 100644
index c0cd7b3a7..000000000
--- a/src/client/views/MainViewNotifs.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { observable } from 'mobx';
-import { observer } from 'mobx-react';
-import "normalize.css";
-import * as React from 'react';
-import { Doc, DocListCast, Opt } from '../../fields/Doc';
-import { returnFalse, setupMoveUpEvents } from '../../Utils';
-import { DragManager } from '../util/DragManager';
-import "./MainViewNotifs.scss";
-import { MainView } from './MainView';
-import { NumCast } from '../../fields/Types';
-import { Id } from '../../fields/FieldSymbols';
-
-
-@observer
-export class MainViewNotifs extends React.Component {
-    @observable static NotifsCol: Opt<Doc>;
-    _notifsRef = React.createRef<HTMLDivElement>();
-
-    onPointerDown = (e: React.PointerEvent) => {
-        setupMoveUpEvents(this, e,
-            (e: PointerEvent) => {
-                const dragData = new DragManager.DocumentDragData([MainViewNotifs.NotifsCol!]);
-                DragManager.StartDocumentDrag([this._notifsRef.current!], dragData, e.x, e.y);
-                return true;
-            },
-            returnFalse,
-            () => MainViewNotifs.NotifsCol && MainView.Instance.selectMenu(MainViewNotifs.NotifsCol, "Sharing"));
-    }
-
-    render() {
-        const length = MainViewNotifs.NotifsCol ? DocListCast(MainViewNotifs.NotifsCol.data).length : 0;
-        const menuStack = Doc.UserDoc().menuStack as Doc;
-        const menuButtons = DocListCast(menuStack.data);
-        let top = 12 - NumCast(menuStack._scrollTop);
-        for (const button of menuButtons) {
-            if (button[Id] !== menuStack.sharingButtonId) top += NumCast(button._height);
-            else break;
-        }
-        return <div className="mainNotifs-container" style={{ width: 15, height: 15, top }} ref={this._notifsRef}>
-            <button className="mainNotifs-badge" style={length > 0 ? { "display": "initial" } : { "display": "none" }}
-                onPointerDown={this.onPointerDown} >
-                {length}
-            </button>
-        </div>;
-    }
-}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index e479fa639..2b7ae4338 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -149,8 +149,6 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
             () => this.pivotField,
             () => this.layoutDoc._columnHeaders = new List()
         );
-
-        this.props.Document._scrollTop = 0;
     }
     componentWillUnmount() {
         super.componentWillUnmount();
@@ -494,7 +492,6 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
                     onScroll={action(e => {
                         if (!this.props.isSelected() && this.props.renderDepth) e.currentTarget.scrollTop = this._scroll;
                         else this._scroll = e.currentTarget.scrollTop;
-                        this.props.Document._scrollTop = this._scroll; // used by MainViewNotifs to determine position of the notification bubble
                     })}
                     onDrop={this.onExternalDrop.bind(this)}
                     onContextMenu={this.onContextMenu}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a1c934e81..820ee2752 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -6,15 +6,13 @@ import { Document } from '../../../fields/documentSchemas';
 import { Id } from '../../../fields/FieldSymbols';
 import { InkTool } from '../../../fields/InkField';
 import { listSpec } from "../../../fields/Schema";
-import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
 import { ScriptField } from '../../../fields/ScriptField';
 import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
 import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
 import { MobileInterface } from '../../../mobile/MobileInterface';
 import { GestureUtils } from '../../../pen-gestures/GestureUtils';
-import { emptyFunction, emptyPath, OmitKeys, returnOne, returnTransparent, Utils } from "../../../Utils";
+import { emptyFunction, OmitKeys, returnOne, returnTransparent, Utils } from "../../../Utils";
 import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
-import { ClientRecommender } from '../../ClientRecommender';
 import { Docs, DocUtils } from "../../documents/Documents";
 import { DocumentType } from '../../documents/DocumentTypes';
 import { DocumentManager } from "../../util/DocumentManager";
@@ -22,7 +20,6 @@ import { DragManager, dropActionType } from "../../util/DragManager";
 import { InteractionUtils } from '../../util/InteractionUtils';
 import { LinkManager } from '../../util/LinkManager';
 import { Scripting } from '../../util/Scripting';
-import { SearchUtil } from '../../util/SearchUtil';
 import { SelectionManager } from "../../util/SelectionManager";
 import SharingManager from '../../util/SharingManager';
 import { SnappingManager } from '../../util/SnappingManager';
@@ -33,7 +30,6 @@ import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from '../ContextMenuItem';
 import { DocComponent } from "../DocComponent";
 import { EditableView } from '../EditableView';
-import { KeyphraseQueryView } from '../KeyphraseQueryView';
 import { DocumentContentsView } from "./DocumentContentsView";
 import { DocumentLinksButton } from './DocumentLinksButton';
 import "./DocumentView.scss";
diff --git a/src/client/views/nodes/FontIconBox.scss b/src/client/views/nodes/FontIconBox.scss
index 6a540269e..75bc90d7a 100644
--- a/src/client/views/nodes/FontIconBox.scss
+++ b/src/client/views/nodes/FontIconBox.scss
@@ -13,6 +13,27 @@
     width: 100%;
 }
 
+.fontIconBadge-container {
+    position:absolute;
+    z-index: 1000;
+    top: 12px;
+
+    .fontIconBadge {
+        position: absolute;
+        top: -10px;
+        right: -10px;
+        color: white;
+        background: #f44b42;
+        font-weight: 300;
+        border-radius: 100%;
+        width: 25px;
+        height: 25px;
+        text-align: center;
+        padding-top: 4px;
+        font-size: 12px;
+    }
+}
+
 .menuButton-round {
     border-radius: 100%;
     background-color: black;
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index 168d640e9..fa21a8594 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -5,13 +5,15 @@ import { createSchema, makeInterface } from '../../../fields/Schema';
 import { DocComponent } from '../DocComponent';
 import './FontIconBox.scss';
 import { FieldView, FieldViewProps } from './FieldView';
-import { StrCast, Cast } from '../../../fields/Types';
-import { Utils } from "../../../Utils";
+import { StrCast, Cast, ScriptCast } from '../../../fields/Types';
+import { Utils, setupMoveUpEvents, returnFalse, emptyFunction } from "../../../Utils";
 import { runInAction, observable, reaction, IReactionDisposer } from 'mobx';
-import { Doc } from '../../../fields/Doc';
+import { Doc, DocListCast } from '../../../fields/Doc';
 import { ContextMenu } from '../ContextMenu';
 import { ScriptField } from '../../../fields/ScriptField';
 import { Tooltip } from '@material-ui/core';
+import { MainViewNotifs } from '../MainViewNotifs';
+import { DragManager } from '../../util/DragManager';
 const FontIconSchema = createSchema({
     icon: "string",
 });
@@ -73,6 +75,7 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
                 {<FontAwesomeIcon className={`menuButton-icon-${shape}`} icon={StrCast(this.dataDoc.icon, "user") as any} color={color}
                     size={this.layoutDoc.iconShape === "square" ? "sm" : "lg"} />}
                 {!label ? (null) : <div className="fontIconBox-label" style={{ color, backgroundColor }}> {label} </div>}
+                {this.props.Document.watchedDocuments ? <FontIconBadge collection={Cast(this.props.Document.watchedDocuments, Doc, null)} /> : (null)}
             </div>
         </button>;
         return !this.layoutDoc.toolTip ? button :
@@ -80,4 +83,34 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
                 {button}
             </Tooltip>;
     }
+}
+
+interface FontIconBadgeProps {
+    collection: Doc;
+}
+
+@observer
+export class FontIconBadge extends React.Component<FontIconBadgeProps> {
+    _notifsRef = React.createRef<HTMLDivElement>();
+
+    onPointerDown = (e: React.PointerEvent) => {
+        setupMoveUpEvents(this, e,
+            (e: PointerEvent) => {
+                const dragData = new DragManager.DocumentDragData([this.props.collection]);
+                DragManager.StartDocumentDrag([this._notifsRef.current!], dragData, e.x, e.y);
+                return true;
+            },
+            returnFalse, emptyFunction, false);
+    }
+
+    render() {
+        if (!(this.props.collection instanceof Doc)) return (null);
+        const length = DocListCast(this.props.collection.data).length;
+        return <div className="fontIconBadge-container" style={{ width: 15, height: 15, top: 12 }} ref={this._notifsRef}>
+            <div className="fontIconBadge" style={length > 0 ? { "display": "initial" } : { "display": "none" }}
+                onPointerDown={this.onPointerDown} >
+                {length}
+            </div>
+        </div>;
+    }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2

