diff --git a/README.md b/README.md index 5ac35da..a131b48 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,18 @@ # Cue View + A dashboard for everything in your show. ![Screen Shot 2021-10-26 at 11 57 21 PM](https://user-images.githubusercontent.com/919746/138997636-dfca293a-7c98-459d-85a3-405c9b11ce8a.png) - - - ## Features + - Tons of supported equipment - Auto discover devices on the network - Live updating - Configurable layout - ## Supported Devices + - QLab 4 - ETC Eos Consoles - Watchout @@ -21,8 +20,8 @@ A dashboard for everything in your show. - X32 Audio Consoles - XAir Audio Consoles - #### Future Devices + - Spikemark - ATEM Video Mixers - Art-Net, sACN Universes @@ -31,6 +30,6 @@ A dashboard for everything in your show. - d&b DS100, amps - Hog - ## Known Issues + - QLab Cue Carts are not supported yet. diff --git a/index.html b/index.html index d8a2d43..81e7818 100644 --- a/index.html +++ b/index.html @@ -1,73 +1,101 @@ - + Cue View - - + - -
- -
- -
- - - - -
- -
-

Click the Search button to find devices on the network.

-
- -
- - - -
- - - -
- - - - - - - - - - - - - - - - - - -
Name:
Type:
Addr:
Port:Pin:
-

No Device Selected

- -
- - +
+
+ + +
-
- - - +
+

+ Click the Search button to find devices on the network. +

+
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
Name: + +
Type: + +
Addr: + +
Port: + + Pin:
+ +

No Device Selected

+
+
+ +
- diff --git a/main.js b/main.js index d25d572..c6f87c5 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,8 @@ const { app, BrowserWindow, Menu } = require('electron'); const path = require('path'); // Handle creating/removing shortcuts on Windows when installing/uninstalling. -if (require('electron-squirrel-startup')) { // eslint-disable-line global-require +if (require('electron-squirrel-startup')) { + // eslint-disable-line global-require app.quit(); } @@ -10,12 +11,10 @@ if (require('electron-squirrel-startup')) { app.quit(); } - var menu; let mainWindow; const createWindow = () => { - mainWindow = new BrowserWindow({ width: 1500, height: 900, @@ -24,45 +23,37 @@ const createWindow = () => { frame: false, show: false, //backgroundColor: "#333333", - vibrancy: "window", - visualEffectState: "followWindow", + vibrancy: 'window', + visualEffectState: 'followWindow', webPreferences: { //enableRemoteModule: true, contextIsolation: false, nodeIntegration: true, - preload: path.join(__dirname, 'preload.js') - } + preload: path.join(__dirname, 'preload.js'), + }, }); mainWindow.loadFile('index.html'); mainWindow.on('ready-to-show', () => { - mainWindow.show(); + mainWindow.show(); }); - if(process.defaultApp){ + if (process.defaultApp) { mainWindow.webContents.openDevTools(); } - menu = Menu.buildFromTemplate(menuTemplate); Menu.setApplicationMenu(menu); - }; - - app.whenReady().then(() => { - createWindow() + createWindow(); app.on('activate', function () { - if (BrowserWindow.getAllWindows().length === 0) createWindow() - }) -}) - - - - + if (BrowserWindow.getAllWindows().length === 0) createWindow(); + }); +}); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { @@ -70,9 +61,7 @@ app.on('window-all-closed', () => { } }); - - -const { ipcMain } = require('electron') +const { ipcMain } = require('electron'); ipcMain.on('enableDeviceDropdown', (event, arg) => { menu.getMenuItemById('devicePin').enabled = true; menu.getMenuItemById('deviceDelete').enabled = true; @@ -89,107 +78,109 @@ ipcMain.on('disableSearchAll', (event, arg) => { menu.getMenuItemById('deviceSearch').enabled = false; }); -ipcMain.on('setDevicePin', function(event, arg){ +ipcMain.on('setDevicePin', function (event, arg) { menu.getMenuItemById('devicePin').checked = arg; -}) +}); -const isMac = process.platform === 'darwin' +const isMac = process.platform === 'darwin'; const menuTemplate = [ { role: 'appMenu' }, { - label: "File", + label: 'File', submenu: [ { - label: "Clear Saved Data", - id: "resetViews", - click: function(menuItem, window, event){ - mainWindow.webContents.send("resetViews"); - - } + label: 'Clear Saved Data', + id: 'resetViews', + click: function (menuItem, window, event) { + mainWindow.webContents.send('resetViews'); + }, }, { - label: "Reload App", - role: "reload" + label: 'Reload App', + role: 'reload', }, { - type: "separator" + type: 'separator', }, isMac ? { role: 'close' } : { role: 'quit' }, - ] + ], }, { role: 'editMenu' }, { - label: "View", + label: 'View', submenu: [ { role: 'togglefullscreen' }, { type: 'separator' }, { - label: "Arrangement 1", - accelerator: "CommandOrControl+1", - id: "window1", + label: 'Arrangement 1', + accelerator: 'CommandOrControl+1', + id: 'window1', enabled: true, - click: function(menuItem, window, event){ - mainWindow.webContents.send("doSlots1"); - } + click: function (menuItem, window, event) { + mainWindow.webContents.send('doSlots1'); + }, }, { - label: "Arrangement 2", - accelerator: "CommandOrControl+2", - id: "window2", + label: 'Arrangement 2', + accelerator: 'CommandOrControl+2', + id: 'window2', enabled: true, - click: function(menuItem, window, event){ - mainWindow.webContents.send("doSlots2"); - } + click: function (menuItem, window, event) { + mainWindow.webContents.send('doSlots2'); + }, }, { - label: "Arrangement 3", - accelerator: "CommandOrControl+3", - id: "window3", + label: 'Arrangement 3', + accelerator: 'CommandOrControl+3', + id: 'window3', enabled: true, - click: function(menuItem, window, event){ - mainWindow.webContents.send("doSlots3"); - } + click: function (menuItem, window, event) { + mainWindow.webContents.send('doSlots3'); + }, }, { type: 'separator' }, - { role: 'toggleDevTools' } - ] + { role: 'toggleDevTools' }, + ], }, { - label: "Device", + label: 'Device', submenu: [ { - label: "Search for Devices", - accelerator: "CommandOrControl+F", - id: "deviceSearch", + label: 'Search for Devices', + accelerator: 'CommandOrControl+F', + id: 'deviceSearch', enabled: true, - click: function(menuItem, window, event){ - mainWindow.webContents.send("doSearch"); - } + click: function (menuItem, window, event) { + mainWindow.webContents.send('doSearch'); + }, }, { - type: "separator" + type: 'separator', }, { - label: "Pinned", - type: "checkbox", + label: 'Pinned', + type: 'checkbox', checked: true, - accelerator: "CommandOrControl+P", - id: "devicePin", + accelerator: 'CommandOrControl+P', + id: 'devicePin', enabled: false, - click: function(menuItem, window, event){ - mainWindow.webContents.send("setActiveDevicePinned", menuItem.checked); - } + click: function (menuItem, window, event) { + mainWindow.webContents.send( + 'setActiveDevicePinned', + menuItem.checked + ); + }, }, { - label: "Delete", - accelerator: "CommandOrControl+Backspace", - id: "deviceDelete", + label: 'Delete', + accelerator: 'CommandOrControl+Backspace', + id: 'deviceDelete', enabled: false, - click: function(menuItem, window, event){ - mainWindow.webContents.send("doDelete"); - } - } - ] - } -] + click: function (menuItem, window, event) { + mainWindow.webContents.send('doDelete'); + }, + }, + ], + }, +]; diff --git a/plugins/eos/eos.css b/plugins/eos/eos.css index 0cf4477..c9a5c93 100644 --- a/plugins/eos/eos.css +++ b/plugins/eos/eos.css @@ -1,69 +1,68 @@ -table{ - background-color: #141414; - border: #404040 1px solid; - border-radius: 4px; - color: #a59baa; +table { + background-color: #141414; + border: #404040 1px solid; + border-radius: 4px; + color: #a59baa; } -th{ - font-size: 14px; - font-weight: normal; - padding: 5px; +th { + font-size: 14px; + font-weight: normal; + padding: 5px; } -td{ - text-align: center; - padding: 6px; +td { + text-align: center; + padding: 6px; } -td:first-child{ - text-align: left; +td:first-child { + text-align: left; } -td.black{ - background-color: black; - border-right: #212021 1px solid; +td.black { + background-color: black; + border-right: #212021 1px solid; } -td.num{ - color: white; - font-weight: 600; - font-size: 16px; +td.num { + color: white; + font-weight: 600; + font-size: 16px; } -.scene{ - background-color: black; - border-top: #141414 2px solid; - border-bottom: #141414 2px solid; +.scene { + background-color: black; + border-top: #141414 2px solid; + border-bottom: #141414 2px solid; } -.scene hr{ - border: #001f10 4px solid; +.scene hr { + border: #001f10 4px solid; } -.scene span{ - display: table; - margin: 0px auto; - margin-top: -25px; - padding: 4px; - background-color: black; - font-weight: bold; - font-size: 14px; +.scene span { + display: table; + margin: 0px auto; + margin-top: -25px; + padding: 4px; + background-color: black; + font-weight: bold; + font-size: 14px; } -.time{ - border: #2f2b35 2px solid; - border-radius: 5px; +.time { + border: #2f2b35 2px solid; + border-radius: 5px; } -tr.active-cue{ - color: #d49800; +tr.active-cue { + color: #d49800; +} +tr.active-cue td.num { + color: #d49800; +} +tr.active-cue .time { + border-color: #d49800; } - tr.active-cue td.num{ - color: #d49800; - } - tr.active-cue .time{ - border-color: #d49800; - } - @media screen and (min-width: 0px) and (max-width: 750px) { - .hide-medium{ - display: none; - } + .hide-medium { + display: none; + } } @media screen and (min-width: 0px) and (max-width: 550px) { - .hide-small{ - display: none; - } -} \ No newline at end of file + .hide-small { + display: none; + } +} diff --git a/plugins/eos/eos.js b/plugins/eos/eos.js index 811a1fb..7113754 100644 --- a/plugins/eos/eos.js +++ b/plugins/eos/eos.js @@ -1,115 +1,144 @@ -exports.defaultName = "ETC Eos"; -exports.connectionType = "osc"; +exports.defaultName = 'ETC Eos'; +exports.connectionType = 'osc'; exports.searchOptions = { - type: "TCPport", - searchBuffer: Buffer.from("\xc0/eos/ping\x00\x00\x2c\x00\x00\x00\xc0", 'ascii'), - testPort: 3032, - validateResponse: function(msg, info){ - return (msg.toString().indexOf("/eos/out")); - } -} + type: 'TCPport', + searchBuffer: Buffer.from( + '\xc0/eos/ping\x00\x00\x2c\x00\x00\x00\xc0', + 'ascii' + ), + testPort: 3032, + validateResponse: function (msg, info) { + return msg.toString().indexOf('/eos/out'); + }, +}; exports.defaultPort = 3032; //"\xc0/eos/ping\x00\x00\x2c\x00\x00\x00\xc0" +exports.ready = function (device) { + device.send('/eos/get/cuelist/count'); + device.send('/eos/get/version'); + device.send('/eos/subscribe', [{ type: 'i', value: 1 }]); +}; -exports.ready = function(device){ - device.send("/eos/get/cuelist/count"); - device.send("/eos/get/version"); - device.send("/eos/subscribe", [{type: "i", value: 1}]); -} +exports.data = function (device, osc) { + var address = osc.address; + var p = osc.address.split('/'); + p.shift(); -exports.data = function(device, osc){ - var address = osc.address; - var p = osc.address.split("/"); - p.shift(); + if (p[1] == 'out' && p[2] == 'show' && p[3] == 'name') { + device.data.showName = osc.args[0]; + device.data.cuelists = {}; + this.deviceInfoUpdate(device, 'defaultName', osc.args[0]); + } else if (osc.address == '/eos/out/get/cuelist/count') { + for (var i = 0; i < osc.args[0]; i++) { + device.send('/eos/get/cuelist/index/' + i); + } + } else if ( + p[1] == 'out' && + p[2] == 'get' && + p[3] == 'cuelist' && + p[5] == 'list' + ) { + device.data.cuelists[p[4]] = {}; + device.send('/eos/get/cue/' + p[4] + '/count'); + } else if ( + p[1] == 'out' && + p[2] == 'get' && + p[3] == 'cue' && + p[5] == 'count' + ) { + for (var i = 0; i < osc.args[0]; i++) { + device.send('/eos/get/cue/' + p[4] + '/index/' + i); + } + } else if ( + p[1] == 'out' && + p[2] == 'get' && + p[3] == 'cue' && + p[7] == 'list' + ) { + this.deviceInfoUpdate(device, 'status', 'ok'); + if (device.data.cuelists[p[4]][p[5]] == undefined) { + device.data.cuelists[p[4]][p[5]] = {}; + } + device.data.cuelists[p[4]][p[5]][p[6]] = { + uid: osc.args[1], + label: osc.args[2], + uptimeduration: osc.args[3], + uptimedelay: osc.args[4], + downtimeduration: osc.args[5], + downtimedelay: osc.args[6], + focustimeduration: osc.args[7], + focustimedelay: osc.args[8], + colortimeduration: osc.args[9], + colortimedelay: osc.args[10], + beamtimeduration: osc.args[11], + beamtimedelay: osc.args[12], + mark: osc.args[16], + block: osc.args[17], + assert: osc.args[18], + follow: osc.args[20], + hang: osc.args[21], + partcount: osc.args[26], + scene: osc.args[28], + duration: Math.max( + osc.args[3], + osc.args[5], + osc.args[7], + osc.args[9], + osc.args[11] + ), + }; - if(p[1]=="out" && p[2]=="show" && p[3]=="name"){ - device.data.showName = osc.args[0]; - device.data.cuelists = {}; - this.deviceInfoUpdate(device, "defaultName", osc.args[0]); - }else if(osc.address=="/eos/out/get/cuelist/count"){ - for(var i=0; i -

