From 3c44131f75fe0c311363b36e824604c91f1babc8 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 1 Oct 2020 11:15:41 -0400
Subject: fixed closed library flyout view to not render a DocumentView.  fixed
 sidebar panels to not be selectable.  fixed changing view of sidebar panel to
 only affect that panel

---
 src/client/views/collections/CollectionMenu.tsx | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 51d1d5559..e9cb57fed 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -234,8 +234,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
 
     @undoBatch
     viewChanged = (e: React.ChangeEvent) => {
+        const target = this.document !== Doc.UserDoc().sidebar ? this.document : this.document.proto as Doc;
         //@ts-ignore
-        this.document._viewType = e.target.selectedOptions[0].value;
+        target._viewType = e.target.selectedOptions[0].value;
     }
 
     commandChanged = (e: React.ChangeEvent) => {
-- 
cgit v1.2.3-70-g09d2


From 3c7f85dbcddca0ffacd82c2d39e88bba8c4b3f3a Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 1 Oct 2020 23:04:31 -0400
Subject: various fixes to new sharing / email normalization

---
 src/client/documents/Documents.ts                  | 12 ++++-----
 src/client/util/CurrentUserUtils.ts                |  9 ++++---
 src/client/util/GroupManager.tsx                   |  2 +-
 src/client/util/SharingManager.tsx                 | 31 +++++++++++-----------
 src/client/views/DocComponent.tsx                  |  4 +--
 src/client/views/PropertiesView.tsx                | 11 ++------
 src/client/views/collections/CollectionMenu.tsx    |  4 +--
 src/client/views/collections/CollectionView.tsx    |  4 +--
 .../views/nodes/formattedText/RichTextRules.ts     |  8 +++---
 9 files changed, 40 insertions(+), 45 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 47fa7067d..7ee8267f8 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -574,7 +574,7 @@ export namespace Docs {
          * only when creating a DockDocument from the current user's already existing
          * main document.
          */
-        export function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data") {
+        export function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string) {
             const { omit: protoProps, extract: delegateProps } = OmitKeys(options, delegateKeys, "^_");
 
             protoProps.system = delegateProps.system;
@@ -590,7 +590,7 @@ export namespace Docs {
 
             protoProps.isPrototype = true;
 
-            const dataDoc = MakeDataDelegate(proto, protoProps, data, fieldKey);
+            const dataDoc = MakeDataDelegate(proto, protoProps, data, fieldKey, protoId);
             const viewDoc = Doc.MakeDelegate(dataDoc, delegId);
 
             // so that the list of annotations is already initialised, prevents issues in addonly.
@@ -620,8 +620,8 @@ export namespace Docs {
          * @param options initial values to apply to this new delegate
          * @param value the data to store in this new delegate
          */
-        function MakeDataDelegate<D extends Field>(proto: Doc, options: DocumentOptions, value?: D, fieldKey: string = "data") {
-            const deleg = Doc.MakeDelegate(proto);
+        function MakeDataDelegate<D extends Field>(proto: Doc, options: DocumentOptions, value?: D, fieldKey: string = "data", id: string | undefined = undefined) {
+            const deleg = Doc.MakeDelegate(proto, id);
             if (value !== undefined) {
                 deleg[fieldKey] = value;
             }
@@ -807,8 +807,8 @@ export namespace Docs {
             return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", dontRegisterChildViews: true, ...options, _viewType: CollectionViewType.Tree }, id);
         }
 
-        export function StackingDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Stacking }, id);
+        export function StackingDocument(documents: Array<Doc>, options: DocumentOptions, id?: string, protoId?: string) {
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Stacking }, id, undefined, protoId);
         }
 
         export function MulticolumnDocument(documents: Array<Doc>, options: DocumentOptions) {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index cff07d48e..ec550c15a 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -30,6 +30,7 @@ import { Scripting } from "./Scripting";
 import { SearchUtil } from "./SearchUtil";
 import { SelectionManager } from "./SelectionManager";
 import { UndoManager } from "./UndoManager";
+import { SharingPermissions } from "../../fields/util";
 
 
 const headerViewVersion = "0.1";
@@ -874,11 +875,13 @@ export class CurrentUserUtils {
     // Sharing sidebar is where shared documents are contained
     static async setupSharingSidebar(doc: Doc, sharingDocumentId: string) {
         if (doc.mySharedDocs === undefined) {
-            let sharedDocs = await DocServer.GetRefField(sharingDocumentId);
+            let sharedDocs = await DocServer.GetRefField(sharingDocumentId + "outer");
             if (!sharedDocs) {
                 sharedDocs = Docs.Create.StackingDocument([], {
-                    title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "none", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, _showTitle: "title", ignoreClick: true, lockedPosition: true
-                }, sharingDocumentId);
+                    title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "none", childLimitHeight: 0, _yMargin: 50, _gridGap: 15,
+                    _showTitle: "title", ignoreClick: true, lockedPosition: true,
+                }, sharingDocumentId + "outer", sharingDocumentId);
+                (sharedDocs as Doc)["acl-Public"] = Doc.GetProto(sharedDocs as Doc)["acl-Public"] = SharingPermissions.Add;
             }
             if (sharedDocs instanceof Doc) {
                 sharedDocs.userColor = sharedDocs.userColor || "#12121233";
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 70ea48ab8..e81c95d83 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -66,7 +66,7 @@ export class GroupManager extends React.Component<{}> {
             const evaluating = raw.map(async user => {
                 const userSharingDocument = await DocServer.GetRefField(user.sharingDocumentId);
                 if (userSharingDocument instanceof Doc) {
-                    const notificationDoc = await Cast(userSharingDocument.mySharedDocs, Doc, null);
+                    const notificationDoc = await Cast(userSharingDocument.data, Doc, null);
                     runInAction(() => notificationDoc && this.users.push(user.email));
                 }
             });
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 0cf6cc87c..c67ec2db5 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -47,7 +47,7 @@ const groupType = "!groupType/";
 const storage = "data";
 
 /**
- * A user who also has a notificationDoc.
+ * A user who also has a sharing doc.
  */
 interface ValidatedUser {
     user: User;         // database minimal info to identify / communicate with a user (email, sharing doc id)
@@ -59,7 +59,7 @@ interface ValidatedUser {
 export class SharingManager extends React.Component<{}> {
     public static Instance: SharingManager;
     @observable private isOpen = false; // whether the SharingManager modal is open or not
-    @observable public users: ValidatedUser[] = []; // the list of users with notificationDocs
+    @observable public users: ValidatedUser[] = []; // the list of users with sharing docs
     @observable private targetDoc: Doc | undefined; // the document being shared
     @observable private targetDocView: DocumentView | undefined; // the DocumentView of the document being shared
     // @observable private copied = false;
@@ -163,9 +163,9 @@ export class SharingManager extends React.Component<{}> {
                 // if documents have been shared, add the doc to that list if it doesn't already exist, otherwise create a new list with the doc
                 group.docsShared ? Doc.IndexOf(doc, DocListCast(group.docsShared)) === -1 && (group.docsShared as List<Doc>).push(doc) : group.docsShared = new List<Doc>([doc]);
 
-                users.forEach(({ user, sharingDoc: notificationDoc }) => {
-                    if (permission !== SharingPermissions.None) Doc.IndexOf(doc, DocListCast(notificationDoc[storage])) === -1 && Doc.AddDocToList(notificationDoc, storage, doc); // add the doc to the notificationDoc if it hasn't already been added
-                    else GetEffectiveAcl(doc, undefined, user.email) === AclPrivate && Doc.IndexOf((doc.aliasOf as Doc || doc), DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, (doc.aliasOf as Doc || doc)); // remove the doc from the list if it already exists
+                users.forEach(({ user, sharingDoc }) => {
+                    if (permission !== SharingPermissions.None) Doc.IndexOf(doc, DocListCast(sharingDoc[storage])) === -1 && Doc.AddDocToList(sharingDoc, storage, doc); // add the doc to the sharingDoc if it hasn't already been added
+                    else GetEffectiveAcl(doc, undefined, user.email) === AclPrivate && Doc.IndexOf((doc.aliasOf as Doc || doc), DocListCast(sharingDoc[storage])) !== -1 && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); // remove the doc from the list if it already exists
                 });
             }
         });
@@ -228,7 +228,7 @@ export class SharingManager extends React.Component<{}> {
                 const members: string[] = JSON.parse(StrCast(group.members));
                 const users: ValidatedUser[] = this.users.filter(({ user: { email } }) => members.includes(email));
 
-                users.forEach(({ sharingDoc: notificationDoc }) => Doc.RemoveDocFromList(notificationDoc, storage, doc));
+                users.forEach(({ sharingDoc }) => Doc.RemoveDocFromList(sharingDoc, storage, doc));
             });
         }
     }
@@ -237,19 +237,18 @@ export class SharingManager extends React.Component<{}> {
      * Shares the document with a user.
      */
     setInternalSharing = (recipient: ValidatedUser, permission: string, targetDoc?: Doc) => {
-        const { user, sharingDoc: notificationDoc } = recipient;
+        const { user, sharingDoc } = recipient;
         const target = targetDoc || this.targetDoc!;
-        const key = normalizeEmail(user.email);
-        const acl = `acl-${key}`;
+        const acl = `acl-${normalizeEmail(user.email)}`;
+        const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`;
 
         const docs = SelectionManager.SelectedDocuments().length < 2 ? [target] : SelectionManager.SelectedDocuments().map(docView => docView.props.Document);
-
         docs.forEach(doc => {
-            doc.author === Doc.CurrentUserEmail && !doc[`acl-${Doc.CurrentUserEmailNormalized}`] && distributeAcls(`acl-${Doc.CurrentUserEmailNormalized}`, SharingPermissions.Admin, doc);
+            doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc);
             distributeAcls(acl, permission as SharingPermissions, doc);
 
-            if (permission !== SharingPermissions.None) Doc.IndexOf(doc, DocListCast(notificationDoc[storage])) === -1 && Doc.AddDocToList(notificationDoc, storage, doc);
-            else GetEffectiveAcl(doc, undefined, user.email) === AclPrivate && Doc.IndexOf((doc.aliasOf as Doc || doc), DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, (doc.aliasOf as Doc || doc));
+            if (permission !== SharingPermissions.None) Doc.IndexOf(doc, DocListCast(sharingDoc[storage])) === -1 && Doc.AddDocToList(sharingDoc, storage, doc);
+            else GetEffectiveAcl(doc, undefined, user.email) === AclPrivate && Doc.IndexOf((doc.aliasOf as Doc || doc), DocListCast(sharingDoc[storage])) !== -1 && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc));
         });
     }
 
@@ -449,7 +448,7 @@ export class SharingManager extends React.Component<{}> {
         const commonKeys = intersection(...docs.map(doc => this.layoutDocAcls ? doc?.[AclSym] && Object.keys(doc[AclSym]) : doc?.[DataSym]?.[AclSym] && Object.keys(doc[DataSym][AclSym])));
 
         // the list of users shared with
-        const userListContents: (JSX.Element | null)[] = users.filter(({ user }) => docs.length > 1 ? commonKeys.includes(`acl-${normalizeEmail(user.email)}`) : docs[0]?.author !== user.email).map(({ user, sharingDoc: notificationDoc, userColor }) => {
+        const userListContents: (JSX.Element | null)[] = users.filter(({ user }) => docs.length > 1 ? commonKeys.includes(`acl-${normalizeEmail(user.email)}`) : docs[0]?.author !== user.email).map(({ user, sharingDoc, userColor }) => {
             const userKey = `acl-${normalizeEmail(user.email)}`;
             const uniform = docs.every(doc => this.layoutDocAcls ? doc?.[AclSym]?.[userKey] === docs[0]?.[AclSym]?.[userKey] : doc?.[DataSym]?.[AclSym]?.[userKey] === docs[0]?.[DataSym]?.[AclSym]?.[userKey]);
             const permissions = uniform ? StrCast(targetDoc?.[userKey]) : "-multiple-";
@@ -465,7 +464,7 @@ export class SharingManager extends React.Component<{}> {
                             <select
                                 className={"permissions-dropdown"}
                                 value={permissions}
-                                onChange={e => this.setInternalSharing({ user, sharingDoc: notificationDoc, userColor }, e.currentTarget.value)}
+                                onChange={e => this.setInternalSharing({ user, sharingDoc: sharingDoc, userColor }, e.currentTarget.value)}
                             >
                                 {this.sharingOptions(uniform)}
                             </select>
@@ -516,7 +515,7 @@ export class SharingManager extends React.Component<{}> {
 
 
         // the list of groups shared with
-        const groupListMap: (Doc | { groupName: string })[] = groups.filter(({ groupName }) => docs.length > 1 ? commonKeys.includes(`acl-${StrCast(groupName).replace('.', '_')}`) : true);
+        const groupListMap: (Doc | { groupName: string })[] = groups.filter(({ groupName }) => docs.length > 1 ? commonKeys.includes(`acl-${normalizeEmail(StrCast(groupName))}`) : true);
         groupListMap.unshift({ groupName: "Public" }, { groupName: "Override" });
         const groupListContents = groupListMap.map(group => {
             const groupKey = `acl-${StrCast(group.groupName)}`;
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 893b74d75..b3fbe418b 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -7,7 +7,7 @@ import { InteractionUtils } from '../util/InteractionUtils';
 import { List } from '../../fields/List';
 import { DateField } from '../../fields/DateField';
 import { ScriptField } from '../../fields/ScriptField';
-import { GetEffectiveAcl, SharingPermissions, distributeAcls } from '../../fields/util';
+import { GetEffectiveAcl, SharingPermissions, distributeAcls, denormalizeEmail } from '../../fields/util';
 
 
 ///  DocComponent returns a generic React base class used by views that don't have 'fieldKey' props (e.g.,CollectionFreeFormDocumentView, DocumentView)
@@ -166,7 +166,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
                     if (this.props.Document[AclSym]) {
                         added.forEach(d => {
                             for (const [key, value] of Object.entries(this.props.Document[AclSym])) {
-                                if (d.author === key.substring(4).replace("_", ".") && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true);
+                                if (d.author === denormalizeEmail(key.substring(4)) && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true);
                                 //else if (this.props.Document[key] === SharingPermissions.Admin) distributeAcls(key, SharingPermissions.Add, d, true);
                                 // else distributeAcls(key, this.AclMap.get(value) as SharingPermissions, d, true);
                             }
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index b30691ff5..f3241e8d9 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -10,7 +10,7 @@ import { Id } from "../../fields/FieldSymbols";
 import { InkField } from "../../fields/InkField";
 import { ComputedField } from "../../fields/ScriptField";
 import { Cast, NumCast, StrCast } from "../../fields/Types";
-import { GetEffectiveAcl, SharingPermissions } from "../../fields/util";
+import { GetEffectiveAcl, SharingPermissions, denormalizeEmail } from "../../fields/util";
 import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne } from "../../Utils";
 import { DocumentType } from "../documents/DocumentTypes";
 import { DocumentManager } from "../util/DocumentManager";
@@ -409,7 +409,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         // DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => {
         if (commonKeys.length) {
             for (const key of commonKeys) {
-                const name = key.substring(4).replace("_", ".");
+                const name = denormalizeEmail(key.substring(4));
                 const uniform = docs.every(doc => this.layoutDocAcls ? doc?.[AclSym]?.[key] === docs[0]?.[AclSym]?.[key] : doc?.[DataSym]?.[AclSym]?.[key] === docs[0]?.[DataSym]?.[AclSym]?.[key]);
                 if (name !== Doc.CurrentUserEmail && name !== target.author && name !== "Public" && name !== "Override"/* && sidebarUsersDisplayed![name] !== false*/) {
                     tableEntries.push(this.sharingItem(name, showAdmin, uniform ? AclMap.get(this.layoutDocAcls ? target[AclSym][key] : target[DataSym][AclSym][key])! : "-multiple-"));
@@ -417,13 +417,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
             }
         }
 
-        //     if (Doc.UserDoc().sidebarUsersDisplayed) {
-        //         for (const [name, value] of Object.entries(sidebarUsersDisplayed!)) {
-        //             if (value === true && !this.selectedDoc![`acl-${name.substring(8).replace(".", "_")}`]) tableEntries.push(this.sharingItem(name.substring(8), effectiveAcl, SharingPermissions.None));
-        //         }
-        //     }
-        // })
-
         const ownerSame = Doc.CurrentUserEmail !== target.author && docs.filter(doc => doc).every(doc => doc.author === docs[0].author);
         // shifts the current user, owner, public to the top of the doc.
         tableEntries.unshift(this.sharingItem("Override", showAdmin, docs.filter(doc => doc).every(doc => doc["acl-Override"] === docs[0]["acl-Override"]) ? (AclMap.get(target[AclSym]?.["acl-Override"]) || "None") : "-multiple-"));
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index e9cb57fed..09ff3bb0c 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -894,14 +894,14 @@ export class CollectionStackingViewChrome extends React.Component<CollectionMenu
             if (docs instanceof Doc) {
                 const keys = Object.keys(docs).filter(key => key.indexOf("title") >= 0 || key.indexOf("author") >= 0 ||
                     key.indexOf("creationDate") >= 0 || key.indexOf("lastModified") >= 0 ||
-                    (key[0].toUpperCase() === key[0] && key.substring(0, 3) !== "acl" && key[0] !== "_"));
+                    (key[0].toUpperCase() === key[0] && key[0] !== "_"));
                 return keys.filter(key => key.toLowerCase().indexOf(val) > -1);
             } else {
                 const keys = new Set<string>();
                 docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
                 const noviceKeys = Array.from(keys).filter(key => key.indexOf("title") >= 0 || key.indexOf("author") >= 0 ||
                     key.indexOf("creationDate") >= 0 || key.indexOf("lastModified") >= 0 ||
-                    (key[0]?.toUpperCase() === key[0] && key.substring(0, 3) !== "acl" && key[0] !== "_"));
+                    (key[0]?.toUpperCase() === key[0] && key[0] !== "_"));
                 return noviceKeys.filter(key => key.toLowerCase().indexOf(val) > -1);
             }
         }
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 522f46280..2bdc8e2f3 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -10,7 +10,7 @@ import { List } from '../../../fields/List';
 import { ObjectField } from '../../../fields/ObjectField';
 import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types';
 import { ImageField } from '../../../fields/URLField';
-import { distributeAcls, GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util';
+import { distributeAcls, GetEffectiveAcl, SharingPermissions, TraceMobx, normalizeEmail, denormalizeEmail } from '../../../fields/util';
 import { returnFalse, Utils } from '../../../Utils';
 import { Docs, DocUtils } from '../../documents/Documents';
 import { DocumentType } from '../../documents/DocumentTypes';
@@ -143,7 +143,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                 if (this.props.Document[AclSym]) {
                     added.forEach(d => {
                         for (const [key, value] of Object.entries(this.props.Document[AclSym])) {
-                            if (d.author === key.substring(4).replace("_", ".") && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true);
+                            if (d.author === denormalizeEmail(key.substring(4)) && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true);
                             //else if (this.props.Document[key] === SharingPermissions.Admin) distributeAcls(key, SharingPermissions.Add, d, true);
                             //else distributeAcls(key, this.AclMap.get(value) as SharingPermissions, d, true);
                         }
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index 921c0e128..72b91c955 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -3,7 +3,8 @@ import { NodeSelection, TextSelection } from "prosemirror-state";
 import { DataSym, Doc } from "../../../../fields/Doc";
 import { Id } from "../../../../fields/FieldSymbols";
 import { ComputedField } from "../../../../fields/ScriptField";
-import { Cast, NumCast, StrCast } from "../../../../fields/Types";
+import { NumCast, StrCast } from "../../../../fields/Types";
+import { normalizeEmail } from "../../../../fields/util";
 import { returnFalse, Utils } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 import { Docs, DocUtils } from "../../../documents/Documents";
@@ -11,7 +12,6 @@ import { FormattedTextBox } from "./FormattedTextBox";
 import { wrappingInputRule } from "./prosemirrorPatches";
 import { RichTextMenu } from "./RichTextMenu";
 import { schema } from "./schema_rts";
-import { List } from "../../../../fields/List";
 
 export class RichTextRules {
     public Document: Doc;
@@ -271,7 +271,7 @@ export class RichTextRules {
                 (state, match, start, end) => {
                     const fieldKey = match[1];
                     const rawdocid = match[3]?.substring(1);
-                    const docid = rawdocid ? (!rawdocid.includes("@") ? Doc.CurrentUserEmail + "@" + rawdocid : rawdocid).replace(".", "_") : undefined;
+                    const docid = rawdocid ? (!rawdocid.includes("@") ? normalizeEmail(Doc.CurrentUserEmail) + "@" + rawdocid : rawdocid) : undefined;
                     const value = match[2]?.substring(1);
                     if (!fieldKey) {
                         const linkId = Utils.GenerateGuid();
@@ -304,7 +304,7 @@ export class RichTextRules {
                     const fieldKey = match[1] || "";
                     const fieldParam = match[2]?.replace("…", "...") || "";
                     const rawdocid = match[3]?.substring(1);
-                    const docid = rawdocid ? (!rawdocid.includes("@") ? Doc.CurrentUserEmail + "@" + rawdocid : rawdocid).replace(".", "_") : undefined;
+                    const docid = rawdocid ? (!rawdocid.includes("@") ? normalizeEmail(Doc.CurrentUserEmail) + "@" + rawdocid : rawdocid) : undefined;
                     if (!fieldKey && !docid) return state.tr;
                     docid && DocServer.GetRefField(docid).then(docx => {
                         if (!(docx instanceof Doc && docx)) {
-- 
cgit v1.2.3-70-g09d2

