downthemall/lib/single.ts

78 lines
1.8 KiB
TypeScript

"use strict";
// License: MIT
// eslint-disable-next-line no-unused-vars
import { Bus, Port } from "./bus";
import { WindowStateTracker } from "./windowstatetracker";
import { Promised, timeout } from "./util";
import { donate } from "./windowutils";
import { windows, CHROME } from "./browser";
// eslint-disable-next-line no-unused-vars
import { BaseItem } from "./item";
export async function single(item: BaseItem | null) {
const tracker = new WindowStateTracker("single", {
minWidth: 700,
minHeight: 460
});
await tracker.init();
const windowOptions = tracker.getOptions({
url: "/windows/single.html",
type: "popup",
});
const window = await windows.create(windowOptions);
tracker.track(window.id);
try {
if (!CHROME) {
windows.update(window.id, tracker.getOptions({}));
}
const port: Port = await Promise.race<Port>([
new Promise<Port>(resolve => Bus.oncePort("single", port => {
resolve(port);
return true;
})),
timeout<Port>(5 * 1000)]);
if (!port.isSelf) {
throw Error("Invalid sender connected");
}
tracker.track(window.id, port);
const done = new Promised();
port.on("disconnect", () => {
done.reject(new Error("Prematurely disconnected"));
});
port.on("queue", msg => {
done.resolve(msg);
});
port.on("cancel", () => {
done.reject(new Error("User canceled"));
});
port.on("donate", () => {
donate();
});
if (item) {
port.post("item", {item});
}
return await done;
}
finally {
try {
await tracker.finalize();
}
catch (ex) {
// window might be gone; ignored
}
try {
await windows.remove(window.id);
}
catch (ex) {
// window might be gone; ignored
}
}
}