219 lines
5.5 KiB
TypeScript
219 lines
5.5 KiB
TypeScript
import { app, BrowserWindow, ipcMain, shell, Menu, Tray, nativeImage } from 'electron';
|
|
import * as path from 'path';
|
|
import * as url from 'url';
|
|
|
|
const isDev = process.env.NODE_ENV === 'development' || !app.isPackaged;
|
|
|
|
let mainWindow: BrowserWindow | null = null;
|
|
let tray: Tray | null = null;
|
|
|
|
function createWindow() {
|
|
mainWindow = new BrowserWindow({
|
|
width: 1400,
|
|
height: 900,
|
|
minWidth: 800,
|
|
minHeight: 600,
|
|
backgroundColor: '#141414',
|
|
titleBarStyle: 'hiddenInset',
|
|
frame: process.platform === 'darwin' ? true : false,
|
|
webPreferences: {
|
|
nodeIntegration: true,
|
|
contextIsolation: false,
|
|
webSecurity: !isDev,
|
|
},
|
|
icon: path.join(__dirname, '../public/icon.png'),
|
|
});
|
|
|
|
// Load the app
|
|
if (isDev) {
|
|
mainWindow.loadURL('http://localhost:5173');
|
|
mainWindow.webContents.openDevTools();
|
|
} else {
|
|
mainWindow.loadURL(
|
|
url.format({
|
|
pathname: path.join(__dirname, '../dist/index.html'),
|
|
protocol: 'file:',
|
|
slashes: true,
|
|
})
|
|
);
|
|
}
|
|
|
|
// Handle external links
|
|
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
|
shell.openExternal(url);
|
|
return { action: 'deny' };
|
|
});
|
|
|
|
mainWindow.on('closed', () => {
|
|
mainWindow = null;
|
|
});
|
|
|
|
// Create application menu
|
|
createMenu();
|
|
}
|
|
|
|
function createMenu() {
|
|
const template: Electron.MenuItemConstructorOptions[] = [
|
|
{
|
|
label: 'beStream',
|
|
submenu: [
|
|
{ label: 'About beStream', role: 'about' },
|
|
{ type: 'separator' },
|
|
{ label: 'Preferences', accelerator: 'CmdOrCtrl+,', click: () => {
|
|
mainWindow?.webContents.send('navigate', '/settings');
|
|
}},
|
|
{ type: 'separator' },
|
|
{ label: 'Hide beStream', role: 'hide' },
|
|
{ role: 'hideOthers' },
|
|
{ role: 'unhide' },
|
|
{ type: 'separator' },
|
|
{ label: 'Quit beStream', role: 'quit' },
|
|
],
|
|
},
|
|
{
|
|
label: 'File',
|
|
submenu: [
|
|
{ label: 'New Window', accelerator: 'CmdOrCtrl+N', click: createWindow },
|
|
{ type: 'separator' },
|
|
{ label: 'Close Window', role: 'close' },
|
|
],
|
|
},
|
|
{
|
|
label: 'Edit',
|
|
submenu: [
|
|
{ role: 'undo' },
|
|
{ role: 'redo' },
|
|
{ type: 'separator' },
|
|
{ role: 'cut' },
|
|
{ role: 'copy' },
|
|
{ role: 'paste' },
|
|
{ role: 'selectAll' },
|
|
],
|
|
},
|
|
{
|
|
label: 'View',
|
|
submenu: [
|
|
{ role: 'reload' },
|
|
{ role: 'forceReload' },
|
|
{ role: 'toggleDevTools' },
|
|
{ type: 'separator' },
|
|
{ role: 'resetZoom' },
|
|
{ role: 'zoomIn' },
|
|
{ role: 'zoomOut' },
|
|
{ type: 'separator' },
|
|
{ role: 'togglefullscreen' },
|
|
],
|
|
},
|
|
{
|
|
label: 'Navigate',
|
|
submenu: [
|
|
{ label: 'Home', accelerator: 'CmdOrCtrl+H', click: () => {
|
|
mainWindow?.webContents.send('navigate', '/');
|
|
}},
|
|
{ label: 'Browse', accelerator: 'CmdOrCtrl+B', click: () => {
|
|
mainWindow?.webContents.send('navigate', '/browse');
|
|
}},
|
|
{ label: 'Watchlist', accelerator: 'CmdOrCtrl+L', click: () => {
|
|
mainWindow?.webContents.send('navigate', '/watchlist');
|
|
}},
|
|
{ label: 'Downloads', accelerator: 'CmdOrCtrl+D', click: () => {
|
|
mainWindow?.webContents.send('navigate', '/downloads');
|
|
}},
|
|
{ type: 'separator' },
|
|
{ label: 'Back', accelerator: 'CmdOrCtrl+[', click: () => {
|
|
mainWindow?.webContents.goBack();
|
|
}},
|
|
{ label: 'Forward', accelerator: 'CmdOrCtrl+]', click: () => {
|
|
mainWindow?.webContents.goForward();
|
|
}},
|
|
],
|
|
},
|
|
{
|
|
label: 'Window',
|
|
submenu: [
|
|
{ role: 'minimize' },
|
|
{ role: 'zoom' },
|
|
{ type: 'separator' },
|
|
{ role: 'front' },
|
|
],
|
|
},
|
|
{
|
|
label: 'Help',
|
|
submenu: [
|
|
{ label: 'Learn More', click: () => shell.openExternal('https://github.com') },
|
|
],
|
|
},
|
|
];
|
|
|
|
const menu = Menu.buildFromTemplate(template);
|
|
Menu.setApplicationMenu(menu);
|
|
}
|
|
|
|
function createTray() {
|
|
const iconPath = path.join(__dirname, '../public/icon.png');
|
|
const icon = nativeImage.createFromPath(iconPath);
|
|
tray = new Tray(icon.resize({ width: 16, height: 16 }));
|
|
|
|
const contextMenu = Menu.buildFromTemplate([
|
|
{ label: 'Open beStream', click: () => mainWindow?.show() },
|
|
{ type: 'separator' },
|
|
{ label: 'Downloads', click: () => {
|
|
mainWindow?.show();
|
|
mainWindow?.webContents.send('navigate', '/downloads');
|
|
}},
|
|
{ type: 'separator' },
|
|
{ label: 'Quit', role: 'quit' },
|
|
]);
|
|
|
|
tray.setToolTip('beStream');
|
|
tray.setContextMenu(contextMenu);
|
|
|
|
tray.on('click', () => {
|
|
mainWindow?.show();
|
|
});
|
|
}
|
|
|
|
// App event handlers
|
|
app.whenReady().then(() => {
|
|
createWindow();
|
|
createTray();
|
|
|
|
app.on('activate', () => {
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
|
createWindow();
|
|
}
|
|
});
|
|
});
|
|
|
|
app.on('window-all-closed', () => {
|
|
if (process.platform !== 'darwin') {
|
|
app.quit();
|
|
}
|
|
});
|
|
|
|
// IPC handlers for renderer communication
|
|
ipcMain.handle('get-app-path', () => {
|
|
return app.getPath('userData');
|
|
});
|
|
|
|
ipcMain.handle('get-downloads-path', () => {
|
|
return app.getPath('downloads');
|
|
});
|
|
|
|
ipcMain.handle('show-item-in-folder', (_event, filePath: string) => {
|
|
shell.showItemInFolder(filePath);
|
|
});
|
|
|
|
ipcMain.handle('open-external', (_event, url: string) => {
|
|
shell.openExternal(url);
|
|
});
|
|
|
|
// Handle certificate errors for development
|
|
if (isDev) {
|
|
app.on('certificate-error', (event, webContents, url, error, certificate, callback) => {
|
|
event.preventDefault();
|
|
callback(true);
|
|
});
|
|
}
|
|
|