From d7150995d62c498ab8435de986b90d98bdca020c Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 12 Nov 2019 15:07:03 -0500 Subject: a bunch of cleanup and bug fixes to text links and doculink buttons --- src/new_fields/Doc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/new_fields') diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 6aad4a6be..3bf1129b5 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -669,8 +669,8 @@ export namespace Doc { return doc; } - export function LinkEndpoint(linkDoc: Doc, anchorDoc: Doc) { return Doc.AreProtosEqual(anchorDoc, Cast(linkDoc.anchor1, Doc) as Doc) ? "layoutKey1" : "layoutKey2"; } + export function LinkEndpoint(linkDoc: Doc, anchorDoc: Doc) { return Doc.AreProtosEqual(anchorDoc, Cast(linkDoc.anchor1, Doc) as Doc) ? "layoutKey1" : "layoutKey2"; } export function linkFollowUnhighlight() { Doc.UnhighlightAll(); document.removeEventListener("pointerdown", linkFollowUnhighlight); -- cgit v1.2.3-70-g09d2 From e1930a62304db60d9eca542148995c5d03b79aea Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 13 Nov 2019 11:44:52 -0500 Subject: fixed search on client/server to work with richTextFields. got rid of 'text' field on richtextfield extensions. --- .vscode/settings.json | 3 ++- src/client/views/DocComponent.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 8 ++++---- src/client/views/nodes/FormattedTextBox.tsx | 18 ++---------------- src/client/views/search/FilterBox.tsx | 2 +- src/new_fields/Doc.ts | 5 +++-- src/new_fields/RichTextField.ts | 10 +++++++--- src/new_fields/RichTextUtils.ts | 2 +- src/server/index.ts | 1 + 9 files changed, 22 insertions(+), 29 deletions(-) (limited to 'src/new_fields') diff --git a/.vscode/settings.json b/.vscode/settings.json index 5df697fee..c999af8b8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,5 +10,6 @@ "editor.detectIndentation": false, "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "search.usePCRE2": true + "search.usePCRE2": true, + "typescript.tsdk": "node_modules\\typescript\\lib" } \ No newline at end of file diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index ae4b7cf3a..92c947fe6 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -34,7 +34,7 @@ export function DocExtendableComponent

