mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-17 21:35:33 +03:00
Re-ordered targets for flasher.
This commit is contained in:
parent
fd13a4483c
commit
3de7f6e167
1 changed files with 169 additions and 115 deletions
|
@ -29,17 +29,14 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
|
|
||||||
var unifiedSource = 'https://api.github.com/repos/betaflight/unified-targets/contents/configs/default';
|
var unifiedSource = 'https://api.github.com/repos/betaflight/unified-targets/contents/configs/default';
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change boldness of firmware option depending on cache status
|
|
||||||
*
|
|
||||||
* @param {Descriptor} release
|
|
||||||
*/
|
|
||||||
function onFirmwareCacheUpdate(release) {
|
function onFirmwareCacheUpdate(release) {
|
||||||
$("option[value='{0}']".format(release.version))
|
$('select[name="firmware_version"] option').each(function () {
|
||||||
.css("font-weight", FirmwareCache.has(release)
|
const option_e = $(this);
|
||||||
? "bold"
|
const optionRelease = option_e.data("summary");
|
||||||
: "normal");
|
if (optionRelease && optionRelease.file === release.file) {
|
||||||
|
option_e.css("font-weight", FirmwareCache.has(release) ? "bold" : "normal");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDocumentLoad() {
|
function onDocumentLoad() {
|
||||||
|
@ -219,27 +216,23 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
loadUnifiedBuilds(releases);
|
loadUnifiedBuilds(releases);
|
||||||
};
|
};
|
||||||
|
|
||||||
function checkOneVersionForUnification(version) {
|
function supportsUnifiedTargets(version) {
|
||||||
return semver.gte(version.split(' ')[0], '4.1.0-RC1');
|
return semver.gte(version.split(' ')[0], '4.1.0-RC1');
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkBuildsForUnification(builds) {
|
function hasUnifiedTargetBuild(builds) {
|
||||||
// Find a build that is newer than 4.1.0, return true if found
|
// Find a build that is newer than 4.1.0, return true if found
|
||||||
let foundSuitable = false;
|
return Object.keys(builds).some(function (key) {
|
||||||
Object.keys(builds).forEach(function (key) {
|
return builds[key].some(function(target) {
|
||||||
builds[key].forEach(function(target) {
|
return supportsUnifiedTargets(target.version);
|
||||||
if (checkOneVersionForUnification(target.version)) {
|
|
||||||
foundSuitable = true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return foundSuitable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadUnifiedBuilds(builds) {
|
function loadUnifiedBuilds(builds) {
|
||||||
var expirationPeriod = 3600 * 2; // Two of your earth hours.
|
var expirationPeriod = 3600 * 2; // Two of your earth hours.
|
||||||
var checkTime = Math.floor(Date.now() / 1000); // Lets deal in seconds.
|
var checkTime = Math.floor(Date.now() / 1000); // Lets deal in seconds.
|
||||||
if (builds && checkBuildsForUnification(builds)) {
|
if (builds && hasUnifiedTargetBuild(builds)) {
|
||||||
console.log('loaded some builds for later');
|
console.log('loaded some builds for later');
|
||||||
var storageTag = 'unifiedSourceCache';
|
var storageTag = 'unifiedSourceCache';
|
||||||
chrome.storage.local.get(storageTag, function (result) {
|
chrome.storage.local.get(storageTag, function (result) {
|
||||||
|
@ -272,46 +265,29 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseUnifiedBuilds(data, builds) {
|
function parseUnifiedBuilds(data, builds) {
|
||||||
if (!data) { return; }
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let releases = {};
|
let releases = {};
|
||||||
let unifiedConfigs = {};
|
let unifiedConfigs = {};
|
||||||
let items = {};
|
let items = {};
|
||||||
let unifiedTargetNames = [];
|
// Get the legacy builds
|
||||||
|
Object.keys(builds).forEach(function (targetName) {
|
||||||
|
items[targetName] = { };
|
||||||
|
releases[targetName] = builds[targetName];
|
||||||
|
});
|
||||||
|
// Get the Unified Target configurations
|
||||||
data.forEach(function(target) {
|
data.forEach(function(target) {
|
||||||
const TARGET_REGEXP = /^(?:([^-]{1,4})-)?(.*).config$/;
|
const TARGET_REGEXP = /^([^-]{1,4})-(.*).config$/;
|
||||||
let targetParts = target.name.match(TARGET_REGEXP);
|
let targetParts = target.name.match(TARGET_REGEXP);
|
||||||
if (!targetParts) {
|
if (!targetParts) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let boardName = targetParts[2];
|
const targetName = targetParts[2];
|
||||||
let manufacturerId = targetParts[1];
|
const manufacturerId = targetParts[1];
|
||||||
let targetName;
|
items[targetName] = { };
|
||||||
let displayName;
|
unifiedConfigs[targetName] = (unifiedConfigs[targetName] || {});
|
||||||
if (manufacturerId) {
|
unifiedConfigs[targetName][manufacturerId] = target.download_url;
|
||||||
targetName = `${boardName}+${manufacturerId}`;
|
|
||||||
displayName = `${boardName} (${manufacturerId})`;
|
|
||||||
} else {
|
|
||||||
targetName = boardName;
|
|
||||||
}
|
|
||||||
unifiedTargetNames.push(boardName);
|
|
||||||
unifiedConfigs[targetName] = target.download_url;
|
|
||||||
items[targetName] = { displayName: displayName };
|
|
||||||
// Chicken and egg problem: We need to know what Unified Target this configuration uses before reading the configuration.
|
|
||||||
// Solving this by assuming that all Unified Targets have the same availability for now.
|
|
||||||
const DEFAULT_UNIFIED_TARGET_NAME = "STM32F405";
|
|
||||||
releases[targetName] = builds[DEFAULT_UNIFIED_TARGET_NAME];
|
|
||||||
});
|
|
||||||
Object.keys(builds).forEach(function (key) {
|
|
||||||
let targetName;
|
|
||||||
let displayName;
|
|
||||||
if (unifiedTargetNames.includes(key)) {
|
|
||||||
targetName = `${key}-legacy`;
|
|
||||||
displayName = i18n.getMessage("firmwareFlasherLegacyLabel", { target: key });
|
|
||||||
} else {
|
|
||||||
targetName = key;
|
|
||||||
}
|
|
||||||
items[targetName] = { displayName: displayName };
|
|
||||||
releases[targetName] = builds[key];
|
|
||||||
});
|
});
|
||||||
var boards_e = $('select[name="board"]');
|
var boards_e = $('select[name="board"]');
|
||||||
var versions_e = $('select[name="firmware_version"]');
|
var versions_e = $('select[name="firmware_version"]');
|
||||||
|
@ -326,7 +302,7 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
.forEach(function(target, i) {
|
.forEach(function(target, i) {
|
||||||
let item = items[target];
|
let item = items[target];
|
||||||
|
|
||||||
var select_e = $("<option value='{0}'>{1}</option>".format(target, items[target].displayName || target));
|
const select_e = $(`<option value='${target}'>${target}</option>"`);
|
||||||
boards_e.append(select_e);
|
boards_e.append(select_e);
|
||||||
});
|
});
|
||||||
TABS.firmware_flasher.releases = releases;
|
TABS.firmware_flasher.releases = releases;
|
||||||
|
@ -432,27 +408,84 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
chrome.storage.local.set({'selected_build_type': build_type});
|
chrome.storage.local.set({'selected_build_type': build_type});
|
||||||
});
|
});
|
||||||
|
|
||||||
function populateVersions(versions_element, targetVersions, target) {
|
function populateBuilds(builds, target, manufacturerId, duplicateName, targetVersions, callback) {
|
||||||
versions_element.empty();
|
|
||||||
if (targetVersions) {
|
if (targetVersions) {
|
||||||
versions_element.append($("<option value='0'>{0} {1}</option>".format(i18n.getMessage('firmwareFlasherOptionLabelSelectFirmwareVersionFor'), target)));
|
|
||||||
targetVersions.forEach(function(descriptor) {
|
targetVersions.forEach(function(descriptor) {
|
||||||
if (self.remoteUnifiedTargetConfig && !checkOneVersionForUnification(descriptor.version)) {
|
const versionRegex = /^(\d.\d.\d(?:-\w+)?)(?: #(\d+))?$/;
|
||||||
|
const versionParts = descriptor.version.match(versionRegex);
|
||||||
|
if (!versionParts) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var select_e =
|
let version = versionParts[1];
|
||||||
$("<option value='{0}'>{0} - {1}</option>".format(
|
const buildNumber = versionParts[2] ? `${versionParts[2]}` : '';
|
||||||
descriptor.version,
|
|
||||||
descriptor.date
|
const build = { descriptor };
|
||||||
))
|
if (manufacturerId) {
|
||||||
.css("font-weight", FirmwareCache.has(descriptor)
|
if (!supportsUnifiedTargets(descriptor.version)) {
|
||||||
? "bold"
|
return;
|
||||||
: "normal"
|
}
|
||||||
);
|
|
||||||
select_e.data('summary', descriptor);
|
version = `${version}+${buildNumber}${manufacturerId}`;
|
||||||
versions_element.append(select_e);
|
build.manufacturerId = manufacturerId;
|
||||||
|
build.duplicateName = duplicateName;
|
||||||
|
} else {
|
||||||
|
version = `${version}+${buildNumber}-legacy`;
|
||||||
|
build.isLegacy = true;
|
||||||
|
}
|
||||||
|
builds[version] = build;
|
||||||
});
|
});
|
||||||
// Assume flashing latest, so default to it.
|
}
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateVersions(versions_element, builds, target) {
|
||||||
|
const sortVersions = function (a, b) {
|
||||||
|
return -semver.compareBuild(a, b);
|
||||||
|
};
|
||||||
|
|
||||||
|
versions_element.empty();
|
||||||
|
const targetVersions = Object.keys(builds);
|
||||||
|
if (targetVersions.length > 0) {
|
||||||
|
versions_element.append($("<option value='0'>{0} {1}</option>".format(i18n.getMessage('firmwareFlasherOptionLabelSelectFirmwareVersionFor'), target)));
|
||||||
|
targetVersions
|
||||||
|
.sort(sortVersions)
|
||||||
|
.forEach(function(versionName) {
|
||||||
|
const version = builds[versionName];
|
||||||
|
if (!version.isLegacy && !supportsUnifiedTargets(version.descriptor.version)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let versionLabel;
|
||||||
|
if (version.isLegacy && Object.values(builds).some(function (build) {
|
||||||
|
return build.descriptor.version === version.descriptor.version && !build.isLegacy;
|
||||||
|
})) {
|
||||||
|
versionLabel = i18n.getMessage("firmwareFlasherLegacyLabel", { target: version.descriptor.version });
|
||||||
|
} else if (!version.isLegacy && Object.values(builds).some(function (build) {
|
||||||
|
return build.descriptor.version === version.descriptor.version && build.manufacturerId !== version.manufacturerId && !build.isLegacy;
|
||||||
|
})) {
|
||||||
|
versionLabel = `${version.descriptor.version} (${version.manufacturerId})`;
|
||||||
|
} else {
|
||||||
|
versionLabel = version.descriptor.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var select_e =
|
||||||
|
$("<option value='{0}'>{2} - {1}</option>".format(
|
||||||
|
versionName,
|
||||||
|
version.descriptor.date,
|
||||||
|
versionLabel
|
||||||
|
))
|
||||||
|
.css("font-weight", FirmwareCache.has(version.descriptor)
|
||||||
|
? "bold"
|
||||||
|
: "normal"
|
||||||
|
);
|
||||||
|
select_e.data('summary', version.descriptor);
|
||||||
|
versions_element.append(select_e);
|
||||||
|
});
|
||||||
|
// Assume flashing latest, so default to it.
|
||||||
versions_element.prop("selectedIndex", 1).change();
|
versions_element.prop("selectedIndex", 1).change();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,7 +504,6 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
function setUnifiedConfig(target, configText, bareBoard) {
|
function setUnifiedConfig(target, configText, bareBoard) {
|
||||||
// a target might request a firmware with the same name, remove configuration in this case.
|
// a target might request a firmware with the same name, remove configuration in this case.
|
||||||
if (bareBoard == target) {
|
if (bareBoard == target) {
|
||||||
console.log(bareBoard, '==', target);
|
|
||||||
if (!self.isConfigLocal) {
|
if (!self.isConfigLocal) {
|
||||||
self.unifiedTargetConfig = undefined;
|
self.unifiedTargetConfig = undefined;
|
||||||
self.unifiedTargetConfigName = undefined;
|
self.unifiedTargetConfigName = undefined;
|
||||||
|
@ -486,6 +518,7 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
self.remoteUnifiedTargetConfig = configText;
|
self.remoteUnifiedTargetConfig = configText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearBufferedFirmware() {
|
function clearBufferedFirmware() {
|
||||||
self.isConfigLocal = false;
|
self.isConfigLocal = false;
|
||||||
self.unifiedTargetConfig = undefined;
|
self.unifiedTargetConfig = undefined;
|
||||||
|
@ -526,7 +559,7 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var versions_e = $('select[name="firmware_version"]');
|
var versions_e = $('select[name="firmware_version"]');
|
||||||
if(target == 0) {
|
if (target == 0) {
|
||||||
// target == 0 is the "Choose a Board" option. Throw out anything loaded
|
// target == 0 is the "Choose a Board" option. Throw out anything loaded
|
||||||
clearBufferedFirmware();
|
clearBufferedFirmware();
|
||||||
|
|
||||||
|
@ -536,65 +569,86 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
// Show a loading message as there is a delay in loading a configuration
|
// Show a loading message as there is a delay in loading a configuration
|
||||||
versions_e.empty();
|
versions_e.empty();
|
||||||
versions_e.append($("<option value='0'>{0}</option>".format(i18n.getMessage('firmwareFlasherOptionLoading'))));
|
versions_e.append($("<option value='0'>{0}</option>".format(i18n.getMessage('firmwareFlasherOptionLoading'))));
|
||||||
|
|
||||||
let selecteBuild = buildTypesToShow[$('select[name="build_type"]').val()];
|
let selecteBuild = buildTypesToShow[$('select[name="build_type"]').val()];
|
||||||
|
const builds = [];
|
||||||
|
|
||||||
|
const finishPopulatingBuilds = function () {
|
||||||
|
if (TABS.firmware_flasher.releases[target]) {
|
||||||
|
TABS.firmware_flasher.bareBoard = target;
|
||||||
|
populateBuilds(builds, target, undefined, false, TABS.firmware_flasher.releases[target]);
|
||||||
|
}
|
||||||
|
|
||||||
|
populateVersions(versions_e, builds, target);
|
||||||
|
};
|
||||||
|
|
||||||
if (TABS.firmware_flasher.unifiedConfigs[target]) {
|
if (TABS.firmware_flasher.unifiedConfigs[target]) {
|
||||||
var storageTag = 'unifiedConfigLast';
|
var storageTag = 'unifiedConfigLast';
|
||||||
var expirationPeriod = 3600; // One of your earth hours.
|
var expirationPeriod = 3600; // One of your earth hours.
|
||||||
var checkTime = Math.floor(Date.now() / 1000); // Lets deal in seconds.
|
var checkTime = Math.floor(Date.now() / 1000); // Lets deal in seconds.
|
||||||
chrome.storage.local.get(storageTag, function (result) {
|
chrome.storage.local.get(storageTag, function (result) {
|
||||||
let storageObj = result[storageTag];
|
let storageObj = result[storageTag];
|
||||||
let bareBoard = null;
|
const unifiedConfigBoard = TABS.firmware_flasher.unifiedConfigs[target];
|
||||||
// Check to see if the cached configuration is the one we want.
|
const duplicateName = Object.keys(unifiedConfigBoard).length > 1;
|
||||||
if (!storageObj || !storageObj.target || storageObj.target != target) {
|
const manufacturerIds = Object.keys(unifiedConfigBoard);
|
||||||
// Have to go and try and get the unified config, and then do stuff
|
|
||||||
$.get(TABS.firmware_flasher.unifiedConfigs[target], function(data) {
|
|
||||||
console.log('got unified config');
|
|
||||||
// cache it for later
|
|
||||||
let tempObj = {};
|
|
||||||
tempObj['data'] = data;
|
|
||||||
tempObj['target'] = target;
|
|
||||||
tempObj['checkTime'] = checkTime;
|
|
||||||
let newStorageObj = {};
|
|
||||||
newStorageObj[storageTag] = tempObj;
|
|
||||||
chrome.storage.local.set(newStorageObj);
|
|
||||||
|
|
||||||
bareBoard = grabBuildNameFromConfig(data);
|
const processManufacturer = function(index) {
|
||||||
|
const processNext = function () {
|
||||||
|
if (index < manufacturerIds.length - 1) {
|
||||||
|
processManufacturer(index + 1);
|
||||||
|
} else {
|
||||||
|
finishPopulatingBuilds();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const manufacturerId = manufacturerIds[index];
|
||||||
|
const targetId = `${target}+${manufacturerId}`;
|
||||||
|
// Check to see if the cached configuration is the one we want.
|
||||||
|
if (!storageObj || !storageObj.target || storageObj.target !== targetId) {
|
||||||
|
// Have to go and try and get the unified config, and then do stuff
|
||||||
|
$.get(unifiedConfigBoard[manufacturerId], function(response) {
|
||||||
|
console.log('got unified config');
|
||||||
|
// cache it for later
|
||||||
|
let tempObj = {};
|
||||||
|
tempObj['data'] = response;
|
||||||
|
tempObj['target'] = targetId;
|
||||||
|
tempObj['checkTime'] = checkTime;
|
||||||
|
let newStorageObj = {};
|
||||||
|
newStorageObj[storageTag] = tempObj;
|
||||||
|
chrome.storage.local.set(newStorageObj);
|
||||||
|
|
||||||
|
const bareBoard = grabBuildNameFromConfig(response);
|
||||||
|
TABS.firmware_flasher.bareBoard = bareBoard;
|
||||||
|
setUnifiedConfig(target, response, bareBoard);
|
||||||
|
populateBuilds(builds, target, manufacturerId, duplicateName, TABS.firmware_flasher.releases[bareBoard], processNext);
|
||||||
|
}).fail(xhr => {
|
||||||
|
//TODO error, populate nothing?
|
||||||
|
self.unifiedTargetConfig = undefined;
|
||||||
|
self.unifiedTargetConfigName = undefined;
|
||||||
|
self.isConfigLocal = false;
|
||||||
|
self.remoteUnifiedTargetConfig = undefined;
|
||||||
|
const baseFileName = unifiedConfigBoard[manufacturerId].reverse()[0];
|
||||||
|
GUI.log(i18n.getMessage('firmwareFlasherFailedToLoadUnifiedConfig',
|
||||||
|
{remote_file: baseFileName}));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('We have the config cached for', targetId);
|
||||||
|
var data = storageObj.data;
|
||||||
|
|
||||||
|
const bareBoard = grabBuildNameFromConfig(data);
|
||||||
TABS.firmware_flasher.bareBoard = bareBoard;
|
TABS.firmware_flasher.bareBoard = bareBoard;
|
||||||
setUnifiedConfig(target, data, bareBoard);
|
setUnifiedConfig(target, data, bareBoard);
|
||||||
populateVersions(versions_e, TABS.firmware_flasher.releases[bareBoard], target);
|
populateBuilds(builds, target, manufacturerId, duplicateName, TABS.firmware_flasher.releases[bareBoard], processNext);
|
||||||
}).fail(xhr => {
|
}
|
||||||
//TODO error, populate nothing?
|
};
|
||||||
self.unifiedTargetConfig = undefined;
|
|
||||||
self.unifiedTargetConfigName = undefined;
|
|
||||||
self.isConfigLocal = false;
|
|
||||||
self.remoteUnifiedTargetConfig = undefined;
|
|
||||||
let baseFileName = TABS.firmware_flasher.unifiedConfigs[target].reverse()[0];
|
|
||||||
GUI.log(i18n.getMessage('firmwareFlasherFailedToLoadUnifiedConfig',
|
|
||||||
{remote_file: baseFileName}));
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log('We have the config cached for', target);
|
|
||||||
var data = storageObj.data;
|
|
||||||
|
|
||||||
bareBoard = grabBuildNameFromConfig(data);
|
processManufacturer(0);
|
||||||
TABS.firmware_flasher.bareBoard = bareBoard;
|
|
||||||
setUnifiedConfig(target, data, bareBoard);
|
|
||||||
populateVersions(versions_e, TABS.firmware_flasher.releases[bareBoard], target);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (!self.isConfigLocal) {
|
setUnifiedConfig(target, null, target);
|
||||||
self.unifiedTargetConfig = undefined;
|
finishPopulatingBuilds();
|
||||||
self.unifiedTargetConfigName = undefined;
|
|
||||||
self.remoteUnifiedTargetConfig = undefined;
|
|
||||||
} else {
|
|
||||||
self.remoteUnifiedTargetConfig = undefined;
|
|
||||||
}
|
|
||||||
TABS.firmware_flasher.bareBoard = target;
|
|
||||||
populateVersions(versions_e, TABS.firmware_flasher.releases[target], target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue