diff options
author | bobzel <zzzman@gmail.com> | 2024-01-04 10:18:57 -0500 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2024-01-04 10:18:57 -0500 |
commit | ebf32ac65d35053f847fb2cf60f915eb29d6fdd5 (patch) | |
tree | aca380ddebb208b8114f75ba7cc07d24ab4158f6 | |
parent | d1b3d3d852e6b8eed7949b17f566a59d97a2dcf4 (diff) |
fixed text references to docs or fields to create docs that don't exist. fixed IsLinkFollowing observable by not making static (to fix docDecorations not appearing after link following)
-rw-r--r-- | src/client/util/LinkFollower.ts | 14 | ||||
-rw-r--r-- | src/client/util/SnappingManager.ts | 15 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 20 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/RichTextRules.ts | 11 | ||||
-rw-r--r-- | src/fields/Doc.ts | 6 |
5 files changed, 39 insertions, 27 deletions
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts index 146eed6c2..2df4d1ca8 100644 --- a/src/client/util/LinkFollower.ts +++ b/src/client/util/LinkFollower.ts @@ -10,6 +10,7 @@ import { LinkManager } from './LinkManager'; import { ScriptingGlobals } from './ScriptingGlobals'; import { SelectionManager } from './SelectionManager'; import { UndoManager } from './UndoManager'; +import { SnappingManager } from './SnappingManager'; /* * link doc: * - link_anchor_1: doc @@ -23,19 +24,18 @@ import { UndoManager } from './UndoManager'; * - user defined kvps */ export class LinkFollower { - @observable public static IsFollowing = false; // follows a link - if the target is on screen, it highlights/pans to it. // if the target isn't onscreen, then it will open up the target in the lightbox, or in place // depending on the followLinkLocation property of the source (or the link itself as a fallback); public static FollowLink = (linkDoc: Opt<Doc>, sourceDoc: Doc, altKey: boolean) => { const batch = UndoManager.StartBatch('Follow Link'); - runInAction(() => (LinkFollower.IsFollowing = true)); // turn off decoration bounds while following links since animations may occur, and DocDecorations is based on screenToLocal which is not always an observable value + runInAction(() => SnappingManager.SetIsLinkFollowing(true)); // turn off decoration bounds while following links since animations may occur, and DocDecorations is based on screenToLocal which is not always an observable value return LinkFollower.traverseLink( linkDoc, sourceDoc, action(() => { batch.end(); - Doc.AddUnHighlightWatcher(action(() => (LinkFollower.IsFollowing = false))); + Doc.AddUnHighlightWatcher(() => SnappingManager.SetIsLinkFollowing(false)); }), altKey ? true : undefined ); @@ -63,10 +63,10 @@ export class LinkFollower { sourceDoc === linkDoc.link_anchor_1 ? linkDoc.link_anchor_2 : sourceDoc === linkDoc.link_anchor_2 - ? linkDoc.link_anchor_1 - : Doc.AreProtosEqual(sourceDoc, linkDoc.link_anchor_1 as Doc) || Doc.AreProtosEqual((linkDoc.link_anchor_1 as Doc).annotationOn as Doc, sourceDoc) - ? linkDoc.link_anchor_2 - : linkDoc.link_anchor_1 + ? linkDoc.link_anchor_1 + : Doc.AreProtosEqual(sourceDoc, linkDoc.link_anchor_1 as Doc) || Doc.AreProtosEqual((linkDoc.link_anchor_1 as Doc).annotationOn as Doc, sourceDoc) + ? linkDoc.link_anchor_2 + : linkDoc.link_anchor_1 ) as Doc; const srcAnchor = LinkManager.getOppositeAnchor(linkDoc, target) ?? sourceDoc; if (target) { diff --git a/src/client/util/SnappingManager.ts b/src/client/util/SnappingManager.ts index c4d299fa1..40c3f76fb 100644 --- a/src/client/util/SnappingManager.ts +++ b/src/client/util/SnappingManager.ts @@ -9,6 +9,7 @@ export class SnappingManager { @observable _shiftKey = false; @observable _ctrlKey = false; + @observable _isLinkFollowing = false; @observable _isDragging: boolean = false; @observable _isResizing: Doc | undefined = undefined; @observable _canEmbed: boolean = false; @@ -31,14 +32,16 @@ export class SnappingManager { public static get VertSnapLines() { return this.Instance._vertSnapLines; } // prettier-ignore public static get ShiftKey() { return this.Instance._shiftKey; } // prettier-ignore public static get CtrlKey() { return this.Instance._ctrlKey; } // prettier-ignore + public static get IsLinkFollowing(){ return this.Instance._isLinkFollowing; } // prettier-ignore public static get IsDragging() { return this.Instance._isDragging; } // prettier-ignore public static get IsResizing() { return this.Instance._isResizing; } // prettier-ignore public static get CanEmbed() { return this.Instance._canEmbed; } // prettier-ignore public static get ExploreMode() { return this.Instance._exploreMode; } // prettier-ignore - public static SetShiftKey = (down: boolean) => runInAction(() => (this.Instance._shiftKey = down)); // prettier-ignore - public static SetCtrlKey = (down: boolean) => runInAction(() => (this.Instance._ctrlKey = down)); // prettier-ignore - public static SetIsDragging = (drag: boolean) => runInAction(() => (this.Instance._isDragging = drag)); // prettier-ignore - public static SetIsResizing = (doc: Opt<Doc>) => runInAction(() => (this.Instance._isResizing = doc)); // prettier-ignore - public static SetCanEmbed = (embed:boolean) => runInAction(() => (this.Instance._canEmbed = embed)); // prettier-ignore - public static SetExploreMode= (state:boolean) => runInAction(() => (this.Instance._exploreMode = state)); // prettier-ignore + public static SetShiftKey = (down: boolean) => runInAction(() => (this.Instance._shiftKey = down)); // prettier-ignore + public static SetCtrlKey = (down: boolean) => runInAction(() => (this.Instance._ctrlKey = down)); // prettier-ignore + public static SetIsLinkFollowing= (follow: boolean) => runInAction(() => (this.Instance._isLinkFollowing = follow)); // prettier-ignore + public static SetIsDragging = (drag: boolean) => runInAction(() => (this.Instance._isDragging = drag)); // prettier-ignore + public static SetIsResizing = (doc: Opt<Doc>) => runInAction(() => (this.Instance._isResizing = doc)); // prettier-ignore + public static SetCanEmbed = (embed:boolean) => runInAction(() => (this.Instance._canEmbed = embed)); // prettier-ignore + public static SetExploreMode = (state:boolean) => runInAction(() => (this.Instance._exploreMode = state)); // prettier-ignore } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index ced8799bf..788e78ed2 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -3,7 +3,9 @@ import { Tooltip } from '@mui/material'; import { IconButton } from 'browndash-components'; import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { FaUndo } from 'react-icons/fa'; +import { Utils, emptyFunction, lightOrDark, numberValue, returnFalse, setupMoveUpEvents } from '../../Utils'; import { DateField } from '../../fields/DateField'; import { Doc, DocListCast, Field, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc'; import { AclAdmin, AclAugment, AclEdit } from '../../fields/DocSymbols'; @@ -12,9 +14,8 @@ import { RichTextField } from '../../fields/RichTextField'; import { ScriptField } from '../../fields/ScriptField'; import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types'; import { GetEffectiveAcl } from '../../fields/util'; -import { emptyFunction, lightOrDark, numberValue, returnFalse, setupMoveUpEvents, Utils } from '../../Utils'; -import { Docs } from '../documents/Documents'; import { DocumentType } from '../documents/DocumentTypes'; +import { Docs } from '../documents/Documents'; import { DocumentManager } from '../util/DocumentManager'; import { DragManager } from '../util/DragManager'; import { LinkFollower } from '../util/LinkFollower'; @@ -22,19 +23,18 @@ import { SelectionManager } from '../util/SelectionManager'; import { SettingsManager } from '../util/SettingsManager'; import { SnappingManager } from '../util/SnappingManager'; import { UndoManager } from '../util/UndoManager'; -import { CollectionDockingView } from './collections/CollectionDockingView'; -import { CollectionFreeFormView } from './collections/collectionFreeForm'; import { DocumentButtonBar } from './DocumentButtonBar'; import './DocumentDecorations.scss'; -import { Colors } from './global/globalEnums'; -import { InkingStroke } from './InkingStroke'; import { InkStrokeProperties } from './InkStrokeProperties'; +import { InkingStroke } from './InkingStroke'; import { LightboxView } from './LightboxView'; +import { ObservableReactComponent } from './ObservableReactComponent'; +import { CollectionDockingView } from './collections/CollectionDockingView'; +import { CollectionFreeFormView } from './collections/collectionFreeForm'; +import { Colors } from './global/globalEnums'; import { DocumentView, OpenWhereMod } from './nodes/DocumentView'; -import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { ImageBox } from './nodes/ImageBox'; -import * as React from 'react'; -import { ObservableReactComponent } from './ObservableReactComponent'; +import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; interface DocumentDecorationsProps { PanelWidth: number; @@ -97,7 +97,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora } @computed get Bounds() { - return (LinkFollower.IsFollowing || SnappingManager.ExploreMode) ? + return (SnappingManager.IsLinkFollowing || SnappingManager.ExploreMode) ? { x: 0, y: 0, r: 0, b: 0 } : SelectionManager.Views .filter(dv => dv._props.renderDepth > 0) diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index 701ee4053..d4bd18948 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -265,9 +265,16 @@ export class RichTextRules { this.TextBox.EditorView?.dispatch(fstate.tr.setSelection(new TextSelection(fstate.doc.resolve(selection)))); } }; + const getTitledDoc = (docTitle: string) => { + if (!DocServer.FindDocByTitle(docTitle)) { + Doc.AddToMyPublished(Docs.Create.TextDocument('', { title: docTitle, _width: 400, _layout_autoHeight: true })); + } + const titledDoc = DocServer.FindDocByTitle(docTitle); + return titledDoc ? Doc.BestEmbedding(titledDoc) : titledDoc; + }; if (!fieldKey) { if (docTitle) { - const target = DocServer.FindDocByTitle(docTitle); + const target = getTitledDoc(docTitle); if (target) { setTimeout(() => linkToDoc(target)); return state.tr.deleteRange(end - 1, end).deleteRange(start, start + 3); @@ -279,7 +286,7 @@ export class RichTextRules { const num = value.match(/^[0-9.]$/); this.Document[DocData][fieldKey] = value === 'true' ? true : value === 'false' ? false : num ? Number(value) : value; } - const target = DocServer.FindDocByTitle(docTitle); + const target = getTitledDoc(docTitle); const fieldView = state.schema.nodes.dashField.create({ fieldKey, docId: target?.[Id], hideKey: false }); return state.tr.setSelection(new TextSelection(state.doc.resolve(start), state.doc.resolve(end))).replaceSelectionWith(fieldView, true); }), diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 9dc3c173d..d726f7064 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -574,8 +574,10 @@ export namespace Doc { } export function BestEmbedding(doc: Doc) { - const bestEmbedding = Doc.GetProto(doc) ? [doc, ...DocListCast(doc.proto_embeddings)].find(doc => !doc.embedContainer && doc.author === Doc.CurrentUserEmail) : doc; - bestEmbedding && Doc.AddDocToList(Doc.GetProto(doc), 'protoEmbeddings', doc); + const dataDoc = doc[DocData]; + const availableEmbeddings = DocListCast(dataDoc.proto_embeddings); + const bestEmbedding = [...(dataDoc !== doc ? [doc] : []), ...availableEmbeddings].find(doc => !doc.embedContainer && doc.author === Doc.CurrentUserEmail); + bestEmbedding && Doc.AddDocToList(dataDoc, 'protoEmbeddings', doc); return bestEmbedding ?? Doc.MakeEmbedding(doc); } |