diff --git a/locales/en/messages.json b/locales/en/messages.json index 281f2589c15..83f0313756d 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -68,6 +68,9 @@ "cancel": { "message": "Cancel" }, + "cancel": { + "message": "Cancel" + }, "autoConnectEnabled": { "message": "Auto-Connect: Enabled - Configurator automatically tries to connect when new port is detected" }, @@ -2923,6 +2926,18 @@ "firmwareFlasherFlashTrigger": { "message": "Detected: $1 - triggering flash on connect" }, + "unstableFirmwareAcknoledgementDialog": { + "message": "You are about to flash a development build of the firmware. These builds are a work in progress, and any of the following can be the case:If you proceed with flashing this firmware, you are assuming full responsibility for the risk of any of the above happening. Furthermore you acknowledge that it is necessary to perform thorough bench tests with props off before any attempts to fly this firmware." + }, + "unstableFirmwareAcknoledgementAcknowledge": { + "message": "I have read the above and I assume full responsibility for flashing unstable firmware" + }, + "unstableFirmwareAcknoledgementFlash": { + "message": "Flash" + }, + "firmwareFlasherPreviousDevice": { + "message": "Detected: $1 - previous device still flashing, please replug to try again" + }, "firmwareFlasherPreviousDevice": { "message": "Detected: $1 - previous device still flashing, please replug to try again" }, diff --git a/src/css/main.css b/src/css/main.css index 3bc115176db..b85c4eb42b6 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -1044,6 +1044,48 @@ dialog { border: 1px solid silver; } +dialog .dialog_toolbar .btn a { + /* common styles for content toolbar buttons */ + margin-top: 0px; + margin-bottom: 0px; + margin-right: 20px; + background-color: var(--accent); + border-radius: 3px; + border: 1px solid #dba718; + color: #000; + float: left; + font-weight: bold; + font-size: 12px; + text-shadow: 0px 1px rgba(255, 255, 255, 0.25); + display: block; + cursor: pointer; + transition: all ease 0.2s; + padding: 0px; + padding-left: 9px; + padding-right: 9px; + line-height: 28px; +} + +dialog .dialog_toolbar .btn a:hover { + background-color: #ffcc3e; + transition: all ease 0.2s; +} + +dialog .dialog_toolbar .btn a:active { + background-color: var(--accent); + transition: all ease 0.0s; + box-shadow: inset 0px 1px 5px rgba(0, 0, 0, 0.35); +} + +dialog .dialog_toolbar .btn a.disabled { + cursor: default; + color: #fff; + background-color: #AFAFAF; + border: 1px solid #AFAFAF; + pointer-events: none; + text-shadow: none; + opacity: 0.5; +} /* Border of the Tab */ /* Tab Title */ diff --git a/src/css/tabs/firmware_flasher.css b/src/css/tabs/firmware_flasher.css index ea46057b707..972b82b8ff4 100644 --- a/src/css/tabs/firmware_flasher.css +++ b/src/css/tabs/firmware_flasher.css @@ -192,63 +192,6 @@ text-decoration: underline; } -.tab-firmware_flasher .buttons { - width: calc(100% - 20px); - margin-top: 10px; - bottom: 10px; -} - -.tab-firmware_flasher .buttons a { - display: block; - float: left; - margin: 0 10px 0 0; - padding: 0 15px 0 15px; - height: 28px; - line-height: 28px; - text-align: center; - font-weight: bold; - border: 1px solid var(--subtleAccent); - background-color: #ececec; -} - -.tab-firmware_flasher .buttons a:hover { - background-color: #dedcdc; -} - -.tab-firmware_flasher .buttons a.exit_dfu.locked { - float: left; - background-color: #b8b8b8; -} - -.tab-firmware_flasher .buttons a.exit_dfu.locked:hover { - float: left; - cursor: default; - background-color: #b8b8b8; -} - -.tab-firmware_flasher .buttons a.flash_firmware.locked { - background-color: #b8b8b8; -} - -.tab-firmware_flasher .buttons a.flash_firmware.locked:hover { - cursor: default; - background-color: #b8b8b8; -} - -.tab-firmware_flasher .buttons a.load_remote_file.locked { - background-color: #b8b8b8; -} - -.tab-firmware_flasher .buttons a.load_remote_file.locked:hover { - cursor: default; - background-color: #b8b8b8; -} - -.tab-firmware_flasher .buttons .back { - float: right; - margin: 0; -} - .btn .disabled { cursor: default; color: #fff; @@ -258,3 +201,16 @@ text-shadow: none; opacity: 0.5; } + +#dialogUnstableFirmwareAcknoledgement .content { + margin-top: 10px; +} + +#dialogUnstableFirmwareAcknoledgement .content div { + margin-bottom: 10px; +} + +#dialogUnstableFirmwareAcknoledgement .content ul { + margin-top: 5px; + margin-bottom: 5px; +} diff --git a/src/js/tabs/firmware_flasher.js b/src/js/tabs/firmware_flasher.js index 96445ab4781..badad9679d8 100644 --- a/src/js/tabs/firmware_flasher.js +++ b/src/js/tabs/firmware_flasher.js @@ -12,6 +12,7 @@ TABS.firmware_flasher = { unifiedTargetConfigName: undefined, isConfigLocal: false, // Set to true if the user loads one locally remoteUnifiedTargetConfig: undefined, // Unified target configuration loaded from the menu, used when throwing out a local config + developmentFirmwareLoaded: false, // Is the firmware to be flashed from the development branch? }; TABS.firmware_flasher.initialize = function (callback) { @@ -236,7 +237,7 @@ TABS.firmware_flasher.initialize = function (callback) { var checkTime = Math.floor(Date.now() / 1000); // Lets deal in seconds. if (builds && hasUnifiedTargetBuild(builds)) { console.log('loaded some builds for later'); - var storageTag = 'unifiedSourceCache'; + const storageTag = 'unifiedSourceCache'; chrome.storage.local.get(storageTag, function (result) { let storageObj = result[storageTag]; if(!storageObj || !storageObj.lastUpdate || checkTime - storageObj.lastUpdate > expirationPeriod ) { @@ -350,7 +351,7 @@ TABS.firmware_flasher.initialize = function (callback) { buildTypesToShow.forEach((build, index) => { buildType_e.append($("".format(index, build.tag ? i18n.getMessage(build.tag) : build.title))) }); - $('select[name="build_type"]').val($('select[name="build_type"] option:first').val()); + buildType_e.val($('select[name="build_type"] option:first').val()); } function showOrHideBuildTypes() { @@ -583,7 +584,7 @@ TABS.firmware_flasher.initialize = function (callback) { }; if (TABS.firmware_flasher.unifiedConfigs[target]) { - var storageTag = 'unifiedConfigLast'; + const storageTag = 'unifiedConfigLast'; var expirationPeriod = 3600; // One of your earth hours. var checkTime = Math.floor(Date.now() / 1000); // Lets deal in seconds. chrome.storage.local.get(storageTag, function (result) { @@ -814,7 +815,7 @@ TABS.firmware_flasher.initialize = function (callback) { // UI Hooks $('a.load_file').click(function () { self.enableFlashing(false); - //self.localFileLoaded = true; + self.developmentFirmwareLoaded = false; analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHANNEL, undefined); analytics.setFirmwareData(analytics.DATA.FIRMWARE_SOURCE, 'file'); @@ -910,6 +911,9 @@ TABS.firmware_flasher.initialize = function (callback) { FirmwareCache.get(release, cached => { analytics.setFirmwareData(analytics.DATA.FIRMWARE_NAME, release.file); console.info("Release found in cache: " + release.file); + + self.developmentFirmwareLoaded = buildTypesToShow[$('select[name="build_type"]').val()].tag === 'firmwareFlasherOptionLabelBuildTypeDevelopment'; + onLoadSuccess(cached.hexdata, release); }); } @@ -923,6 +927,7 @@ TABS.firmware_flasher.initialize = function (callback) { $('a.load_remote_file').click(function (evt) { self.enableFlashing(false); self.localFirmwareLoaded = false; + self.developmentFirmwareLoaded = buildTypesToShow[$('select[name="build_type"]').val()].tag === 'firmwareFlasherOptionLabelBuildTypeDevelopment'; analytics.setFirmwareData(analytics.DATA.FIRMWARE_SOURCE, 'http'); @@ -984,33 +989,97 @@ TABS.firmware_flasher.initialize = function (callback) { $('a.flash_firmware').click(function () { if (!$(this).hasClass('disabled')) { - if (!GUI.connect_lock) { // button disabled while flashing is in progress - if (self.parsed_hex) { - try { - if (self.unifiedTargetConfig && !self.parsed_hex.configInserted) { - var configInserter = new ConfigInserter(); + if (self.developmentFirmwareLoaded) { + checkShowAcknowledgementDialog(); + } else { + startFlashing(); + } + } + }); - if (configInserter.insertConfig(self.parsed_hex, self.unifiedTargetConfig)) { - self.parsed_hex.configInserted = true; - } else { - console.log('Firmware does not support custom defaults.'); + function checkShowAcknowledgementDialog() { + const DAY_MS = 86400 * 1000; + const storageTag = 'lastDevelopmentWarningTimestamp'; - self.unifiedTargetConfig = undefined; - self.unifiedTargetConfigName = undefined; - } - } + function setAcknowledgementTimestamp() { + const storageObj = {}; + storageObj[storageTag] = Date.now(); + chrome.storage.local.set(storageObj); + } + + chrome.storage.local.get(storageTag, function (result) { + if (!result[storageTag] || Date.now() - result[storageTag] > DAY_MS) { + + showAcknowledgementDialog(setAcknowledgementTimestamp); + } else { + startFlashing(); + } + }); + } + + function showAcknowledgementDialog(acknowledgementCallback) { + const dialog = $('#dialogUnstableFirmwareAcknoledgement')[0]; + const flashButtonElement = $('#dialogUnstableFirmwareAcknoledgement-flashbtn'); + const acknowledgeCheckboxElement = $('input[name="dialogUnstableFirmwareAcknoledgement-acknowledge"]'); + + acknowledgeCheckboxElement.change(function () { + if ($(this).is(':checked')) { + flashButtonElement.removeClass('disabled'); + } else { + flashButtonElement.addClass('disabled'); + } + }); + + flashButtonElement.click(function() { + dialog.close(); - flashFirmware(self.parsed_hex); - } catch (e) { - console.log(`Flashing failed: ${e.message}`); + if (acknowledgeCheckboxElement.is(':checked')) { + if (acknowledgementCallback) { + acknowledgementCallback(); + } + + startFlashing(); + } + }); + + $('#dialogUnstableFirmwareAcknoledgement-cancelbtn').click(function() { + dialog.close(); + }); + + dialog.addEventListener('close', function () { + acknowledgeCheckboxElement.prop('checked', false).change(); + }); + + dialog.showModal(); + } + + function startFlashing() { + if (!GUI.connect_lock) { // button disabled while flashing is in progress + if (self.parsed_hex) { + try { + if (self.unifiedTargetConfig && !self.parsed_hex.configInserted) { + var configInserter = new ConfigInserter(); + + if (configInserter.insertConfig(self.parsed_hex, self.unifiedTargetConfig)) { + self.parsed_hex.configInserted = true; + } else { + console.log('Firmware does not support custom defaults.'); + + self.unifiedTargetConfig = undefined; + self.unifiedTargetConfigName = undefined; + } } - } else { - $('span.progressLabel').attr('i18n','firmwareFlasherFirmwareNotLoaded').removeClass('i18n-replaced'); - i18n.localizePage(); + + flashFirmware(self.parsed_hex); + } catch (e) { + console.log(`Flashing failed: ${e.message}`); } + } else { + $('span.progressLabel').attr('i18n','firmwareFlasherFirmwareNotLoaded').removeClass('i18n-replaced'); + i18n.localizePage(); } } - }); + } $('span.progressLabel a.save_firmware').click(function () { var summary = $('select[name="firmware_version"] option:selected').data('summary'); diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js index 85d44eec606..bcd6d09cbb8 100644 --- a/src/js/tabs/pid_tuning.js +++ b/src/js/tabs/pid_tuning.js @@ -1145,7 +1145,7 @@ TABS.pid_tuning.initialize = function (callback) { showAllPids(); updatePidDisplay(); - showAllButton.on('click', function(){ + showAllButton.on('click', function() { self.showAllPids = !self.showAllPids; updatePidDisplay(); diff --git a/src/tabs/firmware_flasher.html b/src/tabs/firmware_flasher.html index 9da43b7cf70..571be7ec091 100644 --- a/src/tabs/firmware_flasher.html +++ b/src/tabs/firmware_flasher.html @@ -151,4 +151,23 @@ + + +

+
+
+
+ + +
+
+
+
+ +
+
+ +
+
+