<%= listName %>

-

<%= data.model %>

+

<%= listName %>

+

<%= data.model %>

- - - - - - - - - - - - - - - <% for(var i=0; i<32; i++){ %> - <% if(data.channelNames[i]=="end"){break;} %> - - - - - - - - <% } %> - + + + + + + + + + + + + + + + <% for(var i=0; i<32; i++){ %> <% if(data.channelNames[i]=="end"){break;} %> + + + + + + + + <% } %>
ChannelMutedBFader
LR
MAIN OUT
M
<%- formatAsDB(data.stereoFaderDB) %>
<%= i+1 %>
<%- data.channelNames[i] || i+1 %>
M
<%- formatAsDB(data.channelFadersDB[i]) %>
ChannelMutedBFader
LR
MAIN OUT
M
<%- formatAsDB(data.stereoFaderDB) %> + +
<%= i+1 %> +
+ <%- data.channelNames[i] || i+1 %> +
+
M
<%- formatAsDB(data.channelFadersDB[i]) %> + +
- - -<% -function formatAsDB(val){ - if(val==-90){ - return "-∞"; - } - if(val>0){ - return "+"+val.toFixed(1); - } - return val.toFixed(1); -} - -%> \ No newline at end of file +<% function formatAsDB(val){ if(val==-90){ return "-∞"; } if(val>0){ +return "+"+val.toFixed(1); } return val.toFixed(1); } %> diff --git a/plugins/x32/x32.js b/plugins/x32/x32.js index e63c418..22f5ab6 100644 --- a/plugins/x32/x32.js +++ b/plugins/x32/x32.js @@ -1,129 +1,132 @@ -exports.defaultName = "X32 Mixer"; -exports.connectionType = "UDPsocket"; +exports.defaultName = 'X32 Mixer'; +exports.connectionType = 'UDPsocket'; exports.heartbeatInterval = 10000; exports.searchOptions = { - type: "UDPsocket", - searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]), - devicePort: 10023, - listenPort: 0, - validateResponse: function(msg, info){ - return (msg.toString().indexOf("/xinfo")==0); - } -} + type: 'UDPsocket', + searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]), + devicePort: 10023, + listenPort: 0, + validateResponse: function (msg, info) { + return msg.toString().indexOf('/xinfo') == 0; + }, +}; exports.defaultPort = 10023; -exports.ready = function(device){ +exports.ready = function (device) { + device.data.channelFaders = new Array(32).fill(0); + device.data.channelFadersDB = new Array(32).fill(0); + device.data.channelMutes = new Array(32).fill(0); + device.data.channelNames = new Array(32).fill('end'); + device.data.channelColors = new Array(32); - device.data.channelFaders = new Array(32).fill(0); - device.data.channelFadersDB = new Array(32).fill(0); - device.data.channelMutes = new Array(32).fill(0); - device.data.channelNames = new Array(32).fill("end"); - device.data.channelColors = new Array(32); + device.data.stereoFader = 0; + device.data.stereoFaderDB = 0; + device.data.stereoMute = 0; - device.data.stereoFader = 0; - device.data.stereoFaderDB = 0; - device.data.stereoMute = 0; + device.send(Buffer.from('/xinfo')); - device.send(Buffer.from("/xinfo")); + //device.send(Buffer.from("\x2f\x62\x61\x74\x63\x68\x73\x75\x62\x73\x63\x72\x69\x62\x65\x00\x2c\x73\x73\x69\x69\x69\x00\x00\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x2f\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); + //device.send(Buffer.from("/batchsubscribe\x00,ssiii\x00\x00meters/0\x00\x00\x00\x00/meters/0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); + //device.send(Buffer.from("/subscribe\x00,si\x00/-stat/solosw/01\x001")); +}; - //device.send(Buffer.from("\x2f\x62\x61\x74\x63\x68\x73\x75\x62\x73\x63\x72\x69\x62\x65\x00\x2c\x73\x73\x69\x69\x69\x00\x00\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x2f\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); - //device.send(Buffer.from("/batchsubscribe\x00,ssiii\x00\x00meters/0\x00\x00\x00\x00/meters/0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); +exports.data = function (device, buf) { + this.deviceInfoUpdate(device, 'status', 'ok'); + var msg = buf.toString().split('\u0000\u0000'); - //device.send(Buffer.from("/subscribe\x00,si\x00/-stat/solosw/01\x001")); + if (msg[0] == '/xinfo') { + this.deviceInfoUpdate(device, 'defaultName', msg[4]); + device.data.name = msg[4]; + device.data.ip = msg[2]; + device.data.firmware = msg[7]; + device.data.model = msg[5]; + device.send(Buffer.from('/lr/mix/fader\u0000\u0000\u0000\u0000')); + device.send(Buffer.from('/lr/mix/on\u0000\u0000\u0000\u0000')); + + for (var i = 0; i <= 32; i++) { + device.send( + Buffer.from( + '/ch/' + + i.toString().padStart(2, '0') + + '/config/name\u0000\u0000\u0000\u0000' + ) + ); + } + device.draw(); + } else if (msg[0] == '/meters/0') { + //console.log(msg) + } else if (msg[0].indexOf('/mix/fader') >= 0) { + var addr = parseAddress(msg[0]); + var channel = Number(addr[1]); + + if (addr[0] == 'ch') { + device.data.channelFaders[channel - 1] = buf.readFloatBE(24); + device.data.channelFadersDB[channel - 1] = convertToDBTheBehringerWay( + buf.readFloatBE(24) + ); + } else if (addr[0] == 'lr') { + device.data.stereoFader = buf.readFloatBE(20); + device.data.stereoFaderDB = convertToDBTheBehringerWay( + buf.readFloatBE(20) + ); + } + + device.draw(); + } else if (msg[0].indexOf('/mix/on') >= 0) { + var addr = parseAddress(msg[0]); + var channel = Number(addr[1]); + + if (addr[0] == 'ch') { + device.data.channelMutes[channel - 1] = buf[23]; + } else if (addr[0] == 'lr') { + device.data.stereoMute = buf[19]; + } + device.draw(); + device.send( + Buffer.from('/ch/' + addr[1] + '/mix/fader\u0000\u0000\u0000\u0000') + ); + } else if (msg[0].indexOf('/config/name') > 0) { + var addr = parseAddress(msg[0]); + var channel = Number(addr[1]); + device.data.channelNames[channel - 1] = msg[2]; + device.draw(); + device.send( + Buffer.from('/ch/' + addr[1] + '/config/color\u0000\u0000\u0000\u0000') + ); + } else if (msg[0].indexOf('/config/color') > 0) { + var addr = parseAddress(msg[0]); + var channel = Number(addr[1]); + device.data.channelColors[channel - 1] = buf.readInt8(27); + device.draw(); + device.send( + Buffer.from('/ch/' + addr[1] + '/mix/on\u0000\u0000\u0000\u0000') + ); + } else { + //console.log(msg) + } + //console.log(msg) +}; + +exports.heartbeat = function (device) { + device.send(Buffer.from('/xremote')); +}; + +function parseAddress(msg) { + var addr = msg.split('/'); + addr.shift(); + return addr; } -exports.data = function(device, buf){ - this.deviceInfoUpdate(device, "status", "ok"); - var msg = buf.toString().split('\u0000\u0000') - - if(msg[0]=="/xinfo"){ - this.deviceInfoUpdate(device, "defaultName", msg[4]); - device.data.name = msg[4]; - device.data.ip = msg[2]; - device.data.firmware = msg[7]; - device.data.model = msg[5]; - - - device.send(Buffer.from("/lr/mix/fader\u0000\u0000\u0000\u0000")); - device.send(Buffer.from("/lr/mix/on\u0000\u0000\u0000\u0000")); - - for(var i=0; i<=32; i++){ - device.send(Buffer.from("/ch/"+i.toString().padStart(2, "0")+"/config/name\u0000\u0000\u0000\u0000")); - } - device.draw(); - - - }else if(msg[0]=="/meters/0"){ - //console.log(msg) - }else if(msg[0].indexOf("/mix/fader")>=0){ - var addr = parseAddress(msg[0]); - var channel = Number(addr[1]); - - if(addr[0]=="ch"){ - device.data.channelFaders[channel-1] = buf.readFloatBE(24); - device.data.channelFadersDB[channel-1] = convertToDBTheBehringerWay(buf.readFloatBE(24)); - }else if(addr[0]=="lr"){ - device.data.stereoFader = buf.readFloatBE(20); - device.data.stereoFaderDB = convertToDBTheBehringerWay(buf.readFloatBE(20)); - } - - device.draw(); - - }else if(msg[0].indexOf("/mix/on")>=0){ - var addr = parseAddress(msg[0]); - var channel = Number(addr[1]); - - if(addr[0]=="ch"){ - device.data.channelMutes[channel-1] = buf[23]; - }else if(addr[0]=="lr"){ - device.data.stereoMute = buf[19]; - } - device.draw(); - device.send(Buffer.from("/ch/"+addr[1]+"/mix/fader\u0000\u0000\u0000\u0000")); - - }else if(msg[0].indexOf("/config/name")>0){ - var addr = parseAddress(msg[0]); - var channel = Number(addr[1]); - device.data.channelNames[channel-1] = msg[2]; - device.draw(); - device.send(Buffer.from("/ch/"+addr[1]+"/config/color\u0000\u0000\u0000\u0000")); - - }else if(msg[0].indexOf("/config/color")>0){ - var addr = parseAddress(msg[0]); - var channel = Number(addr[1]); - device.data.channelColors[channel-1] = buf.readInt8(27); - device.draw(); - device.send(Buffer.from("/ch/"+addr[1]+"/mix/on\u0000\u0000\u0000\u0000")); - - }else{ - //console.log(msg) - } - //console.log(msg) - +function convertToDBTheBehringerWay(f) { + if (f >= 0.5) { + return f * 40 - 30; + } else if (f >= 0.25) { + return f * 80 - 50; + } else if (f >= 0.0625) { + return f * 160 - 70; + } else { + return f * 480 - 90; + } } - -exports.heartbeat = function(device){ - device.send(Buffer.from("/xremote")); -} - - -function parseAddress(msg){ - var addr = msg.split("/"); - addr.shift(); - return addr; -} - -function convertToDBTheBehringerWay(f){ - if(f>=0.5){ - return f*40-30; - }else if(f>=0.25){ - return f*80-50; - }else if(f>=0.0625){ - return f*160-70; - }else{ - return f*480-90; - } -} - diff --git a/plugins/xair/xair.css b/plugins/xair/xair.css index 74b590b..1f25d39 100644 --- a/plugins/xair/xair.css +++ b/plugins/xair/xair.css @@ -1,102 +1,119 @@ -td{ - padding: 3px 16px !important; +td { + padding: 3px 16px !important; } -tr td:first-child{ - text-align: center; +tr td:first-child { + text-align: center; } -.mute-0, .mute-1{ - width: 30px; - padding: 4px; - font-size: 14px; - border: black 2px solid; - text-align: center; - border-radius: 10px; +.mute-0, +.mute-1 { + width: 30px; + padding: 4px; + font-size: 14px; + border: black 2px solid; + text-align: center; + border-radius: 10px; } -.mute-1{ - border-color: gray; - color: gray; +.mute-1 { + border-color: gray; + color: gray; } -.mute-0{ - border-color: #fc3344; - color: #fc3344; +.mute-0 { + border-color: #fc3344; + color: #fc3344; } -.white{ - color: white; +.white { + color: white; } -.color{ - padding: 1px 6px; - border-radius: 10px; - color: black; - text-align: center; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; +.color { + padding: 1px 6px; + border-radius: 10px; + color: black; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } -.color-0{ /*Black*/ - background-color: #212121; - color: white; +.color-0 { + /*Black*/ + background-color: #212121; + color: white; } -.color-1{ /*Red*/ - background-color: #fc545b; +.color-1 { + /*Red*/ + background-color: #fc545b; } -.color-2{ /*Green*/ - background-color: #65b84d; +.color-2 { + /*Green*/ + background-color: #65b84d; } -.color-3{ /*Yellow*/ - background-color: #fec52e; +.color-3 { + /*Yellow*/ + background-color: #fec52e; } -.color-4{ /*Blue*/ - background-color: #157efb; +.color-4 { + /*Blue*/ + background-color: #157efb; } -.color-5{ /*Purple*/ - background-color: #a453a5; +.color-5 { + /*Purple*/ + background-color: #a453a5; } -.color-6{ /*Teal*/ - background-color: #00dae3; +.color-6 { + /*Teal*/ + background-color: #00dae3; } -.color-7{ /*White*/ - background-color: #e0e0e0; +.color-7 { + /*White*/ + background-color: #e0e0e0; } -.color-8{ /*Gray*/ - background-color: #8c8c8c; +.color-8 { + /*Gray*/ + background-color: #8c8c8c; } -.color-9{ /*Red*/ - color: #fc545b; - border: #fc545b 1px solid; +.color-9 { + /*Red*/ + color: #fc545b; + border: #fc545b 1px solid; } -.color-10{ /*Green*/ - color: #65b84d; - border: #65b84d 1px solid; +.color-10 { + /*Green*/ + color: #65b84d; + border: #65b84d 1px solid; } -.color-11{ /*Yellow*/ - color: #fec52e; - border: #fec52e 1px solid; +.color-11 { + /*Yellow*/ + color: #fec52e; + border: #fec52e 1px solid; } -.color-12{ /*Blue*/ - color: #157efb; - border: #157efb 1px solid; +.color-12 { + /*Blue*/ + color: #157efb; + border: #157efb 1px solid; } -.color-13{ /*Purple*/ - color: #a453a5; - border: #a453a5 1px solid; +.color-13 { + /*Purple*/ + color: #a453a5; + border: #a453a5 1px solid; } -.color-14{ /*Teal*/ - color: #00dae3; - border: #00dae3 1px solid; +.color-14 { + /*Teal*/ + color: #00dae3; + border: #00dae3 1px solid; } -.color-15{ /*White*/ - color: #e0e0e0; - border: #e0e0e0 1px solid; +.color-15 { + /*White*/ + color: #e0e0e0; + border: #e0e0e0 1px solid; } -input[type=range] { +input[type='range'] { -webkit-appearance: none; margin: 0px; width: 100%; } -input[type=range]::-webkit-slider-thumb { +input[type='range']::-webkit-slider-thumb { -webkit-appearance: none; margin-top: -9px; height: 26px; @@ -104,9 +121,9 @@ input[type=range]::-webkit-slider-thumb { border-radius: 4px; background: #929292; } -input[type=range]::-webkit-slider-runnable-track { +input[type='range']::-webkit-slider-runnable-track { width: 100%; height: 8px; background: #3b3b3b; border-radius: 4px; -} \ No newline at end of file +} diff --git a/plugins/xair/xair.html b/plugins/xair/xair.html index a534112..c0f95c1 100644 --- a/plugins/xair/xair.html +++ b/plugins/xair/xair.html @@ -1,47 +1,51 @@
-

<%= listName %>

-

<%= data.model %>

+

<%= listName %>

+

<%= data.model %>

- - - - - - - - - - - - - - - <% for(var i=0; i<32; i++){ %> - <% if(data.channelNames[i]=="end"){break;} %> - - - - - - - - <% } %> - + + + + + + + + + + + + + + + <% for(var i=0; i<32; i++){ %> <% if(data.channelNames[i]=="end"){break;} %> + + + + + + + + <% } %>
ChannelMutedBFader
LR
MAIN OUT
M
<%- formatAsDB(data.stereoFaderDB) %>
<%= i+1 %>
<%- data.channelNames[i] || i+1 %>
M
<%- formatAsDB(data.channelFadersDB[i]) %>
ChannelMutedBFader
LR
MAIN OUT
M
<%- formatAsDB(data.stereoFaderDB) %> + +
<%= i+1 %> +
+ <%- data.channelNames[i] || i+1 %> +
+
M
<%- formatAsDB(data.channelFadersDB[i]) %> + +
- - -<% -function formatAsDB(val){ - if(val==-90){ - return "-∞"; - } - if(val>0){ - return "+"+val.toFixed(1); - } - return val.toFixed(1); -} - -%> \ No newline at end of file +<% function formatAsDB(val){ if(val==-90){ return "-∞"; } if(val>0){ +return "+"+val.toFixed(1); } return val.toFixed(1); } %> diff --git a/plugins/xair/xair.js b/plugins/xair/xair.js index 51a7a91..d288dbb 100644 --- a/plugins/xair/xair.js +++ b/plugins/xair/xair.js @@ -1,135 +1,137 @@ -exports.defaultName = "X Air Mixer"; -exports.connectionType = "UDPsocket"; +exports.defaultName = 'X Air Mixer'; +exports.connectionType = 'UDPsocket'; exports.heartbeatInterval = 10000; exports.searchOptions = { - type: "UDPsocket", - searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]), - devicePort: 10024, - listenPort: 0, - validateResponse: function(msg, info){ - return (msg.toString().indexOf("/xinfo")==0); - } -} + type: 'UDPsocket', + searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]), + devicePort: 10024, + listenPort: 0, + validateResponse: function (msg, info) { + return msg.toString().indexOf('/xinfo') == 0; + }, +}; exports.defaultPort = 10024; -exports.ready = function(device){ +exports.ready = function (device) { + device.data.channelFaders = new Array(32).fill(0); + device.data.channelFadersDB = new Array(32).fill(0); + device.data.channelMutes = new Array(32).fill(0); + device.data.channelNames = new Array(32).fill('end'); + device.data.channelColors = new Array(32); - device.data.channelFaders = new Array(32).fill(0); - device.data.channelFadersDB = new Array(32).fill(0); - device.data.channelMutes = new Array(32).fill(0); - device.data.channelNames = new Array(32).fill("end"); - device.data.channelColors = new Array(32); + device.data.stereoFader = 0; + device.data.stereoFaderDB = 0; + device.data.stereoMute = 0; - device.data.stereoFader = 0; - device.data.stereoFaderDB = 0; - device.data.stereoMute = 0; + device.send(Buffer.from('/xinfo')); - device.send(Buffer.from("/xinfo")); + //device.send(Buffer.from("\x2f\x62\x61\x74\x63\x68\x73\x75\x62\x73\x63\x72\x69\x62\x65\x00\x2c\x73\x73\x69\x69\x69\x00\x00\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x2f\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); + //device.send(Buffer.from("/batchsubscribe\x00,ssiii\x00\x00meters/0\x00\x00\x00\x00/meters/0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); + //device.send(Buffer.from("/subscribe\x00,si\x00/-stat/solosw/01\x001")); +}; - //device.send(Buffer.from("\x2f\x62\x61\x74\x63\x68\x73\x75\x62\x73\x63\x72\x69\x62\x65\x00\x2c\x73\x73\x69\x69\x69\x00\x00\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x2f\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); - //device.send(Buffer.from("/batchsubscribe\x00,ssiii\x00\x00meters/0\x00\x00\x00\x00/meters/0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); +exports.data = function (device, buf) { + this.deviceInfoUpdate(device, 'status', 'ok'); + var msg = buf.toString().split('\u0000'); - //device.send(Buffer.from("/subscribe\x00,si\x00/-stat/solosw/01\x001")); + if (msg[0] == '/xinfo') { + if (msg[7].length > 0) { + device.data.name = msg[7]; + } else { + device.data.name = msg[6]; + } + device.data.ip = msg[5]; + device.data.firmware = msg[13]; + device.data.model = msg[9]; + this.deviceInfoUpdate(device, 'defaultName', device.data.name); + + device.send(Buffer.from('/lr/mix/fader\u0000\u0000\u0000\u0000')); + device.send(Buffer.from('/lr/mix/on\u0000\u0000\u0000\u0000')); + + for (var i = 0; i <= 32; i++) { + device.send( + Buffer.from( + '/ch/' + + i.toString().padStart(2, '0') + + '/config/name\u0000\u0000\u0000\u0000' + ) + ); + } + device.draw(); + } else if (msg[0] == '/meters/0') { + //console.log(msg) + } else if (msg[0].indexOf('/mix/fader') >= 0) { + var addr = parseAddress(msg[0]); + var channel = Number(addr[1]); + + if (addr[0] == 'ch') { + device.data.channelFaders[channel - 1] = buf.readFloatBE(24); + device.data.channelFadersDB[channel - 1] = convertToDBTheBehringerWay( + buf.readFloatBE(24) + ); + } else if (addr[0] == 'lr') { + device.data.stereoFader = buf.readFloatBE(20); + device.data.stereoFaderDB = convertToDBTheBehringerWay( + buf.readFloatBE(20) + ); + } + + device.draw(); + } else if (msg[0].indexOf('/mix/on') >= 0) { + var addr = parseAddress(msg[0]); + var channel = Number(addr[1]); + + if (addr[0] == 'ch') { + device.data.channelMutes[channel - 1] = buf[23]; + } else if (addr[0] == 'lr') { + device.data.stereoMute = buf[19]; + } + device.draw(); + device.send( + Buffer.from('/ch/' + addr[1] + '/mix/fader\u0000\u0000\u0000\u0000') + ); + } else if (msg[0].indexOf('/config/name') > 0) { + var addr = parseAddress(msg[0]); + var channel = Number(addr[1]); + device.data.channelNames[channel - 1] = msg[4]; + device.draw(); + device.send( + Buffer.from('/ch/' + addr[1] + '/config/color\u0000\u0000\u0000\u0000') + ); + } else if (msg[0].indexOf('/config/color') > 0) { + var addr = parseAddress(msg[0]); + var channel = Number(addr[1]); + device.data.channelColors[channel - 1] = buf.readInt8(27); + device.draw(); + device.send( + Buffer.from('/ch/' + addr[1] + '/mix/on\u0000\u0000\u0000\u0000') + ); + } else { + //console.log(msg) + } + //console.log(msg) +}; + +exports.heartbeat = function (device) { + device.send(Buffer.from('/xremote')); +}; + +function parseAddress(msg) { + var addr = msg.split('/'); + addr.shift(); + return addr; } -exports.data = function(device, buf){ - this.deviceInfoUpdate(device, "status", "ok"); - var msg = buf.toString().split('\u0000') - - if(msg[0]=="/xinfo"){ - - if(msg[7].length>0){ - device.data.name = msg[7]; - }else{ - device.data.name = msg[6]; - } - - device.data.ip = msg[5]; - device.data.firmware = msg[13]; - device.data.model = msg[9]; - this.deviceInfoUpdate(device, "defaultName", device.data.name); - - - device.send(Buffer.from("/lr/mix/fader\u0000\u0000\u0000\u0000")); - device.send(Buffer.from("/lr/mix/on\u0000\u0000\u0000\u0000")); - - for(var i=0; i<=32; i++){ - device.send(Buffer.from("/ch/"+i.toString().padStart(2, "0")+"/config/name\u0000\u0000\u0000\u0000")); - } - device.draw(); - - - }else if(msg[0]=="/meters/0"){ - //console.log(msg) - }else if(msg[0].indexOf("/mix/fader")>=0){ - var addr = parseAddress(msg[0]); - var channel = Number(addr[1]); - - if(addr[0]=="ch"){ - device.data.channelFaders[channel-1] = buf.readFloatBE(24); - device.data.channelFadersDB[channel-1] = convertToDBTheBehringerWay(buf.readFloatBE(24)); - }else if(addr[0]=="lr"){ - device.data.stereoFader = buf.readFloatBE(20); - device.data.stereoFaderDB = convertToDBTheBehringerWay(buf.readFloatBE(20)); - } - - device.draw(); - - }else if(msg[0].indexOf("/mix/on")>=0){ - var addr = parseAddress(msg[0]); - var channel = Number(addr[1]); - - if(addr[0]=="ch"){ - device.data.channelMutes[channel-1] = buf[23]; - }else if(addr[0]=="lr"){ - device.data.stereoMute = buf[19]; - } - device.draw(); - device.send(Buffer.from("/ch/"+addr[1]+"/mix/fader\u0000\u0000\u0000\u0000")); - - }else if(msg[0].indexOf("/config/name")>0){ - var addr = parseAddress(msg[0]); - var channel = Number(addr[1]); - device.data.channelNames[channel-1] = msg[4]; - device.draw(); - device.send(Buffer.from("/ch/"+addr[1]+"/config/color\u0000\u0000\u0000\u0000")); - - }else if(msg[0].indexOf("/config/color")>0){ - var addr = parseAddress(msg[0]); - var channel = Number(addr[1]); - device.data.channelColors[channel-1] = buf.readInt8(27); - device.draw(); - device.send(Buffer.from("/ch/"+addr[1]+"/mix/on\u0000\u0000\u0000\u0000")); - - }else{ - //console.log(msg) - } - //console.log(msg) - +function convertToDBTheBehringerWay(f) { + if (f >= 0.5) { + return f * 40 - 30; + } else if (f >= 0.25) { + return f * 80 - 50; + } else if (f >= 0.0625) { + return f * 160 - 70; + } else { + return f * 480 - 90; + } } - -exports.heartbeat = function(device){ - device.send(Buffer.from("/xremote")); -} - - -function parseAddress(msg){ - var addr = msg.split("/"); - addr.shift(); - return addr; -} - -function convertToDBTheBehringerWay(f){ - if(f>=0.5){ - return f*40-30; - }else if(f>=0.25){ - return f*80-50; - }else if(f>=0.0625){ - return f*160-70; - }else{ - return f*480-90; - } -} - diff --git a/preload.js b/preload.js index 26075e0..57948ef 100644 --- a/preload.js +++ b/preload.js @@ -1,215 +1,183 @@ - const { remote } = require('electron'); const { ipcRenderer } = require('electron'); //let currWindow = remote.BrowserWindow.getFocusedWindow(); const { v4: uuid } = require('uuid'); let ejs = require('ejs'); -let net = require("net"); +let net = require('net'); - - -let DEVICE = require("./src/device.js"); -let PLUGINS = require("./src/plugins.js"); -let SEARCH = require("./src/search.js"); -let VIEW = require("./src/view.js"); -let SAVESLOTS = require("./src/saveSlots.js"); +let DEVICE = require('./src/device.js'); +let PLUGINS = require('./src/plugins.js'); +let SEARCH = require('./src/search.js'); +let VIEW = require('./src/view.js'); +let SAVESLOTS = require('./src/saveSlots.js'); window.addDevice = DEVICE.addDevice; +window.init = function () { + console.log('init!'); + ipcRenderer.send('enableDeviceDropdown'); + ipcRenderer.send('enableSearchAll'); -window.init = function(){ - - console.log("init!") - - ipcRenderer.send("enableDeviceDropdown"); - ipcRenderer.send("enableSearchAll"); - - PLUGINS.init(function(){ + PLUGINS.init(function () { VIEW.init(); SAVESLOTS.loadDevices(); SAVESLOTS.loadSlot(1); }); - document.getElementById("device-settings-table").onclick = function(e){ + document.getElementById('device-settings-table').onclick = function (e) { e.stopPropagation(); - } - document.getElementById("device-settings-name").onchange = function(e){ + }; + document.getElementById('device-settings-name').onchange = function (e) { e.stopPropagation(); - DEVICE.changeActiveName(e.target.value) - } - document.getElementById("device-settings-plugin-dropdown").onchange = function(e){ + DEVICE.changeActiveName(e.target.value); + }; + document.getElementById('device-settings-plugin-dropdown').onchange = + function (e) { + e.stopPropagation(); + DEVICE.changeActiveType(e.target.value); + }; + document.getElementById('device-settings-ip').onchange = function (e) { e.stopPropagation(); - DEVICE.changeActiveType(e.target.value) - } - document.getElementById("device-settings-ip").onchange = function(e){ + DEVICE.changeActiveIP(e.target.value); + }; + document.getElementById('device-settings-port').onchange = function (e) { e.stopPropagation(); - DEVICE.changeActiveIP(e.target.value) - } - document.getElementById("device-settings-port").onchange = function(e){ + DEVICE.changeActivePort(e.target.value); + }; + document.getElementById('device-settings-pin').onchange = function (e) { e.stopPropagation(); - DEVICE.changeActivePort(e.target.value) - } - document.getElementById("device-settings-pin").onchange = function(e){ - e.stopPropagation(); - if(e.target.checked){ + if (e.target.checked) { VIEW.pinActiveDevice(); - }else{ + } else { VIEW.unpinActiveDevice(); } - } + }; - document.getElementById("save-slot-1").onclick = function(e){ - e.stopPropagation(); - SAVESLOTS.loadSlot(1); - } - document.getElementById("save-slot-2").onclick = function(e){ - e.stopPropagation(); - SAVESLOTS.loadSlot(2); - } - document.getElementById("save-slot-3").onclick = function(e){ - e.stopPropagation(); - SAVESLOTS.loadSlot(3); - } - - document.getElementById("refresh-device-button").onclick = function(e){ + document.getElementById('save-slot-1').onclick = function (e) { e.stopPropagation(); - DEVICE.refreshActive() - } + SAVESLOTS.loadSlot(1); + }; + document.getElementById('save-slot-2').onclick = function (e) { + e.stopPropagation(); + SAVESLOTS.loadSlot(2); + }; + document.getElementById('save-slot-3').onclick = function (e) { + e.stopPropagation(); + SAVESLOTS.loadSlot(3); + }; - document.getElementById("device-list").onclick = function(e){ - e.stopPropagation(); - var deviceID = e.srcElement.id; - if(e.srcElement.id != "device-list"){ - VIEW.switchDevice(deviceID); - } - } + document.getElementById('refresh-device-button').onclick = function (e) { + e.stopPropagation(); + DEVICE.refreshActive(); + }; - document.getElementById("add-device-button").onchange = function(e){ + document.getElementById('device-list').onclick = function (e) { + e.stopPropagation(); + var deviceID = e.srcElement.id; + if (e.srcElement.id != 'device-list') { + VIEW.switchDevice(deviceID); + } + }; - DEVICE.registerDevice({ + document.getElementById('add-device-button').onchange = function (e) { + DEVICE.registerDevice({ type: e.target.value, - defaultName: "New Device", + defaultName: 'New Device', port: undefined, - addresses: [] + addresses: [], }); e.target.selectedIndex = 0; SAVESLOTS.saveAll(); + }; - } - - - - document.onkeyup = function(e){ - switch(e.key){ - case "ArrowUp": + document.onkeyup = function (e) { + switch (e.key) { + case 'ArrowUp': VIEW.selectPreviousDevice(); break; - case "ArrowDown": + case 'ArrowDown': VIEW.selectNextDevice(); break; - case "Tab": - if(document.activeElement.tagName!="INPUT" && document.activeElement.tagName!="SELECT"){ - document.getElementById("device-settings-name").select(); + case 'Tab': + if ( + document.activeElement.tagName != 'INPUT' && + document.activeElement.tagName != 'SELECT' + ) { + document.getElementById('device-settings-name').select(); } break; } - } - + }; // document.getElementById("device-settings-delete").onclick = function(e){ // e.stopPropagation(); // confirm("Are you sure you want to delete device \n\""+VIEW.getActiveDevice().name+"\"?") // } + document.getElementById('device-list-col').onclick = function (e) { + try { + document + .querySelector('#device-list .active-device') + .classList.remove('active-device'); + ipcRenderer.send('disableDeviceDropdown', ''); + } catch (err) { + //console.log(err) + } + try { + document + .getElementsByClassName('active-device-outline')[0] + .classList.remove('active-device-outline'); + } catch (err) { + //console.log(err) + } - - document.getElementById("device-list-col").onclick = function(e){ - - try{ - document.querySelector("#device-list .active-device").classList.remove("active-device"); - ipcRenderer.send("disableDeviceDropdown", ""); - }catch(err){ - //console.log(err) - } - try{ - document.getElementsByClassName("active-device-outline")[0].classList.remove("active-device-outline"); - }catch(err){ - //console.log(err) - } - VIEW.switchDevice(); - } + }; +}; - - - - -} - - - - - - - - - - - -ipcRenderer.on("setActiveDevicePinned", function(event, message){ - if(!message){ +ipcRenderer.on('setActiveDevicePinned', function (event, message) { + if (!message) { VIEW.unpinActiveDevice(); - }else{ + } else { VIEW.pinActiveDevice(); } }); -ipcRenderer.on("doSearch", function(event, message){ +ipcRenderer.on('doSearch', function (event, message) { window.searchAll(); }); -ipcRenderer.on("doDelete", function(event, message){ +ipcRenderer.on('doDelete', function (event, message) { DEVICE.deleteActive(); }); -ipcRenderer.on("resetViews", function(event, message){ +ipcRenderer.on('resetViews', function (event, message) { SAVESLOTS.resetSlots(); }); -ipcRenderer.on("doSlots1", function(event, message){ +ipcRenderer.on('doSlots1', function (event, message) { SAVESLOTS.loadSlot(1); }); -ipcRenderer.on("doSlots2", function(event, message){ +ipcRenderer.on('doSlots2', function (event, message) { SAVESLOTS.loadSlot(2); }); -ipcRenderer.on("doSlots3", function(event, message){ +ipcRenderer.on('doSlots3', function (event, message) { SAVESLOTS.loadSlot(3); }); +function log(type, message) {} - - - - - -function log(type, message){ - -} - -function switchClass(element, className){ - try{ +function switchClass(element, className) { + try { document.getElementsByClassName(className)[0].classList.remove(className); - }catch(err){ + } catch (err) { //console.log(err) } element.classList.add(className); } -window.switchClass = function(element, className){ +window.switchClass = function (element, className) { switchClass(element, className); -} - - - +}; diff --git a/src/defaultPlugin.css b/src/defaultPlugin.css index 2d6d907..82d485e 100644 --- a/src/defaultPlugin.css +++ b/src/defaultPlugin.css @@ -1,88 +1,86 @@ -body{ - color: #6e6c6f; - font-family: sans-serif; - margin: 0px; - margin-top: 40px; - user-select: none; - /*overflow-x: hidden;*/ - visibility: visible !important; - max-width: 100%; - padding: 10px; - +body { + color: #6e6c6f; + font-family: sans-serif; + margin: 0px; + margin-top: 40px; + user-select: none; + /*overflow-x: hidden;*/ + visibility: visible !important; + max-width: 100%; + padding: 10px; } -header{ - position: fixed; - top: 0px; - left: 0px; - height: 36px; - width: 100%; - box-sizing:content-box; +header { + position: fixed; + top: 0px; + left: 0px; + height: 36px; + width: 100%; + box-sizing: content-box; - background-color: rgba(0, 0, 0, 0.2); - border-bottom: black 1px solid; - -webkit-app-region: drag; + background-color: rgba(0, 0, 0, 0.2); + border-bottom: black 1px solid; + -webkit-app-region: drag; } -h1, h2, h3, h4, h5, h6{ - color: white; +h1, +h2, +h3, +h4, +h5, +h6 { + color: white; } -header h1, header h2{ - margin: 8px; - margin-left: 20px; - font-weight: normal; - font-size: 18px; - float: left; +header h1, +header h2 { + margin: 8px; + margin-left: 20px; + font-weight: normal; + font-size: 18px; + float: left; } -header h2{ - color: #b6b6b6; +header h2 { + color: #b6b6b6; } - -table.cv-table{ - border: none; - table-layout: fixed; - border-collapse: collapse; - color: #dddddd; - font-size: 15px; +table.cv-table { + border: none; + table-layout: fixed; + border-collapse: collapse; + color: #dddddd; + font-size: 15px; } - table.cv-table th{ - padding: 6px 16px; - color: #969696; - text-align: left; - border-bottom: #555 1px solid; - border-bottom: #555 1px solid; - font-weight: normal; - background-color: #1e1e1e; - } - table.cv-table tr:nth-child(odd){ - background-color: #292929; - } - table.cv-table tr td:first-child{ - padding-left: 10px; - -webkit-border-top-left-radius: 10px; - -webkit-border-bottom-left-radius: 10px; - } - table.cv-table tr td:last-child{ - padding-right: 10px; - -webkit-border-top-right-radius: 10px; - -webkit-border-bottom-right-radius: 10px; - } - table.cv-table td{ - padding: 7px 16px; - } - - - - - -.not-responding{ +table.cv-table th { + padding: 6px 16px; + color: #969696; + text-align: left; + border-bottom: #555 1px solid; + border-bottom: #555 1px solid; + font-weight: normal; + background-color: #1e1e1e; } -.not-responding em{ - background-color: #3f3f3f; - color: white; - padding: 2px 10px; - display: inline-block; - border-radius: 5px; +table.cv-table tr:nth-child(odd) { + background-color: #292929; +} +table.cv-table tr td:first-child { + padding-left: 10px; + -webkit-border-top-left-radius: 10px; + -webkit-border-bottom-left-radius: 10px; +} +table.cv-table tr td:last-child { + padding-right: 10px; + -webkit-border-top-right-radius: 10px; + -webkit-border-bottom-right-radius: 10px; +} +table.cv-table td { + padding: 7px 16px; } - +.not-responding { +} +.not-responding em { + background-color: #3f3f3f; + color: white; + padding: 2px 10px; + display: inline-block; + border-radius: 5px; +} diff --git a/src/device.js b/src/device.js index a45d680..3e053aa 100644 --- a/src/device.js +++ b/src/device.js @@ -1,274 +1,266 @@ const { v4: uuid } = require('uuid'); -let osc = require("osc"); -let net = require("net"); +let osc = require('osc'); +let net = require('net'); let udp = require('dgram'); var _ = require('lodash/function'); - -let PLUGINS = require("./plugins.js"); -let VIEW = require("./view.js"); -let SAVESLOTS = require("./saveSlots.js"); - +let PLUGINS = require('./plugins.js'); +let VIEW = require('./view.js'); +let SAVESLOTS = require('./saveSlots.js'); var devices = {}; module.exports.all = devices; +registerDevice = function (newDevice) { + console.log(PLUGINS.all); -registerDevice = function(newDevice){ + if (PLUGINS.all[newDevice.type] == undefined) { + console.error('Plugin for device ' + newDevice.type + ' does not exist.'); + return true; + } - console.log(PLUGINS.all) + var initElements = document.getElementsByClassName('init'); + for (var i = 0; i < initElements.length; i++) { + initElements[i].style.display = 'none'; + } - if(PLUGINS.all[newDevice.type]==undefined){ - console.error("Plugin for device "+newDevice.type+" does not exist."); - return true; - } + // only register device if it hasn't already been added + if (newDevice.addresses.length > 0) { + for (var i in devices) { + if ( + devices[i].type == newDevice.type && + JSON.stringify(devices[i].addresses) == + JSON.stringify(newDevice.addresses) + ) { + // This device has already been added + infoUpdate(devices[i], 'status', 'ok'); + return false; + } + } + } - var initElements = document.getElementsByClassName('init'); - for(var i=0; i0){ - for(var i in devices){ - if(devices[i].type==newDevice.type && JSON.stringify(devices[i].addresses) == JSON.stringify(newDevice.addresses)){ - // This device has already been added - infoUpdate(devices[i], "status", "ok"); - return false; - } - } - } + var id = newDevice.id || uuid(); + devices[id] = { + id: id, + status: 'new', + type: newDevice.type, + displayName: newDevice.displayName, + defaultName: newDevice.defaultName, + port: newDevice.port, + addresses: newDevice.addresses, + data: {}, + pinIndex: false, + lastDrawn: 0, + lastHeartbeat: 0, + heartbeatInterval: PLUGINS.all[newDevice.type].heartbeatInterval, + draw: _.debounce( + function () { + VIEW.draw(this); + }, + 30, + { leading: true, trailing: true } + ), + }; - //console.log("Registered new "+newDevice.type) - - var id = newDevice.id || uuid(); - devices[id] = { - id: id, - status: "new", - type: newDevice.type, - displayName: newDevice.displayName, - defaultName: newDevice.defaultName, - port: newDevice.port, - addresses: newDevice.addresses, - data: {}, - pinIndex: false, - lastDrawn: 0, - lastHeartbeat: 0, - heartbeatInterval: PLUGINS.all[newDevice.type].heartbeatInterval, - draw: _.debounce(function(){ VIEW.draw(this); }, 30, { leading: true, trailing: true}) - } - - VIEW.addDeviceToList(devices[id]); - initDeviceConnection(id); - -} + VIEW.addDeviceToList(devices[id]); + initDeviceConnection(id); +}; module.exports.registerDevice = registerDevice; +initDeviceConnection = function (id) { + var device = devices[id]; -initDeviceConnection = function(id){ + infoUpdate(device, 'status', 'new'); + if (device.port == undefined || device.addresses.length == 0) { + return true; + } + try { + // mostly only useful for UDP + device.connection.close(); + } catch (err) {} - var device = devices[id]; + const type = devices[id].type; + var plugins = PLUGINS.all; - infoUpdate(device, "status", "new"); + if (plugins[type].connectionType == 'osc') { + device.connection = new osc.TCPSocketPort({ + address: device.addresses[0], + port: device.port, + }); + device.connection.open(); + device.connection.on('error', function (error) { + //console.error(error) + device.connection.close(); + }); + device.connection.on('ready', function () { + plugins[type].ready(device); + if (Object.keys(devices).length == 1) { + VIEW.switchDevice(device.id); + } + }); + device.connection.on('message', function (message) { + //log("OSC IN", message.address); + plugins[type].data(device, message); + device.lastMessage = Date.now(); + }); + device.send = function (address, args) { + device.connection.send({ address: address, args: args }); + }; + device.plugin = plugins[type]; + } else if (plugins[type].connectionType == 'TCPsocket') { + device.connection = new net.Socket(); - if(device.port==undefined || device.addresses.length==0){ - return true; - } - try{ - // mostly only useful for UDP - device.connection.close(); - }catch(err){} - - const type = devices[id].type; - var plugins = PLUGINS.all; + device.connection.connect( + { port: device.port, host: device.addresses[0] }, + function () {} + ); - if(plugins[type].connectionType == "osc"){ - device.connection = new osc.TCPSocketPort({ - address: device.addresses[0], - port: device.port - }); - device.connection.open(); - device.connection.on("error", function (error) { - //console.error(error) - device.connection.close(); - }); - device.connection.on("ready", function () { - plugins[type].ready(device); - if(Object.keys(devices).length==1){ - VIEW.switchDevice(device.id); - } - }); - device.connection.on("message", function(message){ - //log("OSC IN", message.address); - plugins[type].data(device, message); - device.lastMessage = Date.now(); - }); - device.send = function(address, args){ - device.connection.send({address: address, args: args}); - } - device.plugin = plugins[type]; + device.connection.on('error', function (error) { + //console.error(error) + }); + device.connection.on('ready', function () { + plugins[type].ready(device); + if (Object.keys(devices).length == 1) { + VIEW.switchDevice(device.id); + } + }); + device.connection.on('data', function (message) { + //log("SOCK IN", message); + plugins[type].data(device, message); + device.lastMessage = Date.now(); + infoUpdate(device, 'status', 'ok'); + }); + device.send = function (data) { + //log("SOCK OUT", data); + device.connection.write(data); + }; + } else if (plugins[type].connectionType == 'UDPsocket') { + device.connection = udp.createSocket('udp4'); - }else if(plugins[type].connectionType == "TCPsocket"){ - device.connection = new net.Socket(); + device.connection.bind(function () { + plugins[type].ready(device); - device.connection.connect({port: device.port, host: device.addresses[0]}, function() { - - }); - - device.connection.on("error", function (error) { - //console.error(error) - }); - device.connection.on("ready", function () { - plugins[type].ready(device); - if(Object.keys(devices).length==1){ - VIEW.switchDevice(device.id); - } - }); - device.connection.on("data", function(message){ - //log("SOCK IN", message); - plugins[type].data(device, message); - device.lastMessage = Date.now(); - infoUpdate(device, "status", "ok"); - }); - device.send = function(data){ - //log("SOCK OUT", data); - device.connection.write(data); - } + device.connection.on('message', function (msg, info) { + plugins[type].data(device, msg); + infoUpdate(device, 'status', 'ok'); + }); + }); - }else if(plugins[type].connectionType == "UDPsocket"){ - - device.connection = udp.createSocket('udp4'); - - device.connection.bind(function(){ - - plugins[type].ready(device); - - device.connection.on('message',function(msg,info){ - plugins[type].data(device, msg); - infoUpdate(device, "status", "ok"); - }); - }); - - device.send = function(data){ - device.connection.send(data, device.port, device.addresses[0], function(err){ - //console.log(err); - }); - } - - - } - -} + device.send = function (data) { + device.connection.send( + data, + device.port, + device.addresses[0], + function (err) { + //console.log(err); + } + ); + }; + } +}; module.exports.initDeviceConnection = initDeviceConnection; +module.exports.deleteActive = function () { + var device = VIEW.getActiveDevice(); + var choice = confirm( + 'Are you sure you want to delete ' + + device.type + + ' device "' + + (device.displayName || device.defaultName) + + '"?' + ); -module.exports.deleteActive = function(){ - var device = VIEW.getActiveDevice(); - var choice = confirm("Are you sure you want to delete "+device.type+" device \""+(device.displayName || device.defaultName)+"\"?"); + if (choice) { + VIEW.removeDeviceFromList(device); + delete devices[device.id]; + SAVESLOTS.deleteFromSlots(device); + SAVESLOTS.saveAll(); + SAVESLOTS.reloadActiveSlot(); + } +}; - if(choice){ - VIEW.removeDeviceFromList(device); - delete devices[device.id]; - SAVESLOTS.deleteFromSlots(device); - SAVESLOTS.saveAll(); - SAVESLOTS.reloadActiveSlot(); - } +module.exports.changeActiveType = function (newType) { + var device = VIEW.getActiveDevice(); + device.type = newType; -} + initDeviceConnection(device.id); + VIEW.draw(device); + //SAVESLOTS.saveAll(); +}; -module.exports.changeActiveType = function(newType){ - var device = VIEW.getActiveDevice(); - device.type = newType; +module.exports.changeActiveIP = function (newIP) { + var device = VIEW.getActiveDevice(); + device.addresses[0] = newIP; + initDeviceConnection(device.id); + VIEW.draw(device); + SAVESLOTS.saveAll(); +}; - initDeviceConnection(device.id); - VIEW.draw(device); - //SAVESLOTS.saveAll(); -} +module.exports.changeActivePort = function (newPort) { + var device = VIEW.getActiveDevice(); + device.port = newPort; -module.exports.changeActiveIP = function(newIP){ - var device = VIEW.getActiveDevice(); - device.addresses[0] = newIP; - initDeviceConnection(device.id); - VIEW.draw(device); - SAVESLOTS.saveAll(); -} + initDeviceConnection(device.id); + VIEW.draw(device); + SAVESLOTS.saveAll(); +}; -module.exports.changeActivePort = function(newPort){ - var device = VIEW.getActiveDevice(); - device.port = newPort; +module.exports.changeActiveName = function (newName) { + var device = VIEW.getActiveDevice(); + device.displayName = newName; + infoUpdate(device, 'displayName', newName); + VIEW.draw(device); + SAVESLOTS.saveAll(); +}; +module.exports.changeActivePinIndex = function (newPin) { + var device = VIEW.getActiveDevice(); + device.pinIndex = newPin; + VIEW.draw(device); + SAVESLOTS.saveAll(); +}; +module.exports.changePinIndex = function (device, newPin) { + device.pinIndex = newPin; + //SAVESLOTS.saveAll(); +}; +module.exports.refreshActive = function () { + var device = VIEW.getActiveDevice(); + if (device == undefined) { + return true; + } + initDeviceConnection(device.id); + VIEW.draw(device); +}; - initDeviceConnection(device.id); - VIEW.draw(device); - SAVESLOTS.saveAll(); -} - -module.exports.changeActiveName = function(newName){ - var device = VIEW.getActiveDevice(); - device.displayName = newName; - infoUpdate(device, "displayName", newName); - VIEW.draw(device); - SAVESLOTS.saveAll(); -} -module.exports.changeActivePinIndex = function(newPin){ - var device = VIEW.getActiveDevice(); - device.pinIndex = newPin; - VIEW.draw(device); - SAVESLOTS.saveAll(); -} -module.exports.changePinIndex = function(device, newPin){ - device.pinIndex = newPin; - //SAVESLOTS.saveAll(); -} -module.exports.refreshActive = function(){ - var device = VIEW.getActiveDevice(); - if(device==undefined){ - return true; - } - initDeviceConnection(device.id); - VIEW.draw(device); -} - - - - -infoUpdate = function(device, param, value){ - if(param=="addresses"){ - device.addresses = value.replace(/\s+/g, '').split(","); - }else{ - device[param] = value; - } - VIEW.addDeviceToList(device); -} +infoUpdate = function (device, param, value) { + if (param == 'addresses') { + device.addresses = value.replace(/\s+/g, '').split(','); + } else { + device[param] = value; + } + VIEW.addDeviceToList(device); +}; module.exports.infoUpdate = infoUpdate; - setInterval(heartbeat, 100); -function heartbeat(){ - for(var i in devices){ - var device = devices[i]; - if(Date.now()>=device.lastHeartbeat+device.heartbeatInterval){ - - if(device.status=="broken"){ - initDeviceConnection(i); - }else if(Date.now()-device.lastMessage>10000){ - infoUpdate(device, "status", "broken"); - }else{ - if(device.port!=undefined && device.addresses.length>0){ - PLUGINS.all[device.type].heartbeat(device); - }else{ - //console.error("Invalid IP/Port on device "+device.name) - } - } - device.lastHeartbeat = Date.now(); - } - - } +function heartbeat() { + for (var i in devices) { + var device = devices[i]; + if (Date.now() >= device.lastHeartbeat + device.heartbeatInterval) { + if (device.status == 'broken') { + initDeviceConnection(i); + } else if (Date.now() - device.lastMessage > 10000) { + infoUpdate(device, 'status', 'broken'); + } else { + if (device.port != undefined && device.addresses.length > 0) { + PLUGINS.all[device.type].heartbeat(device); + } else { + //console.error("Invalid IP/Port on device "+device.name) + } + } + device.lastHeartbeat = Date.now(); + } + } } - - - - - - - diff --git a/src/index.css b/src/index.css index 5670761..6b489bc 100644 --- a/src/index.css +++ b/src/index.css @@ -2,343 +2,317 @@ html { font-size: 1rem; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont; } -*, a, button { - cursor: default; - user-select: none; +*, +a, +button { + cursor: default; + user-select: none; } - - -body{ - color: #6e6c6f; - margin: 0px; - user-select: none; - overflow-x: hidden; +body { + color: #6e6c6f; + margin: 0px; + user-select: none; + overflow-x: hidden; } -a{ - text-decoration: none; +a { + text-decoration: none; } -.red{ - color: #eb6b5e; +.red { + color: #eb6b5e; } -.green{ - color: #61c650; +.green { + color: #61c650; } -.left{ - float: left; +.left { + float: left; } - -#main{ - box-sizing: border-box; - display: grid; - width: 100%; - height: 100vh; - grid-template-columns: 270px 1fr; +#main { + box-sizing: border-box; + display: grid; + width: 100%; + height: 100vh; + grid-template-columns: 270px 1fr; } -.col{ - border-right: rgba(0, 0, 0, 0.5) 1px solid; - height: 100vh !important; - overflow: hidden; - box-sizing: border-box; - position: relative; +.col { + border-right: rgba(0, 0, 0, 0.5) 1px solid; + height: 100vh !important; + overflow: hidden; + box-sizing: border-box; + position: relative; } /* FIRST COL */ -#device-list-col{ - background-color: transparent; - color: #707070; +#device-list-col { + background-color: transparent; + color: #707070; } -#view-buttons-bar{ - box-sizing: border-box; - text-align: right; - padding-left: 100px; - padding-right: 7px; - user-select: text; - -webkit-app-region: drag; - z-index: 1000; - /*border-bottom: black 1px solid;*/ - /*background: linear-gradient(#3f3f3f 0%, #343434 100%);*/ - /*background-color: #363636;*/ - /*background-color: rgba(0, 0, 0, 0.4);*/ +#view-buttons-bar { + box-sizing: border-box; + text-align: right; + padding-left: 100px; + padding-right: 7px; + user-select: text; + -webkit-app-region: drag; + z-index: 1000; + /*border-bottom: black 1px solid;*/ + /*background: linear-gradient(#3f3f3f 0%, #343434 100%);*/ + /*background-color: #363636;*/ + /*background-color: rgba(0, 0, 0, 0.4);*/ } -#view-buttons-bar button{ - background-color: rgba(255, 255, 255, 0.07); - width: 26px; - border-radius: 10px; - font-size: 0.8rem; +#view-buttons-bar button { + background-color: rgba(255, 255, 255, 0.07); + width: 26px; + border-radius: 10px; + font-size: 0.8rem; } -#view-buttons-bar button:hover{ - background-color: rgba(255, 255, 255, 0.25); +#view-buttons-bar button:hover { + background-color: rgba(255, 255, 255, 0.25); } - - - -#device-list{ - box-sizing: border-box; - width: 100%; - padding: 0px 10px; +#device-list { + box-sizing: border-box; + width: 100%; + padding: 0px 10px; } - #device-list div{ - pointer-events: none; - } - #device-list .device{ - box-sizing: border-box; - clear: both; - display: block; - width: 100%; - height: 40px; - padding: 10px 5px; - overflow: hidden; - border-radius: 5px; - } - #device-list .device.active-device{ - /*background-color: #0e5ccd;*/ - /*background-color: #c9961f;*/ - background-color: rgba(255, 255, 255, 0.2); - } - #device-list .status{ - float: left; - width: 25px; - font-size: 18px; - } - #device-list .type{ - float: left; - width: 30px; - color: #f6bd26; - } - #device-list .name{ - position: relative; - left: 0px; - color: white; - font-weight: 600; - - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - } - #device-list h3.init{ - margin: 0px auto; - padding-top: 200px; - text-align: center; - font-weight: 300; - font-size: 16px; - width: 210px; - pointer-events: none; - } - - - - -#device-tools{ - position: absolute; - bottom: 210px; - left: 0px; - width: 100%; - height: 30px; - padding-right: 10px; - /*background: linear-gradient(#2f2f2f 0%, #2c2c2c 100%);*/ - background-color: rgba(0, 0, 0, 0.2); - text-align: center; - border-top: rgba(0, 0, 0, 0.3) 1px solid; - /*border-bottom: #3a3a3a 1px solid;*/ +#device-list div { + pointer-events: none; } -#device-tools select{ - text-align: center; +#device-list .device { + box-sizing: border-box; + clear: both; + display: block; + width: 100%; + height: 40px; + padding: 10px 5px; + overflow: hidden; + border-radius: 5px; +} +#device-list .device.active-device { + /*background-color: #0e5ccd;*/ + /*background-color: #c9961f;*/ + background-color: rgba(255, 255, 255, 0.2); +} +#device-list .status { + float: left; + width: 25px; + font-size: 18px; +} +#device-list .type { + float: left; + width: 30px; + color: #f6bd26; +} +#device-list .name { + position: relative; + left: 0px; + color: white; + font-weight: 600; + + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} +#device-list h3.init { + margin: 0px auto; + padding-top: 200px; + text-align: center; + font-weight: 300; + font-size: 16px; + width: 210px; + pointer-events: none; } - - -#device-settings{ - position: absolute; - left: 0px; - bottom: 0px; - height: 200px; - padding: 5px; - color: white; - font-weight: 300; - width: 100%; - background-color: rgba(0, 0, 0, 0.2); +#device-tools { + position: absolute; + bottom: 210px; + left: 0px; + width: 100%; + height: 30px; + padding-right: 10px; + /*background: linear-gradient(#2f2f2f 0%, #2c2c2c 100%);*/ + background-color: rgba(0, 0, 0, 0.2); + text-align: center; + border-top: rgba(0, 0, 0, 0.3) 1px solid; + /*border-bottom: #3a3a3a 1px solid;*/ +} +#device-tools select { + text-align: center; } - #device-settings th{ - text-align: right; - padding-right: 3px; - color: white; - font-weight: normal; - } - #device-settings td{ - padding: 6px; - } - #device-settings-table{ - display: none; - } - #device-settings h3{ - padding-top: 20px; - text-align: center; - font-weight: 300; - } - #device-settings #device-settings-name, - #device-settings #device-settings-ip, - #device-settings #device-settings-plugin-dropdown{ - width: 170px; - } - #device-settings #device-settings-port{ - width: 70px; - } - +#device-settings { + position: absolute; + left: 0px; + bottom: 0px; + height: 200px; + padding: 5px; + color: white; + font-weight: 300; + width: 100%; + background-color: rgba(0, 0, 0, 0.2); +} +#device-settings th { + text-align: right; + padding-right: 3px; + color: white; + font-weight: normal; +} +#device-settings td { + padding: 6px; +} +#device-settings-table { + display: none; +} +#device-settings h3 { + padding-top: 20px; + text-align: center; + font-weight: 300; +} +#device-settings #device-settings-name, +#device-settings #device-settings-ip, +#device-settings #device-settings-plugin-dropdown { + width: 170px; +} +#device-settings #device-settings-port { + width: 70px; +} /* SECOND COL */ -#all-devices{ - display: grid; - grid-template-columns: repeat(4, 1fr); - background-color: rgba(0, 0, 0, 0.3); +#all-devices { + display: grid; + grid-template-columns: repeat(4, 1fr); + background-color: rgba(0, 0, 0, 0.3); } -.device-pin{ - position:absolute; - right: 15px; - top: 8px; - height: 20px; +.device-pin { + position: absolute; + right: 15px; + top: 8px; + height: 20px; } -.device-wrapper{ - box-sizing: border-box; - border-top: rgba(0, 0, 0, 0) 2px solid; - border-bottom: rgba(0, 0, 0, 0) 2px solid; +.device-wrapper { + box-sizing: border-box; + border-top: rgba(0, 0, 0, 0) 2px solid; + border-bottom: rgba(0, 0, 0, 0) 2px solid; } -.draw-area{ - height: 100%; - overflow-y: scroll; - width: 100%; - height: 100%; - border: 0; - +.draw-area { + height: 100%; + overflow-y: scroll; + width: 100%; + height: 100%; + border: 0; } -.active-device-outline{ - outline: #fdea08 2px solid; - border-top: #fdea08 2px solid; - border-bottom: #fdea08 2px solid; +.active-device-outline { + outline: #fdea08 2px solid; + border-top: #fdea08 2px solid; + border-bottom: #fdea08 2px solid; } - - - - - -input{ - display: block; - box-sizing:content-box; - background-color: rgba(0, 0, 0, 0.2); - height: 28px; - padding: 2px 6px; - margin: 0px; - border: rgba(255, 255, 255, 0.1) 1px solid; - border-radius: 4px; - color: #fff; - font-size: 16px; - font-weight: 500; +input { + display: block; + box-sizing: content-box; + background-color: rgba(0, 0, 0, 0.2); + height: 28px; + padding: 2px 6px; + margin: 0px; + border: rgba(255, 255, 255, 0.1) 1px solid; + border-radius: 4px; + color: #fff; + font-size: 16px; + font-weight: 500; } -select{ - display: block; - box-sizing:content-box; - background-color: rgba(255, 255, 255, 0.15); - height: 28px; - padding: 2px 6px; - margin: 0px; - border: rgba(255, 255, 255, 0.1) 1px solid; - border-radius: 4px; - color: #fff; - font-size: 16px; - font-weight: 500; +select { + display: block; + box-sizing: content-box; + background-color: rgba(255, 255, 255, 0.15); + height: 28px; + padding: 2px 6px; + margin: 0px; + border: rgba(255, 255, 255, 0.1) 1px solid; + border-radius: 4px; + color: #fff; + font-size: 16px; + font-weight: 500; } -input:focus, select:focus{ - outline: #fdea08 2px solid; - color: white; +input:focus, +select:focus { + outline: #fdea08 2px solid; + color: white; } -input[type='checkbox']{ - position: relative; - height: 14px; - width: 14px; - padding: 2px; - -webkit-appearance: none; +input[type='checkbox'] { + position: relative; + height: 14px; + width: 14px; + padding: 2px; + -webkit-appearance: none; } -input[type='checkbox']:checked{ - background-color: #616064; +input[type='checkbox']:checked { + background-color: #616064; } input[type='checkbox']:checked:after { - content: '\2713'; - font-size: 18px; - position: absolute; - top: -1px; - left: 1px; - color: white; + content: '\2713'; + font-size: 18px; + position: absolute; + top: -1px; + left: 1px; + color: white; } input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } -button, select.button{ - box-sizing:content-box; - width: 40px; - height: 25px; - margin-top: 7px; - margin-bottom: 7px; - margin-left: 4px; - border: none; - outline: none; - padding: 0px; +button, +select.button { + box-sizing: content-box; + width: 40px; + height: 25px; + margin-top: 7px; + margin-bottom: 7px; + margin-left: 4px; + border: none; + outline: none; + padding: 0px; - color: white; - background: rgba(255, 255, 255, 0.15); - border-radius: 4px; - font-size: 1rem; - user-select: none; + color: white; + background: rgba(255, 255, 255, 0.15); + border-radius: 4px; + font-size: 1rem; + user-select: none; } - button:hover{ - background-color: rgba(255, 255, 255, 0.2); - } - button:focus{ - outline: none; - } - button.active{ - background-color: rgba(255, 255, 255, 0.3); - color: white; - } - button:disabled{ - background: rgba(255, 255, 255, 0.03); - } - button img{ - height: 18px; - } - -select.button:focus{ - outline: none; +button:hover { + background-color: rgba(255, 255, 255, 0.2); +} +button:focus { + outline: none; +} +button.active { + background-color: rgba(255, 255, 255, 0.3); + color: white; +} +button:disabled { + background: rgba(255, 255, 255, 0.03); +} +button img { + height: 18px; } - - - - - - - - - +select.button:focus { + outline: none; +} @font-face { font-family: 'Material Icons'; font-style: normal; font-weight: 400; - src: local('img/Material Icons'), - local('img/MaterialIcons-Regular'), + src: local('img/Material Icons'), local('img/MaterialIcons-Regular'), url(img/MaterialIcons-Regular.ttf) format('truetype'); } .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; - font-size: 24px; /* Preferred icon size */ + font-size: 24px; /* Preferred icon size */ display: inline-block; line-height: 1; text-transform: none; diff --git a/src/index.js b/src/index.js index 47a78df..86763a0 100644 --- a/src/index.js +++ b/src/index.js @@ -1,23 +1,17 @@ -document.onclick = function(e){ - window.closePopovers(); -} +document.onclick = function (e) { + window.closePopovers(); +}; window.init(); +document.getElementById('search-button').onclick = function (e) { + window.searchAll(); +}; +document.getElementById('add-device-button').onclick = function (e) { + //e.stopPropagation(); + //document.getElementById("add-device-popover").style.display = "block"; +}; -document.getElementById("search-button").onclick = function(e){ - window.searchAll(); -} -document.getElementById("add-device-button").onclick = function(e){ - //e.stopPropagation(); - //document.getElementById("add-device-popover").style.display = "block"; -} - - - -window.closePopovers = function(){ - //document.getElementById("add-device-popover").style.display = "none"; -} - - - +window.closePopovers = function () { + //document.getElementById("add-device-popover").style.display = "none"; +}; diff --git a/src/plugins.js b/src/plugins.js index 425e7cf..eaf5307 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -1,38 +1,48 @@ let fs = require('fs'); -let DEVICE = require("./device.js"); -let VIEW = require("./view.js"); - +let DEVICE = require('./device.js'); +let VIEW = require('./view.js'); var allPlugins = {}; module.exports.all = allPlugins; -module.exports.init = function(callback){ +module.exports.init = function (callback) { + console.log('Loading plugin files... ' + __dirname + '/../plugins'); - console.log("Loading plugin files... "+__dirname+"/../plugins") + fs.readdir(__dirname + '/../plugins', function (err, files) { + for (var i in files) { + var plugin = files[i]; - fs.readdir(__dirname+"/../plugins", function(err, files){ - for(var i in files){ - var plugin = files[i]; + if (plugin[0] != '.') { + console.log(i + ' ' + plugin); + allPlugins[plugin] = require(__dirname + + '/../plugins/' + + plugin + + '/' + + plugin + + '.js'); + allPlugins[plugin].deviceInfoUpdate = function (device, param, value) { + DEVICE.infoUpdate(device, param, value); + }; + allPlugins[plugin].draw = function (device) { + VIEW.draw(device); + }; - if(plugin[0]!="."){ - console.log(i+" "+plugin); - allPlugins[plugin] = require(__dirname+"/../plugins/"+plugin+"/"+plugin+".js"); + allPlugins[plugin].template = ejs.compile( + fs.readFileSync( + __dirname + '/../plugins/' + plugin + '/' + plugin + '.html', + 'utf8' + ) + ); - allPlugins[plugin].deviceInfoUpdate = function(device, param, value){ - DEVICE.infoUpdate(device, param, value) - } - allPlugins[plugin].draw = function(device){ - VIEW.draw(device); - } - - allPlugins[plugin].template = ejs.compile(fs.readFileSync(__dirname+"/../plugins/"+plugin+"/"+plugin+".html", 'utf8')); - - if(allPlugins[plugin].heartbeatInterval==undefined || allPlugins[plugin].heartbeatInterval<50){ - allPlugins[plugin].heartbeatInterval = 5000; - } - } - } - callback(); - }); -} \ No newline at end of file + if ( + allPlugins[plugin].heartbeatInterval == undefined || + allPlugins[plugin].heartbeatInterval < 50 + ) { + allPlugins[plugin].heartbeatInterval = 5000; + } + } + } + callback(); + }); +}; diff --git a/src/saveSlots.js b/src/saveSlots.js index 32b0620..fe69798 100644 --- a/src/saveSlots.js +++ b/src/saveSlots.js @@ -1,118 +1,119 @@ -let VIEW = require("./view.js"); -let DEVICE = require("./device.js"); - +let VIEW = require('./view.js'); +let DEVICE = require('./device.js'); var activeSlot = false; var savedSlots = [[], [], [], []]; var savedDevices = []; -var storedSlots = localStorage.getItem('savedSlots');; -if(storedSlots){ - savedSlots = JSON.parse(storedSlots); +var storedSlots = localStorage.getItem('savedSlots'); +if (storedSlots) { + savedSlots = JSON.parse(storedSlots); } -var storedDevices = localStorage.getItem('savedDevices');; -if(storedDevices){ - savedDevices = JSON.parse(storedDevices); +var storedDevices = localStorage.getItem('savedDevices'); +if (storedDevices) { + savedDevices = JSON.parse(storedDevices); } -loadSlot = function(slotIndex){ - - VIEW.toggleSlotButtons(slotIndex); - activeSlot = slotIndex; +loadSlot = function (slotIndex) { + VIEW.toggleSlotButtons(slotIndex); + activeSlot = slotIndex; - for(var d in DEVICE.all){ - DEVICE.changePinIndex(DEVICE.all[d], false); - } - VIEW.resetPinned(); + for (var d in DEVICE.all) { + DEVICE.changePinIndex(DEVICE.all[d], false); + } + VIEW.resetPinned(); - for(var d in savedSlots[slotIndex]){ - var savedDevice = savedSlots[slotIndex][d]; - for(var d in DEVICE.all){ - var device = DEVICE.all[d]; - //if(device.addresses[0] == savedDevice.addresses[0] && device.type == savedDevice.type){ - if(device.id == savedDevice.id){ - VIEW.pinDevice(device); - VIEW.switchDevice(device.id) - }else if(device.addresses[0] == savedDevice.addresses[0] && device.type == savedDevice.type && savedDevice.addresses[0]!=undefined ){ - VIEW.pinDevice(device); - VIEW.switchDevice(device.id) - } - } - } -} + for (var d in savedSlots[slotIndex]) { + var savedDevice = savedSlots[slotIndex][d]; + for (var d in DEVICE.all) { + var device = DEVICE.all[d]; + //if(device.addresses[0] == savedDevice.addresses[0] && device.type == savedDevice.type){ + if (device.id == savedDevice.id) { + VIEW.pinDevice(device); + VIEW.switchDevice(device.id); + } else if ( + device.addresses[0] == savedDevice.addresses[0] && + device.type == savedDevice.type && + savedDevice.addresses[0] != undefined + ) { + VIEW.pinDevice(device); + VIEW.switchDevice(device.id); + } + } + } +}; module.exports.loadSlot = loadSlot; -module.exports.loadDevices = function(){ - console.log("Loading "+savedDevices.length+" saved devices...") - console.log(savedDevices) +module.exports.loadDevices = function () { + console.log('Loading ' + savedDevices.length + ' saved devices...'); + console.log(savedDevices); - for(var i=0; i 2046) { + alert( + 'Unable to search for TCP devices - subnet too large!\n\nCue View requires subnet 255.255.248.0 (/21) or smaller.' + ); + TCPFlag = false; + } - //findOnlineDevices(); - allServers = getServers(); - var TCPFlag = true; - if(allServers.length>2046){ - alert("Unable to search for TCP devices - subnet too large!\n\nCue View requires subnet 255.255.248.0 (/21) or smaller.") - TCPFlag = false; - } + console.log(PLUGINS); - console.log(PLUGINS) + for (var p in PLUGINS.all) { + var plugin = PLUGINS.all[p]; + console.log(p); + try { + switch (plugin.searchOptions.type) { + case 'TCPport': + if (TCPFlag) { + newSearchTCP(p, plugin); + } + break; + case 'Bonjour': + newSearchBonjour(p, plugin); + break; + case 'UDPsocket': + newSearchUDP(p, plugin); + break; + } + } catch (err) { + console.error('Unable to search for plugin ' + p); + } + } - for(var p in PLUGINS.all){ - var plugin = PLUGINS.all[p]; - console.log(p) - try{ - switch(plugin.searchOptions.type){ - case "TCPport": - if(TCPFlag){ - newSearchTCP(p, plugin); - } - break; - case "Bonjour": - newSearchBonjour(p, plugin) - break; - case "UDPsocket": - newSearchUDP(p, plugin) - break; - } - }catch(err){ - console.error("Unable to search for plugin "+p) - } - } + //searchBonjour(); + //searchTCP(); + //searchUDP(); - //searchBonjour(); - //searchTCP(); - //searchUDP(); + setTimeout(function () { + searching = false; + document.getElementById('search-button').style.opacity = ''; - setTimeout(function(){ - searching = false; - document.getElementById("search-button").style.opacity = ""; + for (var i = 0; i < searchSockets.length; i++) { + try { + searchSockets[i].close(); + } catch (err) {} + } - for(var i=0; i { - if(plugin.searchOptions.validateResponse(data)){ - DEVICE.registerDevice({ - type: pluginType, - defaultName: plugin.defaultName, - port: plugin.defaultPort, - addresses: [ip] - }) - } - client.end(); - }); - client.on("error", function(err){ - //no device here - }); -} - - +TCPtest = function (ip, pluginType, plugin) { + var client = net.createConnection( + plugin.searchOptions.testPort, + ip, + function () { + client.write(plugin.searchOptions.searchBuffer); + // DEVICE.registerDevice({ + // type: pluginType, + // defaultName: plugin.defaultName, + // port: plugin.defaultPort, + // addresses: [ip] + // }) + } + ); + client.on('data', (data) => { + if (plugin.searchOptions.validateResponse(data)) { + DEVICE.registerDevice({ + type: pluginType, + defaultName: plugin.defaultName, + port: plugin.defaultPort, + addresses: [ip], + }); + } + client.end(); + }); + client.on('error', function (err) { + //no device here + }); +}; // from local-devices library -function getServers () { - var interfaces = os.networkInterfaces() - var result = [] +function getServers() { + var interfaces = os.networkInterfaces(); + var result = []; for (var key in interfaces) { - var addresses = interfaces[key] - for (var i = addresses.length; i--;) { - var address = addresses[i] + var addresses = interfaces[key]; + for (var i = addresses.length; i--; ) { + var address = addresses[i]; if (address.family === 'IPv4' && !address.internal) { - var subnet = ip.subnet(address.address, address.netmask) - var current = ip.toLong(subnet.firstAddress) - var last = ip.toLong(subnet.lastAddress) - 1 - while (current++ < last) result.push(ip.fromLong(current)) + var subnet = ip.subnet(address.address, address.netmask); + var current = ip.toLong(subnet.firstAddress); + var last = ip.toLong(subnet.lastAddress) - 1; + while (current++ < last) result.push(ip.fromLong(current)); } } } @@ -198,39 +191,38 @@ function getServers () { return result; } +findOnlineDevices = function () { + var allInterfaces = require('os').networkInterfaces(); + var validInterfaces = []; + for (var i in allInterfaces) { + for (var j = 0; j < allInterfaces[i].length; j++) { + var iface = allInterfaces[i][j]; + if ( + iface.family == 'IPv4' && + iface.internal == false && + iface.address.split('.')[0] != '169' + ) { + validInterfaces.push(iface); + } + } + } -findOnlineDevices = function(){ - var allInterfaces = require('os').networkInterfaces(); - var validInterfaces = []; - for(var i in allInterfaces){ - for(var j=0; j { + //console.log(err) + } + ); + setTimeout(function () { + searchSockets[i].send( + plugin.searchOptions.searchBuffer, + plugin.searchOptions.devicePort, + '255.255.255.255', + (err) => { + //console.log(err) + } + ); + }, 100); + setTimeout(function () { + searchSockets[i].send( + plugin.searchOptions.searchBuffer, + plugin.searchOptions.devicePort, + '255.255.255.255', + (err) => { + //console.log(err) + } + ); + }, 400); -newSearchUDP = function(pluginType, plugin){ - var i = searchSockets.push(dgram.createSocket('udp4'))-1; - searchSockets[i].bind(plugin.searchOptions.listenPort, function(){ - searchSockets[i].send(plugin.searchOptions.searchBuffer, plugin.searchOptions.devicePort, '255.255.255.255', (err) => { - //console.log(err) - }); - setTimeout(function(){ - searchSockets[i].send(plugin.searchOptions.searchBuffer, plugin.searchOptions.devicePort, '255.255.255.255', (err) => { - //console.log(err) - }); - }, 100); - setTimeout(function(){ - searchSockets[i].send(plugin.searchOptions.searchBuffer, plugin.searchOptions.devicePort, '255.255.255.255', (err) => { - //console.log(err) - }); - }, 400); - - searchSockets[i].on('message',function(msg,info){ - if(plugin.searchOptions.validateResponse(msg, info)){ - DEVICE.registerDevice({ - type: pluginType, - defaultName: plugin.defaultName, - port: plugin.defaultPort, - addresses: [info.address] - }) - } - }); - - }); - searchSockets[i].on('listening', function(){ - searchSockets[i].setBroadcast(true); - }); -} - + searchSockets[i].on('message', function (msg, info) { + if (plugin.searchOptions.validateResponse(msg, info)) { + DEVICE.registerDevice({ + type: pluginType, + defaultName: plugin.defaultName, + port: plugin.defaultPort, + addresses: [info.address], + }); + } + }); + }); + searchSockets[i].on('listening', function () { + searchSockets[i].setBroadcast(true); + }); +}; // searchUDP = function(){ @@ -362,7 +364,6 @@ newSearchUDP = function(pluginType, plugin){ // dgramPJLink.setBroadcast(true); // }); - // dgramXAir = dgram.createSocket('udp4'); // dgramXAir.bind(function(){ // dgramXAir.send(xAirMessage, 10024, '255.255.255.255', (err) => { @@ -389,11 +390,5 @@ newSearchUDP = function(pluginType, plugin){ // dgramXAir.on('listening', function(){ // dgramXAir.setBroadcast(true); // }); - // } - - - - - diff --git a/src/view.js b/src/view.js index e8790e9..b0bacc2 100644 --- a/src/view.js +++ b/src/view.js @@ -1,293 +1,311 @@ const { ipcRenderer } = require('electron'); -let DEVICE = require("./device.js"); -let PLUGINS = require("./plugins.js"); +let DEVICE = require('./device.js'); +let PLUGINS = require('./plugins.js'); var _ = require('lodash/function'); var pinnedDevices = []; module.exports.pinnedDevices = pinnedDevices; let activeDevice = false; +module.exports.init = function () { + populatePluginLists(); +}; +drawDeviceInterface = function (id) { + // console.log("DRAW") -module.exports.init = function(){ - populatePluginLists(); -} + var $deviceDrawArea = document.getElementById('device-' + id + '-draw-area'); + var $devicePinned = document.getElementById('device-' + id + '-pinned'); + if ($deviceDrawArea == null) { + return true; + } + d = DEVICE.all[id]; -drawDeviceInterface = function(id){ + var str = ''; + if (d.status == 'ok') { + str += + ""; + } - // console.log("DRAW") + //scrollbar styles are inline to prevent the styles flickering in + str += ''; + str += ""; + str += ''; - var $deviceDrawArea = document.getElementById("device-"+id+"-draw-area"); - var $devicePinned = document.getElementById("device-"+id+"-pinned"); + if (d.status == 'ok') { + try { + str += PLUGINS.all[d.type].template({ + data: d.data, + listName: d.displayName || d.defaultName, + }); + } catch (err) { + console.log(err); + str += '

Plugin Template Error

'; + } + } else { + str += '

' + (d.displayName || d.defaultName) + '

'; + str += "
"; + str += + '

' + + d.type + + ' is not responding to requests for data.

'; + str += '

IP ' + d.addresses[0] + '

'; + str += '

Port ' + d.port + '

'; + } - if($deviceDrawArea==null){ - return true; - } + str += ''; - d = DEVICE.all[id]; + $deviceDrawArea.setAttribute('class', d.type + ' draw-area'); + $deviceDrawArea.contentWindow.document.open(); + $deviceDrawArea.contentWindow.document.write(str); - var str = ""; - if(d.status=="ok"){ - str+=""; - } - + if (d.pinIndex) { + $devicePinned.style.display = 'block'; + } else { + $devicePinned.style.display = 'none'; + } +}; - //scrollbar styles are inline to prevent the styles flickering in - str+=""; - str+=""; - str+=""; +module.exports.draw = function (device) { + if (device == undefined) { + return true; + } + drawDeviceInterface(device.id); +}; - if(d.status=="ok"){ - try{ - str += PLUGINS.all[d.type].template({data: d.data, listName: d.displayName || d.defaultName}); - }catch(err){ - console.log(err) - str += "

Plugin Template Error

"; - } - }else{ - str+="

"+(d.displayName || d.defaultName)+"

"; - str+="
"; - str+="

"+d.type+" is not responding to requests for data.

"; - str+="

IP "+d.addresses[0]+"

"; - str+="

Port "+d.port+"

"; - } - - str+=""; +module.exports.addDeviceToList = function (device) { + var d = device; + var addressStr = d.addresses[0] || ''; + for (var i = 1; i < d.addresses.length; i++) { + addressStr += ', ' + d.addresses[i]; + } + var html = ''; + if (d.status == 'ok') { + html += "
done
"; + } else if (d.status == 'refresh') { + html += "
refresh
"; + } else { + html += "
clear
"; + } + html += + "
"; + html += "
" + (d.displayName || d.defaultName) + '
'; - - $deviceDrawArea.setAttribute("class", d.type+" draw-area"); - $deviceDrawArea.contentWindow.document.open(); - $deviceDrawArea.contentWindow.document.write(str); + let elem = document.getElementById(d.id); + if (elem == null) { + document + .getElementById('device-list') + .insertAdjacentHTML( + 'beforeend', + "" + html + '' + ); + } else { + elem.innerHTML = html; + } +}; +module.exports.removeDeviceFromList = function (device) { + var d = device; + document.getElementById(device.id).remove(); +}; +switchDevice = function (id) { + if (activeDevice && activeDevice.pinIndex == false) { + document.getElementById('device-' + activeDevice.id).remove(); + activeDevice = false; + } + activeDevice = DEVICE.all[id]; - if(d.pinIndex){ - $devicePinned.style.display = "block"; - }else{ - $devicePinned.style.display = "none"; - } -} + var cols = 1; + if (pinnedDevices.length > 0) { + cols += pinnedDevices.length; + } + if (pinnedDevices.indexOf(activeDevice) >= 0 || id == undefined) { + cols--; + } -module.exports.draw = function(device){ - if(device==undefined){ - return true; - } - drawDeviceInterface(device.id) -} + document.getElementById('all-devices').style.gridTemplateColumns = + 'repeat(' + cols + ', 1fr)'; + if (id == undefined) { + //document.getElementById('refresh-device-button').style.opacity = 0.2; + document.getElementById('refresh-device-button').disabled = true; + document.getElementById('device-settings-table').style.display = 'none'; + return true; + } else { + document.getElementById('refresh-device-button').disabled = false; + //document.getElementById('refresh-device-button').style.opacity = 1; + } + var i = DEVICE.all[id].id; + var $deviceWrapper = document.getElementById('device-' + i); + if (!$deviceWrapper) { + var html = + '
' + + '' + + '' + + '
'; + document + .getElementById('all-devices') + .insertAdjacentHTML('afterbegin', html); -module.exports.addDeviceToList = function(device){ - var d = device; - var addressStr = d.addresses[0] || ""; - for(var i=1; i
"; - html+="
"+(d.displayName || d.defaultName)+"
"; + $deviceWrapper = document.getElementById('device-' + i); + } - let elem = document.getElementById(d.id); - if(elem==null){ - document.getElementById("device-list").insertAdjacentHTML("beforeend", ""+html+""); - }else{ - elem.innerHTML = html; - } -} -module.exports.removeDeviceFromList = function(device){ - var d = device; - document.getElementById(device.id).remove(); -} + switchClass(document.getElementById(id), 'active-device'); + drawDeviceInterface(id); + switchClass(document.getElementById('device-' + id), 'active-device-outline'); + document.getElementById('device-settings-table').style.display = 'block'; + document.getElementById('device-settings-plugin-dropdown').value = + activeDevice.type; + document.getElementById('device-settings-name').value = + activeDevice.displayName || activeDevice.defaultName || ''; + document.getElementById('device-settings-ip').value = + activeDevice.addresses[0] || ''; + document.getElementById('device-settings-port').value = + activeDevice.port || ''; + document.getElementById('device-settings-pin').checked = + activeDevice.pinIndex; - -switchDevice = function(id){ - - if(activeDevice && activeDevice.pinIndex==false){ - document.getElementById("device-"+activeDevice.id).remove(); - activeDevice = false; - } - activeDevice = DEVICE.all[id]; - - - var cols = 1; - if(pinnedDevices.length>0){ - cols+=pinnedDevices.length; - } - if(pinnedDevices.indexOf(activeDevice)>=0 || id==undefined){ - cols--; - } - - document.getElementById("all-devices").style.gridTemplateColumns = "repeat("+(cols)+", 1fr)"; - - if(id==undefined){ - //document.getElementById('refresh-device-button').style.opacity = 0.2; - document.getElementById('refresh-device-button').disabled = true; - document.getElementById('device-settings-table').style.display = "none"; - return true; - }else{ - document.getElementById('refresh-device-button').disabled = false; - //document.getElementById('refresh-device-button').style.opacity = 1; - } - - - var i = DEVICE.all[id].id; - - var $deviceWrapper = document.getElementById("device-"+i); - if(!$deviceWrapper){ - var html = '
' - +'' - +'' - +'
'; - document.getElementById("all-devices").insertAdjacentHTML("afterbegin", html); - - $deviceWrapper = document.getElementById("device-"+i); - } - - switchClass(document.getElementById(id), "active-device"); - drawDeviceInterface(id); - switchClass(document.getElementById("device-"+id), "active-device-outline"); - - - - document.getElementById('device-settings-table').style.display = "block"; - document.getElementById('device-settings-plugin-dropdown').value=activeDevice.type; - document.getElementById("device-settings-name").value = activeDevice.displayName || activeDevice.defaultName || ""; - document.getElementById("device-settings-ip").value = activeDevice.addresses[0] || ""; - document.getElementById("device-settings-port").value = activeDevice.port || ""; - document.getElementById("device-settings-pin").checked = activeDevice.pinIndex; - - - ipcRenderer.send("enableDeviceDropdown", ""); - ipcRenderer.send("setDevicePin", !DEVICE.all[id].pinIndex==false); - -} + ipcRenderer.send('enableDeviceDropdown', ''); + ipcRenderer.send('setDevicePin', !DEVICE.all[id].pinIndex == false); +}; module.exports.switchDevice = switchDevice; +module.exports.getActiveDevice = function () { + return activeDevice; +}; -module.exports.getActiveDevice = function(){ - return activeDevice; -} +module.exports.pinActiveDevice = function () { + if (activeDevice == undefined) { + return true; + } + if (pinnedDevices.indexOf(DEVICE.all[activeDevice.id]) == -1) { + pinnedDevices.push(DEVICE.all[activeDevice.id]); + } + DEVICE.changeActivePinIndex(true); +}; -module.exports.pinActiveDevice = function(){ - if(activeDevice==undefined){ - return true; - } - if(pinnedDevices.indexOf(DEVICE.all[activeDevice.id])==-1){ - pinnedDevices.push(DEVICE.all[activeDevice.id]); - } - DEVICE.changeActivePinIndex(true); -} +module.exports.unpinActiveDevice = function () { + if (activeDevice == undefined) { + return true; + } + pinnedDevices.splice(pinnedDevices.indexOf(DEVICE.all[activeDevice.id]), 1); + DEVICE.changeActivePinIndex(false); +}; -module.exports.unpinActiveDevice = function(){ - if(activeDevice==undefined){ - return true; - } - pinnedDevices.splice(pinnedDevices.indexOf(DEVICE.all[activeDevice.id]), 1); - DEVICE.changeActivePinIndex(false); -} +module.exports.pinDevice = function (device) { + pinnedDevices.push(device); + DEVICE.changePinIndex(device, true); +}; +module.exports.unpinDevice = function (device) { + pinnedDevices.push(device); + DEVICE.changePinIndex(device, false); +}; -module.exports.pinDevice = function(device){ - pinnedDevices.push(device) - DEVICE.changePinIndex(device, true); -} -module.exports.unpinDevice = function(device){ - pinnedDevices.push(device) - DEVICE.changePinIndex(device, false); -} +module.exports.resetPinned = function () { + pinnedDevices.length = 0; + activeDevice = false; + //switchDevice(); + try { + document + .querySelector('#device-list .active-device') + .classList.remove('active-device'); + } catch (err) {} + document.getElementById('all-devices').innerHTML = ''; +}; -module.exports.resetPinned = function(){ - pinnedDevices.length = 0; - activeDevice = false; - //switchDevice(); - try{ - document.querySelector("#device-list .active-device").classList.remove("active-device"); - }catch(err){} - document.getElementById("all-devices").innerHTML = ""; -} +module.exports.getPinnedDevices = function () { + return pinnedDevices; +}; -module.exports.getPinnedDevices = function(){ - return pinnedDevices; -} +module.exports.toggleSlotButtons = function (slotIndex) { + if (slotIndex == 1) { + document.getElementById('save-slot-1').classList.add('active'); + document.getElementById('save-slot-2').classList.remove('active'); + document.getElementById('save-slot-3').classList.remove('active'); + } else if (slotIndex == 2) { + document.getElementById('save-slot-1').classList.remove('active'); + document.getElementById('save-slot-2').classList.add('active'); + document.getElementById('save-slot-3').classList.remove('active'); + } else if (slotIndex == 3) { + document.getElementById('save-slot-1').classList.remove('active'); + document.getElementById('save-slot-2').classList.remove('active'); + document.getElementById('save-slot-3').classList.add('active'); + } +}; +module.exports.selectPreviousDevice = function () { + if (activeDevice == undefined) { + return true; + } + var keys = Object.keys(DEVICE.all); + var prevIndex = Math.max(0, keys.indexOf(activeDevice.id) - 1); + switchDevice(keys[prevIndex]); +}; +module.exports.selectNextDevice = function () { + if (activeDevice == undefined) { + return true; + } + var keys = Object.keys(DEVICE.all); + var prevIndex = Math.min(keys.length - 1, keys.indexOf(activeDevice.id) + 1); + switchDevice(keys[prevIndex]); +}; -module.exports.toggleSlotButtons = function(slotIndex){ - if(slotIndex==1){ - document.getElementById("save-slot-1").classList.add("active"); - document.getElementById("save-slot-2").classList.remove("active"); - document.getElementById("save-slot-3").classList.remove("active"); - }else if(slotIndex==2){ - document.getElementById("save-slot-1").classList.remove("active"); - document.getElementById("save-slot-2").classList.add("active"); - document.getElementById("save-slot-3").classList.remove("active"); - }else if(slotIndex==3){ - document.getElementById("save-slot-1").classList.remove("active"); - document.getElementById("save-slot-2").classList.remove("active"); - document.getElementById("save-slot-3").classList.add("active"); - } -} +populatePluginLists = function () { + var typeSelect = ''; + var addSelect = ''; -module.exports.selectPreviousDevice = function(){ - if(activeDevice==undefined){ - return true; - } - var keys = Object.keys(DEVICE.all); - var prevIndex = Math.max(0, keys.indexOf(activeDevice.id)-1); - switchDevice(keys[prevIndex]) -} -module.exports.selectNextDevice = function(){ - if(activeDevice==undefined){ - return true; - } - var keys = Object.keys(DEVICE.all); - var prevIndex = Math.min(keys.length-1, keys.indexOf(activeDevice.id)+1); - switchDevice(keys[prevIndex]) -} + for (const pluginType in PLUGINS.all) { + var plugin = PLUGINS.all[pluginType]; + addSelect += + "'; + typeSelect += + "'; + } - -populatePluginLists = function(){ - - var typeSelect = ""; - var addSelect = ''; - - for(const pluginType in PLUGINS.all){ - var plugin = PLUGINS.all[pluginType]; - - addSelect+=""; - typeSelect+=""; - } - - document.getElementById("device-settings-plugin-dropdown").innerHTML = typeSelect; - document.getElementById("add-device-button").innerHTML = addSelect; -} + document.getElementById('device-settings-plugin-dropdown').innerHTML = + typeSelect; + document.getElementById('add-device-button').innerHTML = addSelect; +}; function debounce(func, wait, immediate) { - var timeout; - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) func.apply(context, args); - }; - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) func.apply(context, args); - }; -}; + var timeout; + return function () { + var context = this, + args = arguments; + var later = function () { + timeout = null; + if (!immediate) func.apply(context, args); + }; + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(context, args); + }; +}