aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2021-02-09 19:11:28 -0500
committerbobzel <zzzman@gmail.com>2021-02-09 19:11:28 -0500
commit5fd9ffcc2bb62faa664f33a817ae1fd51c36ef98 (patch)
tree2135c0934f8bd3c5438db6a03c61416ec6995395
parent81bd2378ffa753e851390c2616e66a71d23c9989 (diff)
overhaul of linkdocpreview. delegated linkpreviewing from formattedTextBoxComments to LinkDocPreview
-rw-r--r--src/client/util/LinkManager.ts1
-rw-r--r--src/client/views/MainView.tsx3
-rw-r--r--src/client/views/linking/LinkMenu.tsx3
-rw-r--r--src/client/views/linking/LinkMenuItem.tsx3
-rw-r--r--src/client/views/nodes/AudioBox.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/LinkAnchorBox.tsx3
-rw-r--r--src/client/views/nodes/LinkDocPreview.scss69
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx232
-rw-r--r--src/client/views/nodes/VideoBox.tsx4
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx13
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.scss76
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx255
13 files changed, 283 insertions, 385 deletions
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index ecf245d03..c32a78ef3 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -129,7 +129,6 @@ export class LinkManager {
await LinkManager.traverseLink(linkDoc, sourceDoc, createViewFunc, BoolCast(sourceDoc.followLinkZoom, false), docViewProps.ContainingCollectionDoc, batch.end, altKey ? true : undefined);
}
public static async traverseLink(link: Opt<Doc>, doc: Doc, createViewFunc: CreateViewFunc, zoom = false, currentContext?: Doc, finished?: () => void, traverseBacklink?: boolean) {
- FormattedTextBoxComment.linkDoc = undefined;
const linkDocs = link ? [link] : DocListCast(doc.links);
const firstDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor1 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor1
const secondDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor2 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor2 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor2
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index d53e66c47..d09b0269f 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -626,8 +626,7 @@ export class MainView extends React.Component {
<CollectionMenu />
{LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
{DocumentLinksButton.LinkEditorDocView ? <LinkMenu docView={DocumentLinksButton.LinkEditorDocView} changeFlyout={emptyFunction} /> : (null)}
- {LinkDocPreview.LinkInfo ? <LinkDocPreview location={LinkDocPreview.LinkInfo.Location} docprops={LinkDocPreview.LinkInfo.docprops}
- linkDoc={LinkDocPreview.LinkInfo.linkDoc} linkSrc={LinkDocPreview.LinkInfo.linkSrc} href={LinkDocPreview.LinkInfo.href} /> : (null)}
+ {LinkDocPreview.LinkInfo ? <LinkDocPreview {...LinkDocPreview.LinkInfo} /> : (null)}
<GestureOverlay >
{this.mainContent}
</GestureOverlay>
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index 8cd069210..c7888c5ee 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -30,8 +30,7 @@ export class LinkMenu extends React.Component<Props> {
onPointerDown = (e: PointerEvent) => {
LinkDocPreview.Clear();
- if (this._linkMenuRef && this._editorRef &&
- !this._linkMenuRef.current?.contains(e.target as any) &&
+ if (!this._linkMenuRef.current?.contains(e.target as any) &&
!this._editorRef.current?.contains(e.target as any)) {
DocumentLinksButton.ClearLinkEditor();
}
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index e9866f6e3..2bc2bc6a4 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -143,7 +143,8 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
docprops: this.props.docView.props,
linkSrc: this.props.sourceDoc,
linkDoc: this.props.linkDoc,
- Location: [e.clientX, e.clientY + 20]
+ showHeader: false,
+ location: [e.clientX, e.clientY + 20]
})}
onPointerDown={this.onLinkButtonDown}>
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index fbe289f64..e24a671d0 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -107,7 +107,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
//this._disposers.scrubbing = reaction(() => AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime));
this._disposers.triggerAudio = reaction(
- () => !LinkDocPreview.LinkInfo && !FormattedTextBoxComment.linkDoc && this.props.renderDepth !== -1 ? NumCast(this.Document._triggerAudio, null) : undefined,
+ () => !LinkDocPreview.LinkInfo && this.props.renderDepth !== -1 ? NumCast(this.Document._triggerAudio, null) : undefined,
start => start !== undefined && setTimeout(() => {
this.playFrom(start);
setTimeout(() => {
@@ -119,7 +119,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
);
this._disposers.audioStop = reaction(
- () => this.props.renderDepth !== -1 && !LinkDocPreview.LinkInfo && !FormattedTextBoxComment.linkDoc ? Cast(this.Document._audioStop, "number", null) : undefined,
+ () => this.props.renderDepth !== -1 && !LinkDocPreview.LinkInfo ? Cast(this.Document._audioStop, "number", null) : undefined,
audioStop => audioStop !== undefined && setTimeout(() => {
this.Pause();
setTimeout(() => this.Document._audioStop = undefined, 10);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index f56246e9a..8afa53eac 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -377,7 +377,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
focus = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => {
- this._componentView?.scrollFocus?.(doc, !LinkDocPreview.LinkInfo && !FormattedTextBoxComment.linkDoc); // bcz: smooth parameter should really be passed into focus() instead of inferred here
+ this._componentView?.scrollFocus?.(doc, !LinkDocPreview.LinkInfo); // bcz: smooth parameter should really be passed into focus() instead of inferred here
return this.props.focus(doc, willZoom, scale, afterFocus, dontCenter, focused);
}
onClick = action((e: React.MouseEvent | React.PointerEvent) => {
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index 673c936ce..7a4209563 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -140,7 +140,8 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps, LinkAnch
docprops: this.props,
linkSrc: linkSource,
linkDoc: this.rootDoc,
- Location: [e.clientX, e.clientY + 20]
+ showHeader: true,
+ location: [e.clientX, e.clientY + 20]
})}
onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle} onContextMenu={this.specificContextMenu}
ref={this._ref}
diff --git a/src/client/views/nodes/LinkDocPreview.scss b/src/client/views/nodes/LinkDocPreview.scss
new file mode 100644
index 000000000..abbb8cdf0
--- /dev/null
+++ b/src/client/views/nodes/LinkDocPreview.scss
@@ -0,0 +1,69 @@
+ .linkDocPreview {
+ position: absolute;
+ pointer-events: all;
+ background-color: lightblue;
+ border: 8px solid white;
+ border-radius: 7px;
+ box-shadow: 3px 3px 1.5px grey;
+ border-bottom: 8px solid white;
+ border-right: 8px solid white;
+ z-index: 2004;
+ .linkDocPreview-inner {
+ background-color: white;
+ border: 8px solid white;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+
+ .linkDocPreview-info {
+ height: 37px;
+ white-space: pre;
+
+ .linkDocPreview-title {
+ padding-right: 4px;
+ float: left;
+ width: calc(100% - 48px);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ height: 25px;
+
+ .linkDocPreview-description {
+ text-decoration: none;
+ font-style: italic;
+ color: rgb(95, 97, 102);
+ font-size: 10px;
+ }
+ }
+
+ .linkDocPreview-button {
+ display: inline-flex;
+ margin: 0;
+ margin-right: 3px;
+ border-radius: 50%;
+ pointer-events: auto;
+ background-color: black;
+ color: white;
+ transition: transform 0.2s;
+ text-align: center;
+ position: relative;
+ font-size: 12px;
+ width: 20px;
+ height: 20px;
+ align-items: center;
+ justify-content: center;
+
+ &:hover {
+ background-color: rgb(77, 77, 77);
+ cursor: pointer;
+ }
+ }
+
+ .linkDocPreview-preview-wrapper {
+ overflow: hidden;
+ align-content: center;
+ justify-content: center;
+ background-color: rgb(160, 160, 160);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 4808feb47..04a407eab 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -1,121 +1,197 @@
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Tooltip } from '@material-ui/core';
import { action, computed, observable, runInAction } from 'mobx';
import { observer } from "mobx-react";
import wiki from "wikijs";
-import { Doc, DocCastAsync, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
-import { Id } from '../../../fields/FieldSymbols';
-import { Cast, FieldValue, NumCast } from "../../../fields/Types";
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, emptyPath } from "../../../Utils";
+import { Doc, DocCastAsync, DocListCast, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { NumCast, StrCast } from "../../../fields/Types";
+import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, setupMoveUpEvents, Utils } from "../../../Utils";
+import { DocServer } from '../../DocServer';
import { Docs } from "../../documents/Documents";
import { LinkManager } from '../../util/LinkManager';
import { Transform } from "../../util/Transform";
-import { ContextMenu } from '../ContextMenu';
-import { DocumentLinksButton } from './DocumentLinksButton';
-import { DocumentView, StyleProviderFunc, DocumentViewSharedProps } from "./DocumentView";
+import { DocumentView, DocumentViewSharedProps } from "./DocumentView";
+import './LinkDocPreview.scss';
import React = require("react");
-interface Props {
+interface LinkDocPreviewProps {
linkDoc?: Doc;
linkSrc?: Doc;
href?: string;
docprops: DocumentViewSharedProps;
location: number[];
+ hrefs?: string[];
+ showHeader?: boolean;
}
@observer
-export class LinkDocPreview extends React.Component<Props> {
+export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
@action public static Clear() { LinkDocPreview.LinkInfo = undefined; }
- @action public static SetLinkInfo(info: { linkDoc?: Doc; linkSrc: Doc; href?: string; Location: number[], docprops: DocumentViewSharedProps }) {
- LinkDocPreview.LinkInfo = info;
- }
- @observable public static LinkInfo: Opt<{ linkDoc?: Doc; linkSrc: Doc; href?: string; Location: number[], docprops: DocumentViewSharedProps }>;
+ @action public static SetLinkInfo(info?: LinkDocPreviewProps) { LinkDocPreview.LinkInfo != info && (LinkDocPreview.LinkInfo = info); }
+
+ _infoRef = React.createRef<HTMLDivElement>();
+ @observable public static LinkInfo: Opt<LinkDocPreviewProps>;
@observable _targetDoc: Opt<Doc>;
+ @observable _linkDoc: Opt<Doc>;
+ @observable _linkSrc: Opt<Doc>;
@observable _toolTipText = "";
- _linkTarget: Opt<Doc>;
- _editRef = React.createRef<HTMLDivElement>();
+ @observable _hrefInd = 0;
+ @observable _linkTarget: Opt<Doc>;
- @action
- componentWillUnmount() { LinkDocPreview.LinkInfo = undefined; }
+ @action componentDidUpdate(props: any) {
+ if (props.linkSrc !== this.props.linkSrc ||
+ props.linkDoc !== this.props.linkDoc ||
+ props.hrefs !== this.props.hrefs) {
+ this._linkTarget = this.props.linkDoc;
+ this._linkSrc = this.props.linkSrc;
+ this._linkDoc = this.props.linkDoc;
+ this._toolTipText = "";
+ this.updatePreview();
+ }
+ }
+ @action componentDidMount() {
+ this._linkTarget = this.props.linkDoc;
+ this._linkSrc = this.props.linkSrc;
+ this._linkDoc = this.props.linkDoc;
+ this._toolTipText = "";
+ this.updatePreview();
+ document.addEventListener("pointerdown", this.onPointerDown);
+ }
+
+ componentWillUnmount() {
+ LinkDocPreview.SetLinkInfo(undefined);
+ document.removeEventListener("pointerdown", this.onPointerDown);
+ }
+
+ onPointerDown = (e: PointerEvent) => {
+ !this._infoRef.current?.contains(e.target as any) && LinkDocPreview.Clear();
+ }
- componentDidUpdate() { this.updatePreview(); }
- componentDidMount() { this.updatePreview(); }
- async updatePreview() {
+ updatePreview() {
const linkDoc = this.props.linkDoc;
const linkSrc = this.props.linkSrc;
- if (this.props.href) {
- if (this.props.href.startsWith("https://en.wikipedia.org/wiki/")) {
- wiki().page(this.props.href.replace("https://en.wikipedia.org/wiki/", "")).then(page => page.summary().then(action(summary => this._toolTipText = summary.substring(0, 500))));
+ if (this.props.hrefs?.length) {
+ const href = this.props.hrefs[this._hrefInd];
+ if (href.indexOf(Utils.prepend("/doc/")) !== 0) {
+ if (href.startsWith("https://en.wikipedia.org/wiki/")) {
+ wiki().page(href.replace("https://en.wikipedia.org/wiki/", "")).then(page => page.summary().then(action(summary => this._toolTipText = summary.substring(0, 500))));
+ } else {
+ runInAction(() => this._toolTipText = "external => " + href);
+ }
} else {
- runInAction(() => this._toolTipText = "external => " + this.props.href);
+ const anchorDoc = href.replace(Utils.prepend("/doc/"), "").split("?")[0];
+ anchorDoc && DocServer.GetRefField(anchorDoc).then(action(async anchor => {
+ if (anchor instanceof Doc) {
+ this._linkDoc = DocListCast(anchor.links)[0];
+ this._linkSrc = anchor;
+ const targetanchor = LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
+ runInAction(async () => {
+ this._linkTarget = targetanchor;
+ const target = this._linkTarget?.annotationOn ? await DocCastAsync(this._linkTarget.annotationOn) : this._linkTarget;
+ this._toolTipText = "";
+ runInAction(() => this._targetDoc = target);
+ });
+ }
+ }));
}
- } else if (linkDoc && linkSrc) {
+ } else if (linkDoc) {
const anchor1 = linkDoc.anchor1 as Doc;
const anchor2 = linkDoc.anchor2 as Doc;
- this._linkTarget = Doc.AreProtosEqual(anchor1, linkSrc) || Doc.AreProtosEqual(anchor1.annotationOn as Doc, linkSrc) ? anchor2 : anchor1;
- const target = this._linkTarget?.annotationOn ? await DocCastAsync(this._linkTarget.annotationOn) : this._linkTarget;
- runInAction(() => {
+ runInAction(async () => {
+ this._linkTarget = Doc.AreProtosEqual(anchor1, linkSrc) || Doc.AreProtosEqual(anchor1.annotationOn as Doc, linkSrc) ? anchor2 : anchor1;
+ const target = this._linkTarget?.annotationOn ? await DocCastAsync(this._linkTarget.annotationOn) : this._linkTarget;
this._toolTipText = "";
- this._targetDoc = target;
+ runInAction(() => this._targetDoc = target);
});
}
}
- pointerDown = (e: React.PointerEvent) => {
- if (this.props.linkDoc && this.props.linkSrc) {
- LinkManager.FollowLink(this.props.linkDoc, this.props.linkSrc, this.props.docprops, false);
+ deleteLink = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e, returnFalse, emptyFunction, action(() => this._linkDoc ? LinkManager.Instance.deleteLink(this._linkDoc) : null));
+ }
+ nextHref = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e, returnFalse, emptyFunction, action(() => {
+ this._hrefInd = (this._hrefInd + 1) % (this.props.hrefs?.length || 1);
+ this.updatePreview();
+ }));
+ }
+
+ followLink = (e: React.PointerEvent) => {
+ if (this._linkDoc && this._linkSrc) {
+ LinkManager.FollowLink(this._linkDoc, this._linkSrc, this.props.docprops, false);
} else if (this.props.href) {
this.props.docprops?.addDocTab(Docs.Create.WebDocument(this.props.href, { title: this.props.href, _width: 200, _height: 400, useCors: true }), "add:right");
}
}
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: 225, maxHeight: 225, width: "100%", height: "100%", overflow: "hidden" }}>
- <div style={{ width: "100%", height: "100%", textOverflow: "ellipsis", }} onPointerDown={this.pointerDown}>
- {this._toolTipText}
+ @computed get previewHeader() {
+ return !this._linkDoc || !this._targetDoc || !this._linkSrc ? (null) :
+ <div className="LinkDocPreview-info" ref={this._infoRef}>
+ <div className="LinkDocPreview-title">
+ {StrCast(this._targetDoc.title).length > 16 ? StrCast(this._targetDoc.title).substr(0, 16) + "..." : this._targetDoc.title}
+ <p className="LinkDocPreview-description"> {StrCast(this._linkDoc.description)}</p>
+ </div>
+ <div className="wrapper" style={{ float: "right" }}>
+ {(this.props.hrefs?.length || 0) <= 1 ? (null) :
+ <Tooltip title={<div className="dash-tooltip">Next Link</div>} placement="top">
+ <div className="LinkDocPreview-button" onPointerDown={this.nextHref}>
+ <FontAwesomeIcon className="LinkDocPreview-fa-icon" icon="chevron-right" color="white" size="sm" />
+ </div>
+ </Tooltip>}
+
+ <Tooltip title={<div className="dash-tooltip">Delete Link</div>} placement="top">
+ <div className="LinkDocPreview-button" onPointerDown={this.deleteLink}>
+ <FontAwesomeIcon className="LinkDocPreview-fa-icon" icon="trash" color="white" size="sm" />
+ </div>
+ </Tooltip>
+ </div>
+ </div>;
+ }
+
+ @computed get docPreview() {
+ return (!this._linkDoc || !this._targetDoc || !this._linkSrc) && !this._toolTipText ? (null) :
+ <div className="LinkDocPreview-inner">
+ {!this.props.showHeader ? (null) : this.previewHeader}
+ <div className="LinkDocPreview-preview-wrapper">
+ {this._toolTipText ? this._toolTipText :
+ <DocumentView ref={(r) => {
+ const targetanchor = LinkManager.getOppositeAnchor(this._linkDoc!, this._linkSrc!);
+ targetanchor && this._targetDoc !== targetanchor && r?.focus(targetanchor);
+ }}
+ Document={this._targetDoc}
+ moveDocument={returnFalse}
+ rootSelected={returnFalse}
+ styleProvider={this.props.docprops?.styleProvider}
+ layerProvider={this.props.docprops?.layerProvider}
+ docViewPath={emptyPath}
+ ScreenToLocalTransform={Transform.Identity}
+ parentActive={returnFalse}
+ addDocument={returnFalse}
+ removeDocument={returnFalse}
+ addDocTab={returnFalse}
+ pinToPres={returnFalse}
+ dontRegisterView={true}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ ContainingCollectionDoc={undefined}
+ ContainingCollectionView={undefined}
+ renderDepth={-1}
+ PanelWidth={this.width}
+ PanelHeight={this.height}
+ focus={emptyFunction}
+ whenActiveChanged={returnFalse}
+ bringToFront={returnFalse}
+ NativeWidth={Doc.NativeWidth(this._targetDoc) ? () => Doc.NativeWidth(this._targetDoc) : undefined}
+ NativeHeight={Doc.NativeHeight(this._targetDoc) ? () => Doc.NativeHeight(this._targetDoc) : undefined}
+ />}
</div>
- </div>
- :
- <DocumentView ref={r => this._linkTarget !== this._targetDoc && this._linkTarget && r?.focus(this._linkTarget)}
- Document={this._targetDoc}
- moveDocument={returnFalse}
- rootSelected={returnFalse}
- ScreenToLocalTransform={Transform.Identity}
- parentActive={returnFalse}
- addDocument={returnFalse}
- removeDocument={returnFalse}
- addDocTab={returnFalse}
- pinToPres={returnFalse}
- dontRegisterView={true}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- ContainingCollectionDoc={undefined}
- ContainingCollectionView={undefined}
- renderDepth={-1}
- PanelWidth={this.width}
- PanelHeight={this.height}
- focus={emptyFunction}
- whenActiveChanged={returnFalse}
- bringToFront={returnFalse}
- styleProvider={this.props.docprops?.styleProvider}
- layerProvider={this.props.docprops?.layerProvider}
- docViewPath={emptyPath}
- />;
+ </div>;
}
render() {
- return <div className="linkDocPreview"
- style={{
- position: "absolute", left: this.props.location[0],
- top: this.props.location[1], width: this.width() + 16, height: this.height() + 16,
- zIndex: 2004,
- pointerEvents: "none",
- backgroundColor: "lightblue",
- border: "8px solid white",
- borderRadius: "7px",
- boxShadow: "3px 3px 1.5px grey",
- borderBottom: "8px solid white", borderRight: "8px solid white"
- }}>
- {this.targetDocView}
+ return <div className="linkDocPreview" onPointerDown={this.followLink}
+ style={{ left: this.props.location[0], top: this.props.location[1], width: this.width() + 16 }}>
+ {this.docPreview}
</div>;
}
}
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index c21701f32..324861573 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -211,7 +211,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
},
{ fireImmediately: true });
this._disposers.triggerVideo = reaction(
- () => !LinkDocPreview.LinkInfo && !FormattedTextBoxComment.linkDoc && this.props.renderDepth !== -1 ? NumCast(this.Document._triggerVideo, null) : undefined,
+ () => !LinkDocPreview.LinkInfo && this.props.renderDepth !== -1 ? NumCast(this.Document._triggerVideo, null) : undefined,
time => time !== undefined && setTimeout(() => {
this.player && this.Play();
setTimeout(() => this.Document._triggerVideo = undefined, 10);
@@ -219,7 +219,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
{ fireImmediately: true }
);
this._disposers.triggerStop = reaction(
- () => this.props.renderDepth !== -1 && !LinkDocPreview.LinkInfo && !FormattedTextBoxComment.linkDoc ? NumCast(this.Document._triggerVideoStop, null) : undefined,
+ () => this.props.renderDepth !== -1 && !LinkDocPreview.LinkInfo ? NumCast(this.Document._triggerVideoStop, null) : undefined,
stop => stop !== undefined && setTimeout(() => {
this.player && this.Pause();
setTimeout(() => this.Document._triggerVideoStop = undefined, 10);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 0374b1426..bf868634b 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1215,7 +1215,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const scrollRef = self._scrollRef.current;
if ((docPos.top < viewRect.top || docPos.top > viewRect.bottom) && scrollRef) {
const scrollPos = scrollRef.scrollTop + (docPos.top - viewRect.top) * self.props.ScreenToLocalTransform().Scale;
- if (!LinkDocPreview.LinkInfo && !FormattedTextBoxComment.linkDoc) {
+ if (!LinkDocPreview.LinkInfo) {
scrollPos && smoothScroll(500, scrollRef, scrollPos);
} else {
scrollRef.scrollTo({ top: scrollPos });
@@ -1338,7 +1338,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
onPointerUp = (e: React.PointerEvent): void => {
if (!this._downEvent) return;
this._downEvent = false;
- if (!(e.nativeEvent as any).formattedHandled) {
+ if (!(e.nativeEvent as any).formattedHandled && this.active(true)) {
const editor = this._editorView!;
FormattedTextBoxComment.textBox = this;
const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
@@ -1366,13 +1366,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
e.preventDefault();
}
FormattedTextBoxComment.Hide();
- if (FormattedTextBoxComment.linkDoc) {
- if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
- this.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "add" : "add:right");
- } else {
- LinkManager.FollowLink(FormattedTextBoxComment.linkDoc, this.props.Document, this.props, false);
- }
- }
(e.nativeEvent as any).formattedHandled = true;
@@ -1601,7 +1594,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
eve.stopPropagation(); // drag n drop of text within text note will generate a new note if not caughst, as will dragging in from outside of Dash.
}
onScroll = (ev: React.UIEvent) => {
- if (!LinkDocPreview.LinkInfo && !FormattedTextBoxComment.linkDoc && this._scrollRef.current) {
+ if (!LinkDocPreview.LinkInfo && this._scrollRef.current) {
this._ignoreScroll = true;
this.layoutDoc._scrollTop = this._scrollRef.current.scrollTop;
this._ignoreScroll = false;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
index 81afba4d7..3251319b9 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
@@ -1,6 +1,8 @@
.FormattedTextBox-tooltip {
position: absolute;
- pointer-events: none;
+ pointer-events: all;
+ height: 100%;
+ overflow: hidden;
z-index: 20;
background: white;
border: 1px solid silver;
@@ -9,67 +11,9 @@
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
box-shadow: 3px 3px 1.5px grey;
-
- .FormattedTextBoxComment {
- background-color: white;
- border: 8px solid white;
- //width: 200px;
-
- //display: flex;
- .FormattedTextBoxComment-info {
-
- margin-bottom: 37px;
-
- .FormattedTextBoxComment-title {
- padding-right: 4px;
- float: left;
-
- .FormattedTextBoxComment-description {
- text-decoration: none;
- font-style: italic;
- color: rgb(95, 97, 102);
- font-size: 10px;
- }
- }
-
- .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);
- }
- }
+ max-width: 400;
+ max-height: 235;
+ height:max-content;
}
.FormattedTextBox-tooltip:before {
@@ -96,12 +40,4 @@
border: 5px solid transparent;
border-bottom-width: 0;
border-top-color: white;
-}
-
-.FormattedTextBoxComment-buttons {
- display: none;
- position: absolute;
- top: 50%;
- right: 0;
- transform: translateY(-50%);
} \ 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 d1bb2ad84..827bb2591 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -1,28 +1,17 @@
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Tooltip } from "@material-ui/core";
import { action, observable } from "mobx";
import { Mark, ResolvedPos } from "prosemirror-model";
import { EditorState, Plugin } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import * as ReactDOM from 'react-dom';
-import wiki from "wikijs";
-import { Doc, DocCastAsync, DocListCast, Opt } from "../../../../fields/Doc";
-import { Cast, FieldValue, NumCast, StrCast } from "../../../../fields/Types";
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, Utils, emptyPath } from "../../../../Utils";
+import { Doc, DocListCast, Opt } from "../../../../fields/Doc";
+import { Utils } from "../../../../Utils";
import { DocServer } from "../../../DocServer";
import { Docs } from "../../../documents/Documents";
-import { DocumentType } from "../../../documents/DocumentTypes";
-import { LinkManager } from "../../../util/LinkManager";
-import { Transform } from "../../../util/Transform";
-import { undoBatch } from "../../../util/UndoManager";
-import { DocumentLinksButton } from "../DocumentLinksButton";
-import { DocumentView } from "../DocumentView";
import { LinkDocPreview } from "../LinkDocPreview";
import { FormattedTextBox } from "./FormattedTextBox";
import './FormattedTextBoxComment.scss';
import { schema } from "./schema_rts";
import React = require("react");
-import { DefaultStyleProvider } from "../../StyleProvider";
export let formattedTextBoxCommentPlugin = new Plugin({
view(editorView) { return new FormattedTextBoxComment(editorView); }
@@ -64,67 +53,24 @@ export function findEndOfMark(rpos: ResolvedPos, view: EditorView, finder: (mark
export class FormattedTextBoxComment {
static tooltip: HTMLElement;
static tooltipText: HTMLElement;
- static tooltipInput: HTMLInputElement;
static start: number;
static end: number;
static mark: Mark;
static textBox: FormattedTextBox | undefined;
- static linkDoc: Doc | undefined;
-
- static _deleteRef: Opt<HTMLDivElement | null>;
- static _followRef: Opt<HTMLDivElement | null>;
- static _nextRef: Opt<HTMLDivElement | null>;
-
- static _lastState?: EditorState;
- static _lastView?: EditorView;
-
- @observable static _hrefInd = 0;
- static _hrefs: string[] | undefined = [];
constructor(view: any) {
if (!FormattedTextBoxComment.tooltip) {
const root = document.getElementById("root");
- FormattedTextBoxComment.tooltipInput = document.createElement("input");
- FormattedTextBoxComment.tooltipInput.type = "checkbox";
FormattedTextBoxComment.tooltip = document.createElement("div");
FormattedTextBoxComment.tooltipText = document.createElement("div");
- //FormattedTextBoxComment.tooltipText.style.width = "100%";
- FormattedTextBoxComment.tooltipText.style.height = "100%";
+ FormattedTextBoxComment.tooltipText.style.height = "max-content";
FormattedTextBoxComment.tooltipText.style.textOverflow = "ellipsis";
FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
FormattedTextBoxComment.tooltip.className = "FormattedTextBox-tooltip";
- FormattedTextBoxComment.tooltip.style.pointerEvents = "all";
- FormattedTextBoxComment.tooltip.style.maxWidth = "400px";
- 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 = async (e: PointerEvent) => {
- const keep = e.target && (e.target as any).type === "checkbox" ? true : false;
+ FormattedTextBoxComment.tooltip.onpointerdown = (e: PointerEvent) => {
const textBox = FormattedTextBoxComment.textBox;
- const linkDoc = FormattedTextBoxComment.linkDoc;
- if (linkDoc && !keep && textBox) {
- if (linkDoc.author) {
- if (FormattedTextBoxComment._deleteRef?.contains(e.target as any)) {
- this.deleteLink();
- } else if (FormattedTextBoxComment._nextRef?.contains(e.target as any)) {
- FormattedTextBoxComment.showPreview(FormattedTextBoxComment._lastView!, FormattedTextBoxComment._lastState, FormattedTextBoxComment._hrefs?.[(++FormattedTextBoxComment._hrefInd) % FormattedTextBoxComment._hrefs?.length]);
- } else {
- FormattedTextBoxComment.linkDoc = undefined;
- if (linkDoc.type !== DocumentType.LINK) {
- textBox.props.addDocTab(linkDoc, e.ctrlKey ? "add" : "add:right");
- } else {
- const target = LinkManager.getOppositeAnchor(linkDoc, textBox.dataDoc);
- target && LinkManager.FollowLink(linkDoc, textBox.dataDoc, textBox.props, e.altKey);
- }
- }
- }
- } 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 }), "add:right");
- }
- keep && textBox && FormattedTextBoxComment.start !== undefined && textBox.adoptAnnotation(
+ false && FormattedTextBoxComment.start !== undefined && textBox?.adoptAnnotation(
FormattedTextBoxComment.start, FormattedTextBoxComment.end, FormattedTextBoxComment.mark);
e.stopPropagation();
e.preventDefault();
@@ -132,21 +78,9 @@ export class FormattedTextBoxComment {
root?.appendChild(FormattedTextBoxComment.tooltip);
}
}
-
- @undoBatch
- deleteLink = action(() => {
- FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null;
- FormattedTextBoxComment.Hide();
- });
-
public static Hide() {
FormattedTextBoxComment.textBox = undefined;
- FormattedTextBoxComment.linkDoc = undefined;
FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
- try {
- ReactDOM.unmountComponentAtNode(FormattedTextBoxComment.tooltipText);
- FormattedTextBoxComment.tooltip.removeChild(FormattedTextBoxComment.tooltipText);
- } catch (e) { }
}
public static SetState(textBox: any, start: number, end: number, mark: Mark) {
FormattedTextBoxComment.textBox = textBox;
@@ -170,180 +104,71 @@ export class FormattedTextBoxComment {
const left = Math.max((start.left + end.left) / 2, start.left + 3);
FormattedTextBoxComment.tooltip.style.left = (left - box.left) + "px";
FormattedTextBoxComment.tooltip.style.bottom = (box.bottom - start.top) + "px";
- // const props = FormattedTextBoxComment.textBox?.props.docViewPath.lastElement().props;
- // props && (LinkDocPreview.SetLinkInfo({
- // docprops: props,
- // linkSrc: props.Document,
- // linkDoc: FormattedTextBoxComment.linkDoc,
- // Location: [start.left, start.top + 25]
- // });
}
FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = set);
}
- static update(view: EditorView, lastState?: EditorState, forceUrl: string = "") {
- // Don't do anything if the document/selection didn't change
- if (!forceUrl && lastState?.doc.eq(view.state.doc) && lastState?.selection.eq(view.state.selection)) {
- return;
+ static update(view: EditorView, lastState?: EditorState, hrefs: string = "") {
+ if (FormattedTextBoxComment.textBox && (hrefs || !lastState?.doc.eq(view.state.doc) || !lastState?.selection.eq(view.state.selection))) {
+ FormattedTextBoxComment.setupPreview(view, FormattedTextBoxComment.textBox, hrefs ? hrefs.trim().split(" ") : undefined);
}
- FormattedTextBoxComment._lastState = lastState;
- FormattedTextBoxComment._lastView = view;
- FormattedTextBoxComment._hrefs = forceUrl ? forceUrl.trim().split(" ") : undefined;
- FormattedTextBoxComment._hrefInd = 0;
- FormattedTextBoxComment.linkDoc = undefined;
- FormattedTextBoxComment.showPreview(view, lastState, FormattedTextBoxComment._hrefs?.[FormattedTextBoxComment._hrefInd]);
}
- static showPreview(view: EditorView, lastState?: EditorState, forceUrl: string = "") {
+ static setupPreview(view: EditorView, textBox: FormattedTextBox, hrefs?: string[]) {
const state = view.state;
- const textBox = FormattedTextBoxComment.textBox;
- if (!textBox || !textBox.props) {
- return;
- }
- let set = "none";
- let nbef = 0;
- FormattedTextBoxComment.tooltipInput.style.display = "none";
- FormattedTextBoxComment.tooltip.style.width = "";
- FormattedTextBoxComment.tooltip.style.height = "";
- (FormattedTextBoxComment.tooltipText as any).href = "";
- FormattedTextBoxComment.tooltipText.style.whiteSpace = "";
- FormattedTextBoxComment.tooltipText.style.overflow = "";
// this section checks to see if the insertion point is over text entered by a different user. If so, it sets ths comment text to indicate the user and the modification date
+ var hide = true;
if (state.selection.$from) {
- nbef = findStartOfMark(state.selection.$from, view, findOtherUserMark);
+ const nbef = findStartOfMark(state.selection.$from, view, findOtherUserMark);
const naft = findEndOfMark(state.selection.$from, view, findOtherUserMark);
- const noselection = view.state.selection.$from === view.state.selection.$to;
+ const noselection = state.selection.$from === state.selection.$to;
let child: any = null;
state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node));
const mark = child && findOtherUserMark(child.marks);
if (mark && child && (nbef || naft) && (!mark.attrs.opened || noselection)) {
- FormattedTextBoxComment.SetState(FormattedTextBoxComment.textBox, state.selection.$from.pos - nbef, state.selection.$from.pos + naft, mark);
+ FormattedTextBoxComment.SetState(textBox, state.selection.$from.pos - nbef, state.selection.$from.pos + naft, mark);
}
if (mark && child && ((nbef && naft) || !noselection)) {
FormattedTextBoxComment.tooltipText.textContent = mark.attrs.userid + " on " + (new Date(mark.attrs.modified * 1000)).toLocaleString();
- set = "";
- FormattedTextBoxComment.tooltipInput.style.display = "";
+ FormattedTextBoxComment.showCommentbox("", view, nbef);
+ hide = false;
}
}
// this checks if the selection is a hyperlink. If so, it displays the target doc's text for internal links, and the url of the target for external links.
- if (set === "none" && state.selection.$from) {
- nbef = findStartOfMark(state.selection.$from, view, findLinkMark);
+ if (hide && state.selection.$from) {
+ const nbef = findStartOfMark(state.selection.$from, view, findLinkMark);
const naft = findEndOfMark(state.selection.$from, view, findLinkMark) || nbef;
let child: any = null;
state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node));
child = child || (nbef && state.selection.$from.nodeBefore);
const mark = child ? findLinkMark(child.marks) : undefined;
- const href = forceUrl || (!mark?.attrs.docref || naft === nbef) && mark?.attrs.allAnchors.find((item: { href: string }) => item.href)?.href;
- if (forceUrl || (href && child && nbef && naft && mark?.attrs.showPreview)) {
- try {
- ReactDOM.unmountComponentAtNode(FormattedTextBoxComment.tooltipText);
- FormattedTextBoxComment.tooltip.removeChild(FormattedTextBoxComment.tooltipText);
- } catch (e) { }
- FormattedTextBoxComment.tooltipText = document.createElement("div");
- FormattedTextBoxComment.tooltipText.className = "FormattedTextBoxComment-toolTipText";
- FormattedTextBoxComment.tooltipText.style.width = "100%";
- FormattedTextBoxComment.tooltipText.style.height = "100%";
- FormattedTextBoxComment.tooltipText.style.textOverflow = "ellipsis";
- FormattedTextBoxComment.tooltipText.style.cursor = "pointer";
- FormattedTextBoxComment.tooltipText.textContent = "URL: " + href;
- (FormattedTextBoxComment.tooltipText as any).href = href;
- FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
-
- if (href.startsWith("https://en.wikipedia.org/wiki/")) {
- wiki().page(href.replace("https://en.wikipedia.org/wiki/", "")).then(page => page.summary().then(summary => FormattedTextBoxComment.tooltipText.textContent = summary.substring(0, 500)));
- } else {
- FormattedTextBoxComment.tooltipText.style.whiteSpace = "pre";
- FormattedTextBoxComment.tooltipText.style.overflow = "hidden";
- }
- if (href.indexOf(Utils.prepend("/doc/")) === 0) {
- const anchorDoc = href.replace(Utils.prepend("/doc/"), "").split("?")[0];
- FormattedTextBoxComment.tooltipText.textContent = "target not found...";
- (FormattedTextBoxComment.tooltipText as any).href = "";
- anchorDoc && DocServer.GetRefField(anchorDoc).then(async anchor => {
- if (anchor instanceof Doc) {
- const linkDoc = DocListCast(anchor.links)[0];
- (FormattedTextBoxComment.tooltipText as any).href = href;
- FormattedTextBoxComment.linkDoc = linkDoc;
- const targetanchor = LinkManager.getOppositeAnchor(linkDoc, anchor);
- const target = targetanchor?.annotationOn ? await DocCastAsync(targetanchor.annotationOn) : targetanchor;
- if (target?.author) {
- FormattedTextBoxComment.showCommentbox("", view, nbef);
-
- 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 === "" ? (null) :
- <p className="FormattedTextBoxComment-description"> {StrCast(FormattedTextBoxComment.linkDoc.description)}</p>}
- </div>
- <div className="wrapper" style={{ float: "right" }}>
- {(FormattedTextBoxComment._hrefs?.length || 0) <= 1 ? (null) : <Tooltip title={<><div className="dash-tooltip">Next Link</div></>} placement="top">
- <div className="FormattedTextBoxComment-button" ref={(r) => this._nextRef = r}>
- <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="chevron-right" color="white" size="sm" />
- </div>
- </Tooltip>}
-
- <Tooltip title={<><div className="dash-tooltip">Delete Link</div></>} 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={<><div className="dash-tooltip">Follow Link</div></>} 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">
- <DocumentView ref={(r) => targetanchor && target !== targetanchor && r?.focus(targetanchor)}
- Document={target}
- moveDocument={returnFalse}
- rootSelected={returnFalse}
- styleProvider={DefaultStyleProvider}
- layerProvider={undefined}
- docViewPath={emptyPath}
- ScreenToLocalTransform={Transform.Identity}
- parentActive={returnFalse}
- addDocument={returnFalse}
- removeDocument={returnFalse}
- addDocTab={returnFalse}
- pinToPres={returnFalse}
- dontRegisterView={true}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- ContainingCollectionDoc={undefined}
- ContainingCollectionView={undefined}
- renderDepth={-1}
- PanelWidth={() => 175} //Math.min(350, NumCast(target._width, 350))}
- PanelHeight={() => 175} //Math.min(250, NumCast(target._height, 250))}
- focus={emptyFunction}
- whenActiveChanged={returnFalse}
- bringToFront={returnFalse}
- NativeWidth={Doc.NativeWidth(target) ? (() => Doc.NativeWidth(target)) : undefined}
- NativeHeight={Doc.NativeHeight(target) ? (() => Doc.NativeHeight(target)) : undefined}
- />
- </div>
- </div>;
-
- FormattedTextBoxComment.showCommentbox("", view, nbef);
-
- ReactDOM.render(docPreview, FormattedTextBoxComment.tooltipText);
-
- //FormattedTextBoxComment.tooltip.style.width = "100%";
- FormattedTextBoxComment.tooltip.style.height = "100%";
- }
- }
+ const href = (!mark?.attrs.docref || naft === nbef) && mark?.attrs.allAnchors.find((item: { href: string }) => item.href)?.href;
+ if ((href && child && nbef && naft && mark?.attrs.showPreview)) {
+ const anchorDoc = href.indexOf(Utils.prepend("/doc/")) === 0 ? href.replace(Utils.prepend("/doc/"), "").split("?")[0] : undefined;
+ if (anchorDoc) {
+ DocServer.GetRefField(anchorDoc).then(async anchor =>
+ anchor instanceof Doc && textBox && LinkDocPreview.SetLinkInfo({
+ docprops: textBox.props.docViewPath.lastElement().props,
+ linkSrc: textBox.props.Document,
+ linkDoc: DocListCast(anchor.links)[0],
+ location: ((pos) => [pos.left, pos.top + 25])(view.coordsAtPos(state.selection.from - nbef)),
+ hrefs,
+ showHeader: true
+ })
+ );
+ } else if (hrefs?.length) {
+ LinkDocPreview.SetLinkInfo({
+ docprops: textBox.props.docViewPath.lastElement().props,
+ linkSrc: textBox.props.Document,
+ linkDoc: undefined,
+ location: ((pos) => [pos.left, pos.top + 25])(view.coordsAtPos(state.selection.from - nbef)),
+ hrefs,
+ showHeader: true
});
}
- set = "";
}
}
- FormattedTextBoxComment.showCommentbox(set, view, nbef);
+ if (hide) FormattedTextBoxComment.Hide();
}
destroy() { }