diff options
Diffstat (limited to 'src/client/views/nodes/LinkDocPreview.tsx')
-rw-r--r-- | src/client/views/nodes/LinkDocPreview.tsx | 102 |
1 files changed, 55 insertions, 47 deletions
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 7e4f1da8e..d0a9f10b4 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -1,6 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; -import { action, computed, observable } from 'mobx'; +import { Tooltip } from '@mui/material'; +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import wiki from 'wikijs'; import { Doc, Opt } from '../../../fields/Doc'; @@ -18,7 +18,27 @@ import { SettingsManager } from '../../util/SettingsManager'; import { Transform } from '../../util/Transform'; import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView'; import './LinkDocPreview.scss'; -import React = require('react'); +import * as React from 'react'; +import { ObservableReactComponent } from '../ObservableReactComponent'; + +export class LinkInfo { + private static _instance: Opt<LinkInfo>; + constructor() { + LinkInfo._instance = this; + makeObservable(this); + } + @observable public LinkInfo: Opt<LinkDocPreviewProps> = undefined; + + public static get Instance() { + return LinkInfo._instance ?? new LinkInfo(); + } + public static Clear() { + runInAction(() => LinkInfo.Instance && (LinkInfo.Instance.LinkInfo = undefined)); + } + public static SetLinkInfo(info?: LinkDocPreviewProps) { + runInAction(() => LinkInfo.Instance && (LinkInfo.Instance.LinkInfo = info)); + } +} interface LinkDocPreviewProps { linkDoc?: Doc; @@ -30,36 +50,25 @@ interface LinkDocPreviewProps { noPreview?: boolean; } @observer -export class LinkDocPreview extends React.Component<LinkDocPreviewProps> { - @action public static Clear() { - LinkDocPreview.LinkInfo = undefined; - } - @action public static SetLinkInfo(info?: LinkDocPreviewProps) { - LinkDocPreview.LinkInfo !== info && (LinkDocPreview.LinkInfo = info); - } - - static _instance: Opt<LinkDocPreview>; - +export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps> { _infoRef = React.createRef<HTMLDivElement>(); _linkDocRef = React.createRef<HTMLDivElement>(); - @observable public static LinkInfo: Opt<LinkDocPreviewProps>; - @observable _targetDoc: Opt<Doc>; - @observable _markerTargetDoc: Opt<Doc>; - @observable _linkDoc: Opt<Doc>; - @observable _linkSrc: Opt<Doc>; + @observable _targetDoc: Opt<Doc> = undefined; + @observable _markerTargetDoc: Opt<Doc> = undefined; + @observable _linkDoc: Opt<Doc> = undefined; + @observable _linkSrc: Opt<Doc> = undefined; @observable _toolTipText = ''; @observable _hrefInd = 0; - constructor(props: any) { super(props); - LinkDocPreview._instance = this; + makeObservable(this); } @action init() { - var linkTarget = this.props.linkDoc; - this._linkSrc = this.props.linkSrc; - this._linkDoc = this.props.linkDoc; + var linkTarget = this._props.linkDoc; + this._linkSrc = this._props.linkSrc; + this._linkDoc = this._props.linkDoc; const link_anchor_1 = DocCast(this._linkDoc?.link_anchor_1); const link_anchor_2 = DocCast(this._linkDoc?.link_anchor_2); if (link_anchor_1 && link_anchor_2) { @@ -72,28 +81,28 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> { 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(); + componentDidUpdate(prevProps: Readonly<LinkDocPreviewProps>) { + super.componentDidUpdate(prevProps); + if (prevProps.linkSrc !== this._props.linkSrc || prevProps.linkDoc !== this._props.linkDoc || prevProps.hrefs !== this._props.hrefs) this.init(); } componentDidMount() { this.init(); document.addEventListener('pointerdown', this.onPointerDown, true); } - @action componentWillUnmount() { - LinkDocPreview.SetLinkInfo(undefined); + LinkInfo.Clear(); document.removeEventListener('pointerdown', this.onPointerDown, true); } onPointerDown = (e: PointerEvent) => { - !this._linkDocRef.current?.contains(e.target as any) && LinkDocPreview.Clear(); // close preview when not clicking anywhere other than the info bar of the preview + !this._linkDocRef.current?.contains(e.target as any) && LinkInfo.Clear(); // close preview when not clicking anywhere other than the info bar of the preview }; @action updateHref() { - if (this.props.hrefs?.length) { - const href = this.props.hrefs[this._hrefInd]; + if (this._props.hrefs?.length) { + const href = this._props.hrefs[this._hrefInd]; if (href.indexOf(Doc.localServerPath()) !== 0) { // link to a web page URL -- try to show a preview if (href.startsWith('https://en.wikipedia.org/wiki/')) { @@ -123,7 +132,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> { this._markerTargetDoc = linkTarget; this._targetDoc = /*linkTarget?.type === DocumentType.MARKER &&*/ linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget; } - if (LinkDocPreview.LinkInfo?.noPreview || this._linkSrc?.followLinkToggle || this._markerTargetDoc?.type === DocumentType.PRES) this.followLink(); + if (LinkInfo.Instance?.LinkInfo?.noPreview || this._linkSrc?.followLinkToggle || this._markerTargetDoc?.type === DocumentType.PRES) this.followLink(); } }) ); @@ -143,9 +152,9 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> { action(() => { LinkManager.currentLink = this._linkDoc; LinkManager.currentLinkAnchor = this._linkSrc; - this.props.docProps.DocumentView?.().select(false); - if ((SettingsManager.propertiesWidth ?? 0) < 100) { - SettingsManager.propertiesWidth = 250; + this._props.docProps.DocumentView?.().select(false); + if ((SettingsManager.Instance.propertiesWidth ?? 0) < 100) { + SettingsManager.Instance.propertiesWidth = 250; } }) ); @@ -157,7 +166,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> { returnFalse, emptyFunction, action(() => { - const nextHrefInd = (this._hrefInd + 1) % (this.props.hrefs?.length || 1); + const nextHrefInd = (this._hrefInd + 1) % (this._props.hrefs?.length || 1); if (nextHrefInd !== this._hrefInd) { this._linkDoc = undefined; this._hrefInd = nextHrefInd; @@ -168,19 +177,19 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> { }; followLink = () => { - LinkDocPreview.Clear(); + LinkInfo.Clear(); if (this._linkDoc && this._linkSrc) { LinkFollower.FollowLink(this._linkDoc, this._linkSrc, false); - } else if (this.props.hrefs?.length) { + } else if (this._props.hrefs?.length) { const webDoc = - Array.from(SearchUtil.SearchCollection(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, data_useCors: true }); + Array.from(SearchUtil.SearchCollection(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, data_useCors: true }); DocumentManager.Instance.showDocument(webDoc, { openLocation: OpenWhere.lightbox, willPan: true, zoomTime: 500, }); - //this.props.docProps?.addDocTab(webDoc, OpenWhere.lightbox); + //this._props.docProps?.addDocTab(webDoc, OpenWhere.lightbox); } }; @@ -216,7 +225,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> { </div> <div className="linkDocPreview-buttonBar" style={{ float: 'right' }}> <Tooltip title={<div className="dash-tooltip">Next Link</div>} placement="top"> - <div className="linkDocPreview-button" style={{ background: (this.props.hrefs?.length || 0) <= 1 ? 'gray' : 'green' }} onPointerDown={this.nextHref}> + <div className="linkDocPreview-button" style={{ background: (this._props.hrefs?.length || 0) <= 1 ? 'gray' : 'green' }} onPointerDown={this.nextHref}> <FontAwesomeIcon className="linkDocPreview-fa-icon" icon="chevron-right" color="white" size="sm" /> </div> </Tooltip> @@ -228,7 +237,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> { @computed get docPreview() { return (!this._linkDoc || !this._targetDoc || !this._linkSrc) && !this._toolTipText ? null : ( <div className="linkDocPreview-inner"> - {!this.props.showHeader ? null : this.previewHeader} + {!this._props.showHeader ? null : this.previewHeader} <div className="linkDocPreview-preview-wrapper" onPointerDown={e => @@ -238,7 +247,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> { (e, down, delta) => { if (Math.abs(e.clientX - down[0]) + Math.abs(e.clientY - down[1]) > 100) { DragManager.StartDocumentDrag([this._infoRef.current!], new DragManager.DocumentDragData([this._targetDoc!]), e.pageX, e.pageY); - LinkDocPreview.Clear(); + LinkInfo.Clear(); return true; } return false; @@ -256,12 +265,11 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> { <DocumentView ref={r => { const targetanchor = this._linkDoc && this._linkSrc && LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc); - targetanchor && this._targetDoc !== targetanchor && r?.props.focus?.(targetanchor, {}); + targetanchor && this._targetDoc !== targetanchor && r?._props.focus?.(targetanchor, {}); }} Document={this._targetDoc!} moveDocument={returnFalse} - rootSelected={returnFalse} - styleProvider={this.props.docProps?.styleProvider} + styleProvider={this._props.docProps?.styleProvider} docViewPath={returnEmptyDoclist} ScreenToLocalTransform={Transform.Identity} isDocumentActive={returnFalse} @@ -300,7 +308,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> { className="linkDocPreview" ref={this._linkDocRef} onPointerDown={this.followLinkPointerDown} - style={{ borderColor: SettingsManager.userColor, left: this.props.location[0], top: this.props.location[1], width: this.width() + borders, height: this.height() + borders + (this.props.showHeader ? 37 : 0) }}> + style={{ borderColor: SettingsManager.userColor, 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> ); |