diff options
Diffstat (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index e354aedb7..9f2a9b8e1 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -181,6 +181,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB @observable private gptRes: string = ''; + public makeAIFlashcards: () => void = unimplementedFunction; + public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined; + public static PasteOnLoad: ClipboardEvent | undefined; public static DontSelectInitialText = false; // whether initial text should be selected or not public static SelectOnLoadChar = ''; @@ -240,7 +243,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB @action setupAnchorMenu = () => { AnchorMenu.Instance.Status = 'marquee'; - AnchorMenu.Instance.OnClick = () => { !this.layoutDoc.layout_showSidebar && this.toggleSidebar(); setTimeout(() => this._sidebarRef.current?.anchorMenuClick(this.makeLinkAnchor(undefined, OpenWhere.addRight, undefined, 'Anchored Selection', true))); // give time for sidebarRef to be created @@ -292,6 +294,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.DocumentView?.()!, () => this.getAnchor(true), targetCreator), e.pageX, e.pageY); }); + + AnchorMenu.Instance.setSelectedText(window.getSelection()?.toString() ?? ''); const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to); this._props.rootSelected?.() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom); let ele: Opt<HTMLDivElement>; @@ -319,7 +323,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB return ''; }; dispatchTransaction = (tx: Transaction) => { - if (this._editorView) { + if (this._editorView && !this._editorView.isDestroyed) { const state = this._editorView.state.apply(tx); this._editorView.updateState(state); this.tryUpdateDoc(false); @@ -352,6 +356,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB let unchanged = true; const textChange = newText !== prevData?.Text; // the Text string can change even if the RichText doesn't because dashFieldViews may return new strings as the data they reference changes + const rtField = (layoutData !== prevData ? layoutData : undefined) ?? protoData; if (this._applyingChange !== this.fieldKey && (force || textChange || removeSelection(newJson) !== removeSelection(prevData?.Data))) { this._applyingChange = this.fieldKey; textChange && (dataDoc[this.fieldKey + '_modificationDate'] = new DateField(new Date(Date.now()))); @@ -365,10 +370,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB this._applyingChange = ''; // turning this off here allows a Doc to retrieve data from template if noTemplate below is changed to false unchanged = false; } - } else { + } else if (rtField) { // if we've deleted all the text in a note driven by a template, then restore the template data dataDoc[this.fieldKey] = undefined; - this._editorView.updateState(EditorState.fromJSON(this.config, JSON.parse(((layoutData !== prevData ? layoutData : undefined) ?? protoData)?.Data))); + this._editorView.updateState(EditorState.fromJSON(this.config, JSON.parse(rtField.Data))); ScriptCast(this.layoutDoc.onTextChanged, null)?.script.run({ this: this.layoutDoc, text: newText }); unchanged = false; } @@ -916,6 +921,17 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB }, icon: !this.Document._layout_enableAltContentUI ? 'eye-slash' : 'eye', }); + if (this.Document._layout_enableAltContentUI) { + const usepath = this.layoutDoc[`_${this._props.fieldKey}_usePath`]; + appearanceItems.push({ + description: (this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate:hover' ? 'no hover' : 'hover') + ' to show alt content', + event: () => { + this.layoutDoc[`_${this._props.fieldKey}_usePath`] = usepath === 'alternate' || usepath === undefined ? 'alternate:hover' : undefined; + }, + icon: !this.Document._layout_enableAltContentUI ? 'eye-slash' : 'eye', + }); + } + !Doc.noviceMode && appearanceItems.push({ description: 'Show Highlights...', noexpand: true, subitems: highlighting, icon: 'hand-point-right' }); !Doc.noviceMode && appearanceItems.push({ @@ -953,7 +969,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB icon: 'star', }); optionItems.push({ description: `Generate Dall-E Image`, event: () => this.generateImage(), icon: 'star' }); - optionItems.push({ description: `Ask GPT-3`, event: () => this.askGPT(), icon: 'lightbulb' }); + optionItems.push({ description: `Make AI Flashcards`, event: () => this.makeAIFlashcards(), icon: 'lightbulb' }); + optionItems.push({ description: `Ask GPT-3`, event: this.askGPT, icon: 'lightbulb' }); this._props.renderDepth && optionItems.push({ description: !this.Document._createDocOnCR ? 'Create New Doc on Carriage Return' : 'Allow Carriage Returns', @@ -987,6 +1004,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB askGPT = action(async () => { try { + GPTPopup.Instance.setSidebarId(this.SidebarKey); + GPTPopup.Instance.addDoc = this.sidebarAddDocument; const res = await gptAPICall((this.dataDoc.text as RichTextField)?.Text, GPTCallType.COMPLETION); if (!res) { this.animateRes(0, 'Something went wrong.'); @@ -1571,7 +1590,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB e.preventDefault(); } }; - onSelectEnd = (): void => document.removeEventListener('pointerup', this.onSelectEnd); + onSelectEnd = () => { + GPTPopup.Instance.setSidebarId(this.SidebarKey); + GPTPopup.Instance.addDoc = this.sidebarAddDocument; + document.removeEventListener('pointerup', this.onSelectEnd); + }; onPointerUp = (e: React.PointerEvent): void => { const state = this.EditorView?.state; if (state && this.ProseRef?.children[0].className.includes('-focused') && this._props.isContentActive() && !e.button) { @@ -1953,10 +1976,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB <div className="dash-tooltip"> toggle (%/) between <span style={{ color: usePath === undefined ? 'black' : undefined }}> - <em> primary, </em> + <em> primary </em> </span> + and <span style={{ color: usePath === 'alternate' ? 'black' : undefined }}> - <em>alternate, </em> + <em>alternate </em> </span> and show <span style={{ color: usePath === 'alternate:hover' ? 'black' : undefined }}> @@ -1982,9 +2006,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB } @computed get _fieldKey() { const usePath = this._props.ignoreUsePath ? '' : StrCast(this.layoutDoc[`${this._props.fieldKey}_usePath`]); - return this._props.fieldKey + (usePath && (!usePath.includes(':hover') || this._isHovering || this._props.isContentActive()) ? `_${usePath.replace(':hover', '')}` : ''); + return this._props.fieldKey + (usePath && (!usePath.includes(':hover') || this._props.isHovering?.() || this._props.isContentActive()) ? `_${usePath.replace(':hover', '')}` : ''); } - @observable _isHovering = false; onPassiveWheel = (e: WheelEvent) => { if (e.clientX > this.ProseRef!.getBoundingClientRect().right) { return; @@ -2030,11 +2053,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB return styleFromLayout?.height === '0px' ? null : ( <div className="formattedTextBox" - onPointerEnter={action(() => { - this._isHovering = true; - this.layoutDoc[`_${this._props.fieldKey}_usePath`] && (this.Document.isHovering = true); - })} - onPointerLeave={action(() => { this.Document.isHovering = this._isHovering = false; })} // prettier-ignore ref={r => { this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel); this._oldWheel = r; |