diff options
Diffstat (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 3eecc98a4..ae1db76de 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -4,7 +4,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { isEqual } from "lodash"; import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { baseKeymap } from "prosemirror-commands"; +import { baseKeymap, selectAll } from "prosemirror-commands"; import { history } from "prosemirror-history"; import { inputRules } from 'prosemirror-inputrules'; import { keymap } from "prosemirror-keymap"; @@ -102,6 +102,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp public static FocusedBox: FormattedTextBox | undefined; public static SelectOnLoad = ""; + public static PasteOnLoad: ClipboardEvent | undefined; public static SelectOnLoadChar = ""; public static IsFragment(html: string) { return html.indexOf("data-pm-slice") !== -1; @@ -276,6 +277,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const end = this._editorView.state.doc.nodeSize - 2; this._editorView.dispatch(this._editorView.state.tr.removeMark(0, end, mark).removeMark(0, end, activeMark)); } + if (FormattedTextBox.PasteOnLoad) { + const pdfDocId = FormattedTextBox.PasteOnLoad.clipboardData?.getData("dash/pdfOrigin"); + const pdfRegionId = FormattedTextBox.PasteOnLoad.clipboardData?.getData("dash/pdfRegion"); + FormattedTextBox.PasteOnLoad = undefined; + setTimeout(() => pdfDocId && pdfRegionId && this.addPdfReference(pdfDocId, pdfRegionId, undefined), 10); + } } adoptAnnotation = (start: number, end: number, mark: Mark) => { const view = this._editorView!; @@ -505,6 +512,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } recordDictation = () => { + console.log("recording dictation"); + console.log(this._editorView); DictationManager.Controls.listen({ interimHandler: this.setCurrentBulletContent, continuous: { indefinite: false }, @@ -523,6 +532,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } recordBullet = async () => { + console.log("recording bullet"); const completedCue = "end session"; const results = await DictationManager.Controls.listen({ interimHandler: this.setCurrentBulletContent, @@ -539,6 +549,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp setCurrentBulletContent = (value: string) => { if (this._editorView) { + console.log("this._editorView"); const state = this._editorView.state; const now = Date.now(); let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(now / 1000) }); @@ -727,7 +738,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } const marks = [...node.marks]; const linkIndex = marks.findIndex(mark => mark.type === editor.state.schema.marks.link); - return linkIndex !== -1 && marks[linkIndex].attrs.allRefs.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? node : undefined; + return linkIndex !== -1 && marks[linkIndex].attrs.allHrefs.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? node : undefined; }; let start = 0; @@ -858,8 +869,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp handlePaste = (view: EditorView, event: Event, slice: Slice): boolean => { const cbe = event as ClipboardEvent; - const pdfDocId = cbe.clipboardData && cbe.clipboardData.getData("dash/pdfOrigin"); - const pdfRegionId = cbe.clipboardData && cbe.clipboardData.getData("dash/pdfRegion"); + const pdfDocId = cbe.clipboardData?.getData("dash/pdfOrigin"); + const pdfRegionId = cbe.clipboardData?.getData("dash/pdfRegion"); + return pdfDocId && pdfRegionId && this.addPdfReference(pdfDocId, pdfRegionId, slice) ? true : false; + } + + addPdfReference = (pdfDocId: string, pdfRegionId: string, slice?: Slice) => { + const view = this._editorView!; if (pdfDocId && pdfRegionId) { DocServer.GetRefField(pdfDocId).then(pdfDoc => { DocServer.GetRefField(pdfRegionId).then(pdfRegion => { @@ -867,17 +883,22 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp setTimeout(async () => { const targetField = Doc.LayoutFieldKey(pdfDoc); const targetAnnotations = await DocListCastAsync(pdfDoc[DataSym][targetField + "-annotations"]);// bcz: better to have the PDF's view handle updating its own annotations - targetAnnotations?.push(pdfRegion); + if (targetAnnotations) targetAnnotations.push(pdfRegion); + else Doc.AddDocToList(pdfDoc[DataSym], targetField + "-annotations", pdfRegion); }); const link = DocUtils.MakeLink({ doc: this.rootDoc }, { doc: pdfRegion }, "PDF pasted"); if (link) { - cbe.clipboardData!.setData("dash/linkDoc", link[Id]); const linkId = link[Id]; - const frag = addMarkToFrag(slice.content, (node: Node) => addLinkMark(node, StrCast(pdfDoc.title), linkId)); - slice = new Slice(frag, slice.openStart, slice.openEnd); - const tr = view.state.tr.replaceSelection(slice); - view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); + const quote = view.state.schema.nodes.blockquote.create(); + quote.content = addMarkToFrag(slice?.content || view.state.doc.content, (node: Node) => addLinkMark(node, StrCast(pdfDoc.title), linkId)); + const newSlice = new Slice(Fragment.from(quote), slice?.openStart || 0, slice?.openEnd || 0); + if (slice) { + view.dispatch(view.state.tr.replaceSelection(newSlice).scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); + } else { + selectAll(view.state, (tx: Transaction) => view.dispatch(tx.replaceSelection(newSlice).scrollIntoView())); + + } } } }); @@ -899,7 +920,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } const marks = [...node.marks]; const linkIndex = marks.findIndex(mark => mark.type.name === "link"); - const link = view.state.schema.mark(view.state.schema.marks.link, { href: Utils.prepend(`/doc/${linkId}`), location: "onRight", title: title, docref: true }); + const allHrefs = [{ href: Utils.prepend(`/doc/${linkId}`), title, linkId }]; + const link = view.state.schema.mark(view.state.schema.marks.link, { allHrefs, location: "onRight", title, docref: true }); marks.splice(linkIndex === -1 ? 0 : linkIndex, 1, link); return node.mark(marks); } @@ -934,7 +956,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp clipboardTextSerializer: this.clipboardTextSerializer, handlePaste: this.handlePaste, }); - //applyDevTools.applyDevTools(this._editorView); + !Doc.UserDoc().noviceMode && applyDevTools.applyDevTools(this._editorView); const startupText = !rtfField && this._editorView && Field.toString(this.dataDoc[fieldKey] as Field); if (startupText) { const { state: { tr }, dispatch } = this._editorView; @@ -1014,9 +1036,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const editor = this._editorView!; FormattedTextBoxComment.textBox = this; const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY }); - const node = pcords && editor.state.doc.nodeAt(pcords.pos); // get what prosemirror thinks the clicked node is (if it's null, then we didn't click on any text) - !this.props.isSelected(true) && editor.dispatch(editor.state.tr.setSelection(node && pcords ? - new NodeSelection(editor.state.doc.resolve(pcords.pos)) : new TextSelection(editor.state.doc.resolve(pcords?.pos || 0)))); + !this.props.isSelected(true) && editor.dispatch(editor.state.tr.setSelection(new TextSelection(editor.state.doc.resolve(pcords?.pos || 0)))); FormattedTextBoxComment.update(editor, undefined, (e.target as any)?.className === "prosemirror-dropdownlink" ? (e.target as any).href : ""); } (e.nativeEvent as any).formattedHandled = true; @@ -1194,6 +1214,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } + ondrop = (eve: React.DragEvent) => { + eve.stopPropagation(); // drag n drop of text within text note will generate a new note if not caughst, as will dragging in from outside of Dash. + } onscrolled = (ev: React.UIEvent) => { this.layoutDoc._scrollTop = this._scrollRef.current!.scrollTop; } @@ -1201,13 +1224,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp tryUpdateHeight(limitHeight?: number) { let scrollHeight = this._ref.current?.scrollHeight; if (this.props.renderDepth && this.layoutDoc._autoHeight && !this.props.ignoreAutoHeight && scrollHeight) { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation - scrollHeight = scrollHeight * NumCast(this.layoutDoc.scale, 1); + scrollHeight = scrollHeight * NumCast(this.layoutDoc._viewScale, 1); if (limitHeight && scrollHeight > limitHeight) { scrollHeight = limitHeight; this.layoutDoc.limitHeight = undefined; this.layoutDoc._autoHeight = false; } - const nh = this.layoutDoc.isTemplateForField ? 0 : NumCast(this.dataDoc._nativeHeight, 0); + const nh = this.layoutDoc.isTemplateForField ? 0 : NumCast(this.layoutDoc._nativeHeight, 0); const dh = NumCast(this.rootDoc._height, 0); const newHeight = Math.max(10, (nh ? dh / nh * scrollHeight : scrollHeight) + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0)); if (this.rootDoc !== this.layoutDoc.doc && !this.layoutDoc.resolvedDataDoc) { @@ -1215,11 +1238,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp console.log("Delayed height adjustment..."); setTimeout(() => { this.rootDoc._height = newHeight; - this.dataDoc._nativeHeight = nh ? scrollHeight : undefined; + this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined; }, 10); } else { - this.rootDoc._height = newHeight; - this.dataDoc._nativeHeight = nh ? scrollHeight : undefined; + this.layoutDoc._height = newHeight; + this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined; } } } @@ -1230,7 +1253,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); } render() { TraceMobx(); - const scale = this.props.ContentScaling() * NumCast(this.layoutDoc.scale, 1); + const scale = this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1); const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground; if (this.props.isSelected()) { @@ -1282,7 +1305,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } })} > - <div className={`formattedTextBox-outer`} style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !this.props.isSelected() ? "none" : undefined }} onScroll={this.onscrolled} ref={this._scrollRef}> + <div className={`formattedTextBox-outer`} ref={this._scrollRef} + style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !this.props.isSelected() ? "none" : undefined }} + onScroll={this.onscrolled} onDrop={this.ondrop} > <div className={`formattedTextBox-inner${rounded}${selclass}`} ref={this.createDropTarget} style={{ padding: `${Math.max(0, NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0) + selPad)}px ${NumCast(this.layoutDoc._xMargin, this.props.xMargin || 0) + selPad}px`, |