From d1f81ce2e3f77a4dba8cead377bb7b5a7cd2152a Mon Sep 17 00:00:00 2001 From: Peter Prince Date: Tue, 26 Sep 2023 15:56:17 +0100 Subject: [PATCH] Add 1.1.1 changes --- about.html | 2 +- about.js | 30 ++++++++++---- app.js | 100 ++++++++++++++++++++++++++++------------------ builder.js | 17 ++++---- index.css | 16 ++++++++ index.html | 10 ++--- main.js | 83 +++++++++++++++++++++++++++++--------- nightMode.js | 50 +++++++++++++++++++++++ package.json | 36 ++++++++++------- ui.css | 0 uiNight.css | 18 +++++++++ versionChecker.js | 55 +++++++------------------ 12 files changed, 283 insertions(+), 134 deletions(-) create mode 100644 index.css create mode 100644 nightMode.js create mode 100644 ui.css create mode 100644 uiNight.css diff --git a/about.html b/about.html index 9ee9764..c27fffa 100644 --- a/about.html +++ b/about.html @@ -3,7 +3,7 @@ - About AudioMoth Time App + diff --git a/about.js b/about.js index db623d8..008a817 100644 --- a/about.js +++ b/about.js @@ -9,18 +9,34 @@ /* global document */ const electron = require('electron'); +const {app, process} = require('@electron/remote'); const audiomoth = require('audiomoth-hid'); +const nightMode = require('./nightMode.js'); -var versionDisplay = document.getElementById('version-display'); -var electronVersionDisplay = document.getElementById('electron-version-display'); -var audiomothHidVersionDisplay = document.getElementById('audiomoth-hid-version-display'); -var websiteLink = document.getElementById('website-link'); +const versionDisplay = document.getElementById('version-display'); +const electronVersionDisplay = document.getElementById('electron-version-display'); +const audiomothHidVersionDisplay = document.getElementById('audiomoth-hid-version-display'); +const websiteLink = document.getElementById('website-link'); -versionDisplay.textContent = 'Version ' + electron.remote.app.getVersion(); -electronVersionDisplay.textContent = 'Running on Electron version ' + electron.remote.process.versions.electron; +versionDisplay.textContent = 'Version ' + app.getVersion(); +electronVersionDisplay.textContent = 'Running on Electron version ' + process.versions.electron; audiomothHidVersionDisplay.textContent = 'AudioMoth-HID module ' + audiomoth.version; -websiteLink.addEventListener('click', function () { +electron.ipcRenderer.on('night-mode', (e, nm) => { + + if (nm !== undefined) { + + nightMode.setNightMode(nm); + + } else { + + nightMode.toggle(); + + } + +}); + +websiteLink.addEventListener('click', () => { electron.shell.openExternal('https://openacousticdevices.info'); diff --git a/app.js b/app.js index 0f6ace7..62f197a 100644 --- a/app.js +++ b/app.js @@ -9,34 +9,35 @@ /* global document */ const electron = require('electron'); -const clipboard = electron.remote.clipboard; -const menu = electron.remote.Menu; -const dialog = electron.remote.dialog; +const {clipboard, Menu, dialog, getCurrentWindow} = require('@electron/remote'); const strftime = require('strftime').utc(); const audiomoth = require('audiomoth-hid'); const versionChecker = require('./versionChecker.js'); +const nightMode = require('./nightMode.js'); /* UI components */ -var applicationMenu = menu.getApplicationMenu(); +const applicationMenu = Menu.getApplicationMenu(); -var timeDisplay = document.getElementById('time-display'); -var idLabel = document.getElementById('id-label'); -var idDisplay = document.getElementById('id-display'); -var firmwareVersionLabel = document.getElementById('firmware-version-label'); -var firmwareVersionDisplay = document.getElementById('firmware-version-display'); -var firmwareDescriptionLabel = document.getElementById('firmware-description-label'); -var firmwareDescriptionDisplay = document.getElementById('firmware-description-display'); -var batteryLabel = document.getElementById('battery-label'); -var batteryDisplay = document.getElementById('battery-display'); +const timeDisplay = document.getElementById('time-display'); +const idLabel = document.getElementById('id-label'); +const idDisplay = document.getElementById('id-display'); +const firmwareVersionLabel = document.getElementById('firmware-version-label'); +const firmwareVersionDisplay = document.getElementById('firmware-version-display'); +const firmwareDescriptionLabel = document.getElementById('firmware-description-label'); +const firmwareDescriptionDisplay = document.getElementById('firmware-description-display'); +const batteryLabel = document.getElementById('battery-label'); +const batteryDisplay = document.getElementById('battery-display'); -var setTimeButton = document.getElementById('set-time-button'); +const setTimeButton = document.getElementById('set-time-button'); -var communicating = false; +const MILLISECONDS_IN_SECOND = 1000; -var currentTime, deviceId, firmwareVersion, firmwareDescription; +let communicating = false; + +let currentTime, deviceId, firmwareVersion, firmwareDescription; /* Time display functions */ @@ -80,7 +81,7 @@ function enableDisplayAndShowTime (date) { } - var strftimeUTC = strftime.timezone(0); + const strftimeUTC = strftime.timezone(0); timeDisplay.textContent = strftimeUTC('%H:%M:%S %d/%m/%Y UTC', date); @@ -150,6 +151,8 @@ function requestFirmwareDescription () { audiomoth.getFirmwareDescription(function (err, description) { + if (communicating) return; + if (err) { errorOccurred(err); @@ -174,6 +177,8 @@ function requestFirmwareVersion () { audiomoth.getFirmwareVersion(function (err, versionArr) { + if (communicating) return; + if (err) { errorOccurred(err); @@ -198,6 +203,8 @@ function requestBatteryState () { audiomoth.getBatteryState(function (err, batteryState) { + if (communicating) return; + if (err) { errorOccurred(err); @@ -224,6 +231,8 @@ function requestID () { audiomoth.getID(function (err, id) { + if (communicating) return; + if (err) { errorOccurred(err); @@ -246,14 +255,12 @@ function requestID () { function requestTime () { - if (communicating) { - - return; - - } + if (communicating) return; audiomoth.getTime(function (err, date) { + if (communicating) return; + if (err) { errorOccurred(err); @@ -270,10 +277,16 @@ function requestTime () { } - setTimeout(requestTime, 300); - }); + const milliseconds = Date.now() % MILLISECONDS_IN_SECOND; + + let delay = MILLISECONDS_IN_SECOND / 2 - milliseconds; + + if (delay < 0) delay += MILLISECONDS_IN_SECOND; + + setTimeout(requestTime, delay); + } function setTime (time) { @@ -315,13 +328,11 @@ electron.ipcRenderer.on('update-check', function () { versionChecker.checkLatestRelease(function (response) { - var buttonIndex; - if (response.error) { console.error(response.error); - dialog.showMessageBox(electron.remote.getCurrentWindow(), { + dialog.showMessageBox(getCurrentWindow(), { type: 'error', title: 'Failed to check for updates', message: response.error @@ -333,7 +344,7 @@ electron.ipcRenderer.on('update-check', function () { if (response.updateNeeded === false) { - dialog.showMessageBox(electron.remote.getCurrentWindow(), { + dialog.showMessageBox(getCurrentWindow(), { type: 'info', title: 'Update not needed', message: 'Your app is on the latest version (' + response.latestVersion + ').' @@ -343,7 +354,7 @@ electron.ipcRenderer.on('update-check', function () { } - buttonIndex = dialog.showMessageBoxSync({ + const buttonIndex = dialog.showMessageBoxSync({ type: 'warning', buttons: ['Yes', 'No'], title: 'Are you sure?', @@ -368,16 +379,15 @@ initialiseDisplay(); setTimeButton.addEventListener('click', function () { - var sendTime, now, delay, sendTimeDiff, USB_LAG, MINIMUM_DELAY, MILLISECONDS_IN_SECOND; - communicating = true; + timeDisplay.style.color = 'lightgrey'; - USB_LAG = 20; + const USB_LAG = 20; - MINIMUM_DELAY = 100; + const MINIMUM_DELAY = 100; - MILLISECONDS_IN_SECOND = 1000; + const MILLISECONDS_IN_SECOND = 1000; /* Update button */ @@ -395,9 +405,9 @@ setTimeButton.addEventListener('click', function () { /* Increment to next second transition */ - sendTime = new Date(); + const sendTime = new Date(); - delay = MILLISECONDS_IN_SECOND - sendTime.getMilliseconds() - USB_LAG; + let delay = MILLISECONDS_IN_SECOND - sendTime.getMilliseconds() - USB_LAG; if (delay < MINIMUM_DELAY) delay += MILLISECONDS_IN_SECOND; @@ -405,8 +415,8 @@ setTimeButton.addEventListener('click', function () { /* Calculate how long to wait until second transition */ - now = new Date(); - sendTimeDiff = sendTime.getTime() - now.getTime(); + const now = new Date(); + const sendTimeDiff = sendTime.getTime() - now.getTime(); /* Either send immediately or wait until the transition */ @@ -428,4 +438,18 @@ setTimeButton.addEventListener('click', function () { }); +electron.ipcRenderer.on('night-mode', (e, nm) => { + + if (nm !== undefined) { + + nightMode.setNightMode(nm); + + } else { + + nightMode.toggle(); + + } + +}); + requestTime(); diff --git a/builder.js b/builder.js index 100ae2d..86eb689 100644 --- a/builder.js +++ b/builder.js @@ -9,35 +9,36 @@ const builder = require('electron-builder'); const Platform = builder.Platform; -var config, target; -var argTarget = process.argv[2]; +let config, target; + +const argTarget = process.argv[2]; switch (argTarget) { case 'win': -case 'win64': - console.log('Using build configuration to Windows (64-bit).'); +case 'win32': + console.log('Using build configuration to Windows (32-bit).'); target = Platform.WINDOWS.createTarget(); config = { win: { target: [ { target: 'nsis', - arch: 'x64' + arch: 'ia32' } ] } }; break; -case 'win32': - console.log('Using build configuration to Windows (32-bit).'); +case 'win64': + console.log('Using build configuration to Windows (64-bit).'); target = Platform.WINDOWS.createTarget(); config = { win: { target: [ { target: 'nsis', - arch: 'ia32' + arch: 'x64' } ] } diff --git a/index.css b/index.css new file mode 100644 index 0000000..41d80e4 --- /dev/null +++ b/index.css @@ -0,0 +1,16 @@ +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +*, *::after, *::before { + -webkit-user-select: none; + -webkit-user-drag: none; + -webkit-app-region: no-drag; + cursor: default; +} + +.mono-text { + font-variant-numeric: tabular-nums; +} diff --git a/index.html b/index.html index 0bbbe73..8d2d53a 100644 --- a/index.html +++ b/index.html @@ -3,17 +3,17 @@ - AudioMoth Time App + - -
+ +
- +
@@ -58,7 +58,7 @@
-
+
diff --git a/main.js b/main.js index 39fdd54..7b0b2b8 100644 --- a/main.js +++ b/main.js @@ -6,24 +6,21 @@ 'use strict'; -var electron = require('electron'); -var app = electron.app; +const {app, Menu, shell, ipcMain, BrowserWindow} = require('electron'); -var BrowserWindow = electron.BrowserWindow; -var Menu = electron.Menu; -var shell = electron.shell; +require('@electron/remote/main').initialize(); + +let mainWindow, aboutWindow; require('electron-debug')({ showDevTools: 'undocked' }); -var path = require('path'); +const path = require('path'); function openAboutWindow () { - var aboutWindow, iconLocation; - - iconLocation = '/build/icon.ico'; + let iconLocation = '/build/icon.ico'; if (process.platform === 'linux') { @@ -34,24 +31,64 @@ function openAboutWindow () { aboutWindow = new BrowserWindow({ width: 400, height: 325, + title: 'About AudioMoth Time App', resizable: false, fullscreenable: false, icon: path.join(__dirname, iconLocation), + parent: mainWindow, webPreferences: { - nodeIntegration: true + enableRemoteModule: true, + nodeIntegration: true, + contextIsolation: false } }); aboutWindow.setMenu(null); aboutWindow.loadURL(path.join('file://', __dirname, '/about.html')); + require('@electron/remote/main').enable(aboutWindow.webContents); + + aboutWindow.on('closed', () => { + + aboutWindow = null; + + }); + + aboutWindow.webContents.on('dom-ready', function () { + + mainWindow.webContents.send('poll-night-mode'); + + }); + + ipcMain.on('night-mode-poll-reply', (e, nightMode) => { + + if (aboutWindow) { + + aboutWindow.webContents.send('night-mode', nightMode); + + } + + }); + +} + +function toggleNightMode () { + + mainWindow.webContents.send('night-mode'); + + if (aboutWindow) { + + aboutWindow.webContents.send('night-mode'); + + } + } app.on('ready', function () { - var mainWindow, menuTemplate, menu, windowHeight, iconLocation; + let iconLocation = '/build/icon.ico'; - iconLocation = '/build/icon.ico'; + let windowHeight = 250; if (process.platform === 'darwin') { @@ -62,27 +99,35 @@ app.on('ready', function () { windowHeight = 230; iconLocation = '/build/icon.png'; - } else { - - windowHeight = 250; - } mainWindow = new BrowserWindow({ width: 565, height: windowHeight, useContentSize: true, + title: 'AudioMoth Time App', resizable: false, fullscreenable: false, icon: path.join(__dirname, iconLocation), webPreferences: { - nodeIntegration: true + enableRemoteModule: true, + nodeIntegration: true, + contextIsolation: false } }); - menuTemplate = [{ + require('@electron/remote/main').enable(mainWindow.webContents); + + const menuTemplate = [{ label: 'File', submenu: [{ + type: 'checkbox', + id: 'nightmode', + label: 'Night Mode', + accelerator: 'CommandOrControl+N', + checked: false, + click: toggleNightMode + }, { id: 'copyid', label: 'Copy Device ID', accelerator: 'CommandOrControl+I', @@ -131,7 +176,7 @@ app.on('ready', function () { }] }]; - menu = Menu.buildFromTemplate(menuTemplate); + const menu = Menu.buildFromTemplate(menuTemplate); Menu.setApplicationMenu(menu); diff --git a/nightMode.js b/nightMode.js new file mode 100644 index 0000000..5d76571 --- /dev/null +++ b/nightMode.js @@ -0,0 +1,50 @@ +/**************************************************************************** + * nightMode.js + * openacousticdevices.info + * December 2019 + *****************************************************************************/ + +'use strict'; + +const {app} = require('@electron/remote'); + +let nightMode = false; + +exports.isEnabled = () => { + + return nightMode; + +}; + +function setNightMode (nm) { + + nightMode = nm; + + const oldLink = document.getElementById('uiCSS'); + const newLink = document.createElement('link'); + + newLink.setAttribute('id', 'uiCSS'); + newLink.setAttribute('rel', 'stylesheet'); + newLink.setAttribute('type', 'text/css'); + + if (nightMode) { + + newLink.setAttribute('href', app.getAppPath() + '/uiNight.css'); + + } else { + + newLink.setAttribute('href', app.getAppPath() + '/ui.css'); + + } + + document.getElementsByTagName('head').item(0).replaceChild(newLink, oldLink); + +} + +exports.setNightMode = setNightMode; + +exports.toggle = () => { + + setNightMode(!nightMode); + +}; diff --git a/package.json b/package.json index a34c447..9de528d 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "AudioMoth-Time", - "version": "1.1.0", + "version": "1.1.1", "description": "The time app for the AudioMoth acoustic acoustic monitoring device.", "main": "main.js", "author": "openacousticdevices.info", "license": "ISC", "repository": { - "type" : "git", - "url" : "https://github.com/OpenAcousticDevices/AudioMoth-Time-App.git" + "type": "git", + "url": "https://github.com/OpenAcousticDevices/AudioMoth-Time-App.git" }, "scripts": { "postinstall": "install-app-deps", @@ -45,6 +45,8 @@ }, "nsis": { "createDesktopShortcut": true, + "oneClick": false, + "allowToChangeInstallationDirectory": true, "artifactName": "AudioMothTimeAppSetup${version}.exe", "shortcutName": "AudioMoth Time App", "uninstallDisplayName": "AudioMoth Time App ${version}" @@ -55,22 +57,26 @@ } }, "devDependencies": { - "electron": "8.5.2", - "electron-builder": "^22.8.1", - "eslint": "^6.8.0", - "eslint-config-standard": "^14.1.1", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-node": "^10.0.0", - "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-standard": "^4.0.2" + "electron": "25.3.2", + "electron-builder": "^24.6.3", + "eslint": "^8.45.0", + "eslint-plugin-n": "^16.0.1", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-standard": "^4.1.0" }, "dependencies": { + "@electron/remote": "^2.0.10", "audiomoth-hid": "^2.1.0", - "bootstrap": "4.3.1", - "electron-debug": "3.0.1", - "jquery": "^3.5.1", + "bootstrap": "5.3.1", + "electron-debug": "3.2.0", + "jquery": "^3.7.0", "popper.js": "^1.15.0", - "strftime": "0.10.0" + "strftime": "0.10.2", + "http-cache-semantics": "^4.1.1", + "semver": "^7.5.4" }, "engines": { "node": ">=10.16.2" diff --git a/ui.css b/ui.css new file mode 100644 index 0000000..e69de29 diff --git a/uiNight.css b/uiNight.css new file mode 100644 index 0000000..c1bc0ed --- /dev/null +++ b/uiNight.css @@ -0,0 +1,18 @@ +body { + background: #000000; + color: #FFFFFF; +} + +input { + background: #000000; + color: #FFFFFF; +} + +select { + background: #000000; + color: #FFFFFF; +} + +.grey { + color:#808080; +} \ No newline at end of file diff --git a/versionChecker.js b/versionChecker.js index 016d6d8..3729025 100644 --- a/versionChecker.js +++ b/versionChecker.js @@ -8,42 +8,15 @@ /* global XMLHttpRequest */ -const electron = require('electron'); +const {app} = require('@electron/remote'); -var pjson = require('./package.json'); +const semver = require('semver'); -/* Compare two semantic versions and return true if older */ - -function isOlderSemanticVersion (aVersion, bVersion) { - - var aVersionNum, bVersionNum; - - for (let i = 0; i < aVersion.length; i++) { - - aVersionNum = aVersion[i]; - bVersionNum = bVersion[i]; - - if (aVersionNum > bVersionNum) { - - return false; - - } else if (aVersionNum < bVersionNum) { - - return true; - - } - - } - - return false; - -} +const pjson = require('./package.json'); /* Check current app version in package.json against latest version in repository's releases */ -exports.checkLatestRelease = function (callback) { - - var version, repoGitURL, repoURL, xmlHttp, responseJson, latestVersion, updateNeeded; +exports.checkLatestRelease = (callback) => { /* Check for internet connection */ @@ -54,38 +27,38 @@ exports.checkLatestRelease = function (callback) { } - version = electron.remote.app.getVersion(); + const version = app.getVersion(); /* Transform repository URL into release API URL */ - repoGitURL = pjson.repository.url; - repoURL = repoGitURL.replace('.git', '/releases'); + const repoGitURL = pjson.repository.url; + let repoURL = repoGitURL.replace('.git', '/releases'); repoURL = repoURL.replace('github.com', 'api.github.com/repos'); - xmlHttp = new XMLHttpRequest(); + const xmlHttp = new XMLHttpRequest(); xmlHttp.open('GET', repoURL, true); - xmlHttp.onload = function () { + xmlHttp.onload = () => { if (xmlHttp.status === 200) { - responseJson = JSON.parse(xmlHttp.responseText); + const responseJson = JSON.parse(xmlHttp.responseText); - latestVersion = responseJson[0].tag_name; + const latestVersion = responseJson[0].tag_name; console.log('Comparing latest release (' + latestVersion + ') with currently installed version (' + version + ')'); /* Compare current version in package.json to latest version pulled from Github */ - updateNeeded = isOlderSemanticVersion(version, latestVersion); + const updateNeeded = semver.lt(version, latestVersion); - callback({updateNeeded: updateNeeded, latestVersion: updateNeeded ? latestVersion : version}); + callback({updateNeeded, latestVersion: updateNeeded ? latestVersion : version}); } }; - xmlHttp.onerror = function () { + xmlHttp.onerror = () => { console.error('Failed to pull release information.'); callback({updateNeeded: false, error: 'HTTP connection error, failed to request app version information.'});