Files
ontime/apps/electron/main.js
T
Carlos Valente 55d1aca9b6 V3 (#657)
* refactor: cleanup routes

* style: smaller base font

* chore: upgrade dependencies

* chore: lock node version to electron

* refactor: pass HTTP to integration controller (#652)

* refactor: deprecate onair control

* refactor: remove playback router

* Several project files user folder (#617)

* chore: automated screenshots (#667)

* feat: app settings (#658)

* refactor: remove deprecated event data (#674)

* Studio clock (#663)

---------

Co-authored-by: Carlos Valente <carlosvalente@pm.me>

* Feat: reorder events with alt+ctrl + arrow up/down (#645)

* Warning and danger per event (#677)

---------

Co-authored-by: Fabian Posenau <fabian@fphome.de>

* refactor: stabilise actionHandler (#683)

Co-authored-by: Fabian Posenau <fabian@fphome.de>

* improvement: hide seconds (#675)

* wip: overview (#688)

* fix: focus cursor (#695)

* refactor: update lower third (#665)

* Refactor/time formatting (#696)

---------

Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
Co-authored-by: Carlos Valente <carlosvalente@pm.me>

* feat: multiple selection (#703)

---------

Co-authored-by: asharonbaltazar <asharonbaltazar@outlook.com>
Co-authored-by: Alex <ac@omnivox.dk>

* fix: test - go to `Edit mode` befor tying to click `Event options` button (#708)

* refactor: runtime service (#715)

* fix: issue with loosing cursor position on message (#719)

* remove info panel (#721)

* Event editor continue (#722)

* update API - part  (#709)

---------

Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
Co-authored-by: Carlos Valente <carlosvalente@pm.me>

* refactor: update timers (#729)

* feat: many timers (#706)

---------

Co-authored-by: arc-alex <ac@omnivox.dk>

* refactor: excel cleanup (#734)

* refactor: allow import of blocks and skip import (#735)

* Project manager (#697)

* refactor: UI for linking events (#763)

* upgraded pipeline actions (#777)

* Over under (#771)

* custom fields (#744)


---------

Co-authored-by: Carlos Valente <carlosvalente@pm.me>

* Sheets settings (#774)

---------

Co-authored-by: arc-alex <ac@omnivox.dk>

* style: tweaks to lower thirds (#785)

* refactor: delays account for gaps (#784)

* refactor: partial state updates (#780)

* feat: generate crash report (#787)

* Sheet use limited input device auth flow (#782)

---------

Co-authored-by: cv <34649812+cpvalente@users.noreply.github.com>
Co-authored-by: Carlos Valente <carlosvalente@pm.me>

* Custom fields views (#789)

* refactor: deprecate presenter and subtitle (#795)

* refactor: organise API around resources (#798)

---------

Co-authored-by: Bianca Procopio <biancahprocopio@gmail.com>

* Time to end (#804)

* Skip fixes (#805)

* fix: onair derives from playback

* Param nav (#822)

---------

Co-authored-by: Alex Christoffer Rasmussen <ac@omnivox.dk>

* refactor: download files from interface (#831)

* Quick options (#814)

* End pause (#832)

* chore: bump node version in docker (#834)

* refactor: follow in run mode (#840)

* fix: uncaught error in http integration (#837)

* Apply project (#843)

Co-authored-by: Matteo Gheza <matteo.gheza07@gmail.com>
Co-authored-by: Ary <arylmoraesn@gmail.com>
Co-authored-by: Alex Christoffer Rasmussen <ac@omnivox.dk>
Co-authored-by: Fabian Posenau <19673098+kellhogs@users.noreply.github.com>
Co-authored-by: Fabian Posenau <fabian@fphome.de>
Co-authored-by: Alex Rohleder <alexrohleder96@gmail.com>
Co-authored-by: asharonbaltazar <asharonbaltazar@outlook.com>
Co-authored-by: Bianca Procopio <biancahprocopio@gmail.com>
Co-authored-by: Fabian Posenau <fabianpos99+github@gmail.com>
2024-04-13 10:06:46 +02:00

250 lines
5.9 KiB
JavaScript

const { app, BrowserWindow, Menu, globalShortcut, Tray, dialog, ipcMain, shell, Notification } = require('electron');
const path = require('path');
const electronConfig = require('./electron.config');
const env = process.env.NODE_ENV || 'production';
const isProduction = env === 'production';
const isMac = process.platform === 'darwin';
const isWindows = process.platform === 'win32';
// path to server
const nodePath = isProduction
? path.join(__dirname, electronConfig.server.pathToEntrypoint)
: path.join(__dirname, '../server/dist/index.cjs');
if (!isProduction) {
console.log(`Electron running in ${env} environment`);
console.log(`Ontime server at ${nodePath}`);
process.traceProcessWarnings = true;
}
// path to icons
const trayIcon = path.join(__dirname, electronConfig.assets.pathToAssets, 'background.png');
const appIcon = path.join(__dirname, electronConfig.assets.pathToAssets, 'logo.png');
let loaded = 'Nothing loaded';
let isQuitting = false;
// initialise
let win;
let splash;
let tray = null;
async function startBackend() {
// in dev mode, we expect both UI and server to be running
if (!isProduction) {
return;
}
const ontimeServer = require(nodePath);
const { initAssets, startServer, startIntegrations } = ontimeServer;
await initAssets();
const result = await startServer();
loaded = result.message;
await startIntegrations();
return result.serverPort;
}
/**
* @description utility function to create a notification
* @param title
* @param text
*/
function showNotification(title, text) {
new Notification({
title,
body: text,
silent: true,
}).show();
}
function appShutdown() {
// terminate node service
(async () => {
const ontimeServer = require(nodePath);
const { shutdown } = ontimeServer;
await shutdown(electronConfig.appIni.shutdownCode);
})();
isQuitting = true;
tray.destroy();
win.destroy();
app.quit();
}
function bringToFront() {
win.show();
win.focus();
}
function askToQuit() {
bringToFront();
win.send('user-request-shutdown');
}
// Ensure there isn't another instance of the app running already
const lock = app.requestSingleInstanceLock();
if (!lock) {
dialog.showErrorBox('Multiple instances', 'An instance of the App is already running.');
app.quit();
} else {
app.on('second-instance', () => {
// Someone tried to run a second instance, we should focus our window.
if (win) {
if (win.isMinimized()) {
win.restore();
}
bringToFront();
}
});
}
function createWindow() {
splash = new BrowserWindow({
width: 333,
height: 333,
transparent: true,
icon: appIcon,
resizable: false,
frame: false,
alwaysOnTop: true,
focusable: false,
skipTaskbar: true,
});
splash.setIgnoreMouseEvents(true);
const splashPath = path.join('file://', __dirname, '/src/splash/splash.html');
splash.loadURL(splashPath);
win = new BrowserWindow({
width: 1920,
height: 1000,
minWidth: 525,
minHeight: 405,
backgroundColor: '#101010', // $gray-1350
icon: appIcon,
show: false,
textAreasAreResizable: false,
enableWebSQL: false,
darkTheme: true,
webPreferences: {
preload: path.join(__dirname, './src/preload.js'),
nodeIntegration: true,
contextIsolation: false,
},
});
win.setMenu(null);
}
app.disableHardwareAcceleration();
app.whenReady().then(() => {
// Set app title in windows
if (isWindows) {
app.setAppUserModelId(app.name);
}
createWindow();
// register global shortcuts
// (available regardless of whether app is in focus)
// bring focus to window
globalShortcut.register('Alt+1', () => {
bringToFront();
});
startBackend()
.then((port) => {
// Load page served by node or use React dev run
const clientUrl = isProduction
? electronConfig.reactAppUrl.production(port)
: electronConfig.reactAppUrl.development(port);
win
.loadURL(clientUrl)
.then(() => {
win.webContents.setBackgroundThrottling(false);
win.show();
win.focus();
splash.destroy();
if (typeof loaded === 'string') {
tray.setToolTip(loaded);
} else {
tray.setToolTip('Initialising error: please restart Ontime');
}
})
.catch((error) => {
console.log('ERROR: Ontime failed to reach server', error);
});
})
.catch((error) => {
console.log('ERROR: Ontime failed to start', error);
});
// recreate window if no others open
app.on('activate', () => {
win.show();
});
// Hide on close
win.on('close', function (event) {
event.preventDefault();
if (!isQuitting) {
showNotification('Window Closed', 'App running in background');
win.hide();
}
});
// create tray
tray = new Tray(trayIcon);
// Define context menu
const { getTrayMenu } = require('./src/menu/trayMenu.js');
const trayMenuTemplate = getTrayMenu(bringToFront, askToQuit);
const trayContextMenu = Menu.buildFromTemplate(trayMenuTemplate);
tray.setContextMenu(trayContextMenu);
});
const { getApplicationMenu } = require('./src/menu/applicationMenu.js');
const template = getApplicationMenu(isMac, askToQuit);
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
// unregister shortcuts before quitting
app.once('will-quit', () => {
globalShortcut.unregisterAll();
});
// Ask for main window reload
// Test message
ipcMain.on('reload', () => {
win?.reload();
});
// Terminate
ipcMain.on('shutdown', () => {
console.log('Electron got IPC shutdown');
appShutdown();
});
// Window manipulation
ipcMain.on('set-window', (event, arg) => {
switch (arg) {
case 'show-dev':
win.webContents.openDevTools({ mode: 'detach' });
break;
default:
console.log('Electron unhandled window request', arg);
}
});
// Open links external
ipcMain.on('send-to-link', (event, arg) => {
shell.openExternal(arg);
});