aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DocumentLinksButton.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-04-05 22:44:03 -0400
committerbobzel <zzzman@gmail.com>2023-04-05 22:44:03 -0400
commit9b41da1af16b982ee8ac2fc09f2f8b5d67eac9fb (patch)
treebc3f57cd5b31fd453d272c925f6d5b728ab63bae /src/client/views/nodes/DocumentLinksButton.tsx
parent9dae453967183b294bf4f7444b948023a1d52d39 (diff)
parent8f7e99641f84ad15f34ba9e4a60b664ac93d2e5d (diff)
Merge branch 'master' into data-visualization-view-naafi
Diffstat (limited to 'src/client/views/nodes/DocumentLinksButton.tsx')
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx131
1 files changed, 38 insertions, 93 deletions
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index a37de7f69..df3299eef 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -4,19 +4,19 @@ import { action, computed, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { Doc, Opt } from '../../../fields/Doc';
import { StrCast } from '../../../fields/Types';
-import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../Utils';
+import { emptyFunction, returnFalse, setupMoveUpEvents, StopEvent } from '../../../Utils';
import { DocUtils } from '../../documents/Documents';
import { DragManager } from '../../util/DragManager';
import { Hypothesis } from '../../util/HypothesisUtils';
import { LinkManager } from '../../util/LinkManager';
import { undoBatch, UndoManager } from '../../util/UndoManager';
-import { Colors } from '../global/globalEnums';
import './DocumentLinksButton.scss';
import { DocumentView } from './DocumentView';
import { LinkDescriptionPopup } from './LinkDescriptionPopup';
import { TaskCompletionBox } from './TaskCompletedBox';
import React = require('react');
+import _ = require('lodash');
+import { PinProps } from './trails';
const higflyout = require('@hig/flyout');
export const { anchorPoints } = higflyout;
@@ -24,10 +24,12 @@ export const Flyout = higflyout.default;
interface DocumentLinksButtonProps {
View: DocumentView;
- Offset?: (number | undefined)[];
+ Bottom?: boolean;
AlwaysOn?: boolean;
InMenu?: boolean;
+ OnHover?: boolean;
StartLink?: boolean; //whether the link HAS been started (i.e. now needs to be completed)
+ ShowCount?: boolean;
scaling?: () => number; // how uch doc is scaled so that link buttons can invert it
}
@observer
@@ -39,9 +41,6 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
@observable public static AnnotationUri: string | undefined;
@observable public static LinkEditorDocView: DocumentView | undefined;
- @observable public static invisibleWebDoc: Opt<Doc>;
- public static invisibleWebRef = React.createRef<HTMLDivElement>();
-
@action
@undoBatch
onLinkButtonMoved = (e: PointerEvent) => {
@@ -72,11 +71,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
e,
this.onLinkButtonMoved,
emptyFunction,
- action((e, doubleTap) => {
- if (doubleTap) {
- DocumentView.showBackLinks(this.props.View.rootDoc);
- }
- }),
+ action((e, doubleTap) => doubleTap && DocumentView.showBackLinks(this.props.View.rootDoc)),
undefined,
undefined,
action(() => (DocumentLinksButton.LinkEditorDocView = this.props.View))
@@ -119,7 +114,6 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
DocumentLinksButton.StartLink = this.props.View.props.Document;
DocumentLinksButton.StartLinkView = this.props.View;
}
- //action(() => Doc.BrushDoc(this.props.View.Document));
}
};
@@ -130,55 +124,15 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
returnFalse,
emptyFunction,
undoBatch(
- action((e, doubleTap) => {
- if (doubleTap && !this.props.StartLink) {
- if (DocumentLinksButton.StartLink === this.props.View.props.Document) {
- DocumentLinksButton.StartLink = undefined;
- DocumentLinksButton.StartLinkView = undefined;
- DocumentLinksButton.AnnotationId = undefined;
- } else if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View.props.Document) {
- const sourceDoc = DocumentLinksButton.StartLink;
- const targetDoc = this.props.View.ComponentView?.getAnchor?.() || this.props.View.Document;
- const linkDoc = DocUtils.MakeLink({ doc: sourceDoc }, { doc: targetDoc }, 'links'); //why is long drag here when this is used for completing links by clicking?
-
- LinkManager.currentLink = linkDoc;
-
- runInAction(() => {
- if (linkDoc) {
- TaskCompletionBox.textDisplayed = 'Link Created';
- TaskCompletionBox.popupX = e.screenX;
- TaskCompletionBox.popupY = e.screenY - 133;
- TaskCompletionBox.taskCompleted = true;
-
- LinkDescriptionPopup.popupX = e.screenX;
- LinkDescriptionPopup.popupY = e.screenY - 100;
- LinkDescriptionPopup.descriptionPopup = true;
-
- const rect = document.body.getBoundingClientRect();
- if (LinkDescriptionPopup.popupX + 200 > rect.width) {
- LinkDescriptionPopup.popupX -= 190;
- TaskCompletionBox.popupX -= 40;
- }
- if (LinkDescriptionPopup.popupY + 100 > rect.height) {
- LinkDescriptionPopup.popupY -= 40;
- TaskCompletionBox.popupY -= 40;
- }
-
- setTimeout(
- action(() => (TaskCompletionBox.taskCompleted = false)),
- 2500
- );
- }
- });
- }
- }
+ action(e => {
+ DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this.props.View.props.Document, true, this.props.View);
})
)
);
};
public static finishLinkClick = undoBatch(
- action((screenX: number, screenY: number, startLink: Doc, endLink: Doc, startIsAnnotation: boolean, endLinkView?: DocumentView) => {
+ action((screenX: number, screenY: number, startLink: Doc, endLink: Doc, startIsAnnotation: boolean, endLinkView?: DocumentView, pinProps?: PinProps) => {
if (startLink === endLink) {
DocumentLinksButton.StartLink = undefined;
DocumentLinksButton.StartLinkView = undefined;
@@ -186,9 +140,9 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
DocumentLinksButton.AnnotationUri = undefined;
//!this.props.StartLink
} else if (startLink !== endLink) {
- endLink = endLinkView?.docView?._componentView?.getAnchor?.() || endLink;
- startLink = DocumentLinksButton.StartLinkView?.docView?._componentView?.getAnchor?.() || startLink;
- const linkDoc = DocUtils.MakeLink({ doc: startLink }, { doc: endLink }, DocumentLinksButton.AnnotationId ? 'hypothes.is annotation' : undefined, undefined, undefined, true);
+ endLink = endLinkView?.docView?._componentView?.getAnchor?.(true, pinProps) || endLink;
+ startLink = DocumentLinksButton.StartLinkView?.docView?._componentView?.getAnchor?.(true) || startLink;
+ const linkDoc = DocUtils.MakeLink(startLink, endLink, { linkRelationship: DocumentLinksButton.AnnotationId ? 'hypothes.is annotation' : undefined }, undefined, true);
LinkManager.currentLink = linkDoc;
@@ -256,38 +210,33 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
* todo:glr / anh seperate functionality such as onClick onPointerDown of link menu button
*/
@computed get linkButtonInner() {
- const btnDim = '30px';
- const link = <img style={{ width: '22px', height: '16px' }} src={`/assets/${'link.png'}`} />;
+ const btnDim = 30;
const isActive = DocumentLinksButton.StartLink === this.props.View.props.Document && this.props.StartLink;
- return !this.props.InMenu ? (
- <div className="documentLinksButton-cont" style={{ left: this.props.Offset?.[0], top: this.props.Offset?.[1], right: this.props.Offset?.[2], bottom: this.props.Offset?.[3] }}>
- <div
- className={'documentLinksButton'}
- onPointerDown={this.onLinkMenuOpen}
- onClick={this.onLinkClick}
- style={{
- backgroundColor: Colors.LIGHT_BLUE,
- color: Colors.BLACK,
- fontSize: '20px',
- width: btnDim,
- height: btnDim,
- }}>
- {Array.from(this.filteredLinks).length}
- </div>
+ const scaling = Math.min(1, this.props.scaling?.() || 1);
+ const showLinkCount = (onHover?: boolean, offset?: boolean) => (
+ <div
+ className="documentLinksButton-showCount"
+ onPointerDown={this.onLinkMenuOpen}
+ style={{
+ fontSize: (onHover ? btnDim / 2 : 20) * scaling,
+ width: (onHover ? btnDim / 2 : btnDim) * scaling,
+ height: (onHover ? btnDim / 2 : btnDim) * scaling,
+ bottom: offset ? 5 * scaling : onHover ? (-btnDim / 2) * scaling : undefined,
+ }}>
+ <span style={{ width: '100%', display: 'inline-block', textAlign: 'center' }}>{Array.from(this.filteredLinks).length}</span>
</div>
+ );
+ return this.props.ShowCount ? (
+ showLinkCount(this.props.OnHover, this.props.Bottom)
) : (
<div className="documentLinksButton-menu">
- {this.props.InMenu && !this.props.StartLink && DocumentLinksButton.StartLink !== this.props.View.props.Document ? ( //if the origin node is not this node
- <div
- className={'documentLinksButton-endLink'}
- ref={this._linkButton}
- onPointerDown={DocumentLinksButton.StartLink && this.completeLink}
- onClick={e => DocumentLinksButton.StartLink && DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this.props.View.props.Document, true, this.props.View)}>
+ {this.props.StartLink ? ( //if link has been started from current node, then set behavior of link button to deactivate linking when clicked again
+ <div className={`documentLinksButton ${isActive ? `startLink` : ``}`} ref={this._linkButton} onPointerDown={isActive ? StopEvent : this.onLinkButtonDown} onClick={isActive ? this.clearLinks : this.onLinkClick}>
<FontAwesomeIcon className="documentdecorations-icon" icon="link" />
</div>
) : null}
- {this.props.InMenu && this.props.StartLink ? ( //if link has been started from current node, then set behavior of link button to deactivate linking when clicked again
- <div className={`documentLinksButton ${isActive ? `startLink` : ``}`} ref={this._linkButton} onPointerDown={isActive ? undefined : this.onLinkButtonDown} onClick={isActive ? this.clearLinks : this.onLinkClick}>
+ {!this.props.StartLink && DocumentLinksButton.StartLink !== this.props.View.props.Document ? ( //if the origin node is not this node
+ <div className={'documentLinksButton-endLink'} ref={this._linkButton} onPointerDown={DocumentLinksButton.StartLink && this.completeLink}>
<FontAwesomeIcon className="documentdecorations-icon" icon="link" />
</div>
) : null}
@@ -296,24 +245,20 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
}
render() {
- TraceMobx();
-
const menuTitle = this.props.StartLink ? 'Drag or tap to start link' : 'Tap to complete link';
const buttonTitle = 'Tap to view links; double tap to open link collection';
- const title = this.props.InMenu ? menuTitle : buttonTitle;
+ const title = this.props.ShowCount ? buttonTitle : menuTitle;
//render circular tooltip if it isn't set to invisible and show the number of doc links the node has, and render inner-menu link button for starting/stopping links if currently in menu
return !Array.from(this.filteredLinks).length && !this.props.AlwaysOn ? null : (
<div
className="documentLinksButton-wrapper"
style={{
- transform: `scale(${this.props.scaling?.() || 1})`,
+ position: this.props.InMenu ? 'relative' : 'absolute',
+ top: 0,
+ pointerEvents: 'none',
}}>
- {(this.props.InMenu && (DocumentLinksButton.StartLink || this.props.StartLink)) || (!DocumentLinksButton.LinkEditorDocView && !this.props.InMenu) ? (
- <Tooltip title={<div className="dash-tooltip">{title}</div>}>{this.linkButtonInner}</Tooltip>
- ) : (
- this.linkButtonInner
- )}
+ {DocumentLinksButton.LinkEditorDocView ? this.linkButtonInner : <Tooltip title={<div className="dash-tooltip">{title}</div>}>{this.linkButtonInner}</Tooltip>}
</div>
);
}