From 3d44eeefb315575aa0b0c53314e8dc2b8d88aaaf Mon Sep 17 00:00:00 2001 From: DeionSi Date: Mon, 24 Apr 2023 17:00:35 +0200 Subject: [PATCH] Format with vscode "Format Document". Indentation = 4. Newline at end. --- main.js | 441 ++++++++++++++---------------- renderer.js | 770 +++++++++++++++++++++++++--------------------------- 2 files changed, 576 insertions(+), 635 deletions(-) diff --git a/main.js b/main.js index c6733fc..07c623b 100644 --- a/main.js +++ b/main.js @@ -1,6 +1,6 @@ const { app, BrowserWindow, ipcMain, shell } = require('electron') -const {download} = require('electron-dl') -const {execFile} = require('child_process'); +const { download } = require('electron-dl') +const { execFile } = require('child_process'); const fs = require('fs'); const path = require('path'); @@ -13,49 +13,48 @@ var avrdudeIsRunning = false; var teensyLoaderIsRunning = false; var teensyLoaderErr = "" -function createWindow () -{ - // Create the browser window. - win = new BrowserWindow({ - width: 800, - height: 600, - backgroundColor: '#312450', - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - }, - }); +function createWindow() { + // Create the browser window. + win = new BrowserWindow({ + width: 800, + height: 600, + backgroundColor: '#312450', + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + }, + }); - // Open links in external browser - win.webContents.setWindowOpenHandler(({ url }) => { - if (url.startsWith('https:')) { - shell.openExternal(url); + // Open links in external browser + win.webContents.setWindowOpenHandler(({ url }) => { + if (url.startsWith('https:')) { + shell.openExternal(url); + } + return { action: 'deny' }; + }); + + // auto hide menu bar (Win, Linux) + win.setMenuBarVisibility(false); + win.setAutoHideMenuBar(true); + + // remove completely when app is packaged (Win, Linux) + if (app.isPackaged) { + win.removeMenu(); } - return { action: 'deny' }; - }); - // auto hide menu bar (Win, Linux) - win.setMenuBarVisibility(false); - win.setAutoHideMenuBar(true); + // and load the index.html of the app. + win.loadFile('index.html') - // remove completely when app is packaged (Win, Linux) - if (app.isPackaged) { - win.removeMenu(); - } + // Open the DevTools. + //win.webContents.openDevTools() - // and load the index.html of the app. - win.loadFile('index.html') - - // Open the DevTools. - //win.webContents.openDevTools() - - // Emitted when the window is closed. - win.on('closed', () => { - // Dereference the window object, usually you would store windows - // in an array if your app supports multi windows, this is the time - // when you should delete the corresponding element. - win = null - }) + // Emitted when the window is closed. + win.on('closed', () => { + // Dereference the window object, usually you would store windows + // in an array if your app supports multi windows, this is the time + // when you should delete the corresponding element. + win = null + }) } @@ -70,255 +69,235 @@ app.on('ready', createWindow) // Quit when all windows are closed. app.on('window-all-closed', () => { - // On macOS it is common for applications and their menu bar - // to stay active until the user quits explicitly with Cmd + Q - //if (process.platform !== 'darwin') - { - app.quit() - } + // On macOS it is common for applications and their menu bar + // to stay active until the user quits explicitly with Cmd + Q + //if (process.platform !== 'darwin') + { + app.quit() + } }) app.on('activate', () => { - // On macOS it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (win === null) { - createWindow() - } + // On macOS it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (win === null) { + createWindow() + } }) ipcMain.on('download', (e, args) => { - filename = args.url.substring(args.url.lastIndexOf('/')+1); - dlDir = app.getPath('downloads'); - const path = require('node:path'); - fullFile = path.join(dlDir, filename); + filename = args.url.substring(args.url.lastIndexOf('/') + 1); + dlDir = app.getPath('downloads'); + const path = require('node:path'); + fullFile = path.join(dlDir, filename); + + //Special case for handling the build that is from master. This is ALWAYS downloaded as there's no way of telling when it was last updated. + if (filename.includes("master")) { + if (fs.existsSync(fullFile)) { + fs.unlinkSync(fullFile) + console.log('Master version selected, removing local file forcing re-download: ' + filename); + } - //Special case for handling the build that is from master. This is ALWAYS downloaded as there's no way of telling when it was last updated. - if(filename.includes("master")) - { - if(fs.existsSync(fullFile)) - { - fs.unlinkSync(fullFile) - console.log('Master version selected, removing local file forcing re-download: ' + filename); } - } - - //console.log("Filename: " + fullFile ); - options = {}; - if(filename.split('.').pop() == "msq") - { - options = { saveAs: true }; - } - - fs.exists(fullFile, (exists) => { - if (exists) { - console.log("File " + fullFile + " already exists in Downloads directory. Skipping download"); - e.sender.send( "download complete", fullFile, "exists" ); - } - else { - download(BrowserWindow.getFocusedWindow(), args.url, options) - .then(dl => e.sender.send( "download complete", dl.getSavePath(), dl.getState() ) ) - .catch(console.error); + //console.log("Filename: " + fullFile ); + options = {}; + if (filename.split('.').pop() == "msq") { + options = { saveAs: true }; } - }); - + fs.exists(fullFile, (exists) => { + if (exists) { + console.log("File " + fullFile + " already exists in Downloads directory. Skipping download"); + e.sender.send("download complete", fullFile, "exists"); + } + else { + download(BrowserWindow.getFocusedWindow(), args.url, options) + .then(dl => e.sender.send("download complete", dl.getSavePath(), dl.getState())) + .catch(console.error); + } + }); + + }); ipcMain.on('installWinDrivers', (e, args) => { - var infName = __dirname + "/bin/drivers-win/arduino.inf"; - infName = infName.replace('app.asar',''); - console.log("INF File " + infName); - //syssetup,SetupInfObjectInstallAction DefaultInstall 128 .\.inf + var infName = __dirname + "/bin/drivers-win/arduino.inf"; + infName = infName.replace('app.asar', ''); + console.log("INF File " + infName); + //syssetup,SetupInfObjectInstallAction DefaultInstall 128 .\.inf - var execArgs = ['syssetup,SetupInfObjectInstallAction', 'DefaultInstall 128', infName]; + var execArgs = ['syssetup,SetupInfObjectInstallAction', 'DefaultInstall 128', infName]; - const child = execFile("rundll32", execArgs); + const child = execFile("rundll32", execArgs); }); ipcMain.on('uploadFW', (e, args) => { - if(avrdudeIsRunning == true) { return; } - avrdudeIsRunning = true; //Indicate that an avrdude process has started - var platform; + if (avrdudeIsRunning == true) { return; } + avrdudeIsRunning = true; //Indicate that an avrdude process has started + var platform; - var burnStarted = false; - var burnPercent = 0; + var burnStarted = false; + var burnPercent = 0; - //All Windows builds use the 32-bit binary - if(process.platform == "win32") - { - platform = "avrdude-windows"; - } - //All Mac builds use the 64-bit binary - else if(process.platform == "darwin") - { - platform = "avrdude-darwin-x86_64"; - } - else if(process.platform == "linux") - { - if(process.arch == "x32") { platform = "avrdude-linux_i686"; } - else if(process.arch == "x64") { platform = "avrdude-linux_x86_64"; } - else if(process.arch == "arm") { platform = "avrdude-armhf"; } - else if(process.arch == "arm64") { platform = "avrdude-aarch64"; } - } - - var executableName = __dirname + "/bin/" + platform + "/avrdude"; - executableName = executableName.replace('app.asar',''); //This is important for allowing the binary to be found once the app is packaed into an asar - var configName = executableName + ".conf"; - if(process.platform == "win32") { executableName = executableName + '.exe'; } //This must come after the configName line above - - var hexFile = 'flash:w:' + args.firmwareFile + ':i'; - - var execArgs = ['-v', '-patmega2560', '-C', configName, '-cwiring', '-b 115200', '-P', args.port, '-D', '-U', hexFile]; - - console.log(executableName); - const child = execFile(executableName, execArgs); - - child.stdout.on('data', (data) => { - console.log(`avrdude stdout:\n${data}`); - }); - - child.stderr.on('data', (data) => { - console.log(`avrdude stderr: ${data}`); - avrdudeErr = avrdudeErr + data; - - //Check if avrdude has started the actual burn yet, and if so, track the '#' characters that it prints. Each '#' represents 1% of the total burn process (50 for write and 50 for read) - if (burnStarted == true) - { - if(data=="#") { burnPercent += 1; } - e.sender.send( "upload percent", burnPercent ); + //All Windows builds use the 32-bit binary + if (process.platform == "win32") { + platform = "avrdude-windows"; } - else - { - //This is a hack, but basically watch the output from avrdude for the term 'Writing | ', everything after that is the #s indicating 1% of burn. - if(avrdudeErr.substr(avrdudeErr.length - 10) == "Writing | ") - { - burnStarted = true; - } + //All Mac builds use the 64-bit binary + else if (process.platform == "darwin") { + platform = "avrdude-darwin-x86_64"; + } + else if (process.platform == "linux") { + if (process.arch == "x32") { platform = "avrdude-linux_i686"; } + else if (process.arch == "x64") { platform = "avrdude-linux_x86_64"; } + else if (process.arch == "arm") { platform = "avrdude-armhf"; } + else if (process.arch == "arm64") { platform = "avrdude-aarch64"; } } - }); - child.on('error', (err) => { - console.log('Failed to start subprocess.'); - console.log(err); - avrDudeIsRunning = false; - }); + var executableName = __dirname + "/bin/" + platform + "/avrdude"; + executableName = executableName.replace('app.asar', ''); //This is important for allowing the binary to be found once the app is packaed into an asar + var configName = executableName + ".conf"; + if (process.platform == "win32") { executableName = executableName + '.exe'; } //This must come after the configName line above - child.on('close', (code) => { - avrdudeIsRunning = false; - if (code !== 0) - { - console.log(`avrdude process exited with code ${code}`); - e.sender.send( "upload error", avrdudeErr ) - avrdudeErr = ""; - } - else - { - e.sender.send( "upload completed", code ) - } - }); + var hexFile = 'flash:w:' + args.firmwareFile + ':i'; + + var execArgs = ['-v', '-patmega2560', '-C', configName, '-cwiring', '-b 115200', '-P', args.port, '-D', '-U', hexFile]; + + console.log(executableName); + const child = execFile(executableName, execArgs); + + child.stdout.on('data', (data) => { + console.log(`avrdude stdout:\n${data}`); + }); + + child.stderr.on('data', (data) => { + console.log(`avrdude stderr: ${data}`); + avrdudeErr = avrdudeErr + data; + + //Check if avrdude has started the actual burn yet, and if so, track the '#' characters that it prints. Each '#' represents 1% of the total burn process (50 for write and 50 for read) + if (burnStarted == true) { + if (data == "#") { burnPercent += 1; } + e.sender.send("upload percent", burnPercent); + } + else { + //This is a hack, but basically watch the output from avrdude for the term 'Writing | ', everything after that is the #s indicating 1% of burn. + if (avrdudeErr.substr(avrdudeErr.length - 10) == "Writing | ") { + burnStarted = true; + } + } + }); + + child.on('error', (err) => { + console.log('Failed to start subprocess.'); + console.log(err); + avrDudeIsRunning = false; + }); + + child.on('close', (code) => { + avrdudeIsRunning = false; + if (code !== 0) { + console.log(`avrdude process exited with code ${code}`); + e.sender.send("upload error", avrdudeErr) + avrdudeErr = ""; + } + else { + e.sender.send("upload completed", code) + } + }); }); - ipcMain.on('uploadFW_teensy', (e, args) => { +ipcMain.on('uploadFW_teensy', (e, args) => { - if(teensyLoaderIsRunning == true) { return; } + if (teensyLoaderIsRunning == true) { return; } teensyLoaderIsRunning = true; //Indicate that an avrdude process has started var platform; - + var burnStarted = false; var burnPercent = 0; - + //All Windows builds use the 32-bit binary - if(process.platform == "win32") - { - platform = "teensy_loader_cli-windows"; + if (process.platform == "win32") { + platform = "teensy_loader_cli-windows"; } //All Mac builds use the 64-bit binary - else if(process.platform == "darwin") - { - platform = "teensy_loader_cli-darwin-x86_64"; + else if (process.platform == "darwin") { + platform = "teensy_loader_cli-darwin-x86_64"; } - else if(process.platform == "linux") - { - if(process.arch == "x32") { platform = "teensy_loader_cli-linux_i686"; } - else if(process.arch == "x64") { platform = "teensy_loader_cli-linux_x86_64"; } - else if(process.arch == "arm") { platform = "teensy_loader_cli-armhf"; } - else if(process.arch == "arm64") { platform = "teensy_loader_cli-aarch64"; } + else if (process.platform == "linux") { + if (process.arch == "x32") { platform = "teensy_loader_cli-linux_i686"; } + else if (process.arch == "x64") { platform = "teensy_loader_cli-linux_x86_64"; } + else if (process.arch == "arm") { platform = "teensy_loader_cli-armhf"; } + else if (process.arch == "arm64") { platform = "teensy_loader_cli-aarch64"; } } - + var executableName = __dirname + "/bin/" + platform + "/teensy_post_compile"; - executableName = executableName.replace('app.asar',''); //This is important for allowing the binary to be found once the app is packaed into an asar + executableName = executableName.replace('app.asar', ''); //This is important for allowing the binary to be found once the app is packaed into an asar var configName = executableName + ".conf"; - - - var execArgs = ['-board='+args.board, '-reboot', '-file='+path.basename(args.firmwareFile, '.hex'), '-path='+path.dirname(args.firmwareFile), '-tools='+executableName.replace('/teensy_post_compile', "")]; + + + var execArgs = ['-board=' + args.board, '-reboot', '-file=' + path.basename(args.firmwareFile, '.hex'), '-path=' + path.dirname(args.firmwareFile), '-tools=' + executableName.replace('/teensy_post_compile', "")]; //console.log(execArgs); - - if(process.platform == "win32") { executableName = executableName + '.exe'; } //This must come after the configName line above - + + if (process.platform == "win32") { executableName = executableName + '.exe'; } //This must come after the configName line above + console.log(executableName); const child = execFile(executableName, execArgs); - + child.stdout.on('data', (data) => { - console.log(`teensy_loader_cli stdout:\n${data}`); + console.log(`teensy_loader_cli stdout:\n${data}`); }); - + child.stderr.on('data', (data) => { - console.log(`teensy_loader_cli stderr: ${data}`); - teensyLoaderErr = teensyLoaderErr + data; - - //Check if avrdude has started the actual burn yet, and if so, track the '#' characters that it prints. Each '#' represents 1% of the total burn process (50 for write and 50 for read) - if (burnStarted == true) - { - if(data=="#") { burnPercent += 1; } - e.sender.send( "upload percent", burnPercent ); - } - else - { - //This is a hack, but basically watch the output from teensy loader for the term 'Writing | ', everything after that is the #s indicating 1% of burn. - if(teensyLoaderErr.substr(teensyLoaderErr.length - 10) == "Writing | ") - { - burnStarted = true; + console.log(`teensy_loader_cli stderr: ${data}`); + teensyLoaderErr = teensyLoaderErr + data; + + //Check if avrdude has started the actual burn yet, and if so, track the '#' characters that it prints. Each '#' represents 1% of the total burn process (50 for write and 50 for read) + if (burnStarted == true) { + if (data == "#") { burnPercent += 1; } + e.sender.send("upload percent", burnPercent); } - } - + else { + //This is a hack, but basically watch the output from teensy loader for the term 'Writing | ', everything after that is the #s indicating 1% of burn. + if (teensyLoaderErr.substr(teensyLoaderErr.length - 10) == "Writing | ") { + burnStarted = true; + } + } + }); - child.on('error', (err) => { - console.log('Failed to start subprocess.'); - console.log(err); - teensyLoaderIsRunning = false; - }); + child.on('error', (err) => { + console.log('Failed to start subprocess.'); + console.log(err); + teensyLoaderIsRunning = false; + }); - child.on('close', (code) => { - teensyLoaderIsRunning = false; - if (code !== 0) - { - console.log(`teensyLoader process exited with code ${code}`); - e.sender.send( "upload error", teensyLoaderErr ) - teensyLoaderErr = ""; - } - else - { - e.sender.send( "upload completed", code ) - } - }); + child.on('close', (code) => { + teensyLoaderIsRunning = false; + if (code !== 0) { + console.log(`teensyLoader process exited with code ${code}`); + e.sender.send("upload error", teensyLoaderErr) + teensyLoaderErr = ""; + } + else { + e.sender.send("upload completed", code) + } + }); }); ipcMain.handle('getAppVersion', async (e) => { - return app.getVersion(); + return app.getVersion(); }); ipcMain.handle('quit-app', () => { - app.quit(); + app.quit(); }); ipcMain.handle('show-ini', (event, location) => { - if (location.endsWith('.ini')) - { - shell.showItemInFolder(location); // This function needs to be executed in main.js to bring file explorer to foreground - } -}); \ No newline at end of file + if (location.endsWith('.ini')) { + shell.showItemInFolder(location); // This function needs to be executed in main.js to bring file explorer to foreground + } +}); diff --git a/renderer.js b/renderer.js index 42a309d..68f635e 100644 --- a/renderer.js +++ b/renderer.js @@ -1,156 +1,144 @@ const serialport = require('@serialport/bindings-cpp') const usb = require('usb') -const {ipcRenderer} = require("electron") +const { ipcRenderer } = require("electron") const { shell } = require('electron') var basetuneList = []; -function getTeensyVersion(id) -{ - var idString = "" - switch(id) { - case 0x273: - idString = "LC" - break; - case 0x274: - idString = "3.0" - break; - case 0x275: - idString = "3.2" - break; - case 0x276: - idString = "3.5" - break; - case 0x277: - idString = "3.6" - break; - case 0x279: - idString = "4.0" - break; - case 0x280: - idString = "4.1" - break; - } +function getTeensyVersion(id) { + var idString = "" + switch (id) { + case 0x273: + idString = "LC" + break; + case 0x274: + idString = "3.0" + break; + case 0x275: + idString = "3.2" + break; + case 0x276: + idString = "3.5" + break; + case 0x277: + idString = "3.6" + break; + case 0x279: + idString = "4.0" + break; + case 0x280: + idString = "4.1" + break; + } - return idString; + return idString; } -function refreshSerialPorts() -{ - serialport.autoDetect().list().then(ports => { - console.log('Serial ports found: ', ports); - - if (ports.length === 0) { - document.getElementById('serialDetectError').textContent = 'No ports discovered' - } - - const select = document.getElementById('portsSelect'); +function refreshSerialPorts() { + serialport.autoDetect().list().then(ports => { + console.log('Serial ports found: ', ports); - //Clear the current options - while (select.options.length) - { - select.remove(0); //Always 0 index (As each time an item is removed, everything shuffles up 1 place) - } + if (ports.length === 0) { + document.getElementById('serialDetectError').textContent = 'No ports discovered' + } - //Load the current serial values - for(var i = 0; i < ports.length; i++) - { - var newOption = document.createElement('option'); - newOption.value = ports[i].path; - newOption.innerHTML = ports[i].path; - if(ports[i].vendorId == "2341") - { - //Arduino device - if(ports[i].productId == "0010" || ports[i].productId == "0042") - { - //Mega2560 with 16u2 - newOption.innerHTML = newOption.innerHTML + " (Arduino Mega)"; - newOption.setAttribute("board", "ATMEGA2560"); - } - } - else if(ports[i].vendorId == "16c0" || ports[i].vendorId == "16C0") - { - //Teensy - var teensyDevices = usb.getDeviceList().filter( function(d) { return d.deviceDescriptor.idVendor===0x16C0; }); - var teensyVersion = getTeensyVersion(teensyDevices[0].deviceDescriptor.bcdDevice); - newOption.innerHTML = newOption.innerHTML + " (Teensy " + teensyVersion + ")"; + const select = document.getElementById('portsSelect'); - //Get the short copy of the teensy version - teensyVersion = teensyVersion.replace(".", ""); - newOption.setAttribute("board", "TEENSY"+teensyVersion); + //Clear the current options + while (select.options.length) { + select.remove(0); //Always 0 index (As each time an item is removed, everything shuffles up 1 place) } - else if(ports[i].vendorId == "1a86" || ports[i].vendorId == "1A86") - { - //CH340 - newOption.innerHTML = newOption.innerHTML + " (Arduino Mega CH340)"; - newOption.setAttribute("board", "ATMEGA2560"); - } - else - { - //Unknown device, assume it's a mega2560 - newOption.setAttribute("board", "ATMEGA2560"); - } - select.add(newOption); - } - //Look for any unintialised Teensy boards (ie boards in HID rather than serial mode) - var uninitialisedTeensyDevices = usb.getDeviceList().filter( function(d) { - return d.deviceDescriptor.idVendor===0x16C0 && d.configDescriptor.interfaces[0][0].bInterfaceClass == 3; //Interface class 3 is HID - }); - uninitialisedTeensyDevices.forEach((device, index) => { - console.log("Uninit Teensy found: ", getTeensyVersion(device.deviceDescriptor.bcdDevice)) - var newOption = document.createElement('option'); - newOption.value = "TeensyHID"; - var teensyVersion = getTeensyVersion(device.deviceDescriptor.bcdDevice); - newOption.innerHTML = "Uninitialised Teensy " + teensyVersion; - teensyVersion = teensyVersion.replace(".", ""); - newOption.setAttribute("board", "TEENSY"+teensyVersion); - select.add(newOption); + //Load the current serial values + for (var i = 0; i < ports.length; i++) { + var newOption = document.createElement('option'); + newOption.value = ports[i].path; + newOption.innerHTML = ports[i].path; + if (ports[i].vendorId == "2341") { + //Arduino device + if (ports[i].productId == "0010" || ports[i].productId == "0042") { + //Mega2560 with 16u2 + newOption.innerHTML = newOption.innerHTML + " (Arduino Mega)"; + newOption.setAttribute("board", "ATMEGA2560"); + } + } + else if (ports[i].vendorId == "16c0" || ports[i].vendorId == "16C0") { + //Teensy + var teensyDevices = usb.getDeviceList().filter(function (d) { return d.deviceDescriptor.idVendor === 0x16C0; }); + var teensyVersion = getTeensyVersion(teensyDevices[0].deviceDescriptor.bcdDevice); + newOption.innerHTML = newOption.innerHTML + " (Teensy " + teensyVersion + ")"; + + //Get the short copy of the teensy version + teensyVersion = teensyVersion.replace(".", ""); + newOption.setAttribute("board", "TEENSY" + teensyVersion); + } + else if (ports[i].vendorId == "1a86" || ports[i].vendorId == "1A86") { + //CH340 + newOption.innerHTML = newOption.innerHTML + " (Arduino Mega CH340)"; + newOption.setAttribute("board", "ATMEGA2560"); + } + else { + //Unknown device, assume it's a mega2560 + newOption.setAttribute("board", "ATMEGA2560"); + } + select.add(newOption); + } + + //Look for any unintialised Teensy boards (ie boards in HID rather than serial mode) + var uninitialisedTeensyDevices = usb.getDeviceList().filter(function (d) { + return d.deviceDescriptor.idVendor === 0x16C0 && d.configDescriptor.interfaces[0][0].bInterfaceClass == 3; //Interface class 3 is HID + }); + uninitialisedTeensyDevices.forEach((device, index) => { + console.log("Uninit Teensy found: ", getTeensyVersion(device.deviceDescriptor.bcdDevice)) + var newOption = document.createElement('option'); + newOption.value = "TeensyHID"; + var teensyVersion = getTeensyVersion(device.deviceDescriptor.bcdDevice); + newOption.innerHTML = "Uninitialised Teensy " + teensyVersion; + teensyVersion = teensyVersion.replace(".", ""); + newOption.setAttribute("board", "TEENSY" + teensyVersion); + select.add(newOption); + }) + + var button = document.getElementById("btnInstall") + if (ports.length > 0) { + select.selectedIndex = 0; + button.disabled = false; + } + else { button.disabled = true; } + }) - - var button = document.getElementById("btnInstall") - if(ports.length > 0) - { - select.selectedIndex = 0; - button.disabled = false; - } - else { button.disabled = true; } - - }) } -function refreshDetails() -{ +function refreshDetails() { var selectElement = document.getElementById('versionsSelect'); var version = selectElement.options[selectElement.selectedIndex].value; var url = "https://api.github.com/repos/noisymime/speeduino/releases/tags/" + version; document.getElementById('detailsText').innerHTML = ""; document.getElementById('detailsHeading').innerHTML = version; - - fetch(url) - .then((response) => { - if (response.ok) { - return response.json(); - } - return Promise.reject(response); - }) - .then((result) => { - console.log(result); - //Need to convert the Markdown that comes from Github to HTML - var myMarked = require('marked'); - document.getElementById('detailsText').innerHTML = myMarked.parse(result.body); - document.getElementById('detailsHeading').innerHTML = version + " - " + result.name; - }) - .catch((error) => { - console.log('Could not download details.', error); - }); + fetch(url) + .then((response) => { + if (response.ok) { + return response.json(); + } + return Promise.reject(response); + }) + .then((result) => { + console.log(result); + + //Need to convert the Markdown that comes from Github to HTML + var myMarked = require('marked'); + document.getElementById('detailsText').innerHTML = myMarked.parse(result.body); + document.getElementById('detailsHeading').innerHTML = version + " - " + result.name; + }) + .catch((error) => { + console.log('Could not download details.', error); + }); } -function refreshAvailableFirmwares() -{ +function refreshAvailableFirmwares() { //Disable the buttons. These are only re-enabled if the retrieve is successful var DetailsButton = document.getElementById("btnDetails"); var ChoosePortButton = document.getElementById("btnChoosePort"); @@ -161,95 +149,89 @@ function refreshAvailableFirmwares() const select = document.getElementById('versionsSelect'); - fetch('https://speeduino.com/fw/versions', { signal: AbortSignal.timeout(5000) } ) - .then((response) => { - if (response.ok) { - return response.text(); - } - return Promise.reject(response); - }) - .then((result) => { - var lines = result.split('\n'); - // Continue with your processing here. - - for(var i = 0;i < lines.length;i++) - { - var newOption = document.createElement('option'); - newOption.value = lines[i]; - newOption.innerHTML = lines[i]; - select.appendChild(newOption); - } - select.selectedIndex = 0; - - //Remove the loading spinner - loadingSpinner = document.getElementById("fwVersionsSpinner"); - loadingSpinner.style.display = "none"; - - refreshBasetunes(); - - //Re-enable the buttons - DetailsButton.disabled = false; - ChoosePortButton.disabled = false; - basetuneButton.disabled = false; - - }) - .catch((error) => { - console.log("Error retrieving available firmwares. ", error); - - var newOption = document.createElement('option'); - if(error.code === 'ETIMEDOUT') - { - newOption.value = "Connection timed out"; - newOption.innerHTML = "Connection timed out"; - } - else - { - newOption.value = "Cannot retrieve firmware list"; - newOption.innerHTML = "Cannot retrieve firmware list. Check internet connection and restart"; - } - select.appendChild(newOption); - - //Remove the loading spinner - loadingSpinner = document.getElementById("fwVersionsSpinner"); - loadingSpinner.style.display = "none"; - }); - -} - -function refreshBasetunes() -{ - //Check whether the base tunes list has been populated yet - if(basetuneList === undefined || basetuneList.length == 0) - { - console.log("No tunes loaded. Retrieving from server"); - //Load the json - //var url = "https://speeduino.com/fw/basetunes.json"; - var url = "https://github.com/speeduino/Tunes/raw/main/index.json"; - - fetch(url) + fetch('https://speeduino.com/fw/versions', { signal: AbortSignal.timeout(5000) }) .then((response) => { if (response.ok) { - return response.json(); + return response.text(); } return Promise.reject(response); }) .then((result) => { + var lines = result.split('\n'); + // Continue with your processing here. - basetuneList = result; + for (var i = 0; i < lines.length; i++) { + var newOption = document.createElement('option'); + newOption.value = lines[i]; + newOption.innerHTML = lines[i]; + select.appendChild(newOption); + } + select.selectedIndex = 0; //Remove the loading spinner - loadingSpinner = document.getElementById("baseTuneSpinner"); + loadingSpinner = document.getElementById("fwVersionsSpinner"); loadingSpinner.style.display = "none"; refreshBasetunes(); + + //Re-enable the buttons + DetailsButton.disabled = false; + ChoosePortButton.disabled = false; + basetuneButton.disabled = false; + }) .catch((error) => { - console.log('Could not download base tune list.', error); + console.log("Error retrieving available firmwares. ", error); + + var newOption = document.createElement('option'); + if (error.code === 'ETIMEDOUT') { + newOption.value = "Connection timed out"; + newOption.innerHTML = "Connection timed out"; + } + else { + newOption.value = "Cannot retrieve firmware list"; + newOption.innerHTML = "Cannot retrieve firmware list. Check internet connection and restart"; + } + select.appendChild(newOption); + + //Remove the loading spinner + loadingSpinner = document.getElementById("fwVersionsSpinner"); + loadingSpinner.style.display = "none"; }); +} + +function refreshBasetunes() { + //Check whether the base tunes list has been populated yet + if (basetuneList === undefined || basetuneList.length == 0) { + console.log("No tunes loaded. Retrieving from server"); + //Load the json + //var url = "https://speeduino.com/fw/basetunes.json"; + var url = "https://github.com/speeduino/Tunes/raw/main/index.json"; + + fetch(url) + .then((response) => { + if (response.ok) { + return response.json(); + } + return Promise.reject(response); + }) + .then((result) => { + + basetuneList = result; + + //Remove the loading spinner + loadingSpinner = document.getElementById("baseTuneSpinner"); + loadingSpinner.style.display = "none"; + + refreshBasetunes(); + }) + .catch((error) => { + console.log('Could not download base tune list.', error); + }); + } - else - { + else { //JSON list of base tunes has been downloaded console.log("Tune list downloaded. Populating filters"); @@ -259,9 +241,9 @@ function refreshBasetunes() typeSelect = document.getElementById('basetunesType'); //Clear the current values (There shouldn't be any, but safety first) - while(authorSelect.options.length) { authorSelect.remove(0); } - while(makeSelect.options.length) { makeSelect.remove(0); } - while(typeSelect.options.length) { typeSelect.remove(0); } + while (authorSelect.options.length) { authorSelect.remove(0); } + while (makeSelect.options.length) { makeSelect.remove(0); } + while (typeSelect.options.length) { typeSelect.remove(0); } //Manually add the 'All' entries var newOption1 = document.createElement('option'); @@ -285,138 +267,128 @@ function refreshBasetunes() //Create unique sets with all the options var authorsSet = new Set(); var makesSet = new Set(); - for (var tune in basetuneList) - { - authorsSet.add(basetuneList[tune].provider); - makesSet.add(basetuneList[tune].make); + for (var tune in basetuneList) { + authorsSet.add(basetuneList[tune].provider); + makesSet.add(basetuneList[tune].make); } //Add the options for authors - for(let item of authorsSet.values()) - { - var tempOption = document.createElement('option'); - tempOption.innerHTML = item; - authorSelect.appendChild(tempOption); + for (let item of authorsSet.values()) { + var tempOption = document.createElement('option'); + tempOption.innerHTML = item; + authorSelect.appendChild(tempOption); } //Add the options for makes - for(let item of makesSet.values()) - { - var tempOption = document.createElement('option'); - tempOption.innerHTML = item; - makeSelect.appendChild(tempOption); + for (let item of makesSet.values()) { + var tempOption = document.createElement('option'); + tempOption.innerHTML = item; + makeSelect.appendChild(tempOption); } authorSelect.selectedIndex = 0; makeSelect.selectedIndex = 0; typeSelect.selectedIndex = 0; - + //Apply the filters to the main list refreshBasetunesFilters() } } -function refreshBasetunesFilters() -{ - //Get the display list object - const select = document.getElementById('basetunesSelect'); +function refreshBasetunesFilters() { + //Get the display list object + const select = document.getElementById('basetunesSelect'); - //Get the currently selected Author - selectElement = document.getElementById('basetunesAuthor'); - if(selectElement.selectedIndex == -1) { return; } //Check for no value being selected - var selectedAuthor = selectElement.options[selectElement.selectedIndex].value; + //Get the currently selected Author + selectElement = document.getElementById('basetunesAuthor'); + if (selectElement.selectedIndex == -1) { return; } //Check for no value being selected + var selectedAuthor = selectElement.options[selectElement.selectedIndex].value; - //Get the currently selected Make - selectElement = document.getElementById('basetunesMake'); - if(selectElement.selectedIndex == -1) { return; } //Check for no value being selected - var selectedMake = selectElement.options[selectElement.selectedIndex].value; + //Get the currently selected Make + selectElement = document.getElementById('basetunesMake'); + if (selectElement.selectedIndex == -1) { return; } //Check for no value being selected + var selectedMake = selectElement.options[selectElement.selectedIndex].value; - //Get the currently selected Type - selectElement = document.getElementById('basetunesType'); - if(selectElement.selectedIndex == -1) { return; } //Check for no value being selected - var selectedType = selectElement.options[selectElement.selectedIndex].value; + //Get the currently selected Type + selectElement = document.getElementById('basetunesType'); + if (selectElement.selectedIndex == -1) { return; } //Check for no value being selected + var selectedType = selectElement.options[selectElement.selectedIndex].value; - //Clear the current options from the list - while(select.options.length) - { - select.remove(0); - } + //Clear the current options from the list + while (select.options.length) { + select.remove(0); + } - var validTunes = 0; - for (var tune in basetuneList) - { - //Check whether the current tune meets filters - var AuthorBool = selectedAuthor == "All" || basetuneList[tune].provider == selectedAuthor; - var MakeBool = selectedMake == "All" || basetuneList[tune].make == selectedMake; - var TypeBool = selectedType == "All" || basetuneList[tune].type == selectedType; - if(AuthorBool && MakeBool && TypeBool) - { - //var url = basetuneList[tune].baseURL.replace("$VERSION", selectedFW) + basetuneList[tune].filename; - //console.log("Tune url: " + url); - //console.log("Found a valid tune: " + basetuneList[tune].displayName); - var newOption = document.createElement('option'); - newOption.dataset.filename = basetuneList[tune].filename; - newOption.dataset.make = basetuneList[tune].make; - newOption.dataset.description = basetuneList[tune].description; - newOption.dataset.board = basetuneList[tune].board; - newOption.innerHTML = basetuneList[tune].displayName + " - " + basetuneList[tune].type; - select.appendChild(newOption); + var validTunes = 0; + for (var tune in basetuneList) { + //Check whether the current tune meets filters + var AuthorBool = selectedAuthor == "All" || basetuneList[tune].provider == selectedAuthor; + var MakeBool = selectedMake == "All" || basetuneList[tune].make == selectedMake; + var TypeBool = selectedType == "All" || basetuneList[tune].type == selectedType; + if (AuthorBool && MakeBool && TypeBool) { + //var url = basetuneList[tune].baseURL.replace("$VERSION", selectedFW) + basetuneList[tune].filename; + //console.log("Tune url: " + url); + //console.log("Found a valid tune: " + basetuneList[tune].displayName); + var newOption = document.createElement('option'); + newOption.dataset.filename = basetuneList[tune].filename; + newOption.dataset.make = basetuneList[tune].make; + newOption.dataset.description = basetuneList[tune].description; + newOption.dataset.board = basetuneList[tune].board; + newOption.innerHTML = basetuneList[tune].displayName + " - " + basetuneList[tune].type; + select.appendChild(newOption); - validTunes++; - } - - } - select.selectedIndex = 0; - refreshBasetunesDescription() - console.log("Tunes that met filters: " + validTunes); + validTunes++; + } + + } + select.selectedIndex = 0; + refreshBasetunesDescription() + console.log("Tunes that met filters: " + validTunes); } -function refreshBasetunesDescription() -{ - descriptionElement = document.getElementById('tuneDetailsText'); - //Get the currently selected Tune - selectElement = document.getElementById('basetunesSelect'); - if(selectElement.selectedIndex == -1) { return; } //Check for no value being selected - descriptionElement.innerHTML = selectElement.options[selectElement.selectedIndex].dataset.description; +function refreshBasetunesDescription() { + descriptionElement = document.getElementById('tuneDetailsText'); + //Get the currently selected Tune + selectElement = document.getElementById('basetunesSelect'); + if (selectElement.selectedIndex == -1) { return; } //Check for no value being selected + descriptionElement.innerHTML = selectElement.options[selectElement.selectedIndex].dataset.description; } -function downloadHex(board) -{ +function downloadHex(board) { var e = document.getElementById('versionsSelect'); var DLurl; - switch(board) { - case "TEENSY35": - DLurl = "http://speeduino.com/fw/teensy35/" + e.options[e.selectedIndex].value + "-teensy35.hex"; - console.log("Downloading Teensy 35 firmware: " + DLurl); - break; - case "TEENSY36": - DLurl = "http://speeduino.com/fw/teensy36/" + e.options[e.selectedIndex].value + "-teensy36.hex"; - console.log("Downloading Teensy 36 firmware: " + DLurl); - break; - case "TEENSY41": - DLurl = "http://speeduino.com/fw/teensy41/" + e.options[e.selectedIndex].value + "-teensy41.hex"; - console.log("Downloading Teensy 41 firmware: " + DLurl); - break; - case "ATMEGA2560": - DLurl = "http://speeduino.com/fw/bin/" + e.options[e.selectedIndex].value + ".hex"; - console.log("Downloading AVR firmware: " + DLurl); - break; - default: - DLurl = "http://speeduino.com/fw/bin/" + e.options[e.selectedIndex].value + ".hex"; - console.log("Downloading AVR firmware: " + DLurl); - break; + switch (board) { + case "TEENSY35": + DLurl = "http://speeduino.com/fw/teensy35/" + e.options[e.selectedIndex].value + "-teensy35.hex"; + console.log("Downloading Teensy 35 firmware: " + DLurl); + break; + case "TEENSY36": + DLurl = "http://speeduino.com/fw/teensy36/" + e.options[e.selectedIndex].value + "-teensy36.hex"; + console.log("Downloading Teensy 36 firmware: " + DLurl); + break; + case "TEENSY41": + DLurl = "http://speeduino.com/fw/teensy41/" + e.options[e.selectedIndex].value + "-teensy41.hex"; + console.log("Downloading Teensy 41 firmware: " + DLurl); + break; + case "ATMEGA2560": + DLurl = "http://speeduino.com/fw/bin/" + e.options[e.selectedIndex].value + ".hex"; + console.log("Downloading AVR firmware: " + DLurl); + break; + default: + DLurl = "http://speeduino.com/fw/bin/" + e.options[e.selectedIndex].value + ".hex"; + console.log("Downloading AVR firmware: " + DLurl); + break; } - + //Download the Hex file ipcRenderer.send("download", { url: DLurl, - properties: {directory: "downloads"} + properties: { directory: "downloads" } }); } -function downloadIni() -{ +function downloadIni() { var e = document.getElementById('versionsSelect'); var DLurl = "https://speeduino.com/fw/" + e.options[e.selectedIndex].value + ".ini"; @@ -425,42 +397,39 @@ function downloadIni() //Download the ini file ipcRenderer.send("download", { url: DLurl, - properties: {directory: "downloads"} + properties: { directory: "downloads" } }); } -function downloadBasetune() -{ - console.log("downloading"); - - var basetuneSelect = document.getElementById('basetunesSelect'); - var basetuneOption = basetuneSelect.options[basetuneSelect.selectedIndex]; - //var version = document.getElementById('versionsSelect'); - //var DLurl = "https://github.com/noisymime/speeduino/raw/" + version + "/reference/Base%20Tunes/" + e.options[e.selectedIndex].value; - var DLurl = "https://github.com/speeduino/Tunes/raw/main/" + basetuneOption.dataset.make + "/" + basetuneOption.dataset.filename; - console.log("Downloading: " + DLurl); +function downloadBasetune() { + console.log("downloading"); - //Download the ini file - ipcRenderer.send("download", { - url: DLurl, - properties: {directory: "downloads"} - }); + var basetuneSelect = document.getElementById('basetunesSelect'); + var basetuneOption = basetuneSelect.options[basetuneSelect.selectedIndex]; + //var version = document.getElementById('versionsSelect'); + //var DLurl = "https://github.com/noisymime/speeduino/raw/" + version + "/reference/Base%20Tunes/" + e.options[e.selectedIndex].value; + var DLurl = "https://github.com/speeduino/Tunes/raw/main/" + basetuneOption.dataset.make + "/" + basetuneOption.dataset.filename; + console.log("Downloading: " + DLurl); - const baseTuneLink = document.querySelectorAll('a[href="#basetunes"]'); - baseTuneLink[0].click(); + //Download the ini file + ipcRenderer.send("download", { + url: DLurl, + properties: { directory: "downloads" } + }); + + const baseTuneLink = document.querySelectorAll('a[href="#basetunes"]'); + baseTuneLink[0].click(); } //Installing the Windows drivers -function installDrivers() -{ +function installDrivers() { ipcRenderer.send("installWinDrivers", { }); } -function uploadFW() -{ +function uploadFW() { //Start the spinner var spinner = document.getElementById('progressSpinner'); @@ -491,42 +460,38 @@ function uploadFW() console.log("Saved file: " + file); // Full file path var extension = file.substr(file.length - 3); - if(extension == "ini") - { + if (extension == "ini") { statusText.innerHTML = "Downloading firmware" document.getElementById('iniFileText').style.display = "block" document.getElementById('iniFileLocation').innerHTML = file downloadHex(uploadBoard); } - else if(extension == "hex") - { + else if (extension == "hex") { statusText.innerHTML = "Beginning upload..." //Retrieve the select serial port var e = document.getElementById('portsSelect'); uploadPort = e.options[e.selectedIndex].value; - + console.log("Using port: " + uploadPort); //Show the sponsor banner document.getElementById('sponsorbox').style.display = "block" //Begin the upload - if(uploadBoard.includes("TEENSY")) - { - console.log("Uploading using Teensy_loader") - ipcRenderer.send("uploadFW_teensy", { - port: uploadPort, - firmwareFile: file, - board: uploadBoard - }); + if (uploadBoard.includes("TEENSY")) { + console.log("Uploading using Teensy_loader") + ipcRenderer.send("uploadFW_teensy", { + port: uploadPort, + firmwareFile: file, + board: uploadBoard + }); } - else - { - ipcRenderer.send("uploadFW", { - port: uploadPort, - firmwareFile: file - }); + else { + ipcRenderer.send("uploadFW", { + port: uploadPort, + firmwareFile: file + }); } } }); @@ -569,8 +534,7 @@ function uploadFW() } -async function checkForUpdates() -{ +async function checkForUpdates() { //Adds the current version number to the Titlebar let current_version = await ipcRenderer.invoke("getAppVersion"); document.getElementById('title').innerHTML = "Speeduino Universal Firmware Loader (v" + current_version + ")" @@ -580,28 +544,27 @@ async function checkForUpdates() //document.getElementById('detailsHeading').innerHTML = version; fetch(url) - .then((response) => { - if (response.ok) { - return response.json(); - } - return Promise.reject(response); - }) - .then((result) => { + .then((response) => { + if (response.ok) { + return response.json(); + } + return Promise.reject(response); + }) + .then((result) => { - latest_version = result.tag_name.substring(1); - console.log("Latest version: " + latest_version); + latest_version = result.tag_name.substring(1); + console.log("Latest version: " + latest_version); - var semver = require('semver'); - if(semver.gt(latest_version, current_version)) - { - //New version has been found - document.getElementById('update_url').setAttribute("href", result.html_url); - document.getElementById('update_text').style.display = "block"; - } - }) - .catch((error) => { - console.log('Could not get latest version.', error); - }); + var semver = require('semver'); + if (semver.gt(latest_version, current_version)) { + //New version has been found + document.getElementById('update_url').setAttribute("href", result.html_url); + document.getElementById('update_text').style.display = "block"; + } + }) + .catch((error) => { + console.log('Could not get latest version.', error); + }); } @@ -610,61 +573,60 @@ window.onload = function () { refreshBasetunes(); refreshSerialPorts(); checkForUpdates(); - + }; -$(function(){ +$(function () { - // Button handlers - $(document).on('click', '#btnChoosePort', function(event) { - $("[href='#port']").trigger('click'); - }); + // Button handlers + $(document).on('click', '#btnChoosePort', function (event) { + $("[href='#port']").trigger('click'); + }); - $(document).on('click', '#btnBasetune', function(event) { - $("[href='#basetunes']").trigger('click'); - }); + $(document).on('click', '#btnBasetune', function (event) { + $("[href='#basetunes']").trigger('click'); + }); - $(document).on('click', '#btnLoader', function(event) { - $("[href='#loader']").trigger('click'); - }); + $(document).on('click', '#btnLoader', function (event) { + $("[href='#loader']").trigger('click'); + }); - $(document).on('click', '#btnDetails', function(event) { - refreshDetails(); - $("[href='#details']").trigger('click'); - }); + $(document).on('click', '#btnDetails', function (event) { + refreshDetails(); + $("[href='#details']").trigger('click'); + }); - $(document).on('click', '#btnInstall', function(event) { - $("[href='#progress']").trigger('click'); - uploadFW(); - }); + $(document).on('click', '#btnInstall', function (event) { + $("[href='#progress']").trigger('click'); + uploadFW(); + }); - $(document).on('click', '#btnReinstall', function(event) { - $("[href='#progress']").trigger('click'); - uploadFW(); - }); + $(document).on('click', '#btnReinstall', function (event) { + $("[href='#progress']").trigger('click'); + uploadFW(); + }); - $(document).on('click', '#btnDownloadBasetune', function(event) { - const select = document.getElementById('basetunesSelect'); - const selectedTune = select.options[select.selectedIndex]; - document.getElementById("tuneBoard").innerHTML = selectedTune.dataset.board; + $(document).on('click', '#btnDownloadBasetune', function (event) { + const select = document.getElementById('basetunesSelect'); + const selectedTune = select.options[select.selectedIndex]; + document.getElementById("tuneBoard").innerHTML = selectedTune.dataset.board; - $("[href='#basetunewarning']").trigger('click'); - }); + $("[href='#basetunewarning']").trigger('click'); + }); - $(document).on('click', '#btnDownloadCancel', function(event) { - $("[href='#basetunes']").trigger('click'); - }); + $(document).on('click', '#btnDownloadCancel', function (event) { + $("[href='#basetunes']").trigger('click'); + }); - $(document).on('click', '#btnExit', function(event) { - ipcRenderer.invoke('quit-app'); - }); + $(document).on('click', '#btnExit', function (event) { + ipcRenderer.invoke('quit-app'); + }); - $(document).on('click', '#iniFileLink', function(event) { - var location = document.getElementById('iniFileLocation').innerHTML - if (location != "") - { - ipcRenderer.invoke('show-ini', location); - } - }); + $(document).on('click', '#iniFileLink', function (event) { + var location = document.getElementById('iniFileLocation').innerHTML + if (location != "") { + ipcRenderer.invoke('show-ini', location); + } + }); -}); \ No newline at end of file +});