You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.0 KiB
112 lines
3.0 KiB
'use strict' |
|
|
|
const { app, BrowserWindow, ipcMain, shell, Menu } = require('electron') |
|
const fs = require('fs') |
|
const path = require('path') |
|
|
|
/** True when running from source (`electron .`); false when packaged. */ |
|
const isDev = !app.isPackaged |
|
|
|
function resolveWindowIcon() { |
|
const candidates = isDev |
|
? [path.join(__dirname, '..', 'public', 'favicon.png')] |
|
: [path.join(__dirname, '..', 'dist', 'favicon.png')] |
|
for (const p of candidates) { |
|
try { |
|
if (fs.existsSync(p)) return p |
|
} catch { |
|
// ignore |
|
} |
|
} |
|
return undefined |
|
} |
|
|
|
function loadRenderer(win) { |
|
if (isDev) { |
|
const devUrl = process.env.VITE_DEV_SERVER_URL || 'http://127.0.0.1:5173' |
|
void win.loadURL(devUrl) |
|
if (!win.webContents.isDevToolsOpened()) { |
|
win.webContents.openDevTools({ mode: 'detach' }) |
|
} |
|
return |
|
} |
|
void win.loadFile(path.join(__dirname, '..', 'dist', 'index.html')) |
|
} |
|
|
|
function createWindow() { |
|
const win = new BrowserWindow({ |
|
width: 1280, |
|
height: 840, |
|
minWidth: 400, |
|
minHeight: 500, |
|
show: false, |
|
icon: resolveWindowIcon(), |
|
webPreferences: { |
|
preload: path.join(__dirname, 'preload.cjs'), |
|
contextIsolation: true, |
|
nodeIntegration: false, |
|
sandbox: true |
|
} |
|
}) |
|
|
|
win.once('ready-to-show', () => win.show()) |
|
|
|
loadRenderer(win) |
|
|
|
win.webContents.setWindowOpenHandler(({ url }) => { |
|
if (url.startsWith('http:') || url.startsWith('https:')) { |
|
void shell.openExternal(url) |
|
} |
|
return { action: 'deny' } |
|
}) |
|
|
|
// Electron does not show Chromium’s full-page context menu; without this, users only get in-app UI |
|
// (e.g. selection highlight) and no Copy / Paste / Select all for text fields and content. |
|
win.webContents.on('context-menu', (_event, params) => { |
|
const template = [] |
|
|
|
if (params.linkURL && /^https?:\/\//i.test(params.linkURL)) { |
|
template.push({ |
|
label: 'Open link in browser', |
|
click: () => void shell.openExternal(params.linkURL) |
|
}) |
|
template.push({ type: 'separator' }) |
|
} |
|
|
|
template.push( |
|
{ role: 'cut', enabled: params.editFlags.canCut }, |
|
{ role: 'copy', enabled: params.editFlags.canCopy }, |
|
{ role: 'paste', enabled: params.editFlags.canPaste }, |
|
{ type: 'separator' }, |
|
{ role: 'selectAll', enabled: params.editFlags.canSelectAll } |
|
) |
|
|
|
if (isDev) { |
|
template.push({ type: 'separator' }) |
|
template.push({ |
|
label: 'Inspect element', |
|
click: () => win.webContents.inspectElement(params.x, params.y) |
|
}) |
|
} |
|
|
|
Menu.buildFromTemplate(template).popup({ window: win }) |
|
}) |
|
} |
|
|
|
app.whenReady().then(() => { |
|
ipcMain.handle('imwald:reload-app', async (event) => { |
|
const win = BrowserWindow.fromWebContents(event.sender) |
|
if (!win || win.isDestroyed()) return false |
|
loadRenderer(win) |
|
return true |
|
}) |
|
|
|
createWindow() |
|
app.on('activate', () => { |
|
if (BrowserWindow.getAllWindows().length === 0) createWindow() |
|
}) |
|
}) |
|
|
|
app.on('window-all-closed', () => { |
|
if (process.platform !== 'darwin') app.quit() |
|
})
|
|
|