diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index fd47ad16..098533be 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -5,12 +5,12 @@
"warningTitle": {
"message": "Warning"
},
+ "noticeTitle": {
+ "message": "Notice"
+ },
"options_title": {
"message": "Application Options"
},
- "options_receive_app_notifications": {
- "message": "Receive desktop notification when application updates"
- },
"connect": {
"message": "Connect"
},
@@ -35,6 +35,12 @@
"permanentExpertMode": {
"message": "Permanently enable Expert Mode"
},
+ "checkForConfiguratorUnstableVersions": {
+ "message": "Show update notifications for unstable versions of the configurator"
+ },
+ "configuratorUpdateNotice": {
+ "message": "You are using an outdated version of the Betaflight Configurator.
Version $1 is available online, please visit the release page to download and install the latest version with fixes and improvements.
Please close the configurator window before updating."
+ },
"deviceRebooting": {
"message": "Device - Rebooting"
},
diff --git a/eventPage.js b/eventPage.js
index 54043e5b..f7d57159 100755
--- a/eventPage.js
+++ b/eventPage.js
@@ -84,22 +84,18 @@ chrome.runtime.onInstalled.addListener(function (details) {
// only fire up notification sequence when one of the major version numbers changed
if (currentVersionArr[0] > previousVersionArr[0] || currentVersionArr[1] > previousVersionArr[1]) {
- chrome.storage.local.get('update_notify', function (result) {
- if (result.update_notify === 'undefined' || result.update_notify) {
- var manifest = chrome.runtime.getManifest();
- var options = {
- priority: 0,
- type: 'basic',
- title: manifest.name,
- message: chrome.i18n.getMessage('notifications_app_just_updated_to_version', [getManifestVersion(manifest)]),
- iconUrl: '/images/icon_128.png',
- buttons: [{'title': chrome.i18n.getMessage('notifications_click_here_to_start_app')}]
- };
+ var manifest = chrome.runtime.getManifest();
+ var options = {
+ priority: 0,
+ type: 'basic',
+ title: manifest.name,
+ message: chrome.i18n.getMessage('notifications_app_just_updated_to_version', [getManifestVersion(manifest)]),
+ iconUrl: '/images/icon_128.png',
+ buttons: [{'title': chrome.i18n.getMessage('notifications_click_here_to_start_app')}]
+ };
- chrome.notifications.create('baseflight_update', options, function (notificationId) {
- // empty
- });
- }
+ chrome.notifications.create('baseflight_update', options, function (notificationId) {
+ // empty
});
}
}
diff --git a/gulpfile.js b/gulpfile.js
index e5a115e7..6cb998f7 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -181,6 +181,7 @@ gulp.task('dist', ['clean-dist'], function () {
'./js/RateCurve.js',
'./js/Features.js',
'./js/Beepers.js',
+ './js/release_checker.js',
'./tabs/adjustments.js',
'./tabs/auxiliary.js',
'./tabs/cli.js',
diff --git a/js/gui.js b/js/gui.js
index 78606af2..88a72d01 100644
--- a/js/gui.js
+++ b/js/gui.js
@@ -325,8 +325,7 @@ GUI_control.prototype.show_modal = function (title, message) {
var popup = new jBox('Modal', {
title: title,
content: message,
- closeButton: 'title',
- closeOnClick: 'box'
+ closeButton: 'title'
});
popup.open();
diff --git a/js/release_checker.js b/js/release_checker.js
new file mode 100644
index 00000000..6e2076a8
--- /dev/null
+++ b/js/release_checker.js
@@ -0,0 +1,58 @@
+ 'use strict;'
+
+var ReleaseChecker = function (releaseName, releaseUrl) {
+ var self = this;
+
+ self._releaseName = releaseName;
+ self._releaseDataTag = `${self._releaseName}ReleaseData`;
+ self._releaseLastUpdateTag = `${self._releaseName}ReleaseLastUpdate`
+ self._releaseUrl = releaseUrl;
+
+
+}
+
+ReleaseChecker.prototype.loadReleaseData = function (processFunction) {
+ var self = this;
+ chrome.storage.local.get([self._releaseLastUpdateTag, self._releaseDataTag], function (result) {
+ var releaseDataTimestamp = $.now();
+ var cacheReleaseData = result[self._releaseDataTag];
+ var cachedReleaseLastUpdate = result[self._releaseLastUpdateTag];
+ if (!cacheReleaseData || !cachedReleaseLastUpdate || releaseDataTimestamp - cachedReleaseLastUpdate > 3600 * 1000) {
+ $.get(self._releaseUrl, function (releaseData) {
+ GUI.log(`Loaded release information for ${self._releaseName} from GitHub.`);
+
+ var data = {};
+ data[self._releaseDataTag] = releaseData
+ data[self._releaseLastUpdateTag] = releaseDataTimestamp
+ chrome.storage.local.set(data, function () {});
+
+ self._processReleaseData(releaseData, processFunction);
+ }).fail(function (data) {
+ var message = '';
+ if (data['responseJSON']) {
+ message = data['responseJSON'].message;
+ }
+ GUI.log(`GitHub query for ${self._releaseName} releases failed, using cached information. Reason: ${message}
`);
+
+ self._processReleaseData(cacheReleaseData, processFunction);
+ });
+ } else {
+ if (cacheReleaseData) {
+ GUI.log(`Using cached release information for ${self._releaseName} releases.`);
+ }
+
+ self._processReleaseData(cacheReleaseData, processFunction);
+ }
+ });
+}
+
+
+ReleaseChecker.prototype._processReleaseData = function (releaseData, processFunction) {
+ if (releaseData) {
+ processFunction(releaseData);
+ } else {
+ GUI.log(`No release information available for ${self._releaseName}.`);
+
+ processFunction();
+ }
+}
diff --git a/main.html b/main.html
index ef68f325..b859ddce 100755
--- a/main.html
+++ b/main.html
@@ -73,6 +73,7 @@
+
diff --git a/main.js b/main.js
index 01f40338..e0a73c3c 100644
--- a/main.js
+++ b/main.js
@@ -28,35 +28,7 @@ $(document).ready(function () {
break;
}
- // check for newer releases online to inform people in case they are running an old release
-
- chrome.storage.local.get(['lastVersionChecked', 'lastVersionAvailableOnline'], function (result) {
- if (typeof result.lastVersionChecked === undefined || ($.now() - result.lastVersionChecked) > 3600 * 1000) {
- try {
- var url = 'https://api.github.com/repos/betaflight/betaflight-configurator/tags';
- $.get(url).done(function (data) {
- var versions = data.sort(function (v1, v2) {
- try {
- return semver.compare(v2.name, v1.name);
- } catch (e) {
- return false;
- }
- });
- chrome.storage.local.set({
- 'lastVersionChecked': $.now(),
- 'lastVersionAvailableOnline': versions[0].name
- }, function (result) {
- console.log("Latest version available online: " + versions[0].name);
- });
- notifyOutdatedVersion(versions[0].name);
- });
- } catch (e) {
- // Just to catch and supress warnings if no internet connection is available
- }
- } else if (result.lastVersionAvailableOnline) {
- notifyOutdatedVersion(result.lastVersionAvailableOnline);
- }
- });
+ checkForConfiguratorUpdates();
chrome.storage.local.get('logopen', function (result) {
if (result.logopen) {
@@ -212,19 +184,6 @@ $(document).ready(function () {
// translate to user-selected language
localize();
- // if notifications are enabled, or wasn't set, check the notifications checkbox
- chrome.storage.local.get('update_notify', function (result) {
- if (typeof result.update_notify === 'undefined' || result.update_notify) {
- $('div.notifications input').prop('checked', true);
- }
-
- $('div.notifications input').change(function () {
- var check = $(this).is(':checked');
-
- chrome.storage.local.set({'update_notify': check});
- });
- });
-
chrome.storage.local.get('permanentExpertMode', function (result) {
if (result.permanentExpertMode) {
$('div.permanentExpertMode input').prop('checked', true);
@@ -243,6 +202,21 @@ $(document).ready(function () {
}).change();
});
+ chrome.storage.local.get('checkForConfiguratorUnstableVersions', function (result) {
+ $('div.checkForConfiguratorUnstableVersions input').change(function () {
+ var checked = $(this).is(':checked');
+
+ chrome.storage.local.set({'checkForConfiguratorUnstableVersions': checked});
+
+ $('input[name="checkForConfiguratorUnstableVersions"]').prop('checked', checked).change();
+ checkForConfiguratorUpdates();
+ });
+
+ if (result.checkForConfiguratorUnstableVersions) {
+ $('div.checkForConfiguratorUnstableVersions input').prop('checked', true);
+ }
+ });
+
function close_and_cleanup(e) {
if (e.type == 'click' && !$.contains($('div#options-window')[0], e.target) || e.type == 'keyup' && e.keyCode == 27) {
$(document).unbind('click keyup', close_and_cleanup);
@@ -377,10 +351,36 @@ $(document).ready(function () {
});
});
-function notifyOutdatedVersion(version) {
- if (semver.lt(getManifestVersion(), version)) {
- GUI.log('You are using an old version of ' + chrome.runtime.getManifest().name + '. Version ' + version + ' is available online with possible improvements and fixes.');
- }
+function checkForConfiguratorUpdates() {
+ var releaseChecker = new ReleaseChecker('configurator', 'https://api.github.com/repos/betaflight/betaflight-configurator/releases');
+
+ releaseChecker.loadReleaseData(notifyOutdatedVersion);
+}
+
+function notifyOutdatedVersion(releaseData) {
+ chrome.storage.local.get('checkForConfiguratorUnstableVersions', function (result) {
+ var showUnstableReleases = false;
+ if (result.checkForConfiguratorUnstableVersions) {
+ showUnstableReleases = true;
+ }
+ var versions = releaseData.filter(function (version) {
+ var semVerVersion = semver.parse(version.tag_name);
+ if (semVerVersion && (showUnstableReleases || semVerVersion.prerelease.length === 0)) {
+ return version;
+ }
+ }).sort(function (v1, v2) {
+ try {
+ return semver.compare(v2.tag_name, v1.tag_name);
+ } catch (e) {
+ return false;
+ }
+ });
+
+ if (versions.length > 0 && semver.lt(getManifestVersion(), versions[0].tag_name)) {
+ GUI.show_modal(chrome.i18n.getMessage('noticeTitle'), chrome.i18n.getMessage('configuratorUpdateNotice', [versions[0].tag_name, versions[0].html_url]));
+ GUI.log(chrome.i18n.getMessage('configuratorUpdateNotice', [versions[0].tag_name, versions[0].html_url]));
+ }
+ });
}
function update_packet_error(caller) {
diff --git a/tabs/firmware_flasher.js b/tabs/firmware_flasher.js
index 41aa165e..7e01c585 100755
--- a/tabs/firmware_flasher.js
+++ b/tabs/firmware_flasher.js
@@ -2,6 +2,7 @@
TABS.firmware_flasher = {
releases: null,
+ releaseChecker: new ReleaseChecker('firmware', 'https://api.github.com/repos/betaflight/betaflight/releases')
};
TABS.firmware_flasher.initialize = function (callback) {
@@ -30,144 +31,108 @@ TABS.firmware_flasher.initialize = function (callback) {
}
function buildBoardOptions(releaseData) {
- var boards_e = $('select[name="board"]').empty();
- var showDevReleases = ($('input.show_development_releases').is(':checked'));
- boards_e.append($("".format(chrome.i18n.getMessage('firmwareFlasherOptionLabelSelectBoard'))));
-
- var versions_e = $('select[name="firmware_version"]').empty();
- versions_e.append($("".format(chrome.i18n.getMessage('firmwareFlasherOptionLabelSelectFirmwareVersion'))));
-
- var releases = {};
- var sortedTargets = [];
- var unsortedTargets = [];
- releaseData.forEach(function(release){
- release.assets.forEach(function(asset){
- var targetFromFilenameExpression = /betaflight_([\d.]+)?_?(\w+)(\-.*)?\.(.*)/;
- var match = targetFromFilenameExpression.exec(asset.name);
-
- if ((!showDevReleases && release.prerelease) || !match) {
- return;
- }
- var target = match[2];
- if($.inArray(target, unsortedTargets) == -1) {
- unsortedTargets.push(target);
- }
- });
- sortedTargets = unsortedTargets.sort();
- });
- sortedTargets.forEach(function(release) {
- releases[release] = [];
- });
-
- releaseData.forEach(function(release){
- var versionFromTagExpression = /v?(.*)/;
- var matchVersionFromTag = versionFromTagExpression.exec(release.tag_name);
- var version = matchVersionFromTag[1];
-
- release.assets.forEach(function(asset){
- var targetFromFilenameExpression = /betaflight_([\d.]+)?_?(\w+)(\-.*)?\.(.*)/;
- var match = targetFromFilenameExpression.exec(asset.name);
-
- if ((!showDevReleases && release.prerelease) || !match) {
- return;
- }
-
- var target = match[2];
- var format = match[4];
-
- if (format != 'hex') {
- return;
- }
-
- var date = new Date(release.published_at);
- var formattedDate = ("0" + date.getDate()).slice(-2) + "-" + ("0"+(date.getMonth()+1)).slice(-2) + "-" +
- date.getFullYear() + " " + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2);
-
- var descriptor = {
- "releaseUrl": release.html_url,
- "name" : version,
- "version" : version,
- "url" : asset.browser_download_url,
- "file" : asset.name,
- "target" : target,
- "date" : formattedDate,
- "notes" : release.body,
- "status" : release.prerelease ? "release-candidate" : "stable"
- };
- releases[target].push(descriptor);
- });
- });
- var selectTargets = [];
- Object.keys(releases)
- .sort()
- .forEach(function(target, i) {
- var descriptors = releases[target];
- descriptors.forEach(function(descriptor){
- if($.inArray(target, selectTargets) == -1) {
- selectTargets.push(target);
- var select_e =
- $("".format(
- descriptor.target
- )).data('summary', descriptor);
- boards_e.append(select_e);
- }
- });
- });
- TABS.firmware_flasher.releases = releases;
- chrome.storage.local.get('selected_board', function (result) {
- if (result.selected_board) {
- $('select[name="board"]').val(result.selected_board);
- $('select[name="board"]').trigger("change");
- }
- });
- };
-
- function loadReleaseData() {
- chrome.storage.local.get(['releaseDataLastUpdate', 'releaseData'], function (result) {
- var releaseDataTimestamp = $.now();
- if (!result.releaseData || !result.releaseDataLastUpdate || releaseDataTimestamp - result.releaseDataLastUpdate > 3600 * 1000) {
- $.get('https://api.github.com/repos/betaflight/betaflight/releases', function (releaseData) {
- GUI.log("Loaded release information from GitHub.");
-
- chrome.storage.local.set({'releaseDataLastUpdate': releaseDataTimestamp, 'releaseData': releaseData}, function () {});
-
- processReleaseData(releaseData);
- }).fail(function (data){
- processReleaseData(result.releaseData);
-
- var message = '';
- if (data["responseJSON"]) {
- message = data["responseJSON"].message;
- }
- GUI.log("GitHub query failed: {0}
".format(message));
- });
- } else {
- if (result.releaseData) {
- GUI.log("Using cached release information.");
- }
-
- processReleaseData(result.releaseData);
- }
- });
- }
-
- function processReleaseData(releaseData) {
- if (releaseData) {
- buildBoardOptions(releaseData);
- } else {
- GUI.log("No release information available.");
-
+ if (!releaseData) {
$('select[name="board"]').empty().append('');
$('select[name="firmware_version"]').empty().append('');
+ } else {
+ var boards_e = $('select[name="board"]').empty();
+ var showDevReleases = ($('input.show_development_releases').is(':checked'));
+ boards_e.append($("".format(chrome.i18n.getMessage('firmwareFlasherOptionLabelSelectBoard'))));
+
+ var versions_e = $('select[name="firmware_version"]').empty();
+ versions_e.append($("".format(chrome.i18n.getMessage('firmwareFlasherOptionLabelSelectFirmwareVersion'))));
+
+ var releases = {};
+ var sortedTargets = [];
+ var unsortedTargets = [];
+ releaseData.forEach(function(release){
+ release.assets.forEach(function(asset){
+ var targetFromFilenameExpression = /betaflight_([\d.]+)?_?(\w+)(\-.*)?\.(.*)/;
+ var match = targetFromFilenameExpression.exec(asset.name);
+
+ if ((!showDevReleases && release.prerelease) || !match) {
+ return;
+ }
+ var target = match[2];
+ if($.inArray(target, unsortedTargets) == -1) {
+ unsortedTargets.push(target);
+ }
+ });
+ sortedTargets = unsortedTargets.sort();
+ });
+ sortedTargets.forEach(function(release) {
+ releases[release] = [];
+ });
+
+ releaseData.forEach(function(release){
+ var versionFromTagExpression = /v?(.*)/;
+ var matchVersionFromTag = versionFromTagExpression.exec(release.tag_name);
+ var version = matchVersionFromTag[1];
+
+ release.assets.forEach(function(asset){
+ var targetFromFilenameExpression = /betaflight_([\d.]+)?_?(\w+)(\-.*)?\.(.*)/;
+ var match = targetFromFilenameExpression.exec(asset.name);
+
+ if ((!showDevReleases && release.prerelease) || !match) {
+ return;
+ }
+
+ var target = match[2];
+ var format = match[4];
+
+ if (format != 'hex') {
+ return;
+ }
+
+ var date = new Date(release.published_at);
+ var formattedDate = ("0" + date.getDate()).slice(-2) + "-" + ("0"+(date.getMonth()+1)).slice(-2) + "-" + date.getFullYear() + " " + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2);
+
+ var descriptor = {
+ "releaseUrl": release.html_url,
+ "name" : version,
+ "version" : version,
+ "url" : asset.browser_download_url,
+ "file" : asset.name,
+ "target" : target,
+ "date" : formattedDate,
+ "notes" : release.body,
+ "status" : release.prerelease ? "release-candidate" : "stable"
+ };
+ releases[target].push(descriptor);
+ });
+ });
+ var selectTargets = [];
+ Object.keys(releases)
+ .sort()
+ .forEach(function(target, i) {
+ var descriptors = releases[target];
+ descriptors.forEach(function(descriptor){
+ if($.inArray(target, selectTargets) == -1) {
+ selectTargets.push(target);
+ var select_e =
+ $("".format(
+ descriptor.target
+ )).data('summary', descriptor);
+ boards_e.append(select_e);
+ }
+ });
+ });
+ TABS.firmware_flasher.releases = releases;
+ chrome.storage.local.get('selected_board', function (result) {
+ if (result.selected_board) {
+ $('select[name="board"]').val(result.selected_board);
+ $('select[name="board"]').trigger("change");
+ }
+ });
}
- }
+ };
// translate to user-selected language
localize();
// bind events
$('input.show_development_releases').click(function () {
- loadReleaseData();
+ self.releaseChecker.loadReleaseData(buildBoardOptions);
});
$('select[name="board"]').change(function() {
@@ -518,7 +483,7 @@ TABS.firmware_flasher.initialize = function (callback) {
$('input.show_development_releases').prop('checked', false);
}
- loadReleaseData();
+ self.releaseChecker.loadReleaseData(buildBoardOptions);
$('input.show_development_releases').change(function () {
chrome.storage.local.set({'show_development_releases': $(this).is(':checked')});
diff --git a/tabs/options.html b/tabs/options.html
index d99c3b5b..2a926365 100644
--- a/tabs/options.html
+++ b/tabs/options.html
@@ -1,6 +1,6 @@
-