实现单篇和多篇论文的对比总结
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
import { config } from "../../../package.json";
|
||||
import { getString } from "../../utils/locale";
|
||||
import { normalizeLibraryItems } from "../pdf/multiContext";
|
||||
import { MultiChatView } from "./multiChatView";
|
||||
|
||||
let activeDialog: any = null;
|
||||
let activeView: MultiChatView | null = null;
|
||||
let onDialogResize: (() => void) | null = null;
|
||||
|
||||
function ensureDialogStyles(doc: Document) {
|
||||
const id = "chatpapers-styles";
|
||||
if (doc.getElementById(id)) return;
|
||||
const link = doc.createElement("link");
|
||||
link.id = id;
|
||||
link.rel = "stylesheet";
|
||||
link.type = "text/css";
|
||||
link.href = `chrome://${config.addonRef}/content/chatpapers.css`;
|
||||
doc.documentElement?.appendChild(link);
|
||||
}
|
||||
|
||||
/** Prefer a large window that still fits the current screen. */
|
||||
function getPreferredDialogSize(): { width: number; height: number } {
|
||||
try {
|
||||
const win = Zotero.getMainWindow?.() as Window | undefined;
|
||||
const screen = win?.screen;
|
||||
const aw = screen?.availWidth || win?.outerWidth || 1280;
|
||||
const ah = screen?.availHeight || win?.outerHeight || 800;
|
||||
return {
|
||||
width: Math.max(880, Math.min(Math.round(aw * 0.9), aw - 48)),
|
||||
height: Math.max(640, Math.min(Math.round(ah * 0.88), ah - 48)),
|
||||
};
|
||||
} catch {
|
||||
return { width: 1100, height: 780 };
|
||||
}
|
||||
}
|
||||
|
||||
function hideDialogButtonBox(doc: Document) {
|
||||
const selectors = [
|
||||
"#dialog-button-box",
|
||||
".dialog-button-box",
|
||||
"dialog > vbox.dialog-button-box",
|
||||
"[anonid='buttons']",
|
||||
];
|
||||
for (const sel of selectors) {
|
||||
const nodes = Array.from(doc.querySelectorAll(sel));
|
||||
for (const node of nodes) {
|
||||
(node as HTMLElement).style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Keep chat root filling the window so composer stays pinned to the bottom. */
|
||||
function fitMultiChatRoot(win: Window) {
|
||||
const doc = win.document;
|
||||
hideDialogButtonBox(doc);
|
||||
|
||||
const root = doc.getElementById(
|
||||
"chatpapers-multi-root",
|
||||
) as HTMLElement | null;
|
||||
if (!root) return;
|
||||
|
||||
const html = doc.documentElement as HTMLElement | null;
|
||||
const body = doc.body as HTMLElement | null;
|
||||
if (html) {
|
||||
html.style.height = "100%";
|
||||
html.style.margin = "0";
|
||||
html.style.padding = "0";
|
||||
html.style.overflow = "hidden";
|
||||
html.style.setProperty("scrollbar-width", "thin");
|
||||
}
|
||||
if (body) {
|
||||
body.style.height = "100%";
|
||||
body.style.margin = "0";
|
||||
body.style.padding = "0";
|
||||
body.style.overflow = "hidden";
|
||||
body.style.display = "flex";
|
||||
body.style.flexDirection = "column";
|
||||
body.style.setProperty("scrollbar-width", "thin");
|
||||
}
|
||||
|
||||
// Shrink leftover dialog grid padding around our cell
|
||||
for (const node of Array.from(doc.querySelectorAll("hbox, vbox, dialog"))) {
|
||||
const el = node as HTMLElement;
|
||||
if (
|
||||
el.id === "dialog-button-box" ||
|
||||
el.classList?.contains("dialog-button-box")
|
||||
) {
|
||||
el.style.display = "none";
|
||||
continue;
|
||||
}
|
||||
if (el.tagName?.toLowerCase() === "dialog") {
|
||||
el.style.padding = "0";
|
||||
el.style.margin = "0";
|
||||
el.style.height = "100%";
|
||||
el.style.setProperty("scrollbar-width", "thin");
|
||||
}
|
||||
}
|
||||
|
||||
const pad = 4;
|
||||
const h = Math.max(360, (win.innerHeight || 600) - pad);
|
||||
root.style.width = "100%";
|
||||
root.style.height = `${h}px`;
|
||||
root.style.maxHeight = `${h}px`;
|
||||
root.style.minHeight = "0";
|
||||
root.style.flex = "1 1 auto";
|
||||
root.style.overflow = "hidden";
|
||||
}
|
||||
|
||||
export function openMultiChatDialog(items: Zotero.Item[]) {
|
||||
const selected = normalizeLibraryItems(items);
|
||||
if (!selected.length) {
|
||||
new ztoolkit.ProgressWindow("ChatPapers")
|
||||
.createLine({
|
||||
text: getString("multi-no-items"),
|
||||
type: "fail",
|
||||
})
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected.length > 8) {
|
||||
new ztoolkit.ProgressWindow("ChatPapers")
|
||||
.createLine({
|
||||
text: getString("multi-too-many", {
|
||||
args: { count: selected.length },
|
||||
}),
|
||||
type: "default",
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
// Close previous dialog if any
|
||||
try {
|
||||
if (activeDialog?.window && onDialogResize) {
|
||||
activeDialog.window.removeEventListener("resize", onDialogResize);
|
||||
}
|
||||
activeView?.destroy();
|
||||
activeDialog?.window?.close?.();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
activeView = null;
|
||||
activeDialog = null;
|
||||
onDialogResize = null;
|
||||
|
||||
const size = getPreferredDialogSize();
|
||||
|
||||
const dialogHelper = new ztoolkit.Dialog(1, 1)
|
||||
.addCell(0, 0, {
|
||||
tag: "div",
|
||||
namespace: "html",
|
||||
id: "chatpapers-multi-root",
|
||||
styles: {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
minWidth: "640px",
|
||||
minHeight: "0",
|
||||
overflow: "hidden",
|
||||
boxSizing: "border-box",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
},
|
||||
})
|
||||
.setDialogData({
|
||||
loadCallback: () => {
|
||||
try {
|
||||
const win = dialogHelper.window;
|
||||
const doc = win.document;
|
||||
ensureDialogStyles(doc);
|
||||
hideDialogButtonBox(doc);
|
||||
fitMultiChatRoot(win);
|
||||
onDialogResize = () => fitMultiChatRoot(win);
|
||||
win.addEventListener("resize", onDialogResize);
|
||||
|
||||
const root = doc.getElementById(
|
||||
"chatpapers-multi-root",
|
||||
) as HTMLElement | null;
|
||||
if (!root) return;
|
||||
activeView = new MultiChatView(doc, root, selected.slice(0, 8));
|
||||
void activeView.mount().then(() => fitMultiChatRoot(win));
|
||||
} catch (e) {
|
||||
ztoolkit.log("openMultiChatDialog load failed", e);
|
||||
}
|
||||
},
|
||||
unloadCallback: () => {
|
||||
try {
|
||||
if (activeDialog?.window && onDialogResize) {
|
||||
activeDialog.window.removeEventListener("resize", onDialogResize);
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
onDialogResize = null;
|
||||
activeView?.destroy();
|
||||
activeView = null;
|
||||
activeDialog = null;
|
||||
},
|
||||
});
|
||||
|
||||
activeDialog = dialogHelper;
|
||||
dialogHelper.open(
|
||||
`ChatPapers · ${Math.min(selected.length, 8)} papers`,
|
||||
{
|
||||
centerscreen: true,
|
||||
resizable: true,
|
||||
noDialogMode: true,
|
||||
fitContent: false,
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user