Skip to content

Commit 544dddd

Browse files
authored
Make backup on flash an option (#4360)
* Make backup on flash an option * Move initialization to main * Alternative * Just ask * works locally * Remove console.log * Set no dialog by default * Fix it * Handle cancelling backup * Make sonar happy * Improve error handling * Increase timeout to reduce corruption
1 parent 091bee9 commit 544dddd

File tree

6 files changed

+131
-60
lines changed

6 files changed

+131
-60
lines changed

locales/en/messages.json

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@
5656
"storageDeviceNotReady": {
5757
"message": "The storage device is not ready. In the case of a microSD card, make sure it is properly recognised by your flight controller."
5858
},
59-
"options_title": {
60-
"message": "Application Options"
61-
},
6259
"connect": {
6360
"message": "Connect"
6461
},
@@ -3827,9 +3824,6 @@
38273824
"unstableFirmwareAcknowledgementFlash": {
38283825
"message": "Flash"
38293826
},
3830-
"firmwareFlasherPreviousDevice": {
3831-
"message": "Detected: <strong>$1</strong> - previous device still flashing, please replug to try again"
3832-
},
38333827
"firmwareFlasherRemindBackupTitle": {
38343828
"message": "Wipe out settings",
38353829
"description": "Warning message title before actual flashing takes place"
@@ -3846,6 +3840,15 @@
38463840
"message": "Ignore the risk",
38473841
"description": "Ignore creating a backup before actual flashing takes place"
38483842
},
3843+
"firmwareBackupEnabled": {
3844+
"message": "Backup enabled"
3845+
},
3846+
"firmwareBackupDisabled": {
3847+
"message": "Backup disabled"
3848+
},
3849+
"firmwareBackupAsk": {
3850+
"message": "Ask before backup"
3851+
},
38493852
"ledStripHelp": {
38503853
"message": "The flight controller can control colors and effects of individual LEDs on a strip.<br />Configure LEDs on the grid, configure wiring order then attach LEDs on your aircraft according to grid positions. LEDs without wire ordering number will not be saved.<br />Double-click on a color to edit the HSV values."
38513854
},
@@ -7170,6 +7173,9 @@
71707173
"cliAutoComplete": {
71717174
"message": "Advanced CLI AutoComplete"
71727175
},
7176+
"firmwareBackupOnFlash": {
7177+
"message": "Create a backup before flashing new target"
7178+
},
71737179
"darkTheme": {
71747180
"message": "Enable dark theme"
71757181
},

src/js/FileSystem.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ class FileSystem {
1919
],
2020
});
2121

22+
if (!fileHandle) {
23+
return null;
24+
}
25+
2226
const file = this._createFile(fileHandle);
2327

2428
if (await this.verifyPermission(file, true)) {

src/js/tabs/firmware_flasher.js

Lines changed: 73 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,47 +1089,33 @@ firmware_flasher.initialize = function (callback) {
10891089
setTimeout(() => detectBoardElement.toggleClass("disabled", false), 2000);
10901090
});
10911091

