diff --git a/.eslintrc.js b/.eslintrc.js index 1fcf706..ff8bfb4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -20,6 +20,6 @@ module.exports = { 'no-use-before-define': 'off', 'space-infix-ops': 'warn', 'no-bitwise': 'off', - 'no-restricted-globals': 'off' + 'no-restricted-globals': 'off', }, }; diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c092f47..a11f7db 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -42,4 +42,3 @@ jobs: node-version: 18 - run: npm ci - run: npm run release - diff --git a/README.md b/README.md index 7343493..8ca367c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ ![Latest Release Build Status](https://img.shields.io/github/workflow/status/stagehacks/Cue-View/release?label=release%20build&logo=github) + # Cue View A dashboard for everything in your show. diff --git a/index.html b/index.html index 9476233..c9a73ac 100644 --- a/index.html +++ b/index.html @@ -88,14 +88,12 @@ Pin: - - +

No Device Selected

-
diff --git a/main.js b/main.js index b25251d..aa6b406 100644 --- a/main.js +++ b/main.js @@ -1,4 +1,11 @@ -const { app, BrowserWindow, Menu, ipcMain, nativeTheme, dialog } = require('electron'); +const { + app, + BrowserWindow, + Menu, + ipcMain, + nativeTheme, + dialog, +} = require('electron'); const { autoUpdater } = require('electron-updater'); const path = require('path'); @@ -10,7 +17,6 @@ let manualUpdateCheck = false; let menuObj; let mainWindow; - const menuTemplate = [ ...(isMac ? [{ role: 'appMenu' }] : []), { @@ -19,17 +25,17 @@ const menuTemplate = [ { label: 'Clear Saved Data', id: 'resetViews', - click (menuItem, window, event) { + click(menuItem, window, event) { mainWindow.webContents.send('resetViews'); - } + }, }, { label: 'Reload App', - role: 'reload' + role: 'reload', }, { type: 'separator' }, - ...(isMac ? [{ role: 'close' }] : [{ role: 'quit' }]) - ] + ...(isMac ? [{ role: 'close' }] : [{ role: 'quit' }]), + ], }, { role: 'editMenu' }, { @@ -42,31 +48,31 @@ const menuTemplate = [ accelerator: 'CommandOrControl+1', id: 'window1', enabled: true, - click (menuItem, window, event) { - mainWindow.webContents.send('loadSlot',1); - } + click(menuItem, window, event) { + mainWindow.webContents.send('loadSlot', 1); + }, }, { label: 'Arrangement 2', accelerator: 'CommandOrControl+2', id: 'window2', enabled: true, - click (menuItem, window, event) { - mainWindow.webContents.send('loadSlot',2); - } + click(menuItem, window, event) { + mainWindow.webContents.send('loadSlot', 2); + }, }, { label: 'Arrangement 3', accelerator: 'CommandOrControl+3', id: 'window3', enabled: true, - click (menuItem, window, event) { - mainWindow.webContents.send('loadSlot',3); - } + click(menuItem, window, event) { + mainWindow.webContents.send('loadSlot', 3); + }, }, { type: 'separator' }, - { role: 'toggleDevTools' } - ] + { role: 'toggleDevTools' }, + ], }, { label: 'Device', @@ -76,9 +82,9 @@ const menuTemplate = [ accelerator: 'CommandOrControl+F', id: 'deviceSearch', enabled: true, - click (menuItem, window, event) { + click(menuItem, window, event) { mainWindow.webContents.send('searchAll'); - } + }, }, { type: 'separator' }, { @@ -88,23 +94,23 @@ const menuTemplate = [ accelerator: 'CommandOrControl+P', id: 'devicePin', enabled: false, - click (menuItem, window, event) { + click(menuItem, window, event) { mainWindow.webContents.send( 'setActiveDevicePinned', menuItem.checked ); - } + }, }, { label: 'Delete', accelerator: 'CommandOrControl+Backspace', id: 'deviceDelete', enabled: false, - click (menuItem, window, event) { + click(menuItem, window, event) { mainWindow.webContents.send('deleteActive'); - } - } - ] + }, + }, + ], }, { label: 'Help', @@ -112,67 +118,64 @@ const menuTemplate = [ submenu: [ { label: 'About', - role: 'about' + role: 'about', }, { label: 'Check for Updates', - click: ()=>{ + click: () => { // set manual update flag - manualUpdateCheck = true + manualUpdateCheck = true; autoUpdater.checkForUpdates(); - } + }, }, { label: 'Enable Auto Update', - click: ()=>{ - mainWindow.webContents.send('setAutoUpdate',!autoUpdate); - } - } - ] + click: () => { + mainWindow.webContents.send('setAutoUpdate', !autoUpdate); + }, + }, + ], }, ]; - const windowMac = { - width: 1500, - height: 900, - titleBarStyle: 'hiddenInset', - transparent: true, - frame: false, - show: false, - // backgroundColor: "#333333", - vibrancy: 'window', - visualEffectState: 'followWindow', - webPreferences: { - contextIsolation: false, - nodeIntegration: true, - preload: path.join(__dirname, 'preload.js'), - }, -} - -const windowWin = { width: 1500, height: 900, - backgroundColor: "#333333", + titleBarStyle: 'hiddenInset', + transparent: true, + frame: false, + show: false, + // backgroundColor: "#333333", + vibrancy: 'window', + visualEffectState: 'followWindow', webPreferences: { contextIsolation: false, nodeIntegration: true, preload: path.join(__dirname, 'preload.js'), }, -} +}; -if (isWin) -{ - app.setAppUserModelId(app.name); +const windowWin = { + width: 1500, + height: 900, + backgroundColor: '#333333', + webPreferences: { + contextIsolation: false, + nodeIntegration: true, + preload: path.join(__dirname, 'preload.js'), + }, +}; + +if (isWin) { + app.setAppUserModelId(app.name); } const createWindow = () => { - nativeTheme.themeSource = 'dark'; - - if(isMac){ + + if (isMac) { mainWindow = new BrowserWindow(windowMac); - }else{ + } else { mainWindow = new BrowserWindow(windowWin); } @@ -192,7 +195,7 @@ const createWindow = () => { app.whenReady().then(() => { createWindow(); - + app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); }); @@ -224,134 +227,134 @@ ipcMain.on('setDevicePin', (event, arg) => { menuObj.getMenuItemById('devicePin').checked = arg; }); - // Autoupdate logic -ipcMain.on('checkForUpdates', (event, arg)=>{ +ipcMain.on('checkForUpdates', (event, arg) => { autoUpdater.checkForUpdates(); -}) +}); + +ipcMain.on('setAutoUpdate', (event, _autoUpdate) => { + autoUpdate = _autoUpdate; -ipcMain.on('setAutoUpdate', (event, _autoUpdate)=>{ - autoUpdate = _autoUpdate - // update menu item for enabling/disabling auto update - menuTemplate[menuTemplate.length-1].submenu[2].label = autoUpdate ? 'Disable Auto Update' : 'Enable Auto Update'; + menuTemplate[menuTemplate.length - 1].submenu[2].label = autoUpdate + ? 'Disable Auto Update' + : 'Enable Auto Update'; menuObj = Menu.buildFromTemplate(menuTemplate); Menu.setApplicationMenu(menuObj); -}) +}); // this can be set to true to bypass the download update dialog and skip straight to install prompt autoUpdater.autoDownload = false; autoUpdater.on('update-available', (updateInfo) => { - // skip prompting to download if autoDownload is set - if(autoUpdater.autoDownload){ + if (autoUpdater.autoDownload) { return; } - const msg = `Version v${updateInfo.version} is available. Would you like to download it?` + const msg = `Version v${updateInfo.version} is available. Would you like to download it?`; const title = 'Update Available'; - let dialogOpts = {} + let dialogOpts = {}; - if(isMac){ + if (isMac) { dialogOpts = { type: 'info', buttons: ['Download', 'Cancel'], title: 'Update Available', message: title, - detail: msg - } - }else{ + detail: msg, + }; + } else { dialogOpts = { type: 'info', buttons: ['Download', 'Cancel'], title: 'Update Available', - message: msg - } + message: msg, + }; } - - dialog.showMessageBox(mainWindow,dialogOpts).then((returnValue) => { + + dialog.showMessageBox(mainWindow, dialogOpts).then((returnValue) => { // download was clicked - if (returnValue.response === 0){ + if (returnValue.response === 0) { autoUpdater.downloadUpdate(); } - }) -}) + }); +}); -autoUpdater.on('update-downloaded',(event)=>{ +autoUpdater.on('update-downloaded', (event) => { const title = 'Update Downloaded'; - const msg = `Version v${event.version} has been downloaded. Would you like to install this update now?` + const msg = `Version v${event.version} has been downloaded. Would you like to install this update now?`; - let dialogOpts = {} - - if(isMac){ + let dialogOpts = {}; + + if (isMac) { dialogOpts = { type: 'info', buttons: ['Install', 'Later'], title: 'Update Available', message: title, - detail: msg - } - }else{ + detail: msg, + }; + } else { dialogOpts = { type: 'info', buttons: ['Install', 'Later'], title: 'Update Available', - message: msg - } + message: msg, + }; } - - dialog.showMessageBox(mainWindow,dialogOpts).then((returnValue) => { - if (returnValue.response === 0) autoUpdater.quitAndInstall() - }) -}) -autoUpdater.on('update-not-available',(updateInfo)=>{ - if(manualUpdateCheck){ - let dialogOpts = {} - const msg = `There is no update available at this time. Latest version is v${updateInfo.version}` - if(isMac){ + dialog.showMessageBox(mainWindow, dialogOpts).then((returnValue) => { + if (returnValue.response === 0) autoUpdater.quitAndInstall(); + }); +}); + +autoUpdater.on('update-not-available', (updateInfo) => { + if (manualUpdateCheck) { + let dialogOpts = {}; + const msg = `There is no update available at this time. Latest version is v${updateInfo.version}`; + if (isMac) { dialogOpts = { type: 'info', buttons: ['Ok'], title: 'No Update Available', message: 'No Update Available', - detail: msg - } - }else{ + detail: msg, + }; + } else { dialogOpts = { type: 'info', buttons: ['Ok'], title: 'No Update Available', - message: msg - } + message: msg, + }; } - dialog.showMessageBox(mainWindow,dialogOpts) + dialog.showMessageBox(mainWindow, dialogOpts); // revert manual update flag manualUpdateCheck = false; } -}) +}); -autoUpdater.on('error',(error,message)=>{ - let dialogOpts = {} - - if(isMac){ +autoUpdater.on('error', (error, message) => { + let dialogOpts = {}; + + if (isMac) { dialogOpts = { type: 'error', buttons: ['Ok'], title: 'Update Error', message: 'Update Error', - detail: error.message - } - }else{ + detail: error.message, + }; + } else { dialogOpts = { type: 'error', buttons: ['Ok'], title: 'Update Error', - message: error.message - } + message: error.message, + }; } - dialog.showMessageBox(mainWindow,dialogOpts) -}) + dialog.showMessageBox(mainWindow, dialogOpts); +}); diff --git a/notarize.js b/notarize.js index 418b34a..6d8136a 100644 --- a/notarize.js +++ b/notarize.js @@ -1,41 +1,44 @@ const notarize = require('@electron/notarize'); -const fs = require('fs') -const path = require('path') +const fs = require('fs'); +const path = require('path'); module.exports = async function (params) { - if (process.platform !== 'darwin') { - console.log('Only need to notarize MacOS, skipping') - return - } - - const appId = 'com.stagehacks.cueview' + if (process.platform !== 'darwin') { + console.log('Only need to notarize MacOS, skipping'); + return; + } - const appPath = path.join( - params.appOutDir, - `${params.packager.appInfo.productFilename}.app` - ) + const appId = 'com.stagehacks.cueview'; - if (!fs.existsSync(appPath)) { - console.error('App file not found skipping notarization.'); - return; - } - - if(process.env.APPLE_ID === undefined || process.env.APPLE_ID_PASSWORD === undefined){ - console.log('Apple ID and Password must be set in order to notarize.') - return; - } + const appPath = path.join( + params.appOutDir, + `${params.packager.appInfo.productFilename}.app` + ); - try { - console.log(`Notarizing ${appId} found at ${appPath}`) - await notarize.notarize({ - appBundleId: appId, - appPath, - appleId: process.env.APPLE_ID, - appleIdPassword: process.env.APPLE_ID_PASSWORD, - }) - console.log(`Done notarizing ${appId}`) - } catch (error) { - console.log('There was an error notarizing.') - console.error(error) - } -} \ No newline at end of file + if (!fs.existsSync(appPath)) { + console.error('App file not found skipping notarization.'); + return; + } + + if ( + process.env.APPLE_ID === undefined || + process.env.APPLE_ID_PASSWORD === undefined + ) { + console.log('Apple ID and Password must be set in order to notarize.'); + return; + } + + try { + console.log(`Notarizing ${appId} found at ${appPath}`); + await notarize.notarize({ + appBundleId: appId, + appPath, + appleId: process.env.APPLE_ID, + appleIdPassword: process.env.APPLE_ID_PASSWORD, + }); + console.log(`Done notarizing ${appId}`); + } catch (error) { + console.log('There was an error notarizing.'); + console.error(error); + } +}; diff --git a/preload.js b/preload.js index ef6d29c..e3bd5a2 100644 --- a/preload.js +++ b/preload.js @@ -16,13 +16,13 @@ window.init = function init() { ipcRenderer.send('enableSearchAll'); // load autoUpdate setting from storage and send to main process - const autoUpdate = JSON.parse(localStorage.getItem('autoUpdate')) - if(autoUpdate !== undefined && autoUpdate !== null){ - if(autoUpdate){ + const autoUpdate = JSON.parse(localStorage.getItem('autoUpdate')); + if (autoUpdate !== undefined && autoUpdate !== null) { + if (autoUpdate) { ipcRenderer.send('checkForUpdates'); } // send message so main process knows the state of autoUpdate - ipcRenderer.send('setAutoUpdate', autoUpdate) + ipcRenderer.send('setAutoUpdate', autoUpdate); } PLUGINS.init(() => { @@ -35,31 +35,39 @@ window.init = function init() { SEARCH.searchAll(); }; - document.getElementById('device-settings-table').onclick = function settingsClick(e) { - e.stopPropagation(); - }; - - document.getElementById('device-settings-name').onchange = function nameChange(e) { - e.stopPropagation(); - DEVICE.changeActiveName(e.target.value); - }; - - document.getElementById('device-settings-plugin-dropdown').onchange = function dropdownChange(e) { - e.stopPropagation(); - DEVICE.changeActiveType(e.target.value); - }; + document.getElementById('device-settings-table').onclick = + function settingsClick(e) { + e.stopPropagation(); + }; - document.getElementById('device-settings-ip').onchange = function ipChange(e) { + document.getElementById('device-settings-name').onchange = + function nameChange(e) { + e.stopPropagation(); + DEVICE.changeActiveName(e.target.value); + }; + + document.getElementById('device-settings-plugin-dropdown').onchange = + function dropdownChange(e) { + e.stopPropagation(); + DEVICE.changeActiveType(e.target.value); + }; + + document.getElementById('device-settings-ip').onchange = function ipChange( + e + ) { e.stopPropagation(); DEVICE.changeActiveIP(e.target.value); }; - document.getElementById('device-settings-port').onchange = function portChange(e) { - e.stopPropagation(); - DEVICE.changeActivePort(e.target.value); - }; + document.getElementById('device-settings-port').onchange = + function portChange(e) { + e.stopPropagation(); + DEVICE.changeActivePort(e.target.value); + }; - document.getElementById('device-settings-pin').onchange = function pinChange(e) { + document.getElementById('device-settings-pin').onchange = function pinChange( + e + ) { e.stopPropagation(); if (e.target.checked) { VIEW.pinActiveDevice(); @@ -68,7 +76,6 @@ window.init = function init() { } }; - document.getElementById('save-slot-1').onclick = function slot1click(e) { e.stopPropagation(); SAVESLOTS.loadSlot(1); @@ -84,10 +91,11 @@ window.init = function init() { SAVESLOTS.loadSlot(3); }; - document.getElementById('refresh-device-button').onclick = function refreshClick(e) { - e.stopPropagation(); - DEVICE.refreshActive(); - }; + document.getElementById('refresh-device-button').onclick = + function refreshClick(e) { + e.stopPropagation(); + DEVICE.refreshActive(); + }; document.getElementById('device-list').onclick = function listClick(e) { e.stopPropagation(); @@ -97,26 +105,25 @@ window.init = function init() { } }; - document.getElementById('add-device-button').onchange = function addDeviceClick(e) { - DEVICE.registerDevice({ - type: e.target.value, - defaultName: 'New Device', - port: undefined, - addresses: [], - }); - e.target.selectedIndex = 0; + document.getElementById('add-device-button').onchange = + function addDeviceClick(e) { + DEVICE.registerDevice({ + type: e.target.value, + defaultName: 'New Device', + port: undefined, + addresses: [], + }); + e.target.selectedIndex = 0; - SAVESLOTS.saveAll(); - }; + SAVESLOTS.saveAll(); + }; document.onkeyup = function keyUp(e) { - if(e.key === 'ArrowUp'){ + if (e.key === 'ArrowUp') { VIEW.selectPreviousDevice(); - - }else if(e.key === 'ArrowDown'){ + } else if (e.key === 'ArrowDown') { VIEW.selectNextDevice(); - - }else if(e.key === 'Tab'){ + } else if (e.key === 'Tab') { if ( document.activeElement.tagName !== 'INPUT' && document.activeElement.tagName !== 'SELECT' @@ -124,10 +131,11 @@ window.init = function init() { document.getElementById('device-settings-name').select(); } } - }; - document.getElementById('device-list-col').onclick = function deviceListClick(e) { + document.getElementById('device-list-col').onclick = function deviceListClick( + e + ) { try { document .querySelector('#device-list .active-device') @@ -170,22 +178,20 @@ ipcRenderer.on('resetViews', (event, message) => { }); ipcRenderer.on('loadSlot', (event, slot) => { - if(slot){ + if (slot) { SAVESLOTS.loadSlot(slot); } }); - // message from main process to set autoUpdate state -ipcRenderer.on('setAutoUpdate',(event,autoUpdate)=>{ - localStorage.setItem('autoUpdate',autoUpdate); - if(autoUpdate){ +ipcRenderer.on('setAutoUpdate', (event, autoUpdate) => { + localStorage.setItem('autoUpdate', autoUpdate); + if (autoUpdate) { ipcRenderer.send('checkForUpdates'); } // message to main process that we have updated the state - ipcRenderer.send('setAutoUpdate',autoUpdate); -}) - + ipcRenderer.send('setAutoUpdate', autoUpdate); +}); function switchClass(element, className) { try { @@ -195,4 +201,4 @@ function switchClass(element, className) { } element.classList.add(className); } -window.switchClass = switchClass; \ No newline at end of file +window.switchClass = switchClass;