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/FormattedTextBox.tsx12
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.scss126
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx113
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx30
4 files changed, 146 insertions, 135 deletions
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 3c5c48c7c..d69f8e3db 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -174,19 +174,25 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
linkOnDeselect: Map<string, string> = new Map();
doLinkOnDeselect() {
+
Array.from(this.linkOnDeselect.entries()).map(entry => {
const key = entry[0];
const value = entry[1];
+
const id = Utils.GenerateDeterministicGuid(this.dataDoc[Id] + key);
DocServer.GetRefField(value).then(doc => {
DocServer.GetRefField(id).then(linkDoc => {
this.dataDoc[key] = doc || Docs.Create.FreeformDocument([], { title: value, _width: 500, _height: 500 }, value);
DocUtils.Publish(this.dataDoc[key] as Doc, value, this.props.addDocument, this.props.removeDocument);
- if (linkDoc) { (linkDoc as Doc).anchor2 = this.dataDoc[key] as Doc; }
- else DocUtils.MakeLink({ doc: this.rootDoc }, { doc: this.dataDoc[key] as Doc }, "portal link", "link to named target", id);
+ if (linkDoc) {
+ (linkDoc as Doc).anchor2 = this.dataDoc[key] as Doc;
+ } else {
+ DocUtils.MakeLink({ doc: this.rootDoc }, { doc: this.dataDoc[key] as Doc }, "portal link", "link to named target", id);
+ }
});
});
});
+
this.linkOnDeselect.clear();
}
@@ -944,6 +950,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
frag.forEach(node => nodes.push(marker(node)));
return Fragment.fromArray(nodes);
}
+
+
function addLinkMark(node: Node, title: string, linkId: string) {
if (!node.isText) {
const content = addMarkToFrag(node.content, (node: Node) => addLinkMark(node, title, linkId));
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
index 9089e7039..6a403cb17 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
@@ -4,10 +4,74 @@
z-index: 20;
background: white;
border: 1px solid silver;
- border-radius: 2px;
+ border-radius: 7px;
margin-bottom: 7px;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
+ box-shadow: 3px 3px 1.5px grey;
+
+ .FormattedTextBoxComment {
+ background-color: white;
+ border: 8px solid white;
+
+ //display: flex;
+ .FormattedTextBoxComment-info {
+
+ margin-bottom: 9px;
+
+ .FormattedTextBoxComment-title {
+ padding-right: 4px;
+ float: left;
+
+ .FormattedTextBoxComment-description {
+ text-decoration: none;
+ font-style: italic;
+ color: rgb(95, 97, 102);
+ font-size: 10px;
+ padding-bottom: 4px;
+ margin-bottom: 5px;
+
+ }
+ }
+
+ .FormattedTextBoxComment-button {
+ display: inline;
+ padding-left: 6px;
+ padding-right: 6px;
+ padding-top: 2.5px;
+ padding-bottom: 2.5px;
+ width: 17px;
+ height: 17px;
+ margin: 0;
+ margin-right: 3px;
+ border-radius: 50%;
+ pointer-events: auto;
+ background-color: rgb(0, 0, 0);
+ color: rgb(255, 255, 255);
+ transition: transform 0.2s;
+ text-align: center;
+ position: relative;
+ font-size: 12px;
+
+ &:hover {
+ background-color: rgb(77, 77, 77);
+ cursor: pointer;
+ }
+ }
+ }
+
+ .FormattedTextBoxComment-preview-wrapper {
+ width: 170px;
+ height: 170px;
+ overflow: hidden;
+ //padding-top: 5px;
+ margin-top: 10px;
+ margin-bottom: 8px;
+ align-content: center;
+ justify-content: center;
+ background-color: rgb(160, 160, 160);
+ }
+ }
}
.FormattedTextBox-tooltip:before {
@@ -42,64 +106,4 @@
top: 50%;
right: 0;
transform: translateY(-50%);
-
- .FormattedTextBoxComment-button {
- width: 20px;
- height: 20px;
- margin: 0;
- margin-right: 6px;
- border-radius: 50%;
- pointer-events: auto;
- background-color: rgb(38, 40, 41);
- color: rgb(178, 181, 184);
- font-size: 65%;
- transition: transform 0.2s;
- text-align: center;
- position: relative;
-
- // margin-top: "auto";
- // margin-bottom: "auto";
- // background: black;
- // color: white;
- // display: inline-block;
- // border-radius: 18px;
- // font-size: 12.5px;
- // width: 18px;
- // height: 18px;
- // margin-top: auto;
- // margin-bottom: auto;
- // margin-right: 3px;
- // cursor: pointer;
- // transition: transform 0.2s;
-
- .FormattedTextBoxComment-fa-icon {
- margin-top: "auto";
- margin-bottom: "auto";
- background: black;
- color: white;
- display: inline-block;
- border-radius: 18px;
- font-size: 12.5px;
- width: 18px;
- height: 18px;
- margin-top: auto;
- margin-bottom: auto;
- margin-right: 3px;
- cursor: pointer;
- transition: transform 0.2s;
- // position: absolute;
- // top: 50%;
- // left: 50%;
- // transform: translate(-50%, -50%);
- }
-
- &:last-child {
- margin-right: 0;
- }
-
- &:hover {
- background: rgb(53, 146, 199);
- ;
- }
- }
} \ No newline at end of file
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 56826e5c7..fa2548cb5 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -3,7 +3,7 @@ import { EditorState, Plugin } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import * as ReactDOM from 'react-dom';
import { Doc, DocCastAsync, Opt } from "../../../../fields/Doc";
-import { Cast, FieldValue, NumCast } from "../../../../fields/Types";
+import { Cast, FieldValue, NumCast, StrCast } from "../../../../fields/Types";
import { emptyFunction, returnEmptyString, returnFalse, Utils, emptyPath, returnZero, returnOne, returnEmptyFilter } from "../../../../Utils";
import { DocServer } from "../../../DocServer";
import { DocumentManager } from "../../../util/DocumentManager";
@@ -21,6 +21,7 @@ import { action } from "mobx";
import { LinkManager } from "../../../util/LinkManager";
import { LinkDocPreview } from "../LinkDocPreview";
import { DocumentLinksButton } from "../DocumentLinksButton";
+import { Tooltip } from "@material-ui/core";
export let formattedTextBoxCommentPlugin = new Plugin({
view(editorView) { return new FormattedTextBoxComment(editorView); }
@@ -85,13 +86,13 @@ export class FormattedTextBoxComment {
FormattedTextBoxComment.tooltip.className = "FormattedTextBox-tooltip";
FormattedTextBoxComment.tooltip.style.pointerEvents = "all";
FormattedTextBoxComment.tooltip.style.maxWidth = "200px";
- FormattedTextBoxComment.tooltip.style.maxHeight = "206px";
+ FormattedTextBoxComment.tooltip.style.maxHeight = "235px";
FormattedTextBoxComment.tooltip.style.width = "100%";
FormattedTextBoxComment.tooltip.style.height = "100%";
FormattedTextBoxComment.tooltip.style.overflow = "hidden";
FormattedTextBoxComment.tooltip.style.display = "none";
FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipInput);
- FormattedTextBoxComment.tooltip.onpointerdown = (e: PointerEvent) => {
+ FormattedTextBoxComment.tooltip.onpointerdown = async (e: PointerEvent) => {
const keep = e.target && (e.target as any).type === "checkbox" ? true : false;
const textBox = FormattedTextBoxComment.textBox;
if (FormattedTextBoxComment.linkDoc && !keep && textBox) {
@@ -103,8 +104,22 @@ export class FormattedTextBoxComment {
if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
} else {
- DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
- (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+ const anchor = FieldValue(Doc.AreProtosEqual(FieldValue(Cast(FormattedTextBoxComment.linkDoc.anchor1, Doc)), textBox.dataDoc) ?
+ Cast(FormattedTextBoxComment.linkDoc.anchor2, Doc) : (Cast(FormattedTextBoxComment.linkDoc.anchor1, Doc))
+ || FormattedTextBoxComment.linkDoc);
+ const target = anchor?.annotationOn ? await DocCastAsync(anchor.annotationOn) : anchor;
+
+ if (FormattedTextBoxComment.linkDoc.follow) {
+ if (FormattedTextBoxComment.linkDoc.follow === "Default") {
+ DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document, doc => textBox.props.addDocTab(doc, "onRight"), false);
+ } else if (FormattedTextBoxComment.linkDoc.follow === "Always open in right tab") {
+ if (target) { textBox.props.addDocTab(target, "onRight"); }
+ } else if (FormattedTextBoxComment.linkDoc.follow === "Always open in new tab") {
+ if (target) { textBox.props.addDocTab(target, "inTab"); }
+ }
+ } else {
+ DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document, doc => textBox.props.addDocTab(doc, "onRight"), false);
+ }
}
} else {
if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
@@ -241,55 +256,36 @@ export class FormattedTextBoxComment {
}
if (target?.author) {
FormattedTextBoxComment.showCommentbox("", view, nbef);
- const docPreview = <div style={{ backgroundColor: "white", border: "8px solid white" }}>
- {target.title}
- <div className="wrapper" style={{ float: "right" }}>
- <div title="Delete link" className="FormattedTextBoxComment-button" style={{
- display: "inline",
- paddingLeft: "6px",
- paddingRight: "6px",
- paddingTop: "2.5px",
- paddingBottom: "2.5px",
- width: "20px",
- height: "20px",
- margin: 0,
- marginRight: "6px",
- borderRadius: "50%",
- pointerEvents: "auto",
- backgroundColor: "rgb(38, 40, 41)",
- color: "rgb(178, 181, 184)",
- transition: "transform 0.2s",
- textAlign: "center",
- position: "relative"
- }} ref={(r) => this._deleteRef = r}>
- <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="trash"
- size="sm" /></div>
- <div title="Follow link" className="FormattedTextBoxComment-button" style={{
- display: "inline",
- paddingLeft: "6px",
- paddingRight: "6px",
- paddingTop: "2.5px",
- paddingBottom: "2.5px",
- width: "20px",
- height: "20px",
- margin: 0,
- marginRight: "6px",
- borderRadius: "50%",
- pointerEvents: "auto",
- backgroundColor: "rgb(38, 40, 41)",
- color: "rgb(178, 181, 184)",
- transition: "transform 0.2s",
- textAlign: "center",
- position: "relative"
- }} ref={(r) => this._followRef = r}>
- <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="arrow-right"
- size="sm" />
+
+ const title = StrCast(target.title).length > 16 ?
+ StrCast(target.title).substr(0, 16) + "..." : target.title;
+
+
+ const docPreview = <div className="FormattedTextBoxComment">
+ <div className="FormattedTextBoxComment-info">
+ <div className="FormattedTextBoxComment-title">
+ {title}
+ {FormattedTextBoxComment.linkDoc.description !== "" ? <p className="FormattedTextBoxComment-description">
+ {StrCast(FormattedTextBoxComment.linkDoc.description)}</p> : null}
</div>
- </div>
- <div className="wrapper" style={{
- maxWidth: "180px", maxHeight: "168px", overflow: "hidden",
- overflowY: "hidden", paddingTop: "5px"
- }}>
+ <div className="wrapper" style={{ float: "right" }}>
+
+ <Tooltip title="Delete Link" placement="top">
+ <div className="FormattedTextBoxComment-button"
+ ref={(r) => this._deleteRef = r}>
+ <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="trash" color="white"
+ size="sm" /></div>
+ </Tooltip>
+
+ <Tooltip title="Follow Link" placement="top">
+ <div className="FormattedTextBoxComment-button"
+ ref={(r) => this._followRef = r}>
+ <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="arrow-right" color="white"
+ size="sm" />
+ </div>
+ </Tooltip>
+ </div> </div>
+ <div className="FormattedTextBoxComment-preview-wrapper">
<ContentFittingDocumentView
Document={target}
LibraryPath={emptyPath}
@@ -307,17 +303,20 @@ export class FormattedTextBoxComment {
ContainingCollectionDoc={undefined}
ContainingCollectionView={undefined}
renderDepth={0}
- PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
- PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
+ PanelWidth={() => 175} //Math.min(350, NumCast(target._width, 350))}
+ PanelHeight={() => 175} //Math.min(250, NumCast(target._height, 250))}
focus={emptyFunction}
whenActiveChanged={returnFalse}
bringToFront={returnFalse}
ContentScaling={returnOne}
- NativeWidth={returnZero}
- NativeHeight={returnZero}
+ NativeWidth={() => target._nativeWidth ? NumCast(target._nativeWidth) : 0}
+ NativeHeight={() => target._nativeHeight ? NumCast(target._nativeHeight) : 0}
/>
</div>
</div>;
+
+
+
FormattedTextBoxComment.showCommentbox("", view, nbef);
ReactDOM.render(docPreview, FormattedTextBoxComment.tooltipText);
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index f10c425d4..1a8a4ceb7 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -358,11 +358,11 @@ export default class RichTextMenu extends AntimodeMenu {
const items = options.map(({ title, label, hidden, style }) => {
if (hidden) {
return label === activeOption ?
- <option value={label} title={title} key={label} style={style ? style : {}} selected hidden>{label}</option> :
+ <option value={label} title={title} key={label} style={style ? style : {}} hidden>{label}</option> :
<option value={label} title={title} key={label} style={style ? style : {}} hidden>{label}</option>;
}
return label === activeOption ?
- <option value={label} title={title} key={label} style={style ? style : {}} selected>{label}</option> :
+ <option value={label} title={title} key={label} style={style ? style : {}}>{label}</option> :
<option value={label} title={title} key={label} style={style ? style : {}}>{label}</option>;
});
@@ -385,11 +385,11 @@ export default class RichTextMenu extends AntimodeMenu {
const items = options.map(({ title, label, hidden, style }) => {
if (hidden) {
return label === activeOption ?
- <option value={label} title={title} key={label} style={style ? style : {}} selected hidden>{label}</option> :
+ <option value={label} title={title} key={label} style={style ? style : {}} hidden>{label}</option> :
<option value={label} title={title} key={label} style={style ? style : {}} hidden>{label}</option>;
}
return label === activeOption ?
- <option value={label} title={title} key={label} style={style ? style : {}} selected>{label}</option> :
+ <option value={label} title={title} key={label} style={style ? style : {}}>{label}</option> :
<option value={label} title={title} key={label} style={style ? style : {}}>{label}</option>;
});
@@ -882,22 +882,22 @@ export default class RichTextMenu extends AntimodeMenu {
render() {
TraceMobx();
- const row1 = <div className="antimodeMenu-row" key="row1" style={{ display: this.collapsed ? "none" : undefined }}>{[
+ const row1 = <div className="antimodeMenu-row" key="row 1" style={{ display: this.collapsed ? "none" : undefined }}>{[
!this.collapsed ? this.getDragger() : (null),
- !this.Pinned ? (null) : <> {[
+ !this.Pinned ? (null) : <div key="frag1"> {[
this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)),
this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)),
this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)),
this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)),
this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)),
this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)),
- <div className="richTextMenu-divider" />
- ]}</>,
+ <div className="richTextMenu-divider" key="divider" />
+ ]}</div>,
this.createColorButton(),
this.createHighlighterButton(),
this.createLinkButton(),
this.createBrushButton(),
- <div className="richTextMenu-divider" />,
+ <div className="richTextMenu-divider" key="divider 2" />,
this.createButton("align-left", "Align Left", this.activeAlignment === "left", this.alignLeft),
this.createButton("align-center", "Align Center", this.activeAlignment === "center", this.alignCenter),
this.createButton("align-right", "Align Right", this.activeAlignment === "right", this.alignRight),
@@ -907,20 +907,20 @@ export default class RichTextMenu extends AntimodeMenu {
this.createButton("hand-point-right", "Indent", undefined, this.indentParagraph),
]}</div>;
- const row2 = <div className="antimodeMenu-row row-2" key="antimodemenu row2">
+ const row2 = <div className="antimodeMenu-row row-2" key="row2">
{this.collapsed ? this.getDragger() : (null)}
- <div key="row" style={{ display: this.collapsed ? "none" : undefined }}>
- <div className="richTextMenu-divider" />,
+ <div key="row 2" style={{ display: this.collapsed ? "none" : undefined }}>
+ <div className="richTextMenu-divider" key="divider 3" />,
{[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size"),
this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family"),
- <div className="richTextMenu-divider" />,
+ <div className="richTextMenu-divider" key="divider 4" />,
this.createNodesDropdown(this.activeListType, this.listTypeOptions, "nodes"),
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),
- <div className="richTextMenu-divider" />,]}
+ <div className="richTextMenu-divider" key="divider 5" />,]}
</div>
- <div key="button">
+ <div key="collapser">
{/* <div key="collapser">
<button className="antimodeMenu-button" key="collapse menu" title="Collapse menu" onClick={this.toggleCollapse} style={{ backgroundColor: this.collapsed ? "#121212" : "", width: 25 }}>
<FontAwesomeIcon icon="chevron-left" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.3s", transform: `rotate(${this.collapsed ? 180 : 0}deg)` }} />