diff --git a/addon/chrome/content/icons/in-link-16.svg b/addon/chrome/content/icons/inbound-link-16.svg similarity index 100% rename from addon/chrome/content/icons/in-link-16.svg rename to addon/chrome/content/icons/inbound-link-16.svg diff --git a/addon/chrome/content/icons/in-link-20.svg b/addon/chrome/content/icons/inbound-link-20.svg similarity index 100% rename from addon/chrome/content/icons/in-link-20.svg rename to addon/chrome/content/icons/inbound-link-20.svg diff --git a/addon/chrome/content/icons/out-link-16.svg b/addon/chrome/content/icons/outbound-link-16.svg similarity index 100% rename from addon/chrome/content/icons/out-link-16.svg rename to addon/chrome/content/icons/outbound-link-16.svg diff --git a/addon/chrome/content/icons/out-link-20.svg b/addon/chrome/content/icons/outbound-link-20.svg similarity index 100% rename from addon/chrome/content/icons/out-link-20.svg rename to addon/chrome/content/icons/outbound-link-20.svg diff --git a/addon/locale/en-US/noteRelation.ftl b/addon/locale/en-US/noteRelation.ftl index 6b3705c..9d806d2 100644 --- a/addon/locale/en-US/noteRelation.ftl +++ b/addon/locale/en-US/noteRelation.ftl @@ -5,24 +5,24 @@ note-relation-sidenav = note-relation-refresh = .tooltiptext = Refresh -note-inlink-header = +note-inbound-header = .label = { $count -> [one] { $count } Inbound Link *[other] { $count } Inbound Links } -note-inlink-sidenav = +note-inbound-sidenav = .tooltiptext = Inbound Links -note-inlink-refresh = +note-inbound-refresh = .tooltiptext = Refresh -note-outlink-header = +note-outbound-header = .label = { $count -> [one] { $count } Outbound Link *[other] { $count } Outbound Links } -note-outlink-sidenav = +note-outbound-sidenav = .tooltiptext = Outbound Links -note-outlink-refresh = +note-outbound-refresh = .tooltiptext = Refresh diff --git a/addon/locale/it-IT/noteRelation.ftl b/addon/locale/it-IT/noteRelation.ftl index 6b3705c..9d806d2 100644 --- a/addon/locale/it-IT/noteRelation.ftl +++ b/addon/locale/it-IT/noteRelation.ftl @@ -5,24 +5,24 @@ note-relation-sidenav = note-relation-refresh = .tooltiptext = Refresh -note-inlink-header = +note-inbound-header = .label = { $count -> [one] { $count } Inbound Link *[other] { $count } Inbound Links } -note-inlink-sidenav = +note-inbound-sidenav = .tooltiptext = Inbound Links -note-inlink-refresh = +note-inbound-refresh = .tooltiptext = Refresh -note-outlink-header = +note-outbound-header = .label = { $count -> [one] { $count } Outbound Link *[other] { $count } Outbound Links } -note-outlink-sidenav = +note-outbound-sidenav = .tooltiptext = Outbound Links -note-outlink-refresh = +note-outbound-refresh = .tooltiptext = Refresh diff --git a/addon/locale/ru-RU/noteRelation.ftl b/addon/locale/ru-RU/noteRelation.ftl index 6b3705c..9d806d2 100644 --- a/addon/locale/ru-RU/noteRelation.ftl +++ b/addon/locale/ru-RU/noteRelation.ftl @@ -5,24 +5,24 @@ note-relation-sidenav = note-relation-refresh = .tooltiptext = Refresh -note-inlink-header = +note-inbound-header = .label = { $count -> [one] { $count } Inbound Link *[other] { $count } Inbound Links } -note-inlink-sidenav = +note-inbound-sidenav = .tooltiptext = Inbound Links -note-inlink-refresh = +note-inbound-refresh = .tooltiptext = Refresh -note-outlink-header = +note-outbound-header = .label = { $count -> [one] { $count } Outbound Link *[other] { $count } Outbound Links } -note-outlink-sidenav = +note-outbound-sidenav = .tooltiptext = Outbound Links -note-outlink-refresh = +note-outbound-refresh = .tooltiptext = Refresh diff --git a/addon/locale/tr-TR/noteRelation.ftl b/addon/locale/tr-TR/noteRelation.ftl index 6b3705c..9d806d2 100644 --- a/addon/locale/tr-TR/noteRelation.ftl +++ b/addon/locale/tr-TR/noteRelation.ftl @@ -5,24 +5,24 @@ note-relation-sidenav = note-relation-refresh = .tooltiptext = Refresh -note-inlink-header = +note-inbound-header = .label = { $count -> [one] { $count } Inbound Link *[other] { $count } Inbound Links } -note-inlink-sidenav = +note-inbound-sidenav = .tooltiptext = Inbound Links -note-inlink-refresh = +note-inbound-refresh = .tooltiptext = Refresh -note-outlink-header = +note-outbound-header = .label = { $count -> [one] { $count } Outbound Link *[other] { $count } Outbound Links } -note-outlink-sidenav = +note-outbound-sidenav = .tooltiptext = Outbound Links -note-outlink-refresh = +note-outbound-refresh = .tooltiptext = Refresh diff --git a/addon/locale/zh-CN/noteRelation.ftl b/addon/locale/zh-CN/noteRelation.ftl index 534952e..ae98c1d 100644 --- a/addon/locale/zh-CN/noteRelation.ftl +++ b/addon/locale/zh-CN/noteRelation.ftl @@ -5,24 +5,24 @@ note-relation-sidenav = note-relation-refresh = .tooltiptext = 刷新 -note-inlink-header = +note-inbound-header = .label = { $count -> [one] { $count }条入链 *[other] { $count }条入链 } -note-inlink-sidenav = +note-inbound-sidenav = .tooltiptext = 入链 -note-inlink-refresh = +note-inbound-refresh = .tooltiptext = 刷新 -note-outlink-header = +note-outbound-header = .label = { $count -> [one] { $count }条出链 *[other] { $count }条出链 } -note-outlink-sidenav = +note-outbound-sidenav = .tooltiptext = 出链 -note-outlink-refresh = +note-outbound-refresh = .tooltiptext = 刷新 diff --git a/src/hooks.ts b/src/hooks.ts index 9ab87c3..81a5282 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -39,8 +39,7 @@ import { getFocusedWindow } from "./utils/window"; import { registerNoteRelation } from "./modules/workspace/relation"; import { getPref, setPref } from "./utils/prefs"; import { closeRelationWorker } from "./utils/relation"; -import { registerNoteInboundLink } from "./modules/workspace/inLink"; -import { registerNoteOutboundLink } from "./modules/workspace/outLink"; +import { registerNoteLinkSection } from "./modules/workspace/link"; async function onStartup() { await Promise.all([ @@ -65,9 +64,8 @@ async function onStartup() { registerNoteRelation(); - registerNoteOutboundLink(); - - registerNoteInboundLink(); + registerNoteLinkSection("inbound"); + registerNoteLinkSection("outbound"); initSyncList(); diff --git a/src/modules/workspace/inLink.ts b/src/modules/workspace/link.ts similarity index 70% rename from src/modules/workspace/inLink.ts rename to src/modules/workspace/link.ts index c8c896c..f9a1520 100644 --- a/src/modules/workspace/inLink.ts +++ b/src/modules/workspace/link.ts @@ -1,24 +1,28 @@ import { config } from "../../../package.json"; -export function registerNoteInboundLink() { +export function registerNoteLinkSection(type: "inbound" | "outbound") { const key = Zotero.ItemPaneManager.registerSection({ - paneID: `bn-note-inbound-link`, + paneID: `bn-note-${type}-link`, pluginID: config.addonID, header: { - icon: `chrome://${config.addonRef}/content/icons/in-link-16.svg`, - l10nID: `${config.addonRef}-note-inlink-header`, + icon: `chrome://${config.addonRef}/content/icons/${type}-link-16.svg`, + l10nID: `${config.addonRef}-note-${type}-header`, }, sidenav: { - icon: `chrome://${config.addonRef}/content/icons/in-link-20.svg`, - l10nID: `${config.addonRef}-note-inlink-sidenav`, + icon: `chrome://${config.addonRef}/content/icons/${type}-link-20.svg`, + l10nID: `${config.addonRef}-note-${type}-sidenav`, }, sectionButtons: [ { type: "refreshGraph", icon: "chrome://zotero/skin/16/universal/sync.svg", - l10nID: `${config.addonRef}-note-inlink-refresh`, + l10nID: `${config.addonRef}-note-${type}-refresh`, onClick: ({ body, item, setL10nArgs }) => { - renderSection(body, item, makeSetCount(setL10nArgs)); + renderSection(type, { + body, + item, + setCount: makeSetCount(setL10nArgs), + }); }, }, ], @@ -60,23 +64,44 @@ export function registerNoteInboundLink() { }, onRender: () => {}, onAsyncRender: async ({ body, item, setL10nArgs }) => { - await renderSection(body, item, makeSetCount(setL10nArgs)); + await renderSection(type, { + body, + item, + setCount: makeSetCount(setL10nArgs), + }); }, }); } async function renderSection( - body: HTMLElement, - item: Zotero.Item, - setCount: (count: number) => void, + type: "inbound" | "outbound", + { + body, + item, + setCount, + }: { + body: HTMLElement; + item: Zotero.Item; + setCount: (count: number) => void; + }, ) { body.replaceChildren(); const doc = body.ownerDocument; - const inLinks = await addon.api.relation.getNoteLinkInboundRelation(item.id); + const api = { + inbound: addon.api.relation.getNoteLinkInboundRelation, + outbound: addon.api.relation.getNoteLinkOutboundRelation, + }; + const inLinks = await api[type](item.id); for (const linkData of inLinks) { const fromItem = (await Zotero.Items.getByLibraryAndKeyAsync( - linkData.fromLibID, - linkData.fromKey, + linkData[ + { inbound: "fromLibID", outbound: "toLibID" }[type] as + | "fromLibID" + | "toLibID" + ], + linkData[ + { inbound: "fromKey", outbound: "toKey" }[type] as "fromKey" | "toKey" + ], )) as Zotero.Item; const row = doc.createElement("div"); diff --git a/src/modules/workspace/outLink.ts b/src/modules/workspace/outLink.ts deleted file mode 100644 index 69a9f73..0000000 --- a/src/modules/workspace/outLink.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { config } from "../../../package.json"; - -export function registerNoteOutboundLink() { - const key = Zotero.ItemPaneManager.registerSection({ - paneID: `bn-note-outbound-link`, - pluginID: config.addonID, - header: { - icon: `chrome://${config.addonRef}/content/icons/out-link-16.svg`, - l10nID: `${config.addonRef}-note-outlink-header`, - }, - sidenav: { - icon: `chrome://${config.addonRef}/content/icons/out-link-20.svg`, - l10nID: `${config.addonRef}-note-outlink-sidenav`, - }, - sectionButtons: [ - { - type: "refreshGraph", - icon: "chrome://zotero/skin/16/universal/sync.svg", - l10nID: `${config.addonRef}-note-outlink-refresh`, - onClick: ({ body, item, setL10nArgs }) => { - renderSection(body, item, makeSetCount(setL10nArgs)); - }, - }, - ], - onInit({ body, refresh, getData }) { - const notifierKey = Zotero.Notifier.registerObserver( - { - notify: (event, type, ids, extraData) => { - const item = Zotero.Items.get(body.dataset.itemID || ""); - if ( - item && - // @ts-ignore - event === "updateBNRelation" && - type === "item" && - (ids as number[]).includes(item.id) - ) { - ztoolkit.log("relation notify refresh", item.id); - refresh(); - } - }, - }, - ["item"], - ); - body.classList.add("bn-link-body"); - body.dataset.notifierKey = notifierKey; - }, - onDestroy({ body }) { - const notifierKey = body.dataset.notifierKey; - if (notifierKey) { - Zotero.Notifier.unregisterObserver(notifierKey); - } - }, - onItemChange: ({ body, item, setEnabled }) => { - if (body.closest("bn-workspace") as HTMLElement | undefined) { - setEnabled(true); - body.dataset.itemID = String(item.id); - return; - } - setEnabled(false); - }, - onRender: () => {}, - onAsyncRender: async ({ body, item, setL10nArgs }) => { - await renderSection(body, item, makeSetCount(setL10nArgs)); - }, - }); -} - -async function renderSection( - body: HTMLElement, - item: Zotero.Item, - setCount: (count: number) => void, -) { - body.replaceChildren(); - const doc = body.ownerDocument; - const inLinks = await addon.api.relation.getNoteLinkOutboundRelation(item.id); - for (const linkData of inLinks) { - const toItem = (await Zotero.Items.getByLibraryAndKeyAsync( - linkData.toLibID, - linkData.toKey, - )) as Zotero.Item; - - const row = doc.createElement("div"); - row.className = "row"; - - const icon = ztoolkit - .getGlobal("require")("components/icons") - .getCSSItemTypeIcon("note"); - - const label = doc.createElement("span"); - label.className = "label"; - label.append(toItem.getNoteTitle()); - - const box = doc.createElement("div"); - box.addEventListener("click", () => handleShowItem(toItem.id)); - box.className = "box keyboard-clickable"; - box.setAttribute("tabindex", "0"); - box.append(icon, label); - - row.append(box); - - const note = (doc as any).createXULElement("toolbarbutton"); - note.addEventListener("command", (event: MouseEvent) => { - const position = event.shiftKey ? "window" : "tab"; - addon.hooks.onOpenNote(toItem.id, position); - }); - note.className = "zotero-clicky zotero-clicky-open-link"; - note.setAttribute("tabindex", "0"); - row.append(note); - - body.append(row); - } - - const count = inLinks.length; - setCount(count); -} - -function handleShowItem(id: number) { - ZoteroPane.selectItem(id); -} - -function makeSetCount(setL10nArgs: (str: string) => void) { - return (count: number) => { - setL10nArgs(`{"count": "${count}"}`); - }; -}