refactor: unify in/outbound link section
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = 刷新
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
@ -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}"}`);
|
||||
};
|
||||
}
|
||||