tabs/src/Window.ts

100 lines
3.1 KiB
TypeScript
Raw Normal View History

2020-05-22 10:25:19 +02:00
import {BrowserWindow, BrowserWindowConstructorOptions, ipcMain, IpcMainEvent} from "electron";
import Application from "./Application";
import Config from "./Config";
export default abstract class Window {
2020-09-29 20:43:41 +02:00
private readonly listeners: {
[channel: string]: ((event: IpcMainEvent, ...args: unknown[]) => void)[] | undefined
} = {};
2020-05-22 10:25:19 +02:00
private readonly onCloseListeners: (() => void)[] = [];
protected readonly application: Application;
protected readonly config: Config;
protected readonly parent?: Window;
protected window?: BrowserWindow;
protected constructor(application: Application, parent?: Window) {
this.application = application;
this.parent = parent;
this.config = this.application.getConfig();
}
2020-09-29 20:43:41 +02:00
public setup(options: BrowserWindowConstructorOptions): void {
2020-05-22 10:25:19 +02:00
console.log('Creating window', this.constructor.name);
if (this.parent) {
options.parent = this.parent.getWindow();
}
this.window = new BrowserWindow(options);
this.window.on('close', () => {
this.teardown();
this.window = undefined;
});
this.onIpc('close-window', (
event,
constructorName: string,
) => {
if (constructorName === this.constructor.name) {
console.log('Closing', this.constructor.name);
const window = this.getWindow();
if (window.closable) {
window.close();
}
}
});
2020-05-22 10:25:19 +02:00
}
2020-09-29 20:43:41 +02:00
public teardown(): void {
2020-05-22 10:25:19 +02:00
console.log('Tearing down window', this.constructor.name);
for (const listener of this.onCloseListeners) {
listener();
}
for (const channel in this.listeners) {
2020-09-29 20:43:41 +02:00
const listeners = this.listeners[channel];
if (!listeners) continue;
for (const listener of listeners) {
2020-05-22 10:25:19 +02:00
ipcMain.removeListener(channel, listener);
}
}
this.window = undefined;
}
2020-09-29 20:43:41 +02:00
// This is the spec of ipcMain.on()
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2020-05-22 10:25:19 +02:00
protected onIpc(channel: string, listener: (event: IpcMainEvent, ...args: any[]) => void): this {
ipcMain.on(channel, listener);
if (!this.listeners[channel]) this.listeners[channel] = [];
2020-09-29 20:43:41 +02:00
this.listeners[channel]?.push(listener);
2020-05-22 10:25:19 +02:00
return this;
}
2020-09-29 20:43:41 +02:00
public onClose(listener: () => void): void {
2020-05-22 10:25:19 +02:00
this.onCloseListeners.push(listener);
}
2020-09-29 20:43:41 +02:00
public toggle(): void {
2020-05-22 10:25:19 +02:00
if (this.window) {
if (!this.window.isFocused()) {
console.log('Showing window', this.constructor.name);
this.window.show();
} else {
console.log('Hiding window', this.constructor.name);
this.window.hide();
}
}
}
public getWindow(): BrowserWindow {
if (!this.window) throw Error('Window not initialized.');
else if (this.window.isDestroyed()) throw Error('Window destroyed.');
2020-05-22 10:25:19 +02:00
return this.window;
}
2020-09-29 20:43:41 +02:00
}