1092-
$("a.flash_firmware").on("click", function () {
1093-
self.isFlashing = true;
1094-
GUI.interval_pause("sponsor");
1095-
const isFlashOnConnect = $("input.flash_on_connect").is(":checked");
1092+
function initiateFlashing() {
1093+
if (self.developmentFirmwareLoaded) {
1094+
checkShowAcknowledgementDialog();
1095+
} else {
1096+
startFlashing();
1097+
}
1098+
}
10961099

1097-
self.enableFlashButton(false);
1098-
self.enableDfuExitButton(false);
1099-
self.enableLoadRemoteFileButton(false);
1100-
self.enableLoadFileButton(false);
1100+
// Backup not available in DFU, manual, virtual mode or when using flash on connect
11011101

1102-
function initiateFlashing() {
1103-
if (self.developmentFirmwareLoaded && !isFlashOnConnect) {
1104-
checkShowAcknowledgementDialog();
1102+
function startBackup(callback) {
1103+
// prevent connection while backup is in progress
1104+
GUI.connect_lock = true;
1105+
AutoBackup.execute((result) => {
1106+
GUI.connect_lock = false;
1107+
if (result) {
1108+
callback();
11051109
} else {
1106-
startFlashing();
1110+
self.isFlashing = false;
1111+
self.enableFlashButton(true);
1112+
self.enableLoadRemoteFileButton(true);
1113+
self.enableLoadFileButton(true);
1114+
GUI.interval_resume("sponsor");
1115+
console.log(`${self.logHead} Backup failed, skipping flashing`);
11071116
}
1108-
}
1109-
1110-
// Backup not available in DFU, manual or virtual mode.
1111-
// When flash on connect is enabled, the backup dialog is not shown.
1112-
if (isFlashOnConnect || !(PortHandler.portAvailable || GUI.connect_lock)) {
1113-
initiateFlashing();
1114-
} else {
1115-
GUI.showYesNoDialog({
1116-
title: i18n.getMessage("firmwareFlasherRemindBackupTitle"),
1117-
text: i18n.getMessage("firmwareFlasherRemindBackup"),
1118-
buttonYesText: i18n.getMessage("firmwareFlasherBackup"),
1119-
buttonNoText: i18n.getMessage("firmwareFlasherBackupIgnore"),
1120-
buttonYesCallback: () => {
1121-
// prevent connection while backup is in progress
1122-
GUI.connect_lock = true;
1123-
AutoBackup.execute(() => {
1124-
GUI.connect_lock = false;
1125-
initiateFlashing();
1126-
});
1127-
},
1128-
1129-
buttonNoCallback: initiateFlashing,
1130-
});
1131-
}
1132-
});
1117+
});
1118+
}
11331119

11341120
function checkShowAcknowledgementDialog() {
11351121
const DAY_MS = 86400 * 1000;
@@ -1216,6 +1202,56 @@ firmware_flasher.initialize = function (callback) {
12161202
}
12171203
}
12181204

1205+
$("a.flash_firmware").on("click", function () {
1206+
if (GUI.connect_lock) {
1207+
return;
1208+
}
1209+
1210+
self.isFlashing = true;
1211+
GUI.interval_pause("sponsor");
1212+
1213+
self.enableFlashButton(false);
1214+
self.enableDfuExitButton(false);
1215+
self.enableLoadRemoteFileButton(false);
1216+
self.enableLoadFileButton(false);
1217+
1218+
const isFlashOnConnect = $("input.flash_on_connect").is(":checked");
1219+
1220+
if (isFlashOnConnect || !PortHandler.portAvailable) {
1221+
startFlashing();
1222+
return;
1223+
}
1224+
1225+
// backupOnFlash:
1226+
// 0: disabled (default)
1227+
// 1: backup without dialog
1228+
// 2: backup with dialog
1229+
1230+
const backupOnFlash = getConfig("backupOnFlash", 1).backupOnFlash;
1231+
1232+
switch (backupOnFlash) {
1233+
case 1:
1234+
// prevent connection while backup is in progress
1235+
startBackup(initiateFlashing);
1236+
break;
1237+
case 2:
1238+
GUI.showYesNoDialog({
1239+
title: i18n.getMessage("firmwareFlasherRemindBackupTitle"),
1240+
text: i18n.getMessage("firmwareFlasherRemindBackup"),
1241+
buttonYesText: i18n.getMessage("firmwareFlasherBackup"),
1242+
buttonNoText: i18n.getMessage("firmwareFlasherBackupIgnore"),
1243+
buttonYesCallback: () => {
1244+
startBackup(initiateFlashing);
1245+
},
1246+
buttonNoCallback: initiateFlashing,
1247+
});
1248+
break;
1249+
default:
1250+
initiateFlashing();
1251+
break;
1252+
}
1253+
});
1254+
12191255
$("span.progressLabel").on("click", "a.save_firmware", function () {
12201256
FileSystem.pickSaveFile(
12211257
self.targetDetail.file,

src/js/tabs/options.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ options.initialize = function (callback) {
3434
TABS.options.initUserLanguage();
3535
TABS.options.initShowWarnings();
3636
TABS.options.initMeteredConnection();
37+
TABS.options.initBackupOnFlash();
3738

3839
GUI.content_ready(callback);
3940
});
@@ -256,6 +257,19 @@ options.initMeteredConnection = function () {
256257
.trigger("change");
257258
};
258259

260+
options.initBackupOnFlash = function () {
261+
// default to always backup on flash
262+
const result = getConfig("backupOnFlash", 1);
263+
$("#backupOnFlashSelect").val(result.backupOnFlash);
264+
$("#backupOnFlashSelect")
265+
.on("change", function () {
266+
const value = parseInt($(this).val());
267+
268+
setConfig({ backupOnFlash: value });
269+
})
270+
.trigger("change");
271+
};
272+
259273
options.initUserLanguage = function () {
260274
const userLanguage = i18n.selectedLanguage;
261275
const userLanguageElement = $("#userLanguage");

src/js/utils/AutoBackup.js

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,27 @@ class AutoBackup {
5656
const prefix = "cli_backup";
5757
const suffix = "txt";
5858
const filename = generateFilename(prefix, suffix);
59+
let result = false;
5960

60-
FileSystem.pickSaveFile(
61-
filename,
62-
i18n.getMessage("fileSystemPickerFiles", { typeof: suffix.toUpperCase() }),
63-
`.${suffix}`,
64-
)
65-
.then((file) => {
61+
try {
62+
const file = await FileSystem.pickSaveFile(
63+
filename,
64+
i18n.getMessage("fileSystemPickerFiles", { typeof: suffix.toUpperCase() }),
65+
`.${suffix}`,
66+
);
67+
68+
if (file) {
6669
console.log("Saving config to:", file.name);
67-
FileSystem.writeFile(file, data);
68-
})
69-
.catch((error) => {
70-
console.error("Error saving config:", error);
71-
})
72-
.finally(() => {
73-
if (this.callback) {
74-
this.callback();
75-
}
76-
});
70+
await FileSystem.writeFile(file, data);
71+
result = true;
72+
}
73+
} catch (error) {
74+
console.error("Error saving config:", error);
75+
} finally {
76+
if (this.callback) {
77+
this.callback(result);
78+
}
79+
}
7780
}
7881

7982
async run() {
@@ -102,7 +105,7 @@ class AutoBackup {
102105
setTimeout(() => {
103106
this.outputHistory = "";
104107
resolve();
105-
}, 500);
108+
}, 1000);
106109
});
107110
}
108111

src/tabs/options.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@
8888
</div>
8989
<span class="freelabel" i18n="showNotifications"></span>
9090
</div>
91+
<div class="backupOnFlash margin-bottom">
92+
<select id="backupOnFlashSelect">
93+
<option value="0" i18n="firmwareBackupDisabled"></option>
94+
<option value="1" i18n="firmwareBackupEnabled"></option>
95+
<option value="2" i18n="firmwareBackupAsk"></option>
96+
</select>
97+
<span class="freelabel" i18n="firmwareBackupOnFlash"></span>
98+
</div>
9199
<div class="userLanguage">
92100
<span class="dropdown">
93101
<select class="dropdown-select" id="userLanguage"

0 commit comments

Comments
 (0)