mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-03 06:28:01 +00:00
344 lines
9.6 KiB
JavaScript
344 lines
9.6 KiB
JavaScript
const { Menu, shell } = require('electron');
|
|
|
|
const {
|
|
linkToGitHub,
|
|
linkToDocs,
|
|
linkToDiscord,
|
|
isProduction,
|
|
isMac,
|
|
releaseTag,
|
|
projectsPath,
|
|
corruptProjectsPath,
|
|
crashLogPath,
|
|
stylesPath,
|
|
externalPath,
|
|
downloadPath,
|
|
} = require('../externals.js');
|
|
|
|
/**
|
|
* Creates the application menu
|
|
* @param {function} askToQuit - function for quitting process
|
|
* @param {string} clientUrl - base url for the application
|
|
* @param {string} serverUrl - base url for the application
|
|
* @param {function} redirectWindow - function to redirect main window content
|
|
* @param {function} showDialog - asks the react app to show a user dialog
|
|
* @param {function} download - function to download a resource from url
|
|
* @returns {Menu} - application menu
|
|
*/
|
|
function getApplicationMenu(askToQuit, clientUrl, serverUrl, redirectWindow, showDialog, download) {
|
|
const template = [
|
|
...(isMac ? [makeMacMenu(askToQuit)] : []),
|
|
makeFileMenu(serverUrl, redirectWindow, showDialog, download),
|
|
makeEditMenu(),
|
|
makeViewMenu(clientUrl),
|
|
makeSettingsMenu(redirectWindow),
|
|
makeHelpMenu(redirectWindow),
|
|
...(isProduction ? [] : [{ label: 'Dev', submenu: [{ role: 'toggleDevTools' }] }]),
|
|
];
|
|
return Menu.buildFromTemplate(template);
|
|
}
|
|
|
|
/**
|
|
* Utility function generates the app menu (macOS only)
|
|
* @param {function} askToQuit - function for quitting process
|
|
* @returns {Object}
|
|
*/
|
|
function makeMacMenu(askToQuit) {
|
|
return {
|
|
label: 'Ontime',
|
|
submenu: [
|
|
{ role: 'about', label: 'About Ontime' },
|
|
{ type: 'separator' },
|
|
{ role: 'hide', label: 'Hide Ontime' },
|
|
{ role: 'hideOthers' },
|
|
{ role: 'unhide' },
|
|
{ type: 'separator' },
|
|
{
|
|
label: 'Quit',
|
|
click: askToQuit,
|
|
accelerator: isMac ? 'Cmd+Q' : 'Alt+F4',
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Utility function generates the edit menu
|
|
* @returns {Object}
|
|
*/
|
|
function makeEditMenu() {
|
|
return {
|
|
label: 'Edit',
|
|
submenu: [
|
|
{ label: 'Cut', accelerator: 'CmdOrCtrl+X', role: 'cut' },
|
|
{ label: 'Copy', accelerator: 'CmdOrCtrl+C', role: 'copy' },
|
|
{ label: 'Paste', accelerator: 'CmdOrCtrl+V', role: 'paste' },
|
|
{ label: 'Select All', accelerator: 'CmdOrCtrl+A', role: 'selectAll' },
|
|
],
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Utility function generates the file menu
|
|
* @param {string} serverUrl - base url for the application
|
|
* @param {function} redirectWindow - function to redirect main window content
|
|
* @param {function} showDialog - asks the react app to show a user dialog
|
|
* @param {function} download - function to download a resource from url
|
|
* @returns {Object}
|
|
*/
|
|
function makeFileMenu(serverUrl, redirectWindow, showDialog, download) {
|
|
const downloadProject = () => {
|
|
try {
|
|
download(serverUrl + downloadPath);
|
|
} catch (_error) {
|
|
/** unhandled error */
|
|
}
|
|
};
|
|
|
|
return {
|
|
label: 'File',
|
|
submenu: [
|
|
{
|
|
label: 'New project...',
|
|
click: () => redirectWindow('/editor?settings=project__manage&new=true'),
|
|
},
|
|
{
|
|
label: 'Load...',
|
|
click: () => showDialog('welcome'),
|
|
},
|
|
{
|
|
label: 'Quick start...',
|
|
click: () => redirectWindow('/editor?settings=project__create'),
|
|
},
|
|
{
|
|
label: 'Edit project info...',
|
|
click: () => redirectWindow('/editor?settings=project__data'),
|
|
},
|
|
{
|
|
label: 'Manage projects',
|
|
click: () => redirectWindow('/editor?settings=project__manage'),
|
|
},
|
|
{
|
|
label: 'Download project',
|
|
click: downloadProject,
|
|
},
|
|
{ type: 'separator' },
|
|
{
|
|
label: 'Open directory',
|
|
submenu: [
|
|
makeItemOpenInDesktop('Projects', projectsPath),
|
|
makeItemOpenInDesktop('Corrupted projects', corruptProjectsPath),
|
|
makeItemOpenInDesktop('Crash logs', crashLogPath),
|
|
makeItemOpenInDesktop('CSS override', stylesPath),
|
|
makeItemOpenInDesktop('External', externalPath),
|
|
],
|
|
},
|
|
{ type: 'separator' },
|
|
{ role: isMac ? 'close' : 'quit' },
|
|
],
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Utility function generates the views menu
|
|
* @param {string} clientUrl - base url for the application
|
|
* @returns {Object}
|
|
*/
|
|
function makeViewMenu(clientUrl) {
|
|
return {
|
|
label: 'Views',
|
|
submenu: [
|
|
makeItemOpenInBrowser('Public', `${clientUrl}/public`),
|
|
makeItemOpenInBrowser('Lower Thirds', `${clientUrl}/lower`),
|
|
{ type: 'separator' },
|
|
makeItemOpenInBrowser('Timer', `${clientUrl}/timer`),
|
|
makeItemOpenInBrowser('Minimal Timer', `${clientUrl}/minimal`),
|
|
makeItemOpenInBrowser('Clock', `${clientUrl}/clock`),
|
|
makeItemOpenInBrowser('Backstage', `${clientUrl}/backstage`),
|
|
makeItemOpenInBrowser('Timeline (beta)', `${clientUrl}/timeline`),
|
|
makeItemOpenInBrowser('Studio Clock', `${clientUrl}/studio`),
|
|
makeItemOpenInBrowser('Countdown', `${clientUrl}/countdown`),
|
|
{ type: 'separator' },
|
|
makeItemOpenInBrowser('Editor', `${clientUrl}/editor`),
|
|
makeItemOpenInBrowser('Cuesheet', `${clientUrl}/cuesheet`),
|
|
makeItemOpenInBrowser('Operator', `${clientUrl}/op`),
|
|
makeItemOpenInBrowser('Project info', `${clientUrl}/info`),
|
|
|
|
{ type: 'separator' },
|
|
{ role: 'forceReload' },
|
|
{ type: 'separator' },
|
|
{ role: 'resetZoom' },
|
|
// NOTE: I still contend this zoomin mess is an electron bug
|
|
{ role: 'zoomIn', accelerator: 'CmdOrCtrl+Plus' },
|
|
{ role: 'zoomIn', accelerator: 'CmdOrCtrl+=', visible: false },
|
|
{ role: 'zoomIn', accelerator: 'CmdOrCtrl+numadd', visible: false },
|
|
{ role: 'zoomOut' },
|
|
{ type: 'separator' },
|
|
{ role: 'togglefullscreen' },
|
|
],
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Utility function generates the settings menu
|
|
* @param {function} redirectWindow - function to redirect main window content
|
|
* @returns {Object}
|
|
*/
|
|
function makeSettingsMenu(redirectWindow) {
|
|
return {
|
|
label: 'Settings',
|
|
submenu: [
|
|
{
|
|
label: 'Open Settings',
|
|
accelerator: 'CommandOrControl+,',
|
|
click: () => redirectWindow('/editor?settings=project'),
|
|
},
|
|
{
|
|
label: 'Project',
|
|
submenu: [
|
|
{
|
|
label: 'Project data',
|
|
click: () => redirectWindow('/editor?settings=project__data'),
|
|
},
|
|
{
|
|
label: 'Manage projects',
|
|
click: () => redirectWindow('/editor?settings=project__manage'),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'App Settings',
|
|
submenu: [
|
|
{
|
|
label: 'General settings',
|
|
click: () => redirectWindow('/editor?settings=general__settings'),
|
|
},
|
|
{
|
|
label: 'Editor settings',
|
|
click: () => redirectWindow('/editor?settings=general__editor'),
|
|
},
|
|
{
|
|
label: 'View settings',
|
|
click: () => redirectWindow('/editor?settings=general__view'),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Feature Settings',
|
|
submenu: [
|
|
{
|
|
label: 'Custom fields',
|
|
click: () => redirectWindow('/editor?settings=feature_settings__custom'),
|
|
},
|
|
{
|
|
label: 'URL presets',
|
|
click: () => redirectWindow('/editor?settings=feature_settings__urlpresets'),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Data Sources',
|
|
submenu: [
|
|
{
|
|
label: 'Import spreadsheet',
|
|
click: () => redirectWindow('/editor?settings=sources__xlsx'),
|
|
},
|
|
{
|
|
label: 'Sync with Google Sheet',
|
|
click: () => redirectWindow('/editor?settings=sources__gsheet'),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Integrations',
|
|
submenu: [
|
|
{
|
|
label: 'OSC settings',
|
|
click: () => redirectWindow('/editor?settings=integrations__osc'),
|
|
},
|
|
{
|
|
label: 'HTTP settings',
|
|
click: () => redirectWindow('/editor?settings=integrations__http'),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Network',
|
|
submenu: [
|
|
{
|
|
label: 'Event log',
|
|
click: () => redirectWindow('/editor?settings=network__log'),
|
|
},
|
|
{
|
|
label: 'Manage clients',
|
|
click: () => redirectWindow('/editor?settings=network__clients'),
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Utility function generates the help menu
|
|
* @param {function} redirectWindow - function to redirect main window content
|
|
* @returns {Object}
|
|
*/
|
|
function makeHelpMenu(redirectWindow) {
|
|
return {
|
|
role: 'help',
|
|
submenu: [
|
|
{
|
|
label: `Ontime ${releaseTag}`,
|
|
click: () => redirectWindow('/editor?settings=about'),
|
|
},
|
|
{
|
|
type: 'separator',
|
|
},
|
|
makeItemOpenInBrowser('See on github', linkToGitHub),
|
|
makeItemOpenInBrowser('Online documentation', linkToDocs),
|
|
makeItemOpenInBrowser('Join us on Discord', linkToDiscord),
|
|
],
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Utility function to safely open a URL in the default browser
|
|
* @param {string} label
|
|
* @param {string} url
|
|
* @returns {object} - MenuItem
|
|
*/
|
|
function makeItemOpenInBrowser(label, url) {
|
|
return {
|
|
label: `${label} ↗`,
|
|
click: async () => {
|
|
try {
|
|
await shell.openExternal(url);
|
|
} catch (_error) {
|
|
/** unhandled error */
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Utility function to open a file in the OS explorer / finder
|
|
* @param {string} label
|
|
* @param {string} path
|
|
* @returns {object} - MenuItem
|
|
*/
|
|
function makeItemOpenInDesktop(label, path) {
|
|
return {
|
|
label,
|
|
click: () => {
|
|
try {
|
|
shell.openPath(path);
|
|
} catch (_error) {
|
|
/** unhandled error */
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
module.exports = { getApplicationMenu };
|