diff options
Diffstat (limited to 'src/client/views/nodes/formattedText/RichTextMenu.tsx')
-rw-r--r-- | src/client/views/nodes/formattedText/RichTextMenu.tsx | 84 |
1 files changed, 49 insertions, 35 deletions
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 8da1f99b5..47a4911b8 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -23,7 +23,8 @@ import { updateBullets } from "./ProsemirrorExampleTransfer"; import "./RichTextMenu.scss"; import { schema } from "./schema_rts"; import { TraceMobx } from "../../../../fields/util"; -import { UndoManager } from "../../../util/UndoManager"; +import { UndoManager, undoBatch } from "../../../util/UndoManager"; +import { Tooltip } from "@material-ui/core"; const { toggleMark } = require("prosemirror-commands"); library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faOutdent, faIndent, faHandPointLeft, faHandPointRight, faEyeDropper, faCaretDown, faPalette, faHighlighter, faLink, faPaintRoller); @@ -155,7 +156,9 @@ export default class RichTextMenu extends AntimodeMenu { @action changeView(view: EditorView) { - this.view = view; + if ((view as any)?.TextView?.props.isSelected(true)) { + this.view = view; + } } update(view: EditorView, lastState: EditorState | undefined) { @@ -164,8 +167,7 @@ export default class RichTextMenu extends AntimodeMenu { @action public async updateFromDash(view: EditorView, lastState: EditorState | undefined, props: any) { - if (!view) { - console.log("no editor? why?"); + if (!view || !(view as any).TextView?.props.isSelected(true)) { return; } this.view = view; @@ -218,7 +220,7 @@ export default class RichTextMenu extends AntimodeMenu { // finds font sizes and families in selection getActiveAlignment() { - if (this.view && this.TextView.props.isSelected()) { + if (this.view && this.TextView.props.isSelected(true)) { const path = (this.view.state.selection.$from as any).path; for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) { if (path[i]?.type === this.view.state.schema.nodes.paragraph) { @@ -231,7 +233,7 @@ export default class RichTextMenu extends AntimodeMenu { // finds font sizes and families in selection getActiveListStyle() { - if (this.view && this.TextView.props.isSelected()) { + if (this.view && this.TextView.props.isSelected(true)) { const path = (this.view.state.selection.$from as any).path; for (let i = 0; i < path.length; i += 3) { if (path[i].type === this.view.state.schema.nodes.ordered_list) { @@ -251,7 +253,7 @@ export default class RichTextMenu extends AntimodeMenu { const activeFamilies: string[] = []; const activeSizes: string[] = []; - if (this.TextView.props.isSelected()) { + if (this.TextView.props.isSelected(true)) { const state = this.view.state; const pos = this.view.state.selection.$from; const ref_node = this.reference_node(pos); @@ -279,7 +281,7 @@ export default class RichTextMenu extends AntimodeMenu { //finds all active marks on selection in given group getActiveMarksOnSelection() { let activeMarks: MarkType[] = []; - if (!this.view || !this.TextView.props.isSelected()) return activeMarks; + if (!this.view || !this.TextView.props.isSelected(true)) return activeMarks; const markGroup = [schema.marks.strong, schema.marks.em, schema.marks.underline, schema.marks.strikethrough, schema.marks.superscript, schema.marks.subscript]; if (this.view.state.storedMarks) return this.view.state.storedMarks.map(mark => mark.type); @@ -317,7 +319,7 @@ export default class RichTextMenu extends AntimodeMenu { } destroy() { - this.fadeOut(true); + !this.TextView?.props.isSelected(true) && this.fadeOut(true); } @action @@ -357,9 +359,11 @@ export default class RichTextMenu extends AntimodeMenu { } return ( - <button className={"antimodeMenu-button" + (isActive ? " active" : "")} key={title} title={title} onPointerDown={onClick}> - <FontAwesomeIcon icon={faIcon as IconProp} size="lg" /> - </button> + <Tooltip title={<div className="dash-tooltip">{title}</div>} key={title} placement="bottom"> + <button className={"antimodeMenu-button" + (isActive ? " active" : "")} onPointerDown={onClick}> + <FontAwesomeIcon icon={faIcon as IconProp} size="lg" /> + </button> + </Tooltip> ); } @@ -378,7 +382,7 @@ export default class RichTextMenu extends AntimodeMenu { self.TextView.endUndoTypingBatch(); options.forEach(({ label, mark, command }) => { if (e.target.value === label && mark) { - if (!self.TextView.props.isSelected()) { + if (!self.TextView.props.isSelected(true)) { switch (mark.type) { case schema.marks.pFontFamily: setter(Doc.UserDoc().fontFamily = mark.attrs.family); break; case schema.marks.pFontSize: setter(Doc.UserDoc().fontSize = mark.attrs.fontSize.toString() + "pt"); break; @@ -388,7 +392,9 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - return <select onChange={onChange} value={activeOption} key={key}>{items}</select>; + return <Tooltip key={key} title={<div className="dash-tooltip">{key}</div>} placement="bottom"> + <select onChange={onChange} value={activeOption}>{items}</select> + </Tooltip>; } createNodesDropdown(activeMap: string, options: { node: NodeType | any | null, title: string, label: string, command: (node: NodeType | any) => void, hidden?: boolean, style?: {} }[], key: string, setter: (val: string) => {}): JSX.Element { @@ -405,14 +411,17 @@ export default class RichTextMenu extends AntimodeMenu { self.TextView.endUndoTypingBatch(); options.forEach(({ label, node, command }) => { if (val === label && node) { - if (self.TextView.props.isSelected()) { + if (self.TextView.props.isSelected(true)) { UndoManager.RunInBatch(() => self.view && node && command(node), "nodes dropdown"); setter(val); } } }); } - return <select value={activeOption} onChange={e => onChange(e.target.value)} key={key}>{items}</select>; + + return <Tooltip key={key} title={<div className="dash-tooltip">{key}</div>} placement="bottom"> + <select value={activeOption} onChange={e => onChange(e.target.value)}>{items}</select> + </Tooltip>; } changeFontSize = (mark: Mark, view: EditorView) => { @@ -431,7 +440,7 @@ export default class RichTextMenu extends AntimodeMenu { const nextIsOL = this.view.state.selection.$from.nodeAfter?.type === schema.nodes.ordered_list; let inList: any = undefined; let fromList = -1; - let path: any = Array.from((this.view.state.selection.$from as any).path); + const path: any = Array.from((this.view.state.selection.$from as any).path); for (let i = 0; i < path.length; i++) { if (path[i]?.type === schema.nodes.ordered_list) { inList = path[i]; @@ -469,13 +478,13 @@ export default class RichTextMenu extends AntimodeMenu { return true; } alignCenter = (state: EditorState<any>, dispatch: any) => { - return this.TextView.props.isSelected() && this.alignParagraphs(state, "center", dispatch); + return this.TextView.props.isSelected(true) && this.alignParagraphs(state, "center", dispatch); } alignLeft = (state: EditorState<any>, dispatch: any) => { - return this.TextView.props.isSelected() && this.alignParagraphs(state, "left", dispatch); + return this.TextView.props.isSelected(true) && this.alignParagraphs(state, "left", dispatch); } alignRight = (state: EditorState<any>, dispatch: any) => { - return this.TextView.props.isSelected() && this.alignParagraphs(state, "right", dispatch); + return this.TextView.props.isSelected(true) && this.alignParagraphs(state, "right", dispatch); } alignParagraphs(state: EditorState<any>, align: "left" | "right" | "center", dispatch: any) { @@ -595,10 +604,11 @@ export default class RichTextMenu extends AntimodeMenu { label = "No marks are currently stored"; } - const button = - <button className="antimodeMenu-button" title="" onPointerDown={onBrushClick} style={this.brushMarks?.size > 0 ? { backgroundColor: "121212" } : {}}> + const button = <Tooltip title={<div className="dash-tooltip">style brush</div>} placement="bottom"> + <button className="antimodeMenu-button" onPointerDown={onBrushClick} style={this.brushMarks?.size > 0 ? { backgroundColor: "121212" } : {}}> <FontAwesomeIcon icon="paint-roller" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.brushMarks?.size > 0 ? 45 : 0}deg)` }} /> - </button>; + </button> + </Tooltip>; const dropdownContent = <div className="dropdown"> @@ -647,7 +657,7 @@ export default class RichTextMenu extends AntimodeMenu { @action toggleColorDropdown() { this.showColorDropdown = !this.showColorDropdown; } @action setActiveColor(color: string) { this.activeFontColor = color; } - get TextView() { return (this.view as any).TextView as FormattedTextBox; } + get TextView() { return (this.view as any)?.TextView as FormattedTextBox; } createColorButton() { const self = this; @@ -667,11 +677,12 @@ export default class RichTextMenu extends AntimodeMenu { self.TextView.EditorView!.focus(); } - const button = - <button className="antimodeMenu-button color-preview-button" title="" onPointerDown={onColorClick}> + const button = <Tooltip title={<div className="dash-tooltip">set font color</div>} placement="bottom"> + <button className="antimodeMenu-button color-preview-button" onPointerDown={onColorClick}> <FontAwesomeIcon icon="palette" size="lg" /> <div className="color-preview" style={{ backgroundColor: this.activeFontColor }}></div> - </button>; + </button> + </Tooltip>; const dropdownContent = <div className="dropdown" > @@ -720,11 +731,12 @@ export default class RichTextMenu extends AntimodeMenu { UndoManager.RunInBatch(() => self.view && self.insertHighlight(self.activeHighlightColor, self.view.state, self.view.dispatch), "rt highlighter"); } - const button = - <button className="antimodeMenu-button color-preview-button" title="" key="highilghter-button" onPointerDown={onHighlightClick}> + const button = <Tooltip title={<div className="dash-tooltip">set highlight color</div>} placement="bottom"> + <button className="antimodeMenu-button color-preview-button" key="highilghter-button" onPointerDown={onHighlightClick}> <FontAwesomeIcon icon="highlighter" size="lg" /> <div className="color-preview" style={{ backgroundColor: this.activeHighlightColor }}></div> - </button>; + </button> + </Tooltip>; const dropdownContent = <div className="dropdown"> @@ -763,7 +775,9 @@ export default class RichTextMenu extends AntimodeMenu { const link = this.currentLink ? this.currentLink : ""; - const button = <FontAwesomeIcon icon="link" size="lg" />; + const button = <Tooltip title={<div className="dash-tooltip">set hyperlink</div>} placement="bottom"> + <div><FontAwesomeIcon icon="link" size="lg" /> </div> + </Tooltip>; const dropdownContent = <div className="dropdown link-menu"> @@ -774,9 +788,7 @@ export default class RichTextMenu extends AntimodeMenu { <button className="remove-button" onPointerDown={e => this.deleteLink()}>Remove link</button> </div>; - return ( - <ButtonDropdown view={this.view} key={"link button"} button={button} dropdownContent={dropdownContent} openDropdownOnButton={true} /> - ); + return <ButtonDropdown view={this.view} key={"link button"} button={button} dropdownContent={dropdownContent} openDropdownOnButton={true} />; } async getTextLinkTargetTitle() { @@ -819,6 +831,8 @@ export default class RichTextMenu extends AntimodeMenu { ((this.view as any)?.TextView as FormattedTextBox).makeLinkToSelection("", target, "onRight", "", target); } + @undoBatch + @action deleteLink = () => { if (this.view) { const link = this.view.state.selection.$from.nodeAfter?.marks.find(m => m.type === this.view!.state.schema.marks.linkAnchor); @@ -935,7 +949,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, "nodes", action((val: string) => this.activeListType = val)), + this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", action((val: string) => this.activeListType = val)), 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), |