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
?
:
<>
{refCount + citCount > 0
?
: null}
>
}
);
}
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 };