aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/formattedText
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/formattedText')
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.scss9
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.tsx67
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx43
-rw-r--r--src/client/views/nodes/formattedText/RichTextRules.ts6
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];