import { config } from "../../../package.json"; import { getLocaleID, getString } from "../../utils/locale"; import { ChatView } from "./chatView"; import { applyAdaptiveHeight, applyItemPaneSectionButtonIcons, applyItemPaneSectionHeadLabel, buildItemPaneSectionButtons, clearSectionSummary, onItemPaneSectionToggle, prepareItemPaneBody, refreshSectionOpenHeight, } from "./itemPaneSection"; const views = new WeakMap(); function iconURL(file: string) { return `chrome://${config.addonRef}/content/icons/${file}`; } export function registerChatPane() { Zotero.ItemPaneManager.registerSection({ paneID: "chatpapers-chat", pluginID: config.addonID, header: { l10nID: getLocaleID("item-section-chat-head"), icon: iconURL("chat.svg"), }, sidenav: { l10nID: getLocaleID("item-section-chat-sidenav"), icon: iconURL("chat.svg"), }, sectionButtons: buildItemPaneSectionButtons("chat"), onInit: ({ body }) => { const doc = body.ownerDocument; if (doc) ensureStyles(doc); prepareItemPaneBody(body); applyAdaptiveHeight(body, "chat"); applyItemPaneSectionHeadLabel(body, "chat"); }, onDestroy: ({ body }) => { views.get(body)?.destroy(); views.delete(body); }, onItemChange: ({ item, setEnabled, tabType }) => { // Enable in reader and library item pane when there is an item setEnabled(Boolean(item)); void tabType; return true; }, onRender: ({ body, setSectionSummary }) => { body.replaceChildren(); const doc = body.ownerDocument; if (!doc) return; applyItemPaneSectionHeadLabel(body, "chat"); clearSectionSummary(body, setSectionSummary); applyItemPaneSectionButtonIcons(body); const loading = doc.createElement("div"); loading.className = "chatpapers-loading"; loading.textContent = getString("chat-loading"); body.append(loading); }, onAsyncRender: async ({ body, item, setSectionSummary }) => { if (!item) return; const doc = body.ownerDocument; if (!doc) return; views.get(body)?.destroy(); const view = new ChatView(doc, body, item); views.set(body, view); await view.mount(); applyItemPaneSectionHeadLabel(body, "chat"); clearSectionSummary(body, setSectionSummary); applyAdaptiveHeight(body, "chat"); applyItemPaneSectionButtonIcons(body); const section = body.closest("collapsible-section"); if (section?.hasAttribute("open")) { refreshSectionOpenHeight(body); } else if (section) { onItemPaneSectionToggle({ body }); } }, onToggle: ({ body, event }) => { applyItemPaneSectionButtonIcons(body); onItemPaneSectionToggle({ body, event }); }, }); } export function registerPrefs() { Zotero.PreferencePanes.register({ pluginID: config.addonID, src: rootURI + "content/preferences.xhtml", label: getString("prefs-title"), image: `chrome://${config.addonRef}/content/icons/favicon.png`, }); } export function ensureChatPapersStyles(doc: Document): void { const id = "chatpapers-styles"; const base = `chrome://${config.addonRef}/content/chatpapers.css`; const href = typeof __env__ !== "undefined" && __env__ === "development" ? `${base}?v=${Date.now()}` : base; const existing = doc.getElementById(id) as HTMLLinkElement | null; if (existing) { if (typeof __env__ !== "undefined" && __env__ === "development") { existing.href = href; } return; } const link = doc.createElement("link"); link.id = id; link.rel = "stylesheet"; link.type = "text/css"; link.href = href; doc.documentElement?.appendChild(link); } function ensureStyles(doc: Document) { ensureChatPapersStyles(doc); }