diff options
Diffstat (limited to 'src/client/views/nodes/formattedText')
4 files changed, 30 insertions, 95 deletions
diff --git a/src/client/views/nodes/formattedText/DashFieldView.scss b/src/client/views/nodes/formattedText/DashFieldView.scss index 78bbb520e..2e2e1d41c 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.scss +++ b/src/client/views/nodes/formattedText/DashFieldView.scss @@ -3,7 +3,7 @@ .dashFieldView-active, .dashFieldView { position: relative; - display: inline-flex; + display: contents; align-items: center; .dashFieldView-enumerables { @@ -33,8 +33,11 @@ margin-left: 2px; margin-right: 5px; padding-left: 2px; - display: inline-block; - background-color: rgba(155, 155, 155, 0.24); + font-size: smaller; + display: contents; + > div { + background-color: rgba(155, 155, 155, 0.24); + } span { user-select: all; min-width: 100%; diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index d6d15054b..aa2829aaf 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -1,8 +1,10 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import { Node } from 'prosemirror-model'; import { NodeSelection } from 'prosemirror-state'; +import { EditorView } from 'prosemirror-view'; import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; import { returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../../../ClientUtils'; @@ -13,6 +15,7 @@ import { SchemaHeaderField } from '../../../../fields/SchemaHeaderField'; import { Cast, DocCast } from '../../../../fields/Types'; import { emptyFunction } from '../../../../Utils'; import { DocServer } from '../../../DocServer'; +import { DocumentOptions, FInfo } from '../../../documents/Documents'; import { CollectionViewType } from '../../../documents/DocumentTypes'; import { Transform } from '../../../util/Transform'; import { undoable, undoBatch } from '../../../util/UndoManager'; @@ -23,9 +26,6 @@ import { ObservableReactComponent } from '../../ObservableReactComponent'; import { OpenWhere } from '../OpenWhere'; import './DashFieldView.scss'; import { FormattedTextBox } from './FormattedTextBox'; -import { Node } from 'prosemirror-model'; -import { EditorView } from 'prosemirror-view'; -import { DocumentOptions, FInfo } from '../../../documents/Documents'; @observer export class DashFieldViewMenu extends AntimodeMenu<AntimodeMenuProps> { @@ -99,7 +99,6 @@ interface IDashFieldViewInternal { width: number; height: number; editable: boolean; - nodeSelected: () => boolean; node: Node; getPos: () => number; unclickable: () => boolean; @@ -112,7 +111,7 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi _fieldKey: string; _fieldRef = React.createRef<HTMLDivElement>(); @observable _dashDoc: Doc | undefined = undefined; - @observable _expanded = this._props.nodeSelected(); + @observable _expanded = false; constructor(props: IDashFieldViewInternal) { super(props); @@ -140,7 +139,7 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi componentWillUnmount() { this._reactionDisposer?.(); } - isRowActive = () => (this._props.nodeSelected() || this._expanded) && this._props.editable; + isRowActive = () => this._props.tbox._props.isContentActive() && this._props.editable; finishEdit = action(() => { if (this._expanded) { this._expanded = false; @@ -149,7 +148,7 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi setTimeout(() => !this._props.tbox.ProseRef?.contains(document.activeElement) && this._props.tbox._props.onBlur?.()); } }); - selectedCells = () => (this._dashDoc ? [this._dashDoc] : undefined); + selectedCells = () => (this._dashDoc && this._expanded ? [this._dashDoc] : undefined); columnWidth = () => Math.min(this._props.tbox._props.PanelWidth(), Math.max(50, this._props.tbox._props.PanelWidth() - 100)); // try to leave room for the fieldKey finfo = (fieldKey: string) => (new DocumentOptions() as Record<string, FInfo>)[fieldKey]; @@ -158,15 +157,16 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi @computed get fieldValueContent() { return !this._dashDoc ? null : ( <div + className="dashFieldView-fieldSpan" onPointerDown={action(() => { this._expanded = !this._props.editable ? false : !this._expanded; - })} - style={{ fontSize: 'smaller', width: !this._hideKey && this._expanded ? this.columnWidth() : undefined }}> + })}> <SchemaTableCell Document={this._dashDoc} col={0} deselectCell={emptyFunction} - selectCell={emptyFunction} + selectCell={() => (this._expanded ? true : undefined)} + autoFocus={true} maxWidth={this._props.hideKey || this._hideKey ? undefined : this._props.tbox._props.PanelWidth} columnWidth={returnZero} selectedCells={this.selectedCells} @@ -184,11 +184,10 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi getFinfo={this.finfo} setColumnValues={returnFalse} allowCRs - oneLine={!this._expanded && !this._props.nodeSelected()} + oneLine={!this._expanded} finishEdit={this.finishEdit} transform={Transform.Identity} menuTarget={null} - autoFocus rootSelected={this._props.tbox._props.rootSelected} /> </div> @@ -233,7 +232,7 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi } @computed get _hideValue() { - return this._props.hideValue && !this._props.nodeSelected(); + return this._props.hideValue; } // clicking on the label creates a pivot view collection of all documents @@ -255,7 +254,6 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi }; @computed get values() { - if (this._props.nodeSelected()) return []; const vals = FilterPanel.gatherFieldValues(DocListCast(Doc.ActiveDashboard?.data), this._fieldKey, []); return vals.strings.map(facet => ({ value: facet, label: facet })); @@ -297,8 +295,6 @@ export class DashFieldView { node: Node; tbox: FormattedTextBox; getpos: () => number | undefined; - @observable _nodeSelected = false; - NodeSelected = () => this._nodeSelected; unclickable = () => !this.tbox._props.rootSelected?.() && this.node.marks.some(m => m.type === this.tbox.EditorView?.state.schema.marks.linkAnchor && m.attrs.noPreview); constructor(node: Node, view: EditorView, getPos: () => number | undefined, tbox: FormattedTextBox) { @@ -311,26 +307,13 @@ export class DashFieldView { this.dom.style.width = node.attrs.width; this.dom.style.height = node.attrs.height; this.dom.style.position = 'relative'; - this.dom.style.display = 'inline-block'; + this.dom.style.display = 'inline-flex'; this.dom.onkeypress = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onkeydown = (e: KeyboardEvent) => { + this.dom.onkeydown = action((e: KeyboardEvent) => { e.stopPropagation(); - if (e.key === 'Tab') { - e.preventDefault(); - const editor = tbox.EditorView; - if (editor) { - const { state } = editor; - for (let i = getPosition() + 1; i < state.doc.content.size; i++) { - if (state.doc.nodeAt(i)?.type.name === state.schema.nodes.dashField.name) { - editor.dispatch(state.tr.setSelection(new NodeSelection(state.doc.resolve(i)))); - return; - } - } - } - } - }; + }); this.dom.onkeyup = function (e: KeyboardEvent) { e.stopPropagation(); }; @@ -351,7 +334,6 @@ export class DashFieldView { hideKey={node.attrs.hideKey} hideValue={node.attrs.hideValue} editable={node.attrs.editable} - nodeSelected={this.NodeSelected} tbox={tbox} /> ); @@ -365,19 +347,6 @@ export class DashFieldView { } }); } - deselectNode() { - runInAction(() => { - this._nodeSelected = false; - }); - this.dom.classList.remove('ProseMirror-selectednode'); - } - selectNode() { - setTimeout( - action(() => { - this._nodeSelected = true; - }), - 100 - ); - this.dom.classList.add('ProseMirror-selectednode'); - } + deselectNode() {} + selectNode() {} } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 38817ac6d..7b24125e7 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -13,7 +13,7 @@ import { EditorState, NodeSelection, Plugin, Selection, TextSelection, Transacti import { EditorView, NodeViewConstructor } from 'prosemirror-view'; import * as React from 'react'; import { BsMarkdownFill } from 'react-icons/bs'; -import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivWidth, imageUrlToBase64, returnFalse, returnZero, setupMoveUpEvents, simMouseEvent, smoothScroll, StopEvent } from '../../../../ClientUtils'; +import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivWidth, returnFalse, returnZero, setupMoveUpEvents, simMouseEvent, smoothScroll, StopEvent } from '../../../../ClientUtils'; import { DateField } from '../../../../fields/DateField'; import { CreateLinkToActiveAudio, Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc'; import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, DocData, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols'; @@ -26,7 +26,7 @@ import { ComputedField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, DateCast, DocCast, FieldValue, NumCast, RTFCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util'; import { emptyFunction, numberRange, unimplementedFunction, Utils } from '../../../../Utils'; -import { gptAPICall, GPTCallType, gptImageLabel } from '../../../apis/gpt/GPT'; +import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT'; import { DocServer } from '../../../DocServer'; import { Docs } from '../../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; @@ -226,18 +226,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB return anchor; }; - selectionToFlashcards = async () => { - const queryText = window.getSelection()?.toString() ?? ''; - try { - if (queryText) { - const res = await gptAPICall(queryText, GPTCallType.FLASHCARD); - AnchorMenu.Instance.transferToFlashcard(res || 'Something went wrong', NumCast(this.layoutDoc.x), NumCast(this.layoutDoc.y)); - } - } catch (err) { - console.error(err); - } - }; - @action setupAnchorMenu = () => { AnchorMenu.Instance.Status = 'marquee'; @@ -1012,31 +1000,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB !help && cm.addItem({ description: 'Help...', subitems: helpItems, icon: 'eye' }); }; - findImageTags = async () => { - const c = this.ProseRef?.getElementsByTagName('img'); - if (c) { - for (const i of c) { - // console.log(canvas.toDataURL()); - // canvas.style.zIndex = '2000000'; - // document.body.appendChild(canvas); - if (i.className !== 'ProseMirror-separator') this.getImageDesc(i.src); - } - } - }; - - getImageDesc = async (u: string) => { - try { - const hrefBase64 = await imageUrlToBase64(u); - const response = await gptImageLabel( - hrefBase64, - 'Make flashcards out of this text and image with each question and answer labeled as question and answer. Do not label each flashcard and do not include asterisks: ' + (this.dataDoc.text as RichTextField)?.Text - ); - AnchorMenu.Instance.transferToFlashcard(response || 'Something went wrong', NumCast(this.dataDoc['x']), NumCast(this.dataDoc['y'])); - } catch (error) { - console.log('Error', error); - } - }; - animateRes = (resIndex: number, newText: string) => { if (resIndex < newText.length) { const marks = this.EditorView?.state.storedMarks ?? []; @@ -2113,7 +2076,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB setTimeout(() => !this._props.isContentActive() && FormattedTextBoxComment.textBox === this && FormattedTextBoxComment.Hide); const scrSize = (which: number, view = this._props.docViewPath().slice(-which)[0]) => - [view._props.PanelWidth() / view.screenToLocalScale(), view._props.PanelHeight() / view.screenToLocalScale()]; // prettier-ignore + [view?._props.PanelWidth() /(view?.screenToLocalScale()??1), view?._props.PanelHeight() / (view?.screenToLocalScale()??1)]; // prettier-ignore const scrMargin = [Math.max(0, (scrSize(2)[0] - scrSize(1)[0]) / 2), Math.max(0, (scrSize(2)[1] - scrSize(1)[1]) / 2)]; const paddingX = Math.max(NumCast(this.layoutDoc._xMargin), this._props.xPadding ?? 0, 0, ((this._props.screenXPadding?.() ?? 0) - scrMargin[0]) * this.ScreenToLocalBoxXf().Scale); const paddingY = Math.max(NumCast(this.layoutDoc._yMargin), 0, ((this._props.yPadding ?? 0) - scrMargin[1]) * this.ScreenToLocalBoxXf().Scale); diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index c332c592b..f3ec6cc9d 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -319,10 +319,10 @@ export class RichTextRules { }), // create a text display of a metadata field on this or another document, or create a hyperlink portal to another document - // [@{this,doctitle,}.fieldKey{:,=,:=,=:=}value] - // [@{this,doctitle,}.fieldKey] + // @{this,doctitle,}.fieldKey{:,=,:=,=:=}value + // @{this,doctitle,}.fieldKey new InputRule( - /\[(@|@this\.|@[a-zA-Z_? \-0-9]+\.)([a-zA-Z_?\-0-9]+)((:|=|:=|=:=)([a-zA-Z,_().@?+\-*/ 0-9()]*))?\]/, + /(@|@this\.|@[a-zA-Z_? \-0-9]+\.)([a-zA-Z_?\-0-9]+)((:|=|:=|=:=)([a-zA-Z,_().@?+\-*/ 0-9()]*))?\s/, (state, match, start, end) => { const docTitle = match[1].substring(1).replace(/\.$/, ''); const fieldKey = match[2]; |
