import { memo, useCallback, useMemo, useState } from "react"; import { Button, ButtonGroup, Card, Classes, Collapse, IconName, Tag } from "@blueprintjs/core"; import AuxiliaryDialog from "Components/AuxiliaryDialog"; import ButtonLink from "Components/ButtonLink"; import CitekeyPopover from "Components/CitekeyPopover"; import { ErrorBoundary, ErrorCallout } from "Components/Errors"; import ItemDetails from "Components/ItemDetails"; import NotesImport from "Components/NotesImport"; import SciteBadge from "Components/SciteBadge"; import SemanticPanel from "../SemanticPanel"; import { useAnnotationsSettings, useMetadataSettings, useNotesSettings, usePageMenuSettings, useSciteSettings, useTypemapSettings } from "Components/UserSettings"; import { useRoamCitekeys } from "Components/RoamCitekeysContext"; import { useSemantic } from "@clients/semantic"; import { useBool } from "@hooks"; import { findRoamPage, importItemMetadata } from "@services/roam"; import { cleanSemantic, compareItemsByYear } from "./helpers"; import { showClasses } from "../classes"; import { ShowPropertiesSemantic, ShowTypeSemantic } from "../types"; import { cleanLibraryItem, getLocalLink, getPDFLink, getWebLink, identifyChildren, parseDOI, pluralize } from "../../../utils"; import { CustomClasses } from "../../../constants"; import { SEnrichedItemInLibrary, ZCleanItemTop, ZItemAnnotation, ZItemNote, ZItemTop, ZLibraryContents } from "Types/transforms"; function BacklinksItem({ entry }: { entry: SEnrichedItemInLibrary}) { const { _type, inLibrary, inGraph } = entry; const { children: { pdfs, notes }, raw: item } = inLibrary; const { key, data, meta } = item; const pub_year = meta.parsedDate ? new Date(meta.parsedDate).getUTCFullYear() : ""; const pub_type = _type == "cited" ? "reference" : "citation"; const itemActions = useMemo(() => { return ; }, [inGraph, item, notes, pdfs]); return (
  • {pub_year}
    {meta.creatorSummary || ""} {data.publicationTitle || data.bookTitle || data.university || ""} {data.title}
    {itemActions}
  • ); } type BacklinksProps = { isOpen: boolean, items: SEnrichedItemInLibrary[], origin: string }; const Backlinks = memo(function Backlinks(props) { const { isOpen, items = [], origin } = props; if(items.length == 0){ return null; } else { const itemList = [...items]; const sortedItems = itemList.sort((a,b) => compareItemsByYear(a.inLibrary.raw, b.inLibrary.raw)); const references = sortedItems.filter(it => it._type == "cited"); const citations = sortedItems.filter(it => it._type == "citing"); const separator = {origin}; return (
    {references.length > 0 ?
      {references.map((ref) => )}
    : null} {(references.length > 0 && citations.length > 0) ? separator : null} {citations.length > 0 ?
      {citations.map((cit) => )}
    : null}
    ); } }); type RelatedItemsBarProps = { doi: string, itemList: ZLibraryContents, origin: string, title: string }; function RelatedItemsBar(props: RelatedItemsBarProps) { const { doi, itemList, origin, title } = props; const [roamCitekeys/*, updateCitekeys */] = useRoamCitekeys(); const { isLoading, isError, data, error } = useSemantic(doi); const [isBacklinksListOpen, { toggle: toggleBacklinks }] = useBool(false); const [isDialogOpen, { on: openDialog, off: closeDialog }] = useBool(false); const [isShowing, setShowing] = useState({ title, type: ShowTypeSemantic.REFERENCES }); const showReferences = useCallback(() => { setShowing({ title, type: ShowTypeSemantic.REFERENCES }); openDialog(); }, [title, openDialog]); const showCitations = useCallback(() => { setShowing({ title, type: ShowTypeSemantic.CITATIONS }); openDialog(); }, [title, openDialog]); const refCount = (data || {}).references?.length || 0; const citCount = (data || {}).citations?.length || 0; const cleanSemanticData = useMemo(() => { if(!data){ return { backlinks: [], citations: [], references: [] }; } else { const { citations, references } = data; return cleanSemantic(itemList, { citations, references }, roamCitekeys); } }, [data, itemList, roamCitekeys]); const showBacklinksButtonProps = useMemo(() => { return cleanSemanticData.backlinks.length == 0 ? { "aria-disabled": true, disabled: true, icon: null, text: "No related library items" } : { icon: (isBacklinksListOpen ? "caret-down" : "caret-right") as IconName, text: pluralize(cleanSemanticData.backlinks.length, "related library item") }; }, [cleanSemanticData.backlinks.length, isBacklinksListOpen]); return (
    {isError ? : <>
    ); } function ViewItem({ item }: { item: ZCleanItemTop}) { const [isPanelOpen, { on: openPanel, off: closePanel }] = useBool(false); return ( <> ); } type ViewNotesProps = { item: ZItemTop, notes: (ZItemAnnotation | ZItemNote)[], pageUID: string | false }; function ViewNotes({ item, notes, pageUID }: ViewNotesProps){ const [isPanelOpen, { on: openPanel, off: closePanel }] = useBool(false); return <> ; } type CitekeyMenuProps = { item: ZItemTop, itemList: ZLibraryContents }; const CitekeyMenu = memo(function CitekeyMenu({ item, itemList }) { const [annotationsSettings] = useAnnotationsSettings(); const [metadataSettings] = useMetadataSettings(); const [notesSettings] = useNotesSettings(); const [{ defaults }] = usePageMenuSettings(); const [sciteBadgeSettings] = useSciteSettings(); const [typemap] = useTypemapSettings(); const [roamCitekeys/*, updateCitekeys */] = useRoamCitekeys(); const doi = parseDOI(item.data.DOI); const pageUID = findRoamPage("@" + item.key); const children = useMemo(() => { const itemKey = item.data.key; const location = item.library.type + "s/" + item.library.id; const { pdfs, notes } = itemList; return identifyChildren(itemKey, location, { pdfs: pdfs, notes: notes }); }, [itemList, item]); const doiHeader = useMemo(() => { return doi ? {doi} : null; }, [doi]); const importMetadata = useCallback(async() => { const { pdfs, notes } = children; return await importItemMetadata({ item, pdfs, notes }, pageUID, metadataSettings, typemap, notesSettings, annotationsSettings); }, [annotationsSettings, children, item, metadataSettings, notesSettings, pageUID, typemap]); const pdfLinks = useMemo(() => { if(children.pdfs.length == 0 || !defaults.includes("pdfLinks")) { return null; } else { return ( children.pdfs.map(pdf => { return ( ); }) ); } }, [defaults, children.pdfs]); const notesButton = useMemo(() => { if(children.notes.length == 0 || !defaults.includes("importNotes")){ return null; } else { return ; } }, [defaults, children.notes, item, pageUID]); const open_zotero = useMemo(() => { return ( <> {defaults.includes("openZoteroLocal") ? : null} {defaults.includes("openZoteroWeb") ? : null} ); },[defaults, item]); const sciteBadge = useMemo(() => { return doi && defaults.includes("sciteBadge") ? : null; }, [defaults, doi, sciteBadgeSettings]); const ext_links = useMemo(() => { const connectedPapersLink = defaults.includes("connectedPapers") ? : null; const semanticLink = doi && defaults.includes("semanticScholar") ? : null; const googleScholarLink = defaults.includes("googleScholar") ? : null; return ( <> {connectedPapersLink} {semanticLink} {googleScholarLink} ); }, [defaults, doi, item.data.title]); const relatedBar = useMemo(() => { return doi && defaults.includes("citingPapers") ? : null; }, [defaults, doi, item.key, item.meta.parsedDate, itemList]); const clean_item = useMemo(() => { return cleanLibraryItem(item, children.pdfs, children.notes, roamCitekeys); }, [children, item, roamCitekeys]); return ( {doiHeader}
    {defaults.includes("addMetadata") ? : null} {notesButton} {defaults.includes("viewItemInfo") ? : null} {open_zotero} {pdfLinks} {ext_links} {sciteBadge}
    {relatedBar}
    ); }); export default CitekeyMenu; export { Backlinks };