aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/MainView.tsx19
-rw-r--r--src/client/views/linking/LinkFollowBox.scss23
-rw-r--r--src/client/views/linking/LinkFollowBox.tsx28
-rw-r--r--src/client/views/linking/LinkMenuItem.tsx214
4 files changed, 77 insertions, 207 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index b49274e7e..d580925d6 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -57,8 +57,6 @@ export class MainView extends React.Component {
public overlayTimeout: NodeJS.Timeout | undefined;
- @observable private _linkFollowBox = false;
-
public initiateDictationFade = () => {
let duration = DictationManager.Commands.dictationFadeDuration;
this.overlayTimeout = setTimeout(() => {
@@ -437,17 +435,16 @@ export class MainView extends React.Component {
}
}
- toggleLinkFollowBox = () => {
+ toggleLinkFollowBox = (shouldClose: boolean) => {
if (LinkFollowBox.Instance) {
- console.log("is instance!")
- // if (LinkFollowBox.Instance.props && LinkFollowBox.Instance.props.removeDocument) LinkFollowBox.Instance.props.removeDocument(LinkFollowBox.Instance.props.Document);
+ let dvs = DocumentManager.Instance.getDocumentViews(LinkFollowBox.Instance.props.Document);
+ // if it already exisits, close it
+ if (dvs.length > 0 && shouldClose) LinkFollowBox.Instance.close();
+ // open it if not
+ else Doc.AddDocToList(Cast(CurrentUserUtils.UserDocument.overlays, Doc) as Doc, "data", LinkFollowBox.Instance.props.Document);
}
else {
- let overlayView = document.getElementById("overlayView");
- let overlayWidth = 0;
- if (overlayView) overlayWidth = overlayView.offsetWidth;
- let x: number = overlayWidth - 500;
- let doc = Docs.Create.LinkFollowBoxDocument({ x: x, y: 20, width: 500, height: 370, title: "Link Follower" });
+ let doc = Docs.Create.LinkFollowBoxDocument({ x: this.flyoutWidth, y: 20, width: 500, height: 370, title: "Link Follower" });
Doc.AddDocToList(Cast(CurrentUserUtils.UserDocument.overlays, Doc) as Doc, "data", doc);
}
}
@@ -495,7 +492,7 @@ export class MainView extends React.Component {
<FontAwesomeIcon icon={btn[1]} size="sm" />
</button>
</div></li>)}
- <li key="linkFollow"><button className="add-button round-button" title="Open Link Follower" onClick={this.toggleLinkFollowBox}><FontAwesomeIcon icon="link" size="sm" /></button></li>
+ <li key="linkFollow"><button className="add-button round-button" title="Open Link Follower" onClick={() => this.toggleLinkFollowBox(true)}><FontAwesomeIcon icon="link" size="sm" /></button></li>
<li key="color"><button className="add-button round-button" title="Select Color" style={{ zIndex: 1000 }} onClick={() => this.toggleColorPicker()}><div className="toolbar-color-button" style={{ backgroundColor: InkingControl.Instance.selectedColor }} >
<div className="toolbar-color-picker" onClick={this.onColorClick} style={this._colorPickerDisplay ? { color: "black", display: "block" } : { color: "black", display: "none" }}>
<SketchPicker color={InkingControl.Instance.selectedColor} onChange={InkingControl.Instance.switchColor} />
diff --git a/src/client/views/linking/LinkFollowBox.scss b/src/client/views/linking/LinkFollowBox.scss
index a34285727..e425bde69 100644
--- a/src/client/views/linking/LinkFollowBox.scss
+++ b/src/client/views/linking/LinkFollowBox.scss
@@ -18,12 +18,35 @@
// line-height: 30px;
letter-spacing: 2px;
font-size: 16px;
+ width: 100%;
}
.direction-indicator {
font-size: 12px;
}
+ .closeDocument {
+ position: relative;
+ // z-index: inherit;
+ max-width: 30px;
+ top: -20px;
+ // left: 230px;
+ left: 460px;
+ color: $darker-alt-accent // right: 5px;
+ }
+
+ .closeDocument:hover {
+ color: $main-accent;
+ }
+
+ .topHeader {
+ // display: grid;
+ // grid-template-columns: 90% 10%;
+ width: 100%;
+ // flex-direction: row;
+ height: 25px;
+ }
+
.linkFollowBox-footer {
height: 50px;
text-align: center;
diff --git a/src/client/views/linking/LinkFollowBox.tsx b/src/client/views/linking/LinkFollowBox.tsx
index cf44ae649..588f48017 100644
--- a/src/client/views/linking/LinkFollowBox.tsx
+++ b/src/client/views/linking/LinkFollowBox.tsx
@@ -2,7 +2,7 @@ import { observable, computed, action, trace, ObservableMap, runInAction, reacti
import React = require("react");
import { observer } from "mobx-react";
import { FieldViewProps, FieldView } from "../nodes/FieldView";
-import { Doc } from "../../../new_fields/Doc";
+import { Doc, DocListCastAsync } from "../../../new_fields/Doc";
import { undoBatch } from "../../util/UndoManager";
import { NumCast, FieldValue, Cast, StrCast } from "../../../new_fields/Types";
import { CollectionViewType } from "../collections/CollectionBaseView";
@@ -17,6 +17,9 @@ import { listSpec } from "../../../new_fields/Schema";
import { DocServer } from "../../DocServer";
import { RefField } from "../../../new_fields/RefField";
import { Docs } from "../../documents/Documents";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faTimes } from '@fortawesome/free-solid-svg-icons';
+import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
enum FollowModes {
OPENTAB = "Open in Tab",
@@ -48,7 +51,6 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
@observable canPan: boolean = false;
@observable shouldUseOnlyParentContext = false;
_contextDisposer?: IReactionDisposer;
- collectionTypes: string[];
@observable private _docs: { col: Doc, target: Doc }[] = [];
@observable private _otherDocs: { col: Doc, target: Doc }[] = [];
@@ -56,8 +58,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
constructor(props: FieldViewProps) {
super(props);
LinkFollowBox.Instance = this;
-
- this.collectionTypes = ["Invalid", "Freeform", "Schema", "Docking", "Tree", "Stacking", "Masonry"];
+ this.props.Document.isBackground = true;
}
@computed
@@ -322,7 +323,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
}
//set this to be the default link behavior, can be any of the above
- private defaultLinkBehavior: (options?: any) => void = this.openLinkInPlace;
+ public defaultLinkBehavior: (options?: any) => void = this.openLinkRight;
@action
currentLinkBehavior = () => {
@@ -556,12 +557,20 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
return null;
}
+ async close() {
+ let res = await DocListCastAsync((CurrentUserUtils.UserDocument.overlays as Doc).data);
+ if (res) res.splice(res.indexOf(LinkFollowBox.Instance.props.Document), 1);
+ }
+
render() {
return (
<div className="linkFollowBox-main" style={{ height: NumCast(this.props.Document.height), width: NumCast(this.props.Document.width) }}>
<div className="linkFollowBox-header">
- {LinkFollowBox.linkDoc ? "Link Title: " + StrCast(LinkFollowBox.linkDoc.title) : "No Link Selected"}
- <div className="linkFollowBox-header direction-indicator">{LinkFollowBox.linkDoc ?
+ <div className="topHeader">
+ {LinkFollowBox.linkDoc ? "Link Title: " + StrCast(LinkFollowBox.linkDoc.title) : "No Link Selected"}
+ <div onClick={this.close} className="closeDocument"><FontAwesomeIcon icon={faTimes} size="lg" /></div>
+ </div>
+ <div className=" direction-indicator">{LinkFollowBox.linkDoc ?
LinkFollowBox.sourceDoc && LinkFollowBox.destinationDoc ? "Source: " + StrCast(LinkFollowBox.sourceDoc.title) + ", Destination: " + StrCast(LinkFollowBox.destinationDoc.title)
: "" : ""}</div>
</div>
@@ -587,6 +596,11 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
</div>
<div className="linkFollowBox-footer">
<button
+ onClick={this.resetVars}>
+ Clear Link
+ </button>
+ <div style={{ width: 20 }}></div>
+ <button
onClick={this.currentLinkBehavior}
disabled={(LinkFollowBox.linkDoc) ? false : true}>
Follow Link
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index d2dc3f7ff..0dda948c4 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -17,6 +17,9 @@ import { CollectionViewType } from '../collections/CollectionBaseView';
import { DocumentView } from '../nodes/DocumentView';
import { SearchUtil } from '../../util/SearchUtil';
import { LinkFollowBox } from './LinkFollowBox';
+import { ContextMenu } from '../ContextMenu';
+import { MainView } from '../MainView';
+import { Docs } from '../../documents/Documents';
library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp);
@@ -35,148 +38,6 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
@observable private _showMore: boolean = false;
@action toggleShowMore() { this._showMore = !this._showMore; }
-
- unhighlight = () => {
- Doc.UnhighlightAll();
- document.removeEventListener("pointerdown", this.unhighlight);
- }
-
- @action
- highlightDoc = () => {
- document.removeEventListener("pointerdown", this.unhighlight);
- Doc.HighlightDoc(this.props.destinationDoc);
- window.setTimeout(() => {
- document.addEventListener("pointerdown", this.unhighlight);
- }, 10000);
- }
-
- // NOT TESTED
- // col = collection the doc is in
- // target = the document to center on
- @undoBatch
- openLinkColRight = (col: Doc) => {
- col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col;
- if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
- const newPanX = NumCast(this.props.destinationDoc.x) + NumCast(this.props.destinationDoc.width) / NumCast(this.props.destinationDoc.zoomBasis, 1) / 2;
- const newPanY = NumCast(this.props.destinationDoc.y) + NumCast(this.props.destinationDoc.height) / NumCast(this.props.destinationDoc.zoomBasis, 1) / 2;
- col.panX = newPanX;
- col.panY = newPanY;
- }
- CollectionDockingView.Instance.AddRightSplit(col, undefined);
- }
-
- // DONE
- @undoBatch
- openFullScreen = () => {
- let view: DocumentView | null = DocumentManager.Instance.getDocumentView(this.props.destinationDoc);
- view && CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(view);
- }
-
- // DONE
- // this opens the linked doc in a right split, NOT in its collection
- @undoBatch
- openLinkRight = () => {
- this.highlightDoc();
- let alias = Doc.MakeAlias(this.props.destinationDoc);
- CollectionDockingView.Instance.AddRightSplit(alias, undefined);
- SelectionManager.DeselectAll();
- }
-
- // DONE
- // this is the standard "follow link" (jump to document)
- // taken from follow link
- @undoBatch
- jumpToLink = async (shouldZoom: boolean) => {
- //there is an issue right now so this will be false automatically
- shouldZoom = false;
- this.highlightDoc();
- let jumpToDoc = this.props.destinationDoc;
- let pdfDoc = FieldValue(Cast(this.props.destinationDoc, Doc));
- if (pdfDoc) {
- jumpToDoc = pdfDoc;
- }
- let proto = Doc.GetProto(this.props.linkDoc);
- let targetContext = await Cast(proto.targetContext, Doc);
- let sourceContext = await Cast(proto.sourceContext, Doc);
- let self = this;
-
- let dockingFunc = (document: Doc) => { this.props.addDocTab(document, undefined, "inTab"); SelectionManager.DeselectAll(); };
-
- if (this.props.destinationDoc === self.props.linkDoc.anchor2 && targetContext) {
- DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, false, async document => dockingFunc(document), undefined, targetContext);
- }
- else if (this.props.destinationDoc === self.props.linkDoc.anchor1 && sourceContext) {
- DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, false, document => dockingFunc(sourceContext!));
- }
- else if (DocumentManager.Instance.getDocumentView(jumpToDoc)) {
- DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, undefined, undefined, NumCast((this.props.destinationDoc === self.props.linkDoc.anchor2 ? self.props.linkDoc.anchor2Page : self.props.linkDoc.anchor1Page)));
-
- }
- else {
- DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, false, dockingFunc);
- }
- }
-
- // DONE
- // opens link in new tab (not in a collection)
- // this opens it full screen, do we need a separate full screen option?
- @undoBatch
- openLinkTab = () => {
- this.highlightDoc();
- let fullScreenAlias = Doc.MakeAlias(this.props.destinationDoc);
- this.props.addDocTab(fullScreenAlias, undefined, "inTab");
- SelectionManager.DeselectAll();
- }
-
- // NOT TESTED
- // opens link in new tab in collection
- // col = collection the doc is in
- // target = the document to center on
- @undoBatch
- openLinkColTab = (col: Doc) => {
- this.highlightDoc();
- col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col;
- if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
- const newPanX = NumCast(this.props.destinationDoc.x) + NumCast(this.props.destinationDoc.width) / NumCast(this.props.destinationDoc.zoomBasis, 1) / 2;
- const newPanY = NumCast(this.props.destinationDoc.y) + NumCast(this.props.destinationDoc.height) / NumCast(this.props.destinationDoc.zoomBasis, 1) / 2;
- col.panX = newPanX;
- col.panY = newPanY;
- }
- // CollectionDockingView.Instance.AddRightSplit(col, undefined);
- this.props.addDocTab(col, undefined, "inTab");
- SelectionManager.DeselectAll();
- }
-
- // DONE
- // this will open a link next to the source doc
- @undoBatch
- openLinkInPlace = () => {
- this.highlightDoc();
-
- let alias = Doc.MakeAlias(this.props.destinationDoc);
- let y = NumCast(this.props.sourceDoc.y);
- let x = NumCast(this.props.sourceDoc.x);
-
- let width = NumCast(this.props.sourceDoc.width);
- let height = NumCast(this.props.sourceDoc.height);
-
- alias.x = x + width + 30;
- alias.y = y;
- alias.width = width;
- alias.height = height;
-
- SelectionManager.SelectedDocuments().map(dv => {
- if (dv.props.Document === this.props.sourceDoc) {
- dv.props.addDocument && dv.props.addDocument(alias, false);
- }
- });
-
- this.jumpToLink(false);
- }
-
- //set this to be the default link behavior, can be any of the above
- private defaultLinkBehavior: any = this.openLinkInPlace;
-
onEdit = (e: React.PointerEvent): void => {
e.stopPropagation();
this.props.showEditor(this.props.linkDoc);
@@ -226,6 +87,26 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
e.stopPropagation();
}
+ onContextMenu = (e: React.MouseEvent) => {
+ e.preventDefault();
+ ContextMenu.Instance.addItem({ description: "Open in Link Follower", event: () => console.log("opening 1!"), icon: "link" });
+ ContextMenu.Instance.addItem({ description: "Follow Default Link", event: () => this.followDefault(), icon: "arrow-right" });
+ ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
+ }
+
+ followDefault = () => {
+ if (!LinkFollowBox.Instance) {
+ Docs.Create.LinkFollowBoxDocument({ x: MainView.Instance.flyoutWidth, y: 20, width: 500, height: 370, title: "Link Follower" });
+ }
+ LinkFollowBox.Instance.setLinkDocs(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc);
+ LinkFollowBox.Instance.defaultLinkBehavior();
+ }
+
+ openLinkFollower = () => {
+ LinkFollowBox.Instance.setLinkDocs(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc);
+ MainView.Instance.toggleLinkFollowBox(false);
+ }
+
render() {
let keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType);
@@ -240,12 +121,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
{canExpand ? <div title="Show more" className="button" onPointerDown={() => this.toggleShowMore()}>
<FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>}
<div title="Edit link" className="button" onPointerDown={this.onEdit}><FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
- {/* Original */}
- {/* <div title="Follow link" className="button" onPointerDown={this.onFollowLink}><FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" /></div> */}
- {/* New */}
- <div title="Follow link" className="button" onClick={() => LinkFollowBox.Instance.setLinkDocs(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc)}><FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" /></div>
- {/* <div title="Follow link" className="button" onClick={this.defaultLinkBehavior}><FontAwesomeIcon className="fa-icon" icon="arrow-right" 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>
</div>
</div>
{this._showMore ? this.renderMetadata() : <></>}
@@ -254,44 +130,4 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
</div >
);
}
-}
-
- // @undoBatch
- // onFollowLink = async (e: React.PointerEvent): Promise<void> => {
- // e.stopPropagation();
- // e.persist();
- // let jumpToDoc = this.props.destinationDoc;
- // let pdfDoc = FieldValue(Cast(this.props.destinationDoc, Doc));
- // if (pdfDoc) {
- // jumpToDoc = pdfDoc;
- // }
- // let proto = Doc.GetProto(this.props.linkDoc);
- // let targetContext = await Cast(proto.targetContext, Doc);
- // let sourceContext = await Cast(proto.sourceContext, Doc);
- // let self = this;
-
-
- // let dockingFunc = (document: Doc) => { this.props.addDocTab(document, undefined, "inTab"); SelectionManager.DeselectAll(); };
- // if (e.ctrlKey) {
- // dockingFunc = (document: Doc) => CollectionDockingView.Instance.AddRightSplit(document, undefined);
- // }
-
- // if (this.props.destinationDoc === self.props.linkDoc.anchor2 && targetContext) {
- // DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, false, async document => dockingFunc(document), undefined, targetContext!);
- // console.log("1")
- // }
- // else if (this.props.destinationDoc === self.props.linkDoc.anchor1 && sourceContext) {
- // DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, false, document => dockingFunc(sourceContext!));
- // console.log("2")
- // }
- // else if (DocumentManager.Instance.getDocumentView(jumpToDoc)) {
- // DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, undefined, NumCast((this.props.destinationDoc === self.props.linkDoc.anchor2 ? self.props.linkDoc.anchor2Page : self.props.linkDoc.anchor1Page)));
- // console.log("3")
-
- // }
- // else {
- // DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, false, dockingFunc);
- // console.log("4")
-
- // }
- // } \ No newline at end of file
+} \ No newline at end of file