aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/ContentFittingDocumentView.tsx3
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx125
-rw-r--r--src/client/views/nodes/DocumentView.scss9
-rw-r--r--src/client/views/nodes/DocumentView.tsx13
-rw-r--r--src/client/views/nodes/FontIconBox.scss93
-rw-r--r--src/client/views/nodes/FontIconBox.tsx60
-rw-r--r--src/client/views/nodes/LabelBox.tsx2
-rw-r--r--src/client/views/nodes/LinkDescriptionPopup.tsx14
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx71
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>
);