diff options
-rw-r--r-- | package-lock.json | 54 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | src/client/views/DocumentButtonBar.tsx | 2 | ||||
-rw-r--r-- | src/client/views/linking/LinkMenu.tsx | 7 | ||||
-rw-r--r-- | src/client/views/linking/LinkMenuGroup.tsx | 4 | ||||
-rw-r--r-- | src/client/views/linking/LinkMenuItem.scss | 1 | ||||
-rw-r--r-- | src/client/views/linking/LinkMenuItem.tsx | 30 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentLinksButton.tsx | 21 | ||||
-rw-r--r-- | src/client/views/nodes/LinkDocPreview.tsx | 54 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBoxComment.scss | 57 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx | 118 |
11 files changed, 278 insertions, 71 deletions
diff --git a/package-lock.json b/package-lock.json index f03a39df0..d42e286e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -853,6 +853,16 @@ "@types/prosemirror-view": "*" } }, + "@types/prosemirror-dev-tools": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/prosemirror-dev-tools/-/prosemirror-dev-tools-2.1.0.tgz", + "integrity": "sha512-OhnSaC4yrrEMLPRUkEWcHAIPVqgKlLkE4kISqL3cHeAYxASouSPvPMLqhBIbWkGwaozy43DjjVC1OXkxTo+y5Q==", + "dev": true, + "requires": { + "@types/prosemirror-state": "*", + "@types/prosemirror-view": "*" + } + }, "@types/prosemirror-history": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/prosemirror-history/-/prosemirror-history-1.0.1.tgz", @@ -2966,7 +2976,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -2984,11 +2995,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3001,15 +3014,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3112,7 +3128,8 @@ }, "inherits": { "version": "2.0.4", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3122,6 +3139,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3134,17 +3152,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "1.2.5", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.9.0", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3161,6 +3182,7 @@ "mkdirp": { "version": "0.5.3", "bundled": true, + "optional": true, "requires": { "minimist": "^1.2.5" } @@ -3216,7 +3238,8 @@ }, "npm-normalize-package-bin": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "npm-packlist": { "version": "1.4.8", @@ -3241,7 +3264,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3251,6 +3275,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3319,7 +3344,8 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3349,6 +3375,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3366,6 +3393,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3404,11 +3432,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.1.1", - "bundled": true + "bundled": true, + "optional": true } } } diff --git a/package.json b/package.json index 2a08a6bf1..5e7598376 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@types/passport-local": "^1.0.33", "@types/pdfjs-dist": "^2.1.4", "@types/prosemirror-commands": "^1.0.1", + "@types/prosemirror-dev-tools": "^2.1.0", "@types/prosemirror-history": "^1.0.1", "@types/prosemirror-inputrules": "^1.0.2", "@types/prosemirror-keymap": "^1.0.2", diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index c05ca33fb..d544e13eb 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -271,7 +271,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV const considerPush = isText && this.considerGoogleDocsPush; return <div className="documentButtonBar"> <div className="documentButtonBar-button"> - <DocumentLinksButton View={this.view0} AlwaysOn={true} /> + <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} /> </div> <div className="documentButtonBar-button"> {this.templateButton} diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx index de1d60a09..2a9bbed39 100644 --- a/src/client/views/linking/LinkMenu.tsx +++ b/src/client/views/linking/LinkMenu.tsx @@ -31,6 +31,10 @@ export class LinkMenu extends React.Component<Props> { if (this._linkMenuRef?.contains(e.target as any)) { DocumentLinksButton.EditLink = undefined; } + + // if (this._linkMenuRef && !this._linkMenuRef.contains(e.target)) { + // DocumentLinksButton.EditLink = undefined; + // } } @action componentDidMount() { @@ -70,7 +74,8 @@ export class LinkMenu extends React.Component<Props> { render() { const sourceDoc = this.props.docView.props.Document; const groups: Map<string, Doc[]> = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc); - return <div className="linkMenu-list" ref={(r) => this._linkMenuRef = r} style={{ left: this.props.location[0], top: this.props.location[1] }}> + return <div className="linkMenu-list" + ref={(r) => this._linkMenuRef = r} style={{ left: this.props.location[0], top: this.props.location[1] }}> {!this._editingLink ? this.renderAllGroups(groups) : <LinkEditor sourceDoc={this.props.docView.props.Document} linkDoc={this._editingLink} showLinks={action(() => this._editingLink = undefined)} /> diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx index 89deb3a55..7892d381b 100644 --- a/src/client/views/linking/LinkMenuGroup.tsx +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -80,11 +80,11 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> { return ( <div className="linkMenu-group"> - <div className="linkMenu-group-name"> + {/* <div className="linkMenu-group-name"> <p ref={this._drag} onPointerDown={this.onLinkButtonDown} className={this.props.groupType === "*" || this.props.groupType === "" ? "" : "expand-one"} > {this.props.groupType}:</p> {this.props.groupType === "*" || this.props.groupType === "" ? <></> : this.viewGroupAsTable(this.props.groupType)} - </div> + </div> */} <div className="linkMenu-group-wrapper"> {groupItems} </div> diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss index fd0954f65..1669fc39d 100644 --- a/src/client/views/linking/LinkMenuItem.scss +++ b/src/client/views/linking/LinkMenuItem.scss @@ -61,7 +61,6 @@ margin: 0; margin-right: 6px; border-radius: 50%; - cursor: pointer; pointer-events: auto; background-color: $dark-color; color: $light-color; diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index edc18b6a9..d5d31d1ba 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -13,6 +13,8 @@ import React = require("react"); import { DocumentManager } from '../../util/DocumentManager'; import { setupMoveUpEvents, emptyFunction } from '../../../Utils'; import { DocumentView } from '../nodes/DocumentView'; +import { DocumentLinksButton } from '../nodes/DocumentLinksButton'; +import { LinkDocPreview } from '../nodes/LinkDocPreview'; library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp); @@ -124,7 +126,10 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { e.stopPropagation(); } + @action onContextMenu = (e: React.MouseEvent) => { + DocumentLinksButton.EditLink = undefined; + LinkDocPreview.LinkInfo = undefined; e.preventDefault(); ContextMenu.Instance.addItem({ description: "Follow Default Link", event: () => this.followDefault(), icon: "arrow-right" }); ContextMenu.Instance.displayMenu(e.clientX, e.clientY); @@ -132,9 +137,19 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { @action.bound async followDefault() { + DocumentLinksButton.EditLink = undefined; + LinkDocPreview.LinkInfo = undefined; DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false); } + @action + deleteLink = (): void => { + LinkManager.Instance.deleteLink(this.props.linkDoc); + //this.props.showLinks(); + LinkDocPreview.LinkInfo = undefined; + DocumentLinksButton.EditLink = undefined; + } + render() { const keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType); const canExpand = keys ? keys.length > 0 : false; @@ -142,12 +157,23 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { return ( <div className="linkMenu-item"> <div className={canExpand ? "linkMenu-item-content expand-three" : "linkMenu-item-content expand-two"}> - <div ref={this._drag} className="linkMenu-name" title="drag to view target. click to customize." onPointerDown={this.onLinkButtonDown}> + <div ref={this._drag} className="linkMenu-name" title="drag to view target. click to customize." + onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)} + onPointerEnter={action(e => this.props.linkDoc && (LinkDocPreview.LinkInfo = { + addDocTab: this.props.addDocTab, + linkSrc: this.props.sourceDoc, + linkDoc: this.props.linkDoc, + Location: [e.clientX, e.clientY + 20] + }))} + onPointerDown={this.onLinkButtonDown}> <p >{StrCast(this.props.destinationDoc.title)}</p> <div className="linkMenu-item-buttons"> {canExpand ? <div title="Show more" className="button" onPointerDown={e => this.toggleShowMore(e)}> <FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>} - <div title="Edit link" className="button" ref={this._editRef} onPointerDown={this.onEdit}><FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div> + + {/* <div title="Edit link" className="button" ref={this._editRef} onPointerDown={this.onEdit}><FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div> */} + <div title="Delete link" className="button" ref={this._editRef} onPointerDown={this.deleteLink}> + <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div> <div title="Follow link" className="button" onClick={this.followDefault} onContextMenu={this.onContextMenu}> <FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" /> </div> diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 4f4f12521..c625c4cd6 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -18,6 +18,7 @@ interface DocumentLinksButtonProps { View: DocumentView; Offset?: number[]; AlwaysOn?: boolean; + InMenu?: boolean; } @observer export class DocumentLinksButton extends React.Component<DocumentLinksButtonProps, {}> { @@ -52,10 +53,11 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp @observable static StartLink: DocumentView | undefined; onLinkButtonDown = (e: React.PointerEvent): void => { + setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => { if (doubleTap) { DocumentLinksButton.StartLink = this.props.View; - } else { + } else if (!!!this.props.InMenu) { DocumentLinksButton.EditLink = this.props.View; DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY]; } @@ -85,14 +87,15 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp <div title="Drag(create link) Tap(view links)" ref={this._linkButton} style={{ minWidth: 20, minHeight: 20, position: "absolute", left: this.props.Offset?.[0] }}> <div className={"documentLinksButton"} style={{ backgroundColor: DocumentLinksButton.StartLink ? "transparent" : "" }} onPointerDown={this.onLinkButtonDown} - onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)} - onPointerEnter={action(e => links.length && (LinkDocPreview.LinkInfo = { - addDocTab: this.props.View.props.addDocTab, - linkSrc: this.props.View.props.Document, - linkDoc: links[0], - Location: [e.clientX, e.clientY + 20] - }))} > - {links.length ? links.length : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />} + // onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)} + // onPointerEnter={action(e => links.length && (LinkDocPreview.LinkInfo = { + // addDocTab: this.props.View.props.addDocTab, + // linkSrc: this.props.View.props.Document, + // linkDoc: links[0], + // Location: [e.clientX, e.clientY + 20] + // }))} + > + {links.length && !!!this.props.InMenu ? links.length : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />} </div> {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"} onPointerDown={this.completeLink} /> : (null)} {DocumentLinksButton.StartLink === this.props.View ? <div className={"documentLinksButton-startLink"} /> : (null)} diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 92b443d3b..d02896436 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -10,6 +10,11 @@ import { Transform } from "../../util/Transform"; import { ContentFittingDocumentView } from "./ContentFittingDocumentView"; import React = require("react"); import { DocumentView } from './DocumentView'; +import { sortAndDeduplicateDiagnostics } from 'typescript'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { LinkManager } from '../../util/LinkManager'; +import { DocumentLinksButton } from './DocumentLinksButton'; +import { ContextMenu } from '../ContextMenu'; interface Props { linkDoc?: Doc; @@ -24,6 +29,31 @@ export class LinkDocPreview extends React.Component<Props> { @observable public static LinkInfo: Opt<{ linkDoc?: Doc; addDocTab: (document: Doc, where: string) => boolean, linkSrc: Doc; href?: string; Location: number[] }>; @observable _targetDoc: Opt<Doc>; @observable _toolTipText = ""; + _editRef = React.createRef<HTMLDivElement>(); + + @action + deleteLink = (): void => { + this.props.linkDoc ? LinkManager.Instance.deleteLink(this.props.linkDoc) : null; + //this.props.showLinks(); + LinkDocPreview.LinkInfo = undefined; + DocumentLinksButton.EditLink = undefined; + } + + @action + onContextMenu = (e: React.MouseEvent) => { + DocumentLinksButton.EditLink = undefined; + LinkDocPreview.LinkInfo = undefined; + e.preventDefault(); + ContextMenu.Instance.addItem({ description: "Follow Default Link", event: () => this.followDefault(), icon: "arrow-right" }); + ContextMenu.Instance.displayMenu(e.clientX, e.clientY); + } + + @action.bound + async followDefault() { + DocumentLinksButton.EditLink = undefined; + LinkDocPreview.LinkInfo = undefined; + this._targetDoc ? DocumentManager.Instance.FollowLink(this.props.linkDoc, this._targetDoc, doc => this.props.addDocTab(doc, "onRight"), false) : null; + } componentDidUpdate() { this.updatePreview(); } componentDidMount() { this.updatePreview(); } @@ -56,15 +86,30 @@ export class LinkDocPreview extends React.Component<Props> { this.props.addDocTab(Docs.Create.WebDocument(this.props.href, { title: this.props.href, _width: 200, _height: 400, UseCors: true }), "onRight"); } } - width = () => Math.min(350, NumCast(this._targetDoc?.[WidthSym](), 350)); - height = () => Math.min(350, NumCast(this._targetDoc?.[HeightSym](), 350)); + width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225)); + height = () => Math.min(225, NumCast(this._targetDoc?.[HeightSym](), 225)); @computed get targetDocView() { return !this._targetDoc ? - <div style={{ pointerEvents: "all", maxWidth: 350, maxHeight: 250, width: "100%", height: "100%", overflow: "hidden" }}> + <div style={{ + pointerEvents: "all", maxWidth: 225, maxHeight: 225, width: "100%", height: "100%", + overflow: "hidden" + }}> <div style={{ width: "100%", height: "100%", textOverflow: "ellipsis", }} onPointerDown={this.pointerDown}> {this._toolTipText} </div> </div> : + // <div style={{ + // border: "6px solid white", + // }}> + // <div style={{ backgroundColor: "white" }}> {this._targetDoc.title} + // <div className="wrapper" style={{ float: "right" }}> + // <div title="Delete link" className="button" style={{ display: "inline" }} ref={this._editRef} onPointerDown={this.deleteLink}> + // <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div> + // <div title="Follow link" className="button" style={{ display: "inline" }} onClick={this.followDefault} onContextMenu={this.onContextMenu}> + // <FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" /> + // </div> + // </div> + // </div> <ContentFittingDocumentView Document={this._targetDoc} LibraryPath={emptyPath} @@ -92,6 +137,7 @@ export class LinkDocPreview extends React.Component<Props> { NativeWidth={returnZero} NativeHeight={returnZero} />; + //</div>; } render() { @@ -99,7 +145,7 @@ export class LinkDocPreview extends React.Component<Props> { style={{ position: "absolute", left: this.props.location[0], top: this.props.location[1], width: this.width(), height: this.height(), - boxShadow: "black 2px 2px 1em" + boxShadow: "black 2px 2px 1em", zIndex: 1000 }}> {this.targetDocView} </div>; diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss index 2dd63ec21..adef7f81f 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss @@ -8,10 +8,12 @@ margin-bottom: 7px; -webkit-transform: translateX(-50%); transform: translateX(-50%); - } - .FormattedTextBox-tooltip:before { +} + +.FormattedTextBox-tooltip:before { content: ""; - height: 0; width: 0; + height: 0; + width: 0; position: absolute; left: 50%; margin-left: -5px; @@ -19,10 +21,12 @@ border: 5px solid transparent; border-bottom-width: 0; border-top-color: silver; - } - .FormattedTextBox-tooltip:after { +} + +.FormattedTextBox-tooltip:after { content: ""; - height: 0; width: 0; + height: 0; + width: 0; position: absolute; left: 50%; margin-left: -5px; @@ -30,4 +34,43 @@ border: 5px solid transparent; border-bottom-width: 0; border-top-color: white; - }
\ No newline at end of file +} + +.FormattedTextBox-buttons { + display: none; + position: absolute; + top: 50%; + right: 0; + transform: translateY(-50%); + + .FormattedTextBox-button { + width: 20px; + height: 20px; + margin: 0; + margin-right: 6px; + border-radius: 50%; + pointer-events: auto; + background-color: rgb(53, 146, 199); + color: rgb(150, 211, 248); + font-size: 65%; + transition: transform 0.2s; + text-align: center; + position: relative; + + .FormattedTextBox-fa-icon { + 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 90f2c0aa6..c600e4861 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -2,7 +2,7 @@ import { Mark, ResolvedPos } from "prosemirror-model"; import { EditorState, Plugin } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import * as ReactDOM from 'react-dom'; -import { Doc, DocCastAsync } from "../../../../fields/Doc"; +import { Doc, DocCastAsync, Opt } from "../../../../fields/Doc"; import { Cast, FieldValue, NumCast } from "../../../../fields/Types"; import { emptyFunction, returnEmptyString, returnFalse, Utils, emptyPath, returnZero, returnOne, returnEmptyFilter } from "../../../../Utils"; import { DocServer } from "../../../DocServer"; @@ -16,6 +16,11 @@ import React = require("react"); import { Docs } from "../../../documents/Documents"; import wiki from "wikijs"; import { DocumentType } from "../../../documents/DocumentTypes"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action } from "mobx"; +import { LinkManager } from "../../../util/LinkManager"; +import { LinkDocPreview } from "../LinkDocPreview"; +import { DocumentLinksButton } from "../DocumentLinksButton"; export let formattedTextBoxCommentPlugin = new Plugin({ view(editorView) { return new FormattedTextBoxComment(editorView); } @@ -62,6 +67,10 @@ export class FormattedTextBoxComment { static mark: Mark; static textBox: FormattedTextBox | undefined; static linkDoc: Doc | undefined; + + static _deleteRef: Opt<HTMLDivElement | null>; + static _followRef: Opt<HTMLDivElement | null>; + constructor(view: any) { if (!FormattedTextBoxComment.tooltip) { const root = document.getElementById("root"); @@ -87,12 +96,25 @@ export class FormattedTextBoxComment { const textBox = FormattedTextBoxComment.textBox; if (FormattedTextBoxComment.linkDoc && !keep && textBox) { if (FormattedTextBoxComment.linkDoc.author) { - if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) { - textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight"); + + if (FormattedTextBoxComment._deleteRef && FormattedTextBoxComment._deleteRef.contains(e.target as any)) { + this.deleteLink(); + } else if (FormattedTextBoxComment._followRef && FormattedTextBoxComment._followRef.contains(e.target as any)) { + 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)); + } } else { - DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document, - (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation)); + 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)); + } } + } } else if (textBox && (FormattedTextBoxComment.tooltipText as any).href) { textBox.props.addDocTab(Docs.Create.WebDocument((FormattedTextBoxComment.tooltipText as any).href, { title: (FormattedTextBoxComment.tooltipText as any).href, _width: 200, _height: 400, UseCors: true }), "onRight"); @@ -106,6 +128,15 @@ export class FormattedTextBoxComment { } } + @action + deleteLink = () => { + FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null; + LinkDocPreview.LinkInfo = undefined; + DocumentLinksButton.EditLink = undefined; + //FormattedTextBoxComment.tooltipText = undefined; + FormattedTextBoxComment.Hide(); + } + public static Hide() { FormattedTextBoxComment.textBox = undefined; FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none"); @@ -210,32 +241,55 @@ export class FormattedTextBoxComment { } if (target?.author) { FormattedTextBoxComment.showCommentbox("", view, nbef); - ReactDOM.render(<ContentFittingDocumentView - Document={target} - LibraryPath={emptyPath} - fitToBox={true} - moveDocument={returnFalse} - rootSelected={returnFalse} - ScreenToLocalTransform={Transform.Identity} - parentActive={returnFalse} - addDocument={returnFalse} - removeDocument={returnFalse} - addDocTab={returnFalse} - pinToPres={returnFalse} - dontRegisterView={true} - docFilters={returnEmptyFilter} - ContainingCollectionDoc={undefined} - ContainingCollectionView={undefined} - renderDepth={0} - PanelWidth={() => Math.min(350, NumCast(target._width, 350))} - PanelHeight={() => Math.min(250, NumCast(target._height, 250))} - focus={emptyFunction} - whenActiveChanged={returnFalse} - bringToFront={returnFalse} - ContentScaling={returnOne} - NativeWidth={returnZero} - NativeHeight={returnZero} - />, FormattedTextBoxComment.tooltipText); + const docPreview = <div style={{ backgroundColor: "white", border: "7px solid white" }}> + {target.title} + <div className="wrapper" style={{ float: "right" }}> + <div title="Delete link" className="FormattedTextBoxComment-button" style={{ + display: "inline", + paddingLeft: "5px", + paddingRight: "5px" + }} 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", + paddingRight: "5px" + }} ref={(r) => this._followRef = r}> + <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="arrow-right" + size="sm" /> + </div> + </div> + <ContentFittingDocumentView + Document={target} + LibraryPath={emptyPath} + fitToBox={true} + moveDocument={returnFalse} + rootSelected={returnFalse} + ScreenToLocalTransform={Transform.Identity} + parentActive={returnFalse} + addDocument={returnFalse} + removeDocument={returnFalse} + addDocTab={returnFalse} + pinToPres={returnFalse} + dontRegisterView={true} + docFilters={returnEmptyFilter} + ContainingCollectionDoc={undefined} + ContainingCollectionView={undefined} + renderDepth={0} + PanelWidth={() => Math.min(350, NumCast(target._width, 350))} + PanelHeight={() => Math.min(250, NumCast(target._height, 250))} + focus={emptyFunction} + whenActiveChanged={returnFalse} + bringToFront={returnFalse} + ContentScaling={returnOne} + NativeWidth={returnZero} + NativeHeight={returnZero} + /> + </div>; + FormattedTextBoxComment.showCommentbox("", view, nbef); + + ReactDOM.render(docPreview, FormattedTextBoxComment.tooltipText); + FormattedTextBoxComment.tooltip.style.width = NumCast(target._width) ? `${NumCast(target._width)}` : "100%"; FormattedTextBoxComment.tooltip.style.height = NumCast(target._height) ? `${NumCast(target._height)}` : "100%"; } @@ -249,4 +303,4 @@ export class FormattedTextBoxComment { } destroy() { } -} +}
\ No newline at end of file |