refactor: popup window

This commit is contained in:
xiangyu 2023-01-06 12:13:42 +08:00
parent 25befec9c6
commit 398bf89a23
4 changed files with 123 additions and 108 deletions

View File

@ -1,34 +1,36 @@
import { BasicExampleFactory, UIExampleFactory } from "./modules/examples";
import {
changeProgressWindowLine,
isProgressWindow,
showProgressWindow,
} from "./modules/progressWindow";
import { PopupWindow } from "./modules/popup";
import { config } from "../package.json";
import { getString, initLocale } from "./modules/locale";
import { registerPrefsScripts } from "./modules/preferenceScript";
async function onStartup() {
await Promise.all([
Zotero.initializationPromise,
Zotero.unlockPromise,
Zotero.uiReadyPromise,
]);
initLocale();
const progWin = showProgressWindow(
config.addonName,
getString("startup.begin"),
"default",
{
closeTime: -1,
}
);
changeProgressWindowLine(progWin, { newProgress: 0 });
const popupWin = new PopupWindow(config.addonName, {
closeOnClick: true,
closeTime: -1,
})
.createLine({
text: getString("startup.begin"),
type: "default",
progress: 0,
})
.show();
BasicExampleFactory.registerPrefs();
BasicExampleFactory.registerNotifier();
await Zotero.Promise.delay(1000);
changeProgressWindowLine(progWin, {
newProgress: 30,
newText: `[30%] ${getString("startup.begin")}`,
popupWin.changeLine({
progress: 30,
text: `[30%] ${getString("startup.begin")}`,
});
UIExampleFactory.registerStyleSheet();
@ -50,13 +52,12 @@ async function onStartup() {
await UIExampleFactory.registerReaderTabPanel();
await Zotero.Promise.delay(1000);
changeProgressWindowLine(progWin, {
newProgress: 100,
newText: `[100%] ${getString("startup.finish")}`,
popupWin.changeLine({
progress: 100,
text: `[100%] ${getString("startup.finish")}`,
});
if (isProgressWindow(progWin)) {
(progWin as _ZoteroProgressWindow).startCloseTimer(5000);
}
popupWin.startCloseTimer(5000);
}
function onShutdown(): void {

View File

@ -1,6 +1,6 @@
import { config } from "../../package.json";
import { getString } from "./locale";
import { showProgressWindow } from "./progressWindow";
import { PopupWindow } from "./popup";
function example(
target: any,
@ -35,7 +35,7 @@ export class BasicExampleFactory {
ids: Array<string>,
extraData: { [key: string]: any }
) => {
if (!addon.data.alive) {
if (!addon?.data.alive) {
this.unregisterNotifier(notifierID);
return;
}
@ -62,7 +62,13 @@ export class BasicExampleFactory {
@example
static exampleNotifierCallback() {
showProgressWindow(config.addonName, "Open Tab Detected!", "success");
new PopupWindow(config.addonName)
.createLine({
text: "Open Tab Detected!",
type: "success",
progress: 100,
})
.show();
}
@example

90
src/modules/popup.ts Normal file
View File

@ -0,0 +1,90 @@
import { config } from "../../package.json";
const progressWindowIcon = {
success: "chrome://zotero/skin/tick.png",
fail: "chrome://zotero/skin/cross.png",
default: `chrome://${config.addonRef}/content/icons/favicon.png`,
};
interface LineOptions {
type?: keyof typeof progressWindowIcon;
icon?: string;
text?: string;
progress?: number;
idx?: number;
}
// @ts-ignore
export class PopupWindow extends Zotero.ProgressWindow {
private lines: _ZoteroItemProgress[];
private closeTime: number | undefined;
private originalShow: Function;
public show: typeof this.showWithTimer;
constructor(
header: string,
options: {
window?: Window;
closeOnClick?: boolean;
closeTime?: number;
} = {
closeOnClick: true,
closeTime: 5000,
}
) {
super(options);
this.lines = [];
this.closeTime = options.closeTime || 5000;
this.changeHeadline(header);
// @ts-ignore
this.originalShow = this.show;
this.show = this.showWithTimer;
}
createLine(options: LineOptions) {
const icon = this.getIcon(options.type, options.icon);
const line = new this.ItemProgress(
icon || "",
options.text || ""
) as _ZoteroItemProgress;
if (typeof options.progress === "number") {
line.setProgress(options.progress);
}
this.lines.push(line);
return this;
}
changeLine(options: LineOptions) {
if (this.lines?.length === 0) {
return this;
}
const idx =
typeof options.idx !== "undefined" &&
options.idx >= 0 &&
options.idx < this.lines.length
? options.idx
: 0;
const icon = this.getIcon(options.type, options.icon);
options.text && this.lines[idx].setText(options.text);
icon && this.lines[idx].setIcon(icon);
typeof options.progress === "number" &&
this.lines[idx].setProgress(options.progress);
return this;
}
protected showWithTimer(closeTime: number | undefined = undefined) {
this.originalShow();
typeof closeTime !== "undefined" && (this.closeTime = closeTime);
if (this.closeTime && this.closeTime > 0) {
this.startCloseTimer(this.closeTime);
}
return this;
}
protected getIcon(
type: keyof typeof progressWindowIcon | undefined,
defaulIcon?: string | undefined
) {
return type ? progressWindowIcon[type] : defaulIcon;
}
}

View File

@ -1,82 +0,0 @@
import { config } from "../../package.json";
const progressWindowIcon = {
success: "chrome://zotero/skin/tick.png",
fail: "chrome://zotero/skin/cross.png",
default: `chrome://${config.addonRef}/content/icons/favicon.png`,
};
export function showProgressWindow(
header: string,
context: string,
type: "success" | "fail" | "default" = "default",
options: {
closeTime?: number;
backend?: "Zotero" | "system";
} = {
closeTime: 5000,
backend: "Zotero",
}
): _ZoteroProgressWindow | Notification {
// Currently Zotero 7 doesn't support progress window.
// Use system backend on Zotero 7.
if (options.backend === "system" || ztoolkit.Compat.isZotero7()) {
Zotero.Prefs.set("alerts.useSystemBackend", true, true);
const notification = new (ztoolkit.Compat.getGlobal(
"Notification"
) as typeof Notification)(header, {
body: context,
icon: progressWindowIcon[type],
tag: config.addonName,
});
if (options.closeTime) {
(ztoolkit.Compat.getGlobal("setTimeout") as typeof setTimeout)(() => {
notification.close();
}, options.closeTime);
}
return notification;
} else {
// A simple wrapper of the Zotero ProgressWindow
const progressWindow = new Zotero.ProgressWindow({
closeOnClick: true,
}) as _ZoteroProgressWindow;
progressWindow.changeHeadline(header);
// @ts-ignore
progressWindow.progress = new progressWindow.ItemProgress(
progressWindowIcon[type],
context
);
progressWindow.show();
if (options.closeTime) {
progressWindow.startCloseTimer(options.closeTime);
}
return progressWindow;
}
}
export function changeProgressWindowLine(
progressWindow: _ZoteroProgressWindow | Notification,
options: {
newText?: string;
newIcon?: string;
newProgress?: number;
}
) {
if (!isProgressWindow(progressWindow)) {
return;
}
// @ts-ignore
const progress = progressWindow.progress as _ZoteroItemProgress;
if (!progress) {
return;
}
options.newText && progress.setText(options.newText);
options.newIcon && progress.setIcon(options.newIcon);
options.newProgress && progress.setProgress(options.newProgress);
}
export function isProgressWindow(
progressWindow: _ZoteroProgressWindow | Notification
) {
return !(progressWindow as Notification).title;
}