diff options
author | Melissa Zhang <mzhang19096@gmail.com> | 2020-07-30 21:13:08 -0700 |
---|---|---|
committer | Melissa Zhang <mzhang19096@gmail.com> | 2020-07-30 21:13:08 -0700 |
commit | 3e6dfbb32b9cafaafe178c8e8e427207a17325e2 (patch) | |
tree | 18b3ccb1c3292fe6d0e77a0e39842ff4cb37a988 /src | |
parent | 3d02d928ad869b9157019aec356e2f1ea2ce47d6 (diff) |
change DocumentLinksButton.StartLink to use Doc instead of DocumentView
Diffstat (limited to 'src')
-rw-r--r-- | src/client/apis/hypothesis/HypothesisUtils.ts | 19 | ||||
-rw-r--r-- | src/client/views/MainView.tsx | 45 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentLinksButton.tsx | 55 |
3 files changed, 80 insertions, 39 deletions
diff --git a/src/client/apis/hypothesis/HypothesisUtils.ts b/src/client/apis/hypothesis/HypothesisUtils.ts index a9d807976..855964bf6 100644 --- a/src/client/apis/hypothesis/HypothesisUtils.ts +++ b/src/client/apis/hypothesis/HypothesisUtils.ts @@ -3,8 +3,8 @@ import { SearchUtil } from "../../util/SearchUtil"; import { action } from "mobx"; import { Doc } from "../../../fields/Doc"; import { DocumentType } from "../../documents/DocumentTypes"; -import { WebField } from "../../../fields/URLField"; -import { DocumentManager } from "../../util/DocumentManager"; +import { Docs } from "../../documents/Documents"; +import { SelectionManager } from "../../util/SelectionManager"; export namespace Hypothesis { @@ -39,20 +39,21 @@ export namespace Hypothesis { // Return corres export const getSourceWebDoc = async (uri: string) => { + const currentDoc = SelectionManager.SelectedDocuments()[0].props.Document; + if (StrCast(currentDoc.data) === uri) return currentDoc; // always check first whether the current doc is the source, only resort to Search otherwise + const results: Doc[] = []; await SearchUtil.Search("web", true).then(action(async (res: SearchUtil.DocSearchResult) => { const docs = await Promise.all(res.docs.map(async doc => (await Cast(doc.extendsDoc, Doc)) || doc)); const filteredDocs = docs.filter(doc => - doc.type === DocumentType.WEB && doc.data + doc.author === Doc.CurrentUserEmail && doc.type === DocumentType.WEB && doc.data ); - filteredDocs.forEach(doc => { - console.log(uri, Cast(doc.data, WebField)?.url.href, uri === Cast(doc.data, WebField)?.url.href); - (uri === Cast(doc.data, WebField)?.url.href) && results.push(doc); // TODO check history? imperfect matches? - }); + filteredDocs.forEach(doc => { uri === StrCast(doc.data) && results.push(doc); }); // TODO check history? imperfect matches? })); - // TODO: open & return new Web doc with given uri if no matching Web docs are found - return results.length ? DocumentManager.Instance.getFirstDocumentView(results[0]) : undefined; + results.forEach(doc => console.log(doc.title, StrCast(doc.data))); + + return results.length ? results[0] : Docs.Create.WebDocument(uri, { _nativeWidth: 850, _nativeHeight: 962, _width: 600 }); // create and return a new Web doc with given uri if no matching docs are found }; export const scrollToAnnotation = (annotationId: string) => { diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index dd8433866..93e4d1a6f 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -55,10 +55,8 @@ import { LinkDocPreview } from './nodes/LinkDocPreview'; import { TaskCompletionBox } from './nodes/TaskCompletedBox'; import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup'; import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane"; -import HypothesisAuthenticationManager from '../apis/HypothesisAuthenticationManager'; import CollectionMenu from './collections/CollectionMenu'; import { Hypothesis } from '../apis/hypothesis/HypothesisUtils'; -import { SelectionManager } from '../util/SelectionManager'; @observer export class MainView extends React.Component { @@ -107,19 +105,37 @@ export class MainView extends React.Component { }); }); document.addEventListener("linkAnnotationToDash", async (e: any) => { // listen for event from Hypothes.is plugin to link an annotation to Dash - const annotationId = e.detail.id; - const annotationUri = e.detail.uri; - const sourceDoc = await Hypothesis.getSourceWebDoc(annotationUri); - console.log("sourceDoc: ", sourceDoc ? sourceDoc.title : "not found"); - - // TO BE FIXED, currently cannot start links from new webpages that don't exist in Dash - const source = sourceDoc || SelectionManager.SelectedDocuments()[0]; - runInAction(() => { - DocumentLinksButton.AnnotationId = annotationId; - DocumentLinksButton.AnnotationUri = annotationUri; - DocumentLinksButton.StartLink = source; - }); + if (!DocumentLinksButton.StartLink) { // starts link only if there are none already started (else, a listener in DocumentLinksButton will handle link completion) + const annotationId = e.detail.id; + const annotationUri = e.detail.uri; + const sourceDoc = await Hypothesis.getSourceWebDoc(annotationUri); + console.log("sourceDoc: ", sourceDoc.title); + + runInAction(() => { + DocumentLinksButton.AnnotationId = annotationId; + DocumentLinksButton.AnnotationUri = annotationUri; + DocumentLinksButton.StartLink = sourceDoc; + }); + } }); + + // reaction(() => SelectionManager.SelectedDocuments(), selected => { + // console.log("selection changed"); + // const selectedWebDocs = selected.map(docView => docView.props.Document).filter(doc => doc.type === DocumentType.WEB); + // const urls = selectedWebDocs.map(doc => Cast(doc.data, WebField)?.url.href).filter(url => url !== undefined); + // console.log("urls", urls); + + // const frame = document.getElementById('hyp_sidebar') as HTMLIFrameElement; + // console.log("contentwindow?", frame.contentDocument); + // if (frame.contentWindow) { + // frame.contentWindow.postMessage("hello sidebar", window.origin); + // } + + // document.dispatchEvent(new CustomEvent('showAnnotations', { + // detail: urls, + // bubbles: true + // })); + // }); } componentWillUnMount() { @@ -623,7 +639,6 @@ export class MainView extends React.Component { <SettingsManager /> <GroupManager /> <GoogleAuthenticationManager /> - <HypothesisAuthenticationManager /> <DocumentDecorations /> <CollectionMenu /> <FormatShapePane /> diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 445ab6cd4..581d84eae 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -3,6 +3,7 @@ import { Tooltip } from "@material-ui/core"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast } from "../../../fields/Doc"; +import { DocumentType } from "../../documents/DocumentTypes"; import { emptyFunction, setupMoveUpEvents, returnFalse, Utils } from "../../../Utils"; import { TraceMobx } from "../../../fields/util"; import { DocUtils } from "../../documents/Documents"; @@ -34,10 +35,36 @@ interface DocumentLinksButtonProps { export class DocumentLinksButton extends React.Component<DocumentLinksButtonProps, {}> { private _linkButton = React.createRef<HTMLDivElement>(); - @observable public static StartLink: DocumentView | undefined; + @observable public static StartLink: Doc | undefined; @observable public static AnnotationId: string | undefined; @observable public static AnnotationUri: string | undefined; + componentDidMount() { + document.addEventListener("linkAnnotationToDash", this.onLinkFromAnnotation); + } + + componentWillUnmount() { + document.removeEventListener("linkAnnotationToDash", this.onLinkFromAnnotation); + } + + onLinkFromAnnotation = async (e: any) => { + const annotationUri = e.detail.uri; + const sourceDoc = DocumentLinksButton.StartLink && await Hypothesis.getSourceWebDoc(annotationUri); + + this.props.View.props.Document.type === DocumentType.WEB && console.log(sourceDoc === this.props.View.props.Document, + sourceDoc, + this.props.View.props.Document, + sourceDoc!.title, + this.props.View.props.Document, + sourceDoc!.data, + this.props.View.props.Document.data); + + if (sourceDoc === this.props.View.props.Document && sourceDoc !== DocumentLinksButton.StartLink) { + this.finishLinkClick(20, 20); + console.log("completed link from annotation"); + } + } + @action @undoBatch onLinkButtonMoved = (e: PointerEvent) => { if (this.props.InMenu && this.props.StartLink) { @@ -73,7 +100,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => { if (doubleTap && this.props.InMenu && this.props.StartLink) { //action(() => Doc.BrushDoc(this.props.View.Document)); - DocumentLinksButton.StartLink = this.props.View; + DocumentLinksButton.StartLink = this.props.View.props.Document; } else if (!this.props.InMenu) { DocumentLinksButton.EditLink = this.props.View; DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY]; @@ -84,7 +111,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp @action @undoBatch onLinkClick = (e: React.MouseEvent): void => { if (this.props.InMenu && this.props.StartLink) { - DocumentLinksButton.StartLink = this.props.View; + DocumentLinksButton.StartLink = this.props.View.props.Document; //action(() => Doc.BrushDoc(this.props.View.Document)); } else if (!this.props.InMenu) { DocumentLinksButton.EditLink = this.props.View; @@ -96,21 +123,20 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp completeLink = (e: React.PointerEvent): void => { setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e, doubleTap) => { if (doubleTap && this.props.InMenu && !!!this.props.StartLink) { - if (DocumentLinksButton.StartLink === this.props.View) { + if (DocumentLinksButton.StartLink === this.props.View.props.Document) { DocumentLinksButton.StartLink = undefined; DocumentLinksButton.AnnotationId = undefined; } else { - if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View) { - const sourceDoc = DocumentLinksButton.StartLink.props.Document; + if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View.props.Document) { + const sourceDoc = DocumentLinksButton.StartLink; const targetDoc = this.props.View.props.Document; const linkDoc = DocUtils.MakeLink({ doc: sourceDoc }, { doc: targetDoc }, DocumentLinksButton.AnnotationId ? "hypothes.is annotation" : "long drag"); // TODO: Not currently possible to drag to complete links to annotations if (DocumentLinksButton.AnnotationId && DocumentLinksButton.AnnotationUri) { - const sourceUrl = DocumentLinksButton.AnnotationUri; Doc.GetProto(linkDoc as Doc).linksToAnnotation = true; Doc.GetProto(linkDoc as Doc).annotationId = DocumentLinksButton.AnnotationId; - Doc.GetProto(linkDoc as Doc).annotationUrl = Hypothesis.makeAnnotationUrl(DocumentLinksButton.AnnotationId, sourceUrl); // redirect web doc to this URL when following link + Doc.GetProto(linkDoc as Doc).annotationUri = DocumentLinksButton.AnnotationUri; Hypothesis.makeLink(StrCast(targetDoc.title), Utils.prepend("/doc/" + targetDoc[Id]), DocumentLinksButton.AnnotationId); // update and link placeholder annotation } @@ -139,13 +165,13 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp @action @undoBatch finishLinkClick = (screenX: number, screenY: number) => { - if (DocumentLinksButton.StartLink === this.props.View) { + if (DocumentLinksButton.StartLink === this.props.View.props.Document) { DocumentLinksButton.StartLink = undefined; DocumentLinksButton.AnnotationId = undefined; } else { if (this.props.InMenu && !!!this.props.StartLink) { - if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View) { - const linkDoc = DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, DocumentLinksButton.AnnotationId ? "hypothes.is annotation" : "long drag"); + if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View.props.Document) { + const linkDoc = DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink }, { doc: this.props.View.props.Document }, DocumentLinksButton.AnnotationId ? "hypothes.is annotation" : "long drag"); // this notifies any of the subviews that a document is made so that they can make finer-grained hyperlinks (). see note above in onLInkButtonMoved runInAction(() => DocumentLinksButton.StartLink!._link = this.props.View._link = linkDoc); setTimeout(action(() => DocumentLinksButton.StartLink!._link = this.props.View._link = undefined), 0); @@ -153,11 +179,10 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp // if the link is to a Hypothes.is annotation if (DocumentLinksButton.AnnotationId && DocumentLinksButton.AnnotationUri) { - const sourceUrl = DocumentLinksButton.AnnotationUri; // the URL of the annotation's source web page const targetDoc = this.props.View.props.Document; Doc.GetProto(linkDoc as Doc).linksToAnnotation = true; Doc.GetProto(linkDoc as Doc).annotationId = DocumentLinksButton.AnnotationId; - Doc.GetProto(linkDoc as Doc).annotationUrl = Hypothesis.makeAnnotationUrl(DocumentLinksButton.AnnotationId, sourceUrl); // redirect web doc to this URL when following link + Doc.GetProto(linkDoc as Doc).annotationUri = DocumentLinksButton.AnnotationUri; Hypothesis.makeLink(StrCast(targetDoc.title), Utils.prepend("/doc/" + targetDoc[Id]), DocumentLinksButton.AnnotationId); // update and link placeholder annotation } @@ -231,10 +256,10 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp <FontAwesomeIcon className="documentdecorations-icon" icon="hand-paper" size="sm" /> : links.length} </div> - {DocumentLinksButton.StartLink && this.props.InMenu && !!!this.props.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"} + {DocumentLinksButton.StartLink && this.props.InMenu && !!!this.props.StartLink && DocumentLinksButton.StartLink !== this.props.View.props.Document ? <div className={"documentLinksButton-endLink"} style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }} onPointerDown={this.completeLink} onClick={e => this.finishLinkClick(e.screenX, e.screenY)} /> : (null)} - {DocumentLinksButton.StartLink === this.props.View && this.props.InMenu && this.props.StartLink ? <div className={"documentLinksButton-startLink"} + {DocumentLinksButton.StartLink === this.props.View.props.Document && this.props.InMenu && this.props.StartLink ? <div className={"documentLinksButton-startLink"} style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }} /> : (null)} </div>; |