aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-01-04 10:18:57 -0500
committerbobzel <zzzman@gmail.com>2024-01-04 10:18:57 -0500
commitebf32ac65d35053f847fb2cf60f915eb29d6fdd5 (patch)
treeaca380ddebb208b8114f75ba7cc07d24ab4158f6
parentd1b3d3d852e6b8eed7949b17f566a59d97a2dcf4 (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.ts14
-rw-r--r--src/client/util/SnappingManager.ts15
-rw-r--r--src/client/views/DocumentDecorations.tsx20
-rw-r--r--src/client/views/nodes/formattedText/RichTextRules.ts11
-rw-r--r--src/fields/Doc.ts6
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);
}