(schemaCt //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then @computed get Document(): T { return schemaCtor(this.props.Document); } @computed get layoutDoc() { return Doc.Layout(this.props.Document); } - @computed get dataDoc() { return (this.props.DataDoc && this.props.Document.isTemplateField ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; } + @computed get dataDoc() { return (this.props.DataDoc && (this.props.Document.isTemplateField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; } @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); } active = () => !this.props.Document.isBackground && (this.props.Document.forceActive || this.props.isSelected() || this.props.renderDepth === 0);// && !InkingControl.Instance.selectedTool; // bcz: inking state shouldn't affect static tools } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 4fbb0516f..7e81cd673 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -138,7 +138,7 @@ export class DocumentView extends DocComponent(Docu (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) { e.stopPropagation(); let preventDefault = true; - if (this._doubleTap && this.props.renderDepth && (!this.onClickHandler || !this.onClickHandler.script)) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click + if (this._doubleTap && this.props.renderDepth && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click let fullScreenAlias = Doc.MakeAlias(this.props.Document); if (StrCast(fullScreenAlias.layoutKey) !== "layoutCustom" && fullScreenAlias.layoutCustom !== undefined) { fullScreenAlias.layoutKey = "layoutCustom"; @@ -352,9 +352,9 @@ export class DocumentView extends DocComponent(Docu @undoBatch @action setCustomView = (custom: boolean): void => { - if (this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.DataDoc) { - Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.ContainingCollectionView.props.DataDoc); - } else { // bcz: not robust -- for now documents with string layout are native documents, and those with Doc layouts are customized + if (this.props.ContainingCollectionView?.props.DataDoc || this.props.ContainingCollectionView?.props.Document.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.ContainingCollectionView.props.Document); + } else { custom ? DocumentView.makeCustomViewClicked(this.props.Document, this.props.DataDoc) : DocumentView.makeNativeViewClicked(this.props.Document); } } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 24d6f2509..65a51b357 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -85,7 +85,6 @@ export class FormattedTextBox extends DocExtendableComponent<(FieldViewProps & F private _searchReactionDisposer?: Lambda; private _scrollToRegionReactionDisposer: Opt; private _reactionDisposer: Opt; - private _textReactionDisposer: Opt; private _heightReactionDisposer: Opt; private _rulesReactionDisposer: Opt; private _proxyReactionDisposer: Opt; @@ -191,9 +190,8 @@ export class FormattedTextBox extends DocExtendableComponent<(FieldViewProps & F let tsel = this._editorView.state.selection.$from; tsel.marks().filter(m => m.type === this._editorView!.state.schema.marks.user_mark).map(m => AudioBox.SetScrubTime(Math.max(0, m.attrs.modified * 5000 - 1000))); this._applyingChange = true; - this.extensionDoc && (this.extensionDoc.text = state.doc.textBetween(0, state.doc.content.size, "\n\n")); this.extensionDoc && (this.extensionDoc.lastModified = new DateField(new Date(Date.now()))); - this.dataDoc[this.props.fieldKey] = new RichTextField(JSON.stringify(state.toJSON())); + this.dataDoc[this.props.fieldKey] = new RichTextField(JSON.stringify(state.toJSON()), state.doc.textBetween(0, state.doc.content.size, "\n\n")); this._applyingChange = false; this.updateTitle(); this.tryUpdateHeight(); @@ -250,7 +248,7 @@ export class FormattedTextBox extends DocExtendableComponent<(FieldViewProps & F // replace text contents whend dragging with Alt if (draggedDoc && draggedDoc.type === DocumentType.TEXT && !Doc.AreProtosEqual(draggedDoc, this.props.Document) && de.mods === "AltKey") { if (draggedDoc.data instanceof RichTextField) { - Doc.GetProto(this.dataDoc)[this.props.fieldKey] = new RichTextField(draggedDoc.data.Data); + Doc.GetProto(this.dataDoc)[this.props.fieldKey] = new RichTextField(draggedDoc.data.Data, draggedDoc.data.Text); e.stopPropagation(); } // apply as template when dragging with Meta @@ -510,17 +508,6 @@ export class FormattedTextBox extends DocExtendableComponent<(FieldViewProps & F () => this.tryUpdateHeight() ); - this._textReactionDisposer = reaction( - () => this.extensionDoc, - () => { - if (this.extensionDoc && (this.dataDoc.text || this.dataDoc.lastModified)) { - this.extensionDoc.text = this.dataDoc.text; - this.extensionDoc.lastModified = DateCast(this.dataDoc.lastModified)[Copy](); - this.dataDoc.text = undefined; - this.dataDoc.lastModified = undefined; - } - }, { fireImmediately: true }); - this.setupEditor(this.config, this.dataDoc, this.props.fieldKey); @@ -834,7 +821,6 @@ export class FormattedTextBox extends DocExtendableComponent<(FieldViewProps & F this._rulesReactionDisposer && this._rulesReactionDisposer(); this._reactionDisposer && this._reactionDisposer(); this._proxyReactionDisposer && this._proxyReactionDisposer(); - this._textReactionDisposer && this._textReactionDisposer(); this._pushReactionDisposer && this._pushReactionDisposer(); this._pullReactionDisposer && this._pullReactionDisposer(); this._heightReactionDisposer && this._heightReactionDisposer(); diff --git a/src/client/views/search/FilterBox.tsx b/src/client/views/search/FilterBox.tsx index b841190d4..6e7e4ee1b 100644 --- a/src/client/views/search/FilterBox.tsx +++ b/src/client/views/search/FilterBox.tsx @@ -33,7 +33,7 @@ export enum Keys { export class FilterBox extends React.Component { static Instance: FilterBox; - public _allIcons: string[] = [DocumentType.AUDIO, DocumentType.COL, DocumentType.IMG, DocumentType.LINK, DocumentType.PDF, DocumentType.TEXT, DocumentType.VID, DocumentType.WEB]; + public _allIcons: string[] = [DocumentType.AUDIO, DocumentType.COL, DocumentType.IMG, DocumentType.LINK, DocumentType.PDF, DocumentType.TEXT, DocumentType.VID, DocumentType.WEB, DocumentType.TEMPLATE]; //if true, any keywords can be used. if false, all keywords are required. //this also serves as an indicator if the word status filter is applied diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 3bf1129b5..4531fd5e0 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -473,8 +473,9 @@ export namespace Doc { export function CreateDocumentExtensionForField(doc: Doc, fieldKey: string) { let docExtensionForField = new Doc(doc[Id] + fieldKey, true); - docExtensionForField.title = fieldKey + ".ext"; + docExtensionForField.title = fieldKey + ".ext"; // courtesy field--- shouldn't be needed except maybe for debugging docExtensionForField.extendsDoc = doc; // this is used by search to map field matches on the extension doc back to the document it extends. + docExtensionForField.extendsField = fieldKey; // this can be used by search to map matches on the extension doc back to the field that was extended. docExtensionForField.type = DocumentType.EXTENSION; let proto: Doc | undefined = doc; while (proto && !Doc.IsPrototype(proto) && proto.proto) { @@ -568,7 +569,7 @@ export namespace Doc { let layoutCustomLayout = Doc.MakeDelegate(templateDoc); titleTarget && (Doc.GetProto(target).title = titleTarget); - target.type = DocumentType.TEMPLATE; + Doc.GetProto(target).type = DocumentType.TEMPLATE; target.onClick = templateDoc.onClick instanceof ObjectField && templateDoc.onClick[Copy](); Doc.GetProto(target)[targetKey] = layoutCustomLayout; diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts index d2f76c969..fd5459876 100644 --- a/src/new_fields/RichTextField.ts +++ b/src/new_fields/RichTextField.ts @@ -10,17 +10,21 @@ export class RichTextField extends ObjectField { @serializable(true) readonly Data: string; - constructor(data: string) { + @serializable(true) + readonly Text: string; + + constructor(data: string, text: string = "") { super(); this.Data = data; + this.Text = text; } [Copy]() { - return new RichTextField(this.Data); + return new RichTextField(this.Data, this.Text); } [ToScriptString]() { - return `new RichTextField("${this.Data}")`; + return `new RichTextField("${this.Data}", "${this.Text}")`; } } \ No newline at end of file diff --git a/src/new_fields/RichTextUtils.ts b/src/new_fields/RichTextUtils.ts index 601939ed2..c2cca859c 100644 --- a/src/new_fields/RichTextUtils.ts +++ b/src/new_fields/RichTextUtils.ts @@ -52,7 +52,7 @@ export namespace RichTextUtils { }; export const Synthesize = (plainText: string, oldState?: RichTextField) => { - return new RichTextField(ToProsemirrorState(plainText, oldState)); + return new RichTextField(ToProsemirrorState(plainText, oldState), plainText); }; export const ToPlainText = (state: EditorState) => { diff --git a/src/server/index.ts b/src/server/index.ts index 1595781dc..ddd909479 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -1163,6 +1163,7 @@ const suffixMap: { [type: string]: (string | [string, string | ((json: any) => a "pdf": ["_t", "url"], "audio": ["_t", "url"], "web": ["_t", "url"], + "RichTextField": ["_t", value => value.Text], "date": ["_d", value => new Date(value.date).toISOString()], "proxy": ["_i", "fieldId"], "list": ["_l", list => { -- cgit v1.2.3-70-g09d2 From e87b4b99323875afce2d9847f3bddd4196b85b81 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 13 Nov 2019 14:48:57 -0500 Subject: added a lockedTransform field to lock pan/zoom. fixed text scrollintoview to scroll only when necessary. --- src/client/documents/Documents.ts | 3 ++- src/client/util/RichTextSchema.tsx | 1 + .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 4 ++-- src/client/views/nodes/DocumentView.tsx | 7 +++++++ src/client/views/nodes/FormattedTextBox.tsx | 4 +++- src/new_fields/documentSchemas.ts | 3 ++- 6 files changed, 17 insertions(+), 5 deletions(-) (limited to 'src/new_fields') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ba9f87025..1a9d67d83 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -76,7 +76,8 @@ export interface DocumentOptions { viewType?: number; backgroundColor?: string; ignoreClick?: boolean; - lockedPosition?: boolean; + lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged + lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed opacity?: number; defaultBackgroundColor?: string; dropAction?: dropActionType; diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 1004cb3d4..0d1ae3841 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -679,6 +679,7 @@ export class DashDocView { bringToFront={emptyFunction} zoomToScale={emptyFunction} getScale={returnOne} + dontRegisterView={true} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} ContentScaling={this.contentScaling} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 6e0f75bc1..0c5f4ec80 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -333,7 +333,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @action onPointerWheel = (e: React.WheelEvent): void => { - if (this.props.Document.lockedPosition || this.props.Document.inOverlay) return; + if (this.props.Document.lockedTransform || this.props.Document.inOverlay) return; if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming e.stopPropagation(); } @@ -355,7 +355,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @action setPan(panX: number, panY: number, panType: string = "None") { - if (!this.Document.lockedPosition || this.Document.inOverlay) { + if (!this.Document.lockedTransform || this.Document.inOverlay) { this.Document.panTransformType = panType; var scale = this.getLocalTransform().inverse().Scale; const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX)); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7e81cd673..98c610c68 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -372,6 +372,12 @@ export class DocumentView extends DocComponent(Docu this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true; } + @undoBatch + @action + toggleLockTransform = (): void => { + this.Document.lockedTransform = this.Document.lockedTransform ? undefined : true; + } + listen = async () => { Doc.GetProto(this.props.Document).transcript = await DictationManager.Controls.listen({ continuous: { indefinite: true }, @@ -444,6 +450,7 @@ export class DocumentView extends DocComponent(Docu layoutItems.push({ description: `${this.Document.autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc.autoHeight = !this.layoutDoc.autoHeight, icon: "plus" }); layoutItems.push({ description: this.Document.ignoreAspect || !this.Document.nativeWidth || !this.Document.nativeHeight ? "Freeze" : "Unfreeze", event: this.freezeNativeDimensions, icon: "snowflake" }); layoutItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); + layoutItems.push({ description: this.Document.lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" }); layoutItems.push({ description: "Center View", event: () => this.props.focus(this.props.Document, false), icon: "crosshairs" }); layoutItems.push({ description: "Zoom to Document", event: () => this.props.focus(this.props.Document, true), icon: "search" }); if (this.Document.type !== DocumentType.COL && this.Document.type !== DocumentType.TEMPLATE) { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 8b1e65663..015a21fd2 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -774,7 +774,9 @@ export class FormattedTextBox extends DocExtendableComponent<(FieldViewProps & F while (refNode && !("getBoundingClientRect" in refNode)) refNode = refNode.parentElement; let r1 = refNode && refNode.getBoundingClientRect(); let r3 = self._ref.current!.getBoundingClientRect(); - r1 && (self._ref.current!.scrollTop += (r1.top - r3.top) * self.props.ScreenToLocalTransform().Scale); + if (r1.top < r3.top || r1.top > r3.bottom) { + r1 && (self._ref.current!.scrollTop += (r1.top - r3.top) * self.props.ScreenToLocalTransform().Scale); + } return true; }, dispatchTransaction: this.dispatchTransaction, diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts index e2730914f..fa47374f1 100644 --- a/src/new_fields/documentSchemas.ts +++ b/src/new_fields/documentSchemas.ts @@ -31,7 +31,8 @@ export const documentSchema = createSchema({ summarizedDocs: listSpec(Doc), // documents that are summarized by this document (and which will typically be opened by clicking this document) maximizedDocs: listSpec(Doc), // documents to maximize when clicking this document (generally this document will be an icon) maximizeLocation: "string", // flag for where to place content when following a click interaction (e.g., onRight, inPlace, inTab) - lockedPosition: "boolean", // whether the document can be spatially manipulated + lockedPosition: "boolean", // whether the document can be moved (dragged) + lockedTransform: "boolean", // whether the document can be panned/zoomed inOverlay: "boolean", // whether the document is rendered in an OverlayView which handles selection/dragging differently borderRounding: "string", // border radius rounding of document searchFields: "string", // the search fields to display when this document matches a search in its metadata -- cgit v1.2.3-70-g09d2