diff options
-rw-r--r-- | src/client/views/DocumentButtonBar.tsx | 29 | ||||
-rw-r--r-- | src/client/views/GlobalKeyHandler.ts | 2 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentLinksButton.scss | 14 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentLinksButton.tsx | 35 |
5 files changed, 64 insertions, 18 deletions
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 208b4d57a..8cd1b650e 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -1,28 +1,28 @@ import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faArrowAltCircleDown, faPhotoVideo, faArrowAltCircleUp, faArrowAltCircleRight, faCheckCircle, faCloudUploadAlt, faLink, faShare, faStopCircle, faSyncAlt, faTag, faTimes } from '@fortawesome/free-solid-svg-icons'; +import { faArrowAltCircleDown, faArrowAltCircleRight, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faPhotoVideo, faShare, faStopCircle, faSyncAlt, faTag, faTimes } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast } from "../../fields/Doc"; import { RichTextField } from '../../fields/RichTextField'; -import { NumCast, StrCast, Cast } from "../../fields/Types"; +import { Cast, NumCast } from "../../fields/Types"; import { emptyFunction, setupMoveUpEvents } from "../../Utils"; +import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager'; import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils'; +import { Docs, DocUtils } from '../documents/Documents'; +import { DragManager } from '../util/DragManager'; import { UndoManager } from "../util/UndoManager"; import { CollectionDockingView, DockedFrameRenderer } from './collections/CollectionDockingView'; import { ParentDocSelector } from './collections/ParentDocumentSelector'; import './collections/ParentDocumentSelector.scss'; import './DocumentButtonBar.scss'; -import { LinkMenu } from "./linking/LinkMenu"; +import { MetadataEntryMenu } from './MetadataEntryMenu'; import { DocumentView } from './nodes/DocumentView'; import { GoogleRef } from "./nodes/formattedText/FormattedTextBox"; import { TemplateMenu } from "./TemplateMenu"; import { Template, Templates } from "./Templates"; import React = require("react"); -import { DragManager } from '../util/DragManager'; -import { MetadataEntryMenu } from './MetadataEntryMenu'; -import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager'; -import { Docs } from '../documents/Documents'; +import { DocumentLinksButton } from './nodes/DocumentLinksButton'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -142,7 +142,16 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV onLinkButtonDown = (e: React.PointerEvent): void => { - setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, emptyFunction); + setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, (e, doubleTap) => { + if (doubleTap) { + if (!DocumentLinksButton.StartLink) { + runInAction(() => DocumentLinksButton.StartLink = this.view0); + } else { + DocumentLinksButton.StartLink !== this.view0 && this.view0 && + DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.view0.props.Document }, "long drag"); + } + } + }); } @@ -242,7 +251,9 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV return !view0 || linkCount ? (null) : <div className="documentButtonBar-button"> <div title="Drag(create link) Tap(view links)" className="documentButtonBar-linkFlyout" ref={this._linkButton}> - <div className={"documentButtonBar-linkButton-" + (linkCount ? "nonempty" : "empty")} onPointerDown={this.onLinkButtonDown} > + <div className={"documentButtonBar-linkButton-" + (linkCount ? "nonempty" : "empty")} + style={{ backgroundColor: "lightBlue", color: "black", border: DocumentLinksButton.StartLink ? "solid red 2px" : "" }} + onPointerDown={this.onLinkButtonDown} > {linkCount ? linkCount : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />} </div> </div> diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 27755737e..7bc8cf6a7 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -19,6 +19,7 @@ import { MarqueeView } from "./collections/collectionFreeForm/MarqueeView"; import { DocumentDecorations } from "./DocumentDecorations"; import { MainView } from "./MainView"; import { DocumentView } from "./nodes/DocumentView"; +import { DocumentLinksButton } from "./nodes/DocumentLinksButton"; const modifiers = ["control", "meta", "shift", "alt"]; type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo | Promise<KeyControlInfo>; @@ -77,6 +78,7 @@ export default class KeyManager { // MarqueeView.DragMarquee = !MarqueeView.DragMarquee; // bcz: this needs a better disclosure UI break; case "escape": + DocumentLinksButton.StartLink = undefined; const main = MainView.Instance; Doc.SetSelectedTool(InkTool.None); if (main.isPointerDown) { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 3a8778c14..eddc225b1 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -245,7 +245,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P // const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, x: xp, y: yp, title: "dropped annotation" }); // this.props.addDocument(source); // linkDragData.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: linkDragData.linkSourceDocument }, "doc annotation"); // TODODO this is where in text links get passed - return false; + return false; } else { const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, x: xp, y: yp, title: "dropped annotation" }); this.props.addDocument(source); diff --git a/src/client/views/nodes/DocumentLinksButton.scss b/src/client/views/nodes/DocumentLinksButton.scss index b9d5d437b..b4c59b91c 100644 --- a/src/client/views/nodes/DocumentLinksButton.scss +++ b/src/client/views/nodes/DocumentLinksButton.scss @@ -13,14 +13,16 @@ cursor: pointer; } +.documentLinksButton-button, .documentLinksButton-button-empty, .documentLinksButton-button-nonempty { height: 20px; width: 20px; + left: -15px; + position: absolute; border-radius: 50%; opacity: 0.9; pointer-events: auto; - background-color: $link-color; color: black; text-transform: uppercase; letter-spacing: 2px; @@ -36,4 +38,14 @@ transform: scale(1.05); cursor: pointer; } +} +.documentLinksButton-button-nonempty { + background-color: $link-color; +} +.documentLinksButton-button-empty { + border: red solid 2px; +} +.documentLinksButton-button { + border: red solid 2px; + background-color: rgba(255, 192, 203, 0.5); }
\ No newline at end of file diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 8ab3aed00..c9083a65f 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -1,12 +1,14 @@ import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast } from "../../../fields/Doc"; -import { emptyFunction, setupMoveUpEvents } from "../../../Utils"; +import { emptyFunction, setupMoveUpEvents, returnFalse } from "../../../Utils"; import { DragManager } from "../../util/DragManager"; import { UndoManager } from "../../util/UndoManager"; import './DocumentLinksButton.scss'; import { DocumentView } from "./DocumentView"; import React = require("react"); +import { DocUtils } from "../../documents/Documents"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -45,10 +47,27 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp return false; } + @observable static StartLink: DocumentView | undefined; onLinkButtonDown = (e: React.PointerEvent): void => { - setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e) => { - DocumentLinksButton.EditLink = this.props.View; - DocumentLinksButton.EditLinkLoc = [e.clientX, e.clientY]; + setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => { + if (doubleTap) { + DocumentLinksButton.StartLink = this.props.View; + } else { + DocumentLinksButton.EditLink = this.props.View; + DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY]; + } + })); + } + completeLink = (e: React.PointerEvent): void => { + setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e, doubleTap) => { + if (doubleTap) { + if (DocumentLinksButton.StartLink === this.props.View) { + DocumentLinksButton.StartLink = undefined; + } else { + DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View && + DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag"); + } + } })); } @@ -59,11 +78,13 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp @computed get linkButton() { const links = DocListCast(this.props.View.props.Document.links); - return !this.props.View || !links.length || links[0].hidden ? (null) : - <div title="Drag(create link) Tap(view links)" style={{ position: "absolute", left: -15, bottom: -15 }} ref={this._linkButton}> + return !links.length || links[0].hidden ? (null) : + <div title="Drag(create link) Tap(view links)" ref={this._linkButton}> <div className={"documentLinksButton-button-nonempty"} onPointerDown={this.onLinkButtonDown} > - {links.length} + {links.length ? links.length : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />} </div> + {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-button-empty"} onPointerDown={this.completeLink} /> : (null)} + {DocumentLinksButton.StartLink === this.props.View ? <div className={"documentLinksButton-button"} /> : (null)} </div>; } render() { |