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/DashDocView.tsx4
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx22
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx68
3 files changed, 53 insertions, 41 deletions
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 212da3f3d..145ee8c2e 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -114,7 +114,7 @@ export class DashDocView extends React.Component<IDashDocView> {
}
/*endregion*/
- componentWillMount = () => {
+ componentWillUnmount = () => {
this._reactionDisposer?.();
}
@@ -254,7 +254,7 @@ export class DashDocView extends React.Component<IDashDocView> {
whenActiveChanged={returnFalse}
bringToFront={emptyFunction}
dontRegisterView={false}
- docFilters={this.props.tbox?.props.docFilters||returnEmptyFilter}
+ docFilters={this.props.tbox?.props.docFilters || returnEmptyFilter}
ContainingCollectionView={this._textBox.props.ContainingCollectionView}
ContainingCollectionDoc={this._textBox.props.ContainingCollectionDoc}
ContentScaling={this.contentScaling}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 8c05d3603..d4c9f74d5 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -34,7 +34,7 @@ import { DictationManager } from '../../../util/DictationManager';
import { DragManager } from "../../../util/DragManager";
import { makeTemplate } from '../../../util/DropConverter';
import buildKeymap, { updateBullets } from "./ProsemirrorExampleTransfer";
-import RichTextMenu from './RichTextMenu';
+import RichTextMenu, { RichTextMenuPlugin } from './RichTextMenu';
import { RichTextRules } from "./RichTextRules";
//import { DashDocView } from "./DashDocView";
@@ -304,18 +304,19 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
// for inserting timestamps
insertTime = () => {
+ let audioState;
if (this._first) {
- this._first = false;
DocListCast(this.dataDoc.links).map((l, i) => {
let la1 = l.anchor1 as Doc;
let la2 = l.anchor2 as Doc;
this._linkTime = NumCast(l.anchor2_timecode);
+ audioState = la2.audioState;
if (Doc.AreProtosEqual(la2, this.dataDoc)) {
la1 = l.anchor2 as Doc;
la2 = l.anchor1 as Doc;
this._linkTime = NumCast(l.anchor1_timecode);
+ audioState = la1.audioState;
}
-
});
}
this._currentTime = Date.now();
@@ -336,7 +337,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
}
}
- if (time) {
+ if (time && audioState === "recording") {
let value = "";
this._break = false;
value = this.layoutDoc._timeStampOnEnter ? "[" + time + "] " : "\n" + "[" + time + "] ";
@@ -407,8 +408,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const lastSel = Math.min(flattened.length - 1, this._searchIndex);
flattened.forEach((h: TextSelection, ind: number) => tr = tr.addMark(h.from, h.to, ind === lastSel ? activeMark : mark));
flattened[lastSel] && this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(flattened[lastSel].from), tr.doc.resolve(flattened[lastSel].to))).scrollIntoView());
-
- console.log(this._searchIndex);
}
}
@@ -1306,7 +1305,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
// jump rich text menu to this textbox
const bounds = this._ref.current?.getBoundingClientRect();
- if (bounds && this.layoutDoc._chromeStatus !== "disabled") {
+ if (bounds && this.layoutDoc._chromeStatus !== "disabled" && RichTextMenu.Instance) {
const x = Math.min(Math.max(bounds.left, 0), window.innerWidth - RichTextMenu.Instance.width);
let y = Math.min(Math.max(0, bounds.top - RichTextMenu.Instance.height - 50), window.innerHeight - RichTextMenu.Instance.height);
if (coords && coords.left > x && coords.left < x + RichTextMenu.Instance.width && coords.top > y && coords.top < y + RichTextMenu.Instance.height + 50) {
@@ -1410,11 +1409,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
}
+ menuPlugin: any;
+
richTextMenuPlugin() {
+ const self = this;
return new Plugin({
view(newView) {
- RichTextMenu.Instance?.changeView(newView);
- return RichTextMenu.Instance;
+ self.props.isSelected(true) && (RichTextMenu.Instance.view = newView);
+ return self.menuPlugin = new RichTextMenuPlugin({ editorProps: this.props });
}
});
}
@@ -1524,7 +1526,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const scale = this.props.hideOnLeave ? 1 : 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;
- setTimeout(() => this._editorView && RichTextMenu.Instance.updateFromDash(this._editorView, undefined, this.props), this.props.isSelected() ? 10 : 0); // need to make sure that we update a text box that is selected after updating the one that was deselected
+ this.props.isSelected() && setTimeout(() => this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props), 0); // need to make sure that we update a text box that is selected after updating the one that was deselected
if (!this.props.isSelected() && FormattedTextBoxComment.textBox === this) {
setTimeout(() => FormattedTextBoxComment.Hide(), 0);
}
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index b683fb25d..213b341e8 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -16,7 +16,7 @@ import { unimplementedFunction, Utils } from "../../../../Utils";
import { DocServer } from "../../../DocServer";
import { LinkManager } from "../../../util/LinkManager";
import { SelectionManager } from "../../../util/SelectionManager";
-import AntimodeMenu from "../../AntimodeMenu";
+import AntimodeMenu, { AntimodeMenuProps } from "../../AntimodeMenu";
import { FieldViewProps } from "../FieldView";
import { FormattedTextBox, FormattedTextBoxProps } from "./FormattedTextBox";
import { updateBullets } from "./ProsemirrorExampleTransfer";
@@ -31,11 +31,11 @@ library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSup
@observer
-export default class RichTextMenu extends AntimodeMenu {
+export default class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
static Instance: RichTextMenu;
public overMenu: boolean = false; // kind of hacky way to prevent selects not being selectable
- private view?: EditorView;
+ public view?: EditorView;
public editorProps: FieldViewProps & FormattedTextBoxProps | undefined;
public _brushMap: Map<string, Set<Mark>> = new Map();
@@ -156,22 +156,8 @@ export default class RichTextMenu extends AntimodeMenu {
public delayHide = () => this._delayHide = true;
@action
- changeView(view: EditorView) {
- if ((view as any)?.TextView?.props.isSelected(true)) {
- this.view = view;
- }
- }
-
- update(view: EditorView, lastState: EditorState | undefined) {
- RichTextMenu.Instance.updateFromDash(view, lastState, this.editorProps);
- }
-
- @action
- public async updateFromDash(view: EditorView, lastState: EditorState | undefined, props: any) {
- RichTextMenu.Instance.finalUpdateFromDash(view, lastState, props);
- }
- public async finalUpdateFromDash(view: EditorView, lastState: EditorState | undefined, props: any) {
- if (!view || !(view as any).TextView?.props.isSelected(true)) {
+ public updateMenu(view: EditorView, lastState: EditorState | undefined, props: any) {
+ if (!view || !(view as any).TextView?.props.isSelected(true) || !view.hasFocus()) {
return;
}
this.view = view;
@@ -199,8 +185,7 @@ export default class RichTextMenu extends AntimodeMenu {
this.activeHighlightColor = !activeHighlights.length ? "" : activeHighlights.length === 1 ? String(activeHighlights[0]) : "...";
// update link in current selection
- const targetTitle = await this.getTextLinkTargetTitle();
- this.setCurrentLink(targetTitle);
+ this.getTextLinkTargetTitle().then(targetTitle => this.setCurrentLink(targetTitle));
}
setMark = (mark: Mark, state: EditorState<any>, dispatch: any, dontToggle: boolean = false) => {
@@ -268,7 +253,9 @@ export default class RichTextMenu extends AntimodeMenu {
const pos = this.view.state.selection.$from;
const ref_node = this.reference_node(pos);
if (ref_node && ref_node !== this.view.state.doc && ref_node.isText) {
- ref_node.marks.forEach(m => {
+ const marks = Array.from(ref_node.marks);
+ marks.push(...(this.view.state.storedMarks as any));
+ marks.forEach(m => {
m.type === state.schema.marks.pFontFamily && activeFamilies.push(m.attrs.family);
m.type === state.schema.marks.pFontColor && activeColors.push(m.attrs.color);
m.type === state.schema.marks.pFontSize && activeSizes.push(String(m.attrs.fontSize) + "pt");
@@ -443,14 +430,20 @@ export default class RichTextMenu extends AntimodeMenu {
if ((this.view?.state.selection.$from.pos || 0) < 2) {
this.TextView.layoutDoc._fontSize = mark.attrs.fontSize;
}
- this.setMark(view.state.schema.marks.pFontSize.create({ fontSize: mark.attrs.fontSize }), view.state, view.dispatch, true);
+ const fmark = view.state.schema.marks.pFontSize.create({ fontSize: mark.attrs.fontSize });
+ this.setMark(fmark, view.state, (tx: any) => view.dispatch(tx.addStoredMark(fmark)), true);
+ view.focus();
+ this.updateMenu(view, undefined, this.props);
}
changeFontFamily = (mark: Mark, view: EditorView) => {
if ((this.view?.state.selection.$from.pos || 0) < 2) {
this.TextView.layoutDoc._fontFamily = mark.attrs.family;
}
- this.setMark(view.state.schema.marks.pFontFamily.create({ family: mark.attrs.family }), view.state, view.dispatch, true);
+ const fmark = view.state.schema.marks.pFontFamily.create({ family: mark.attrs.family });
+ this.setMark(fmark, view.state, (tx: any) => view.dispatch(tx.addStoredMark(fmark)), true);
+ view.focus();
+ this.updateMenu(view, undefined, this.props);
}
// TODO: remove doesn't work
@@ -486,6 +479,8 @@ export default class RichTextMenu extends AntimodeMenu {
this.view.dispatch(tx3);
}
}
+ this.view.focus();
+ this.updateMenu(this.view, undefined, this.props);
}
insertSummarizer(state: EditorState<any>, dispatch: any) {
@@ -690,16 +685,22 @@ export default class RichTextMenu extends AntimodeMenu {
e.preventDefault();
e.stopPropagation();
self.TextView.endUndoTypingBatch();
- UndoManager.RunInBatch(() => self.view && self.insertColor(self.activeFontColor, self.view.state, self.view.dispatch), "rt menu color");
- self.TextView.EditorView!.focus();
+ if (self.view) {
+ UndoManager.RunInBatch(() => self.view && self.insertColor(self.activeFontColor, self.view.state, self.view.dispatch), "rt menu color");
+ self.view.focus();
+ self.updateMenu(self.view, undefined, self.props);
+ }
}
function changeColor(e: React.PointerEvent, color: string) {
e.preventDefault();
e.stopPropagation();
self.setActiveColor(color);
self.TextView.endUndoTypingBatch();
- UndoManager.RunInBatch(() => self.view && self.insertColor(self.activeFontColor, self.view.state, self.view.dispatch), "rt menu color");
- self.TextView.EditorView!.focus();
+ if (self.view) {
+ UndoManager.RunInBatch(() => self.view && self.insertColor(self.activeFontColor, self.view.state, self.view.dispatch), "rt menu color");
+ self.view.focus();
+ self.updateMenu(self.view, undefined, self.props);
+ }
}
// onPointerDown={onColorClick}
@@ -988,7 +989,7 @@ export default class RichTextMenu extends AntimodeMenu {
{[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => this.activeFontSize = val)),
this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family", action((val: string) => this.activeFontFamily = val)),
<div className="richTextMenu-divider" key="divider 4" />,
- this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", action((val: string) => this.activeListType = val)),
+ this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", () => ({})),
this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer),
this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote),
this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule),
@@ -1070,4 +1071,13 @@ export class ButtonDropdown extends React.Component<ButtonDropdownProps> {
</div>
);
}
+}
+
+
+interface RichTextMenuPluginProps {
+ editorProps: any;
+}
+export class RichTextMenuPlugin extends React.Component<RichTextMenuPluginProps> {
+ render() { return null; }
+ update(view: EditorView, lastState: EditorState | undefined) { RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps); }
} \ No newline at end of file