aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/LinkDocPreview.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/LinkDocPreview.tsx')
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx73
1 files changed, 43 insertions, 30 deletions
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index b2fdd93fc..1eab06381 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -4,7 +4,7 @@ import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import wiki from 'wikijs';
import { Doc, DocCastAsync, DocListCast, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { Cast, DocCast, NumCast, PromiseValue, StrCast } from '../../../fields/Types';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils';
import { DocServer } from '../../DocServer';
import { Docs, DocUtils } from '../../documents/Documents';
@@ -17,7 +17,8 @@ import { Transform } from '../../util/Transform';
import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView';
import './LinkDocPreview.scss';
import React = require('react');
-import { SelectionManager } from '../../util/SelectionManager';
+import { SearchUtil } from '../../util/SearchUtil';
+import { SearchBox } from '../search/SearchBox';
interface LinkDocPreviewProps {
linkDoc?: Doc;
@@ -37,6 +38,8 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
LinkDocPreview.LinkInfo !== info && (LinkDocPreview.LinkInfo = info);
}
+ static _instance: Opt<LinkDocPreview>;
+
_infoRef = React.createRef<HTMLDivElement>();
_linkDocRef = React.createRef<HTMLDivElement>();
@observable public static LinkInfo: Opt<LinkDocPreviewProps>;
@@ -47,6 +50,11 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
@observable _toolTipText = '';
@observable _hrefInd = 0;
+ constructor(props: any) {
+ super(props);
+ LinkDocPreview._instance = this;
+ }
+
@action init() {
var linkTarget = this.props.linkDoc;
this._linkSrc = this.props.linkSrc;
@@ -63,6 +71,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
this._markerTargetDoc = this._targetDoc = linkTarget;
}
this._toolTipText = '';
+ this.updateHref();
}
componentDidUpdate(props: any) {
if (props.linkSrc !== this.props.linkSrc || props.linkDoc !== this.props.linkDoc || props.hrefs !== this.props.hrefs) this.init();
@@ -72,6 +81,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
document.addEventListener('pointerdown', this.onPointerDown, true);
}
+ @action
componentWillUnmount() {
LinkDocPreview.SetLinkInfo(undefined);
document.removeEventListener('pointerdown', this.onPointerDown, true);
@@ -81,7 +91,8 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
!this._linkDocRef.current?.contains(e.target as any) && LinkDocPreview.Clear(); // close preview when not clicking anywhere other than the info bar of the preview
};
- @computed get href() {
+ @action
+ updateHref() {
if (this.props.hrefs?.length) {
const href = this.props.hrefs[this._hrefInd];
if (href.indexOf(Doc.localServerPath()) !== 0) {
@@ -91,33 +102,33 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
.page(href.replace('https://en.wikipedia.org/wiki/', ''))
.then(page => page.summary().then(action(summary => (this._toolTipText = summary.substring(0, 500)))));
} else {
- setTimeout(action(() => (this._toolTipText = 'url => ' + href)));
+ this._toolTipText = 'url => ' + href;
}
} else {
// hyperlink to a document .. decode doc id and retrieve from the server. this will trigger vals() being invalidated
- const anchorDoc = href.replace(Doc.localServerPath(), '').split('?')[0];
- anchorDoc &&
- DocServer.GetRefField(anchorDoc).then(
- action(anchor => {
- if (anchor instanceof Doc && DocListCast(anchor.links).length) {
- this._linkDoc = this._linkDoc ?? DocListCast(anchor.links)[0];
- const automaticLink = this._linkDoc.linkRelationship === LinkManager.AutoKeywords;
- if (automaticLink) {
- // automatic links specify the target in the link info, not the source
- const linkTarget = anchor;
- this._linkSrc = LinkManager.getOppositeAnchor(this._linkDoc, linkTarget);
- this._markerTargetDoc = this._targetDoc = linkTarget;
- } else {
- this._linkSrc = anchor;
- const linkTarget = LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
- this._markerTargetDoc = linkTarget;
- this._targetDoc = /*linkTarget?.type === DocumentType.MARKER &&*/ linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget;
- }
- this._toolTipText = '';
- if (LinkDocPreview.LinkInfo?.noPreview) this.followLink();
+ const anchorDocId = href.replace(Doc.localServerPath(), '').split('?')[0];
+ const anchorDoc = anchorDocId ? PromiseValue(DocCast(DocServer.GetCachedRefField(anchorDocId) ?? DocServer.GetRefField(anchorDocId))) : undefined;
+ anchorDoc?.then?.(
+ action(anchor => {
+ if (anchor instanceof Doc && DocListCast(anchor.links).length) {
+ this._linkDoc = this._linkDoc ?? DocListCast(anchor.links)[0];
+ const automaticLink = this._linkDoc.linkRelationship === LinkManager.AutoKeywords;
+ if (automaticLink) {
+ // automatic links specify the target in the link info, not the source
+ const linkTarget = anchor;
+ this._linkSrc = LinkManager.getOppositeAnchor(this._linkDoc, linkTarget);
+ this._markerTargetDoc = this._targetDoc = linkTarget;
+ } else {
+ this._linkSrc = anchor;
+ const linkTarget = LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
+ this._markerTargetDoc = linkTarget;
+ this._targetDoc = /*linkTarget?.type === DocumentType.MARKER &&*/ linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget;
}
- })
- );
+ this._toolTipText = 'link to ' + this._targetDoc?.title;
+ if (LinkDocPreview.LinkInfo?.noPreview || this._linkSrc?.followLinkToggle || this._markerTargetDoc?.type === DocumentType.PRES) this.followLink();
+ }
+ })
+ );
}
return href;
}
@@ -159,11 +170,14 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
};
followLink = () => {
+ LinkDocPreview.Clear();
if (this._linkDoc && this._linkSrc) {
- LinkDocPreview.Clear();
LinkFollower.FollowLink(this._linkDoc, this._linkSrc, this.props.docProps, false);
} else if (this.props.hrefs?.length) {
- this.props.docProps?.addDocTab(Docs.Create.WebDocument(this.props.hrefs[0], { title: this.props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, useCors: true }), OpenWhere.addRight);
+ const webDoc =
+ Array.from(SearchBox.staticSearchCollection(Doc.MyFilesystem, this.props.hrefs[0]).keys()).lastElement() ??
+ Docs.Create.WebDocument(this.props.hrefs[0], { title: this.props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, useCors: true });
+ this.props.docProps?.addDocTab(webDoc, OpenWhere.lightbox);
}
};
@@ -209,7 +223,6 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
}
@computed get docPreview() {
- const href = this.href; // needs to be here to trigger lookup of web pages and docs on server
return (!this._linkDoc || !this._targetDoc || !this._linkSrc) && !this._toolTipText ? null : (
<div className="linkDocPreview-inner">
{!this.props.showHeader ? null : this.previewHeader}
@@ -286,7 +299,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
className="linkDocPreview"
ref={this._linkDocRef}
onPointerDown={this.followLinkPointerDown}
- style={{ left: this.props.location[0], top: this.props.location[1], width: this.width() + borders, height: this.height() + borders + (this.props.showHeader ? 37 : 0) }}>
+ style={{ display: !this._toolTipText ? 'none' : undefined, left: this.props.location[0], top: this.props.location[1], width: this.width() + borders, height: this.height() + borders + (this.props.showHeader ? 37 : 0) }}>
{this.docPreview}
</div>
);