120 lines
3.8 KiB
TypeScript
120 lines
3.8 KiB
TypeScript
/* eslint-disable */
|
|
import { BrowserWindow, app, type BrowserWindowConstructorOptions } from 'electron'
|
|
import { EventEmitter } from 'events'
|
|
const DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL
|
|
const isProduction = process.env.NODE_ENV === 'production'
|
|
const isDev = process.env.NODE_ENV === 'development'
|
|
|
|
const fs = import("node:fs");
|
|
|
|
export default class BrowserWinHandler {
|
|
|
|
private _eventEmitter: EventEmitter;
|
|
private allowRecreate: boolean;
|
|
private options: Electron.BrowserWindowConstructorOptions;
|
|
private browserWindow: BrowserWindow|null;
|
|
|
|
/**
|
|
*
|
|
* @param options browser window options
|
|
* @param allowRecreate
|
|
*/
|
|
constructor (options: BrowserWindowConstructorOptions, allowRecreate: boolean = true) {
|
|
this._eventEmitter = new EventEmitter()
|
|
this.allowRecreate = allowRecreate
|
|
this.options = options
|
|
this.browserWindow = null
|
|
this._createInstance()
|
|
}
|
|
|
|
_createInstance () {
|
|
// This method will be called when Electron has finished
|
|
// initialization and is ready to create browser windows.
|
|
// Some APIs can only be used after this event occurs.
|
|
if (app.isReady()) this._create()
|
|
else {
|
|
app.once('ready', () => {
|
|
this._create()
|
|
})
|
|
}
|
|
|
|
// On macOS it's common to re-create a window in the app when the
|
|
// dock icon is clicked and there are no other windows open.
|
|
if (!this.allowRecreate) return
|
|
app.on('activate', () => this._recreate())
|
|
}
|
|
|
|
_create () {
|
|
this.browserWindow = new BrowserWindow({
|
|
...this.options,
|
|
webPreferences: {
|
|
...this.options.webPreferences,
|
|
webSecurity: isProduction, // disable on dev to allow loading local resources
|
|
nodeIntegration: false,
|
|
contextIsolation: true
|
|
}
|
|
})
|
|
this.browserWindow.on('closed', () => {
|
|
// Dereference the window object
|
|
this.browserWindow = null
|
|
})
|
|
this._eventEmitter.emit('created');
|
|
this.browserWindow.webContents.on('before-input-event', (_, input) => {
|
|
if (input.type === 'keyDown' && input.key === 'F12' && this.browserWindow) {
|
|
this.browserWindow.webContents.openDevTools({ mode: 'detach' });
|
|
}
|
|
});
|
|
this.browserWindow.removeMenu();
|
|
this.browserWindow.setMenu(null);
|
|
}
|
|
|
|
_recreate () {
|
|
if (this.browserWindow === null) this._create()
|
|
}
|
|
|
|
onCreated (callback: (browserWindow: BrowserWindow|null) => void) {
|
|
if (this.browserWindow !== null) return callback(this.browserWindow);
|
|
this._eventEmitter.once('created', () => {
|
|
callback(this.browserWindow)
|
|
})
|
|
}
|
|
|
|
async loadPage(pagePath: string) {
|
|
if (!this.browserWindow) return Promise.reject(new Error('The page could not be loaded before win \'created\' event'))
|
|
const serverUrl = isDev ? DEV_SERVER_URL : 'app://./index.html'
|
|
const fullPath = serverUrl + '/' + pagePath;
|
|
await this.browserWindow.loadURL(fullPath)
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @returns {Promise<BrowserWindow>}
|
|
*/
|
|
created () {
|
|
return new Promise(resolve => {
|
|
this.onCreated(() => resolve(this.browserWindow))
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Open dev tools if ti can be
|
|
*/
|
|
openDevTool() {
|
|
const browserWindow = this.browserWindow;
|
|
if (!browserWindow) {
|
|
throw new Error("No window is loaded");
|
|
}
|
|
browserWindow.webContents.openDevTools();
|
|
}
|
|
|
|
quit() {
|
|
const browserWindow = this.browserWindow;
|
|
if (!browserWindow) {
|
|
throw new Error("No window is loaded");
|
|
}
|
|
browserWindow.on('closed', () => {
|
|
this.browserWindow = null
|
|
});
|
|
browserWindow.close();
|
|
}
|
|
}
|