ldc-showroom/electron/browserWinHandler.ts

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();
}
}