diff --git a/locales/en/messages.json b/locales/en/messages.json
index 9325a1d4..f1b72c4b 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:
the firmware does not work at all;
the firmware is not flyable;
there are safety issues with the firmware, for example flyaways
the firmware can cause the flight controller to become unresponsive, or damaged
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 3bc11517..b85c4eb4 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 ea46057b..972b82b8 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 96445ab4..badad967 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,34 +989,98 @@ 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 (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;
- }
- }
-
- flashFirmware(self.parsed_hex);
- } catch (e) {
- console.log(`Flashing failed: ${e.message}`);
- }
- } else {
- $('span.progressLabel').attr('i18n','firmwareFlasherFirmwareNotLoaded').removeClass('i18n-replaced');
- i18n.localizePage();
- }
+ if (self.developmentFirmwareLoaded) {
+ checkShowAcknowledgementDialog();
+ } else {
+ startFlashing();
}
}
});
+ function checkShowAcknowledgementDialog() {
+ const DAY_MS = 86400 * 1000;
+ const storageTag = 'lastDevelopmentWarningTimestamp';
+
+ 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();
+
+ 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;
+ }
+ }
+
+ 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');
chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: summary.file, accepts: [{description: 'HEX files', extensions: ['hex']}]}, function (fileEntry) {
diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js
index 85d44eec..bcd6d09c 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 9da43b7c..571be7ec 100644
--- a/src/tabs/firmware_flasher.html
+++ b/src/tabs/firmware_flasher.html
@@ -151,4 +151,23 @@
+
+