diff options
Diffstat (limited to 'src/client/apis')
| -rw-r--r-- | src/client/apis/hypothesis/HypothesisUtils.ts | 133 | 
1 files changed, 67 insertions, 66 deletions
| diff --git a/src/client/apis/hypothesis/HypothesisUtils.ts b/src/client/apis/hypothesis/HypothesisUtils.ts index 5c6e4d31d..f3ff196a8 100644 --- a/src/client/apis/hypothesis/HypothesisUtils.ts +++ b/src/client/apis/hypothesis/HypothesisUtils.ts @@ -1,7 +1,7 @@  import { StrCast, Cast } from "../../../fields/Types";  import { SearchUtil } from "../../util/SearchUtil";  import { action, runInAction } from "mobx"; -import { Doc } from "../../../fields/Doc"; +import { Doc, Opt } from "../../../fields/Doc";  import { DocumentType } from "../../documents/DocumentTypes";  import { Docs, DocUtils } from "../../documents/Documents";  import { SelectionManager } from "../../util/SelectionManager"; @@ -10,17 +10,23 @@ import { DocumentManager } from "../../util/DocumentManager";  import { DocumentLinksButton } from "../../views/nodes/DocumentLinksButton";  import { LinkManager } from "../../util/LinkManager";  import { TaskCompletionBox } from "../../views/nodes/TaskCompletedBox"; -import { Utils } from "../../../Utils"; +import { Utils, simulateMouseClick } from "../../../Utils";  import { LinkDescriptionPopup } from "../../views/nodes/LinkDescriptionPopup";  import { Id } from "../../../fields/FieldSymbols"; +import { DocumentView } from "../../views/nodes/DocumentView";  export namespace Hypothesis { -    // Return web doc with the given uri, or create and create a new doc with the given uri      export const getSourceWebDoc = async (uri: string) => { -        const currentDoc = SelectionManager.SelectedDocuments()[0].props.Document; -        console.log(Cast(currentDoc.data, WebField)?.url.href === uri, uri, Cast(currentDoc.data, WebField)?.url.href); -        if (Cast(currentDoc.data, WebField)?.url.href === uri) return currentDoc; // always check first whether the current doc is the source, only resort to Search otherwise +        const result = await findWebDoc(uri); +        return result || Docs.Create.WebDocument(uri, { _nativeWidth: 850, _nativeHeight: 962, _width: 600, UseCors: true }); // create and return a new Web doc with given uri if no matching docs are found +    }; + +    // Search for a web Doc whose url field matches the given uri, return undefined if not found +    export const findWebDoc = async (uri: string) => { +        const currentDoc = SelectionManager.SelectedDocuments().length && SelectionManager.SelectedDocuments()[0].props.Document; +        currentDoc && console.log(Cast(currentDoc.data, WebField)?.url.href === uri, uri, Cast(currentDoc.data, WebField)?.url.href); +        if (currentDoc && Cast(currentDoc.data, WebField)?.url.href === 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) => { @@ -34,17 +40,64 @@ export namespace Hypothesis {          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, UseCors: true }); // create and return a new Web doc with given uri if no matching docs are found +        return results.length ? results[0] : undefined;      }; -    // Send Hypothes.is client request to edit an annotation to add a Dash hyperlink -    export const makeLink = async (title: string, url: string, annotationId: string) => { +    // Ask Hypothes.is client to edit an annotation to add a Dash hyperlink +    export const makeLink = async (title: string, url: string, annotationId: string, annotationSourceDoc: Doc) => { +        // if the annotation's source webpage isn't currently loaded in Dash, we're not able to access and edit the annotation from the client +        // so we're loading the webpage and its annotations invisibly in a WebBox in MainView.tsx, until the editing is done +        !DocumentManager.Instance.getFirstDocumentView(annotationSourceDoc) && runInAction(() => DocumentLinksButton.invisibleWebDoc = annotationSourceDoc); + +        var success = false; +        const onSuccess = action(() => { +            console.log("EDITSUCCESS"); +            clearTimeout(interval); +            DocumentLinksButton.invisibleWebDoc = undefined; +            document.removeEventListener("editSuccess", onSuccess); +            success = true; +        }); +          console.log("SEND addLink");          const newHyperlink = `[${title}\n](${url})`; -        document.dispatchEvent(new CustomEvent<{ newHyperlink: string, id: string }>("addLink", { -            detail: { newHyperlink: newHyperlink, id: annotationId }, -            bubbles: true -        })); +        const interval = setInterval(() => // keep trying to scroll every 250ms until annotations have loaded and editing is successful +            !success && document.dispatchEvent(new CustomEvent<{ newHyperlink: string, id: string }>("addLink", { +                detail: { newHyperlink: newHyperlink, id: annotationId }, +                bubbles: true +            })), 300); + +        setTimeout(action(() => { +            if (!success) { +                clearInterval(interval); +                DocumentLinksButton.invisibleWebDoc = undefined; +            } +        }), 15000); // give up if no success after 15s + +        document.addEventListener("editSuccess", onSuccess); +    }; + +    export const scrollToAnnotation = (annotationId: string, target: Doc) => { +        var success = false; +        const onSuccess = () => { +            console.log("scroll success!!"); +            document.removeEventListener('scrollSuccess', onSuccess); +            clearInterval(interval); +            success = true; +        }; + +        const interval = setInterval(() => { // keep trying to scroll every 250ms until annotations have loaded and scrolling is successful +            console.log("send scroll"); +            document.dispatchEvent(new CustomEvent('scrollToAnnotation', { +                detail: annotationId, +                bubbles: true +            })); +            const targetView: Opt<DocumentView> = DocumentManager.Instance.getFirstDocumentView(target); +            const position = targetView?.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); +            targetView && position && simulateMouseClick(targetView.ContentDiv!, position[0], position[1], position[0], position[1], false); +        }, 300); + +        document.addEventListener('scrollSuccess', onSuccess); // listen for success message from client +        setTimeout(() => !success && clearInterval(interval), 10000); // give up if no success after 10s      };      // Send Hypothes.is client request to edit an annotation to find and remove a dash hyperlink @@ -80,7 +133,7 @@ export namespace Hypothesis {              Doc.GetProto(linkDoc as Doc).linksToAnnotation = true;              Doc.GetProto(linkDoc as Doc).annotationId = DocumentLinksButton.AnnotationId;              Doc.GetProto(linkDoc as Doc).annotationUri = DocumentLinksButton.AnnotationUri; -            makeLink(StrCast(DocumentLinksButton.StartLink.title), Utils.prepend("/doc/" + DocumentLinksButton.StartLink[Id]), StrCast(DocumentLinksButton.AnnotationId)); // update and link placeholder annotation +            makeLink(StrCast(DocumentLinksButton.StartLink.title), Utils.prepend("/doc/" + DocumentLinksButton.StartLink[Id]), StrCast(DocumentLinksButton.AnnotationId), sourceDoc); // update and link placeholder annotation              runInAction(() => {                  if (linkDoc) { @@ -99,56 +152,4 @@ export namespace Hypothesis {              });          }      }; - -    // Return web doc with the given uri, or create and create a new doc with the given uri -    export const getSourceWebDocView = async (uri: string) => { -        const currentDoc = SelectionManager.SelectedDocuments()[0].props.Document; -        console.log(Cast(currentDoc.data, WebField)?.url.href === uri, uri, Cast(currentDoc.data, WebField)?.url.href); -        if (Cast(currentDoc.data, WebField)?.url.href === 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.author === Doc.CurrentUserEmail && doc.type === DocumentType.WEB && doc.data -            ); -            filteredDocs.forEach(doc => console.log("web docs:", doc.title, Cast(doc.data, WebField)?.url.href)); -            filteredDocs.forEach(doc => { uri === Cast(doc.data, WebField)?.url.href && results.push(doc); }); // TODO check history? imperfect matches? -        })); - -        results.forEach(doc => { -            const docView = DocumentManager.Instance.getFirstDocumentView(doc); -            if (docView) { -                console.log(doc.title, StrCast(doc.data)); -                return docView; -            } -        }); - -        return undefined; -    }; - -    export const createInvisibleDoc = (uri: string) => { -        const newDoc = Docs.Create.WebDocument(uri, { _nativeWidth: 0, _nativeHeight: 0, _width: 0, UseCors: true }); -    }; - -    export const scrollToAnnotation = (annotationId: string) => { -        var success = false; -        const onSuccess = () => { -            console.log("scroll success!!"); -            document.removeEventListener('scrollSuccess', onSuccess); -            clearTimeout(interval); -            success = true; -        }; - -        const interval = setInterval(() => { // keep trying to scroll every 200ms until annotations have loaded and scrolling is successful -            console.log("send scroll"); -            document.dispatchEvent(new CustomEvent('scrollToAnnotation', { -                detail: annotationId, -                bubbles: true -            })); -        }, 250); - -        document.addEventListener('scrollSuccess', onSuccess); // listen for success message from client -        setTimeout(() => !success && clearTimeout(interval), 10000); // give up if no success after 10s -    };  }
\ No newline at end of file | 
