diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/ContentFittingDocumentView.tsx | 3 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentLinksButton.tsx | 125 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.scss | 9 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 13 | ||||
| -rw-r--r-- | src/client/views/nodes/FontIconBox.scss | 93 | ||||
| -rw-r--r-- | src/client/views/nodes/FontIconBox.tsx | 60 | ||||
| -rw-r--r-- | src/client/views/nodes/LabelBox.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/LinkDescriptionPopup.tsx | 14 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/RichTextMenu.tsx | 71 |
9 files changed, 193 insertions, 197 deletions
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index f7e253f42..6081def5d 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -78,9 +78,6 @@ export class ContentFittingDocumentView extends React.Component<DocumentViewProp render() { TraceMobx(); - if (this.props.Document.title === "Archive") { - console.log(""); - } return (<div className="contentFittingDocumentView" style={{ width: Math.abs(this.centeringYOffset) > 0.001 ? "auto" : this.props.PanelWidth(), height: Math.abs(this.centeringOffset) > 0.0001 ? "auto" : this.props.PanelHeight(), diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 198a90225..4713ce447 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -4,7 +4,7 @@ import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../../fields/Doc"; import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../../Utils"; +import { emptyFunction, returnFalse, setupMoveUpEvents, emptyPath } from "../../../Utils"; import { DocUtils } from "../../documents/Documents"; import { DragManager } from "../../util/DragManager"; import { LinkManager } from "../../util/LinkManager"; @@ -67,7 +67,11 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => { if (doubleTap && this.props.InMenu && this.props.StartLink) { //action(() => Doc.BrushDoc(this.props.View.Document)); - DocumentLinksButton.StartLink = this.props.View; + if (DocumentLinksButton.StartLink === this.props.View) { + DocumentLinksButton.StartLink = undefined; + } else { + DocumentLinksButton.StartLink = this.props.View; + } } else if (!this.props.InMenu) { DocumentLinksButton.EditLink = this.props.View; DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY]; @@ -78,7 +82,12 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp @action @undoBatch onLinkClick = (e: React.MouseEvent): void => { if (this.props.InMenu && this.props.StartLink) { - DocumentLinksButton.StartLink = this.props.View; + if (DocumentLinksButton.StartLink === this.props.View) { + DocumentLinksButton.StartLink = undefined; + } else { + DocumentLinksButton.StartLink = this.props.View; + } + //action(() => Doc.BrushDoc(this.props.View.Document)); } else if (!this.props.InMenu) { DocumentLinksButton.EditLink = this.props.View; @@ -86,77 +95,65 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp } } - @action @undoBatch completeLink = (e: React.PointerEvent): void => { - setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e, doubleTap) => { - if (doubleTap && this.props.InMenu && !!!this.props.StartLink) { + setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action((e, doubleTap) => { + if (doubleTap && this.props.InMenu && !this.props.StartLink) { if (DocumentLinksButton.StartLink === this.props.View) { DocumentLinksButton.StartLink = undefined; - } else { - - if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View) { - const linkDoc = DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag"); - LinkManager.currentLink = linkDoc; - - runInAction(() => { - if (linkDoc) { - TaskCompletionBox.textDisplayed = "Link Created"; - TaskCompletionBox.popupX = e.screenX; - TaskCompletionBox.popupY = e.screenY - 133; - TaskCompletionBox.taskCompleted = true; - - LinkDescriptionPopup.popupX = e.screenX; - LinkDescriptionPopup.popupY = e.screenY - 100; - LinkDescriptionPopup.descriptionPopup = true; + } else if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View) { + const linkDoc = DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag"); + LinkManager.currentLink = linkDoc; + if (linkDoc) { + TaskCompletionBox.textDisplayed = "Link Created"; + TaskCompletionBox.popupX = e.screenX; + TaskCompletionBox.popupY = e.screenY - 133; + TaskCompletionBox.taskCompleted = true; - setTimeout(action(() => { TaskCompletionBox.taskCompleted = false; }), 2500); - } + LinkDescriptionPopup.popupX = e.screenX; + LinkDescriptionPopup.popupY = e.screenY - 100; + LinkDescriptionPopup.descriptionPopup = true; - }); + setTimeout(action(() => TaskCompletionBox.taskCompleted = false), 2500); } } } - })); + }))); } - - @action @undoBatch - finishLinkClick = (screenX: number, screenY: number) => { + finishLinkClick = undoBatch(action((screenX: number, screenY: number) => { if (DocumentLinksButton.StartLink === this.props.View) { DocumentLinksButton.StartLink = undefined; - } else { - if (this.props.InMenu && !!!this.props.StartLink) { - if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View) { - const linkDoc = DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag"); - // this notifies any of the subviews that a document is made so that they can make finer-grained hyperlinks (). see note above in onLInkButtonMoved - runInAction(() => DocumentLinksButton.StartLink!._link = this.props.View._link = linkDoc); - setTimeout(action(() => DocumentLinksButton.StartLink!._link = this.props.View._link = undefined), 0); - LinkManager.currentLink = linkDoc; - - runInAction(() => { - if (linkDoc) { - TaskCompletionBox.textDisplayed = "Link Created"; - TaskCompletionBox.popupX = screenX; - TaskCompletionBox.popupY = screenY - 133; - TaskCompletionBox.taskCompleted = true; - - if (LinkDescriptionPopup.showDescriptions === "ON" || !LinkDescriptionPopup.showDescriptions) { - LinkDescriptionPopup.popupX = screenX; - LinkDescriptionPopup.popupY = screenY - 100; - LinkDescriptionPopup.descriptionPopup = true; - } - - setTimeout(action(() => { TaskCompletionBox.taskCompleted = false; }), 2500); - } - }); + } else if (this.props.InMenu && !this.props.StartLink && DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View) { + const linkDoc = DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag"); + // this notifies any of the subviews that a document is made so that they can make finer-grained hyperlinks (). see note above in onLInkButtonMoved + DocumentLinksButton.StartLink!._link = this.props.View._link = linkDoc; + setTimeout(action(() => DocumentLinksButton.StartLink!._link = this.props.View._link = undefined), 0); + LinkManager.currentLink = linkDoc; + if (linkDoc) { + TaskCompletionBox.textDisplayed = "Link Created"; + TaskCompletionBox.popupX = screenX; + TaskCompletionBox.popupY = screenY - 133; + TaskCompletionBox.taskCompleted = true; + + if (LinkDescriptionPopup.showDescriptions === "ON" || !LinkDescriptionPopup.showDescriptions) { + LinkDescriptionPopup.popupX = screenX; + LinkDescriptionPopup.popupY = screenY - 100; + LinkDescriptionPopup.descriptionPopup = true; } + + setTimeout(action(() => TaskCompletionBox.taskCompleted = false), 2500); } } - } + })); @observable public static EditLink: DocumentView | undefined; public static EditLinkLoc: number[] = [0, 0]; + + @action clearLinks() { + DocumentLinksButton.StartLink = undefined; + } + @computed get linkButton() { TraceMobx(); @@ -205,18 +202,26 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp link : links.length} </div> - {DocumentLinksButton.StartLink && this.props.InMenu && !!!this.props.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"} - style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }} - onPointerDown={this.completeLink} onClick={e => this.finishLinkClick(e.screenX, e.screenY)} /> : (null)} + {DocumentLinksButton.StartLink && this.props.InMenu && !this.props.StartLink && + DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"} + style={{ + width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px", + backgroundColor: DocumentLinksButton.StartLink ? "" : "grey", + border: DocumentLinksButton.StartLink ? "" : "none" + }} + onPointerDown={DocumentLinksButton.StartLink ? this.completeLink : emptyFunction} + onClick={e => DocumentLinksButton.StartLink ? this.finishLinkClick(e.screenX, e.screenY) : emptyFunction} /> : (null)} {DocumentLinksButton.StartLink === this.props.View && this.props.InMenu && this.props.StartLink ? <div className={"documentLinksButton-startLink"} - style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }} /> : (null)} + style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }} + onPointerDown={this.clearLinks} onClick={this.clearLinks} + /> : (null)} </div>; return (!links.length) && !this.props.AlwaysOn ? (null) : this.props.InMenu ? <Tooltip title={<><div className="dash-tooltip">{title}</div></>}> {linkButton} - </Tooltip> : !!!DocumentLinksButton.EditLink ? + </Tooltip> : !!!DocumentLinksButton.EditLink && !this.props.InMenu ? <Tooltip title={<><div className="dash-tooltip">{title}</div></>}> {linkButton} </Tooltip> : diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index b978f6245..e6b8928d4 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -54,6 +54,15 @@ } } + .documentView-anchorCont { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: inline-block; + } + .documentView-lock { width: 20; height: 20; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 22a2bb8fe..e6e709621 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -677,10 +677,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu @action onCopy = () => { - const copy = Doc.MakeCopy(this.props.Document, true); - copy.x = NumCast(this.props.Document.x) + NumCast(this.props.Document._width); - copy.y = NumCast(this.props.Document.y) + 30; - this.props.addDocument?.(copy); + const alias = Doc.MakeAlias(this.props.Document); + alias.x = NumCast(this.props.Document.x) + NumCast(this.props.Document._width); + alias.y = NumCast(this.props.Document.y) + 30; + this.props.addDocument?.(alias); } @action @@ -760,6 +760,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu moreItems.push({ description: "Write Back Link to Album", event: () => GooglePhotos.Transactions.AddTextEnrichment(this.props.Document), icon: "caret-square-right" }); } moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); + Doc.AreProtosEqual(this.props.Document, Doc.UserDoc()) && moreItems.push({ description: "Toggle Always Show Link End", event: () => Doc.UserDoc()["documentLinksButton-hideEnd"] = !Doc.UserDoc()["documentLinksButton-hideEnd"], icon: "eye" }); } //GetEffectiveAcl(this.props.Document) === AclEdit && moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" }); @@ -890,7 +891,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu this.rootDoc.type === DocumentType.LINK || this.props.dontRegisterView ? (null) : // view that are not registered DocUtils.FilterDocs(this.directLinks, this.props.docFilters(), []).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) => - <DocumentView {...this.props} key={i + 1} + <div className="documentView-anchorCont" key={i + 1}> <DocumentView {...this.props} Document={d} ContainingCollectionView={this.props.ContainingCollectionView} ContainingCollectionDoc={this.props.Document} // bcz: hack this.props.Document is not a collection Need a better prop for passing the containing document to the LinkAnchorBox @@ -903,7 +904,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu pointerEvents={false} LayoutTemplate={undefined} LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(d, this.props.Document)}`)} - />); + /></div >); } @computed get innards() { TraceMobx(); diff --git a/src/client/views/nodes/FontIconBox.scss b/src/client/views/nodes/FontIconBox.scss index 13af511a6..5bdafd857 100644 --- a/src/client/views/nodes/FontIconBox.scss +++ b/src/client/views/nodes/FontIconBox.scss @@ -1,77 +1,62 @@ -.fontIconBox-outerDiv { +.fontIconBox-label { + color: white; + margin-right: 4px; + margin-top: 1px; + position: relative; + text-align: center; + font-size: 7px; + letter-spacing: normal; + background-color: inherit; + border-radius: 8px; + margin-top: -8px; + padding: 0; width: 100%; - height: 100%; - pointer-events: all; - touch-action: none; - border-radius: inherit; - background: black; +} + +.menuButton-round { border-radius: 100%; - transform-origin: top left; .fontIconBox-label { - background: gray; - color: white; - border-radius: 8px; - width: 100%; + margin-left: -10px; // button padding is 10px; + bottom: 0; position: absolute; - text-align: center; - font-size: 8px; - //margin-top:4px; - letter-spacing: normal; - left: 0; - overflow: hidden; } +} - svg { - width: 95% !important; - height: 95%; +.menuButton-square { + padding-top: 3px; + padding-bottom: 3px; + padding-left: 5px; + + .fontIconBox-label { + border-radius: 0px; + margin-top: 0px; + border-radius: "inherit"; } } -.menuButton { - //padding: 7px; - padding-left: 5px; +.menuButton, +.menuButton-round, +.menuButton-square { width: 100%; - width: 60px; - height: 70px; - padding-top: 3px; - padding-bottom: 3px; + height: 100%; + pointer-events: all; + touch-action: none; .menuButton-wrap { - width: 45px; - /* padding: 5px; */ touch-action: none; - background: black; - transform-origin: top left; - /* margin-bottom: 5px; */ - margin-top: 5px; - margin-right: 25px; border-radius: 8px; - &:hover { - background: rgb(61, 61, 61); - cursor: pointer; - } - } - - .menuButton-label { - color: white; - margin-right: 4px; - border-radius: 8px; - width: 42px; - position: relative; - text-align: center; - font-size: 7px; - margin-top: 1px; - letter-spacing: normal; - padding: 3px; - background-color: inherit; + // &:hover { + // background: rgb(61, 61, 61); + // cursor: pointer; + // } } - .menuButton-icon { + .menuButton-icon-square { width: auto; height: 32px; - padding: 5px; + padding: 4px; } svg { diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx index 720d6a15d..eff5a4160 100644 --- a/src/client/views/nodes/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox.tsx @@ -6,14 +6,12 @@ import { DocComponent } from '../DocComponent'; import './FontIconBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; import { StrCast, Cast, NumCast } from '../../../fields/Types'; -import { Utils } from "../../../Utils"; +import { Utils, emptyFunction } from "../../../Utils"; import { runInAction, observable, reaction, IReactionDisposer } from 'mobx'; import { Doc } from '../../../fields/Doc'; import { ContextMenu } from '../ContextMenu'; import { ScriptField } from '../../../fields/ScriptField'; import { Tooltip } from '@material-ui/core'; -import { createUnionOrIntersectionTypeNode } from 'typescript'; -import { CurrentUserUtils } from '../../util/CurrentUserUtils'; const FontIconSchema = createSchema({ icon: "string", }); @@ -61,45 +59,23 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>( } render() { - - //style={{ backgroundColor: this.props.backgroundColor?.(this.props.Document) }}> - - if (this.layoutDoc.menuIcon) { - - let backgroundColor = "black"; - if (this.dataDoc.title === "Sharing" || this.dataDoc.title === "Help" || this.dataDoc.title === "Settings" || this.dataDoc.title === "Import") { - backgroundColor = "black"; - } else { - backgroundColor = CurrentUserUtils.selectedPanel === this.dataDoc.title ? "lightgrey" : "black"; - } - - const color = backgroundColor === "lightgrey" ? "black" : "white"; - const menuBTN = <div className="menuButton" style={{ backgroundColor: backgroundColor }}> - - <div className="menuButton-wrap" style={{ backgroundColor: backgroundColor }}> - <FontAwesomeIcon className="menuButton-icon" icon={StrCast(this.dataDoc.icon, "user") as any} color={color} size="lg" /> - <div className="menuButton-label" style={{ color: color }}> {this.dataDoc.title} </div> + const label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title)); + const color = StrCast(this.layoutDoc.color, this._foregroundColor); + const backgroundColor = StrCast(this.layoutDoc._backgroundColor, StrCast(this.rootDoc.backgroundColor, this.props.backgroundColor?.(this.rootDoc))); + const shape = StrCast(this.layoutDoc.iconShape, "round"); + const button = <> + <button className={`menuButton-${shape}`} ref={this._ref} onContextMenu={this.specificContextMenu} + style={{ boxShadow: this.layoutDoc.ischecked ? `4px 4px 12px black` : undefined, backgroundColor }}> + <div className="menuButton-wrap"> + {<FontAwesomeIcon className={`menuButton-icon-${shape}`} icon={StrCast(this.dataDoc.icon, "user") as any} color={color} + size={this.layoutDoc.iconShape === "square" ? "sm" : "lg"} />} + {!label ? (null) : <div className="fontIconBox-label" style={{ color, backgroundColor }}> {label} </div>} </div> - </div>; - - return menuBTN; - } else { - const referenceDoc = (this.layoutDoc.dragFactory instanceof Doc ? this.layoutDoc.dragFactory : this.layoutDoc); - const refLayout = Doc.Layout(referenceDoc); - const button = <button className="fontIconBox-outerDiv" ref={this._ref} onContextMenu={this.specificContextMenu} - style={{ - padding: Cast(this.layoutDoc._xPadding, "number", null), - background: StrCast(refLayout._backgroundColor, StrCast(refLayout.backgroundColor)), - boxShadow: this.layoutDoc.ischecked ? `4px 4px 12px black` : undefined - }}> - <FontAwesomeIcon className="fontIconBox-icon" icon={StrCast(this.dataDoc.icon, "user") as any} color={StrCast(this.layoutDoc.color, this._foregroundColor)} size="sm" /> - {!this.rootDoc.title ? (null) : <div className="fontIconBox-label" style={{ width: this.rootDoc.label ? "max-content" : undefined }}> {StrCast(this.rootDoc.label, StrCast(this.rootDoc.title).substring(0, 6))} </div>} - </button>; - return !this.layoutDoc.toolTip ? button : - <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}> - {button} - </Tooltip>; - } - + </button> + </>; + return !this.layoutDoc.toolTip ? button : + <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}> + {button} + </Tooltip>; } }
\ No newline at end of file diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index 0dfbdc5cf..05ba6628c 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -41,7 +41,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps, LabelDocument }, icon: "trash" }); - ContextMenu.Instance.addItem({ description: "OnClick...", noexpand: true, subitems: funcs, icon: "asterisk" }); + ContextMenu.Instance.addItem({ description: "OnClick...", noexpand: true, subitems: funcs, icon: "mouse-pointer" }); } @undoBatch diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx index d8fe47f4e..720af6c9d 100644 --- a/src/client/views/nodes/LinkDescriptionPopup.tsx +++ b/src/client/views/nodes/LinkDescriptionPopup.tsx @@ -19,12 +19,15 @@ export class LinkDescriptionPopup extends React.Component<{}> { @action descriptionChanged = (e: React.ChangeEvent<HTMLInputElement>) => { - LinkManager.currentLink && (LinkManager.currentLink.description = e.currentTarget.value); + this.description = e.currentTarget.value; } @action - onDismiss = () => { + onDismiss = (add: boolean) => { LinkDescriptionPopup.descriptionPopup = false; + if (add) { + LinkManager.currentLink && (LinkManager.currentLink.description = this.description); + } } @action @@ -50,15 +53,16 @@ export class LinkDescriptionPopup extends React.Component<{}> { left: LinkDescriptionPopup.popupX ? LinkDescriptionPopup.popupX : 700, top: LinkDescriptionPopup.popupY ? LinkDescriptionPopup.popupY : 350, }}> - <input className="linkDescriptionPopup-input" onKeyPress={e => e.key === "Enter" && this.onDismiss()} + <input className="linkDescriptionPopup-input" + onKeyPress={e => e.key === "Enter" && this.onDismiss(true)} placeholder={"(optional) enter link label..."} onChange={(e) => this.descriptionChanged(e)}> </input> <div className="linkDescriptionPopup-btn"> <div className="linkDescriptionPopup-btn-dismiss" - onPointerDown={this.onDismiss}> Dismiss </div> + onPointerDown={e => this.onDismiss(false)}> Dismiss </div> <div className="linkDescriptionPopup-btn-add" - onPointerDown={this.onDismiss}> Add </div> + onPointerDown={e => this.onDismiss(true)}> Add </div> </div> </div>; } diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index f76707a79..6e268be48 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -185,11 +185,15 @@ export default class RichTextMenu extends AntimodeMenu { const active = this.getActiveFontStylesOnSelection(); const activeFamilies = active.activeFamilies; const activeSizes = active.activeSizes; + const activeColors = active.activeColors; + const activeHighlights = active.activeHighlights; this.activeListType = this.getActiveListStyle(); this.activeAlignment = this.getActiveAlignment(); this.activeFontFamily = !activeFamilies.length ? "Arial" : activeFamilies.length === 1 ? String(activeFamilies[0]) : "various"; this.activeFontSize = !activeSizes.length ? "13pt" : activeSizes.length === 1 ? String(activeSizes[0]) : "..."; + this.activeFontColor = !activeColors.length ? "black" : activeColors.length === 1 ? String(activeColors[0]) : "..."; + this.activeHighlightColor = !activeHighlights.length ? "" : activeHighlights.length === 1 ? String(activeHighlights[0]) : "..."; // update link in current selection const targetTitle = await this.getTextLinkTargetTitle(); @@ -250,10 +254,12 @@ export default class RichTextMenu extends AntimodeMenu { // finds font sizes and families in selection getActiveFontStylesOnSelection() { - if (!this.view) return { activeFamilies: [], activeSizes: [] }; + if (!this.view) return { activeFamilies: [], activeSizes: [], activeColors: [], activeHighlights: [] }; const activeFamilies: string[] = []; const activeSizes: string[] = []; + const activeColors: string[] = []; + const activeHighlights: string[] = []; if (this.TextView.props.isSelected(true)) { const state = this.view.state; const pos = this.view.state.selection.$from; @@ -261,15 +267,20 @@ export default class RichTextMenu extends AntimodeMenu { if (ref_node && ref_node !== this.view.state.doc && ref_node.isText) { ref_node.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"); + m.type === state.schema.marks.marker && activeHighlights.push(String(m.attrs.highlight)); }); } !activeFamilies.length && (activeFamilies.push(StrCast(this.TextView.layoutDoc._fontFamily, StrCast(Doc.UserDoc().fontFamily)))); !activeSizes.length && (activeSizes.push(StrCast(this.TextView.layoutDoc._fontSize, StrCast(Doc.UserDoc().fontSize)))); + !activeColors.length && (activeSizes.push(StrCast(this.TextView.layoutDoc.color, StrCast(Doc.UserDoc().fontColor)))); } !activeFamilies.length && (activeFamilies.push(StrCast(Doc.UserDoc().fontFamily))); !activeSizes.length && (activeSizes.push(StrCast(Doc.UserDoc().fontSize))); - return { activeFamilies, activeSizes }; + !activeColors.length && (activeColors.push(StrCast(Doc.UserDoc().fontColor, "black"))); + !activeHighlights.length && (activeHighlights.push(StrCast(Doc.UserDoc().fontHighlight, ""))); + return { activeFamilies, activeSizes, activeColors, activeHighlights }; } getMarksInSelection(state: EditorState<any>) { @@ -426,10 +437,16 @@ export default class RichTextMenu extends AntimodeMenu { } changeFontSize = (mark: Mark, view: EditorView) => { + 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); } 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); } @@ -606,8 +623,11 @@ export default class RichTextMenu extends AntimodeMenu { label = "No marks are currently stored"; } + //onPointerDown={onBrushClick} + 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" } : {}}> + + <button className="antimodeMenu-button" 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> </Tooltip>; @@ -616,11 +636,11 @@ export default class RichTextMenu extends AntimodeMenu { <div className="dropdown"> <p>{label}</p> <button onPointerDown={this.clearBrush}>Clear brush</button> - <input placeholder="-brush name-" ref={this._brushNameRef} onKeyPress={this.onBrushNameKeyPress}></input> + <input placeholder="-brush name-" ref={this._brushNameRef} onKeyPress={this.onBrushNameKeyPress} /> </div>; return ( - <ButtonDropdown view={this.view} key={"brush dropdown"} button={button} dropdownContent={dropdownContent} /> + <ButtonDropdown view={this.view} key={"brush dropdown"} button={button} dropdownContent={dropdownContent} openDropdownOnButton={true} /> ); } @@ -679,8 +699,9 @@ export default class RichTextMenu extends AntimodeMenu { self.TextView.EditorView!.focus(); } + // 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}> + <button className="antimodeMenu-button color-preview-button"> <FontAwesomeIcon icon="palette" size="lg" /> <div className="color-preview" style={{ backgroundColor: this.activeFontColor }}></div> </button> @@ -701,7 +722,7 @@ export default class RichTextMenu extends AntimodeMenu { </div>; return ( - <ButtonDropdown view={this.view} key={"color dropdown"} button={button} dropdownContent={dropdownContent} /> + <ButtonDropdown view={this.view} key={"color dropdown"} button={button} dropdownContent={dropdownContent} openDropdownOnButton={true} /> ); } @@ -733,8 +754,9 @@ export default class RichTextMenu extends AntimodeMenu { UndoManager.RunInBatch(() => self.view && self.insertHighlight(self.activeHighlightColor, self.view.state, self.view.dispatch), "rt highlighter"); } + //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}> + <button className="antimodeMenu-button color-preview-button" key="highilghter-button" > <FontAwesomeIcon icon="highlighter" size="lg" /> <div className="color-preview" style={{ backgroundColor: this.activeHighlightColor }}></div> </button> @@ -755,7 +777,7 @@ export default class RichTextMenu extends AntimodeMenu { </div>; return ( - <ButtonDropdown view={this.view} key={"highlighter"} button={button} dropdownContent={dropdownContent} /> + <ButtonDropdown view={this.view} key={"highlighter"} button={button} dropdownContent={dropdownContent} openDropdownOnButton={true} /> ); } @@ -778,7 +800,9 @@ export default class RichTextMenu extends AntimodeMenu { const link = this.currentLink ? this.currentLink : ""; const button = <Tooltip title={<div className="dash-tooltip">set hyperlink</div>} placement="bottom"> - <div><FontAwesomeIcon icon="link" size="lg" /> </div> + <button className="antimodeMenu-button color-preview-button"> + <FontAwesomeIcon icon="link" size="lg" /> + </button> </Tooltip>; const dropdownContent = @@ -790,7 +814,8 @@ 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} link={true} />; } async getTextLinkTargetTitle() { @@ -877,10 +902,11 @@ export default class RichTextMenu extends AntimodeMenu { if (pos.nodeBefore !== null && pos.nodeBefore !== undefined) { ref_node = pos.nodeBefore; } - else if (pos.nodeAfter !== null && pos.nodeAfter !== undefined) { - ref_node = pos.nodeAfter; + if (pos.nodeAfter !== null && pos.nodeAfter !== undefined) { + if (!pos.nodeBefore || this.view.state.selection.$from.pos !== this.view.state.selection.$to.pos) + ref_node = pos.nodeAfter; } - else if (pos.pos > 0) { + if (!ref_node && pos.pos > 0) { let skip = false; for (let i: number = pos.pos - 1; i > 0; i--) { this.view.state.doc.nodesBetween(i, pos.pos, (node: ProsNode) => { @@ -989,6 +1015,7 @@ interface ButtonDropdownProps { button: JSX.Element; dropdownContent: JSX.Element; openDropdownOnButton?: boolean; + link?: boolean; } @observer @@ -1031,18 +1058,10 @@ export class ButtonDropdown extends React.Component<ButtonDropdownProps> { render() { return ( <div className="button-dropdown-wrapper" ref={node => this.ref = node}> - {this.props.openDropdownOnButton ? - <button className="antimodeMenu-button dropdown-button-combined" onPointerDown={this.onDropdownClick}> - {this.props.button} - <FontAwesomeIcon icon="caret-down" size="sm" /> - </button> : - <> - {this.props.button} - <button className="dropdown-button antimodeMenu-button" key="antimodebutton" onPointerDown={this.onDropdownClick}> - <FontAwesomeIcon icon="caret-down" size="sm" /> - </button> - </>} - + <div className="antimodeMenu-button dropdown-button-combined" onPointerDown={this.onDropdownClick}> + {this.props.button} + <div style={{ marginTop: "-8.5" }}><FontAwesomeIcon icon="caret-down" size="sm" /></div> + </div> {this.showDropdown ? this.props.dropdownContent : (null)} </div> ); |
