mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-26 09:45:28 +03:00
Add metered connection and usability check (#4168)
* Add Metered connection and usability check * Add network speed to status bar * Add network type * Introduce network status * Rephrase option * Add network info to setup tab * Reserve statusbar for something else * Make sonar happy
This commit is contained in:
parent
4e553d9607
commit
5ef26ae89e
11 changed files with 133 additions and 14 deletions
|
@ -138,6 +138,10 @@
|
||||||
"rememberLastTab": {
|
"rememberLastTab": {
|
||||||
"message": "Reopen last tab on connect"
|
"message": "Reopen last tab on connect"
|
||||||
},
|
},
|
||||||
|
"meteredConnection": {
|
||||||
|
"message": "Disable internet access (for metered or slow connections)",
|
||||||
|
"description": "Text for the option to disable internet access for metered connection or to disable data over slow connections"
|
||||||
|
},
|
||||||
"analyticsOptOut": {
|
"analyticsOptOut": {
|
||||||
"message": "Opt out of the anonymised collection of statistics data"
|
"message": "Opt out of the anonymised collection of statistics data"
|
||||||
},
|
},
|
||||||
|
@ -1198,6 +1202,34 @@
|
||||||
"initialSetupEepromSaved": {
|
"initialSetupEepromSaved": {
|
||||||
"message": "EEPROM <span class=\"message-positive\">saved</span>"
|
"message": "EEPROM <span class=\"message-positive\">saved</span>"
|
||||||
},
|
},
|
||||||
|
"initialSetupNetworkInfo": {
|
||||||
|
"message": "Network info"
|
||||||
|
},
|
||||||
|
"initialSetupNetworkInfoHelp": {
|
||||||
|
"message": "Shows network connection status",
|
||||||
|
"description": "Message that pops up to describe the Network Connection section"
|
||||||
|
},
|
||||||
|
"initialSetupNetworkInfoStatus": {
|
||||||
|
"message": "Status:"
|
||||||
|
},
|
||||||
|
"initialSetupNetworkInfoStatusOnline": {
|
||||||
|
"message": "Online"
|
||||||
|
},
|
||||||
|
"initialSetupNetworkInfoStatusOffline": {
|
||||||
|
"message": "Offline"
|
||||||
|
},
|
||||||
|
"initialSetupNetworkInfoStatusSlow": {
|
||||||
|
"message": "Slow"
|
||||||
|
},
|
||||||
|
"initialSetupNetworkType": {
|
||||||
|
"message": "Type:"
|
||||||
|
},
|
||||||
|
"initialSetupNetworkRtt": {
|
||||||
|
"message": "RTT:"
|
||||||
|
},
|
||||||
|
"initialSetupNetworkDownlink": {
|
||||||
|
"message": "Downlink:"
|
||||||
|
},
|
||||||
"featureNone": {
|
"featureNone": {
|
||||||
"message": "<Select One>"
|
"message": "<Select One>"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import BuildApi from './BuildApi';
|
import BuildApi from './BuildApi';
|
||||||
import DarkTheme from './DarkTheme';
|
import DarkTheme from './DarkTheme';
|
||||||
|
import { ispConnected } from './utils/connection';
|
||||||
|
|
||||||
export default class Sponsor {
|
export default class Sponsor {
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
this._api = new BuildApi();
|
this._api = new BuildApi();
|
||||||
this._timer = setInterval(() => { this.Refresh(); }, 30000);
|
this._timer = ispConnected() ? setInterval(() => { this.Refresh(); }, 30000) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Refresh() {
|
Refresh() {
|
||||||
if (!navigator.onLine) {
|
if (!ispConnected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import BuildApi from "./BuildApi";
|
||||||
|
|
||||||
import { serialShim } from "./serial_shim.js";
|
import { serialShim } from "./serial_shim.js";
|
||||||
import { EventBus } from "../components/eventBus";
|
import { EventBus } from "../components/eventBus";
|
||||||
|
import { ispConnected } from "./utils/connection";
|
||||||
|
|
||||||
let serial = serialShim();
|
let serial = serialShim();
|
||||||
|
|
||||||
|
@ -463,7 +464,7 @@ function checkReportProblems() {
|
||||||
|
|
||||||
if (needsProblemReportingDialog) {
|
if (needsProblemReportingDialog) {
|
||||||
|
|
||||||
problems.map((problem) => {
|
problems.forEach((problem) => {
|
||||||
problemItemTemplate.clone().html(problem.description).appendTo(problemDialogList);
|
problemItemTemplate.clone().html(problem.description).appendTo(problemDialogList);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -491,7 +492,7 @@ async function processBuildOptions() {
|
||||||
|
|
||||||
// firmware 1_45 or higher is required to support cloud build options
|
// firmware 1_45 or higher is required to support cloud build options
|
||||||
// firmware 1_46 or higher retrieves build options from the flight controller
|
// firmware 1_46 or higher retrieves build options from the flight controller
|
||||||
if (supported && FC.CONFIG.buildKey.length === 32 && navigator.onLine) {
|
if (supported && FC.CONFIG.buildKey.length === 32 && ispConnected()) {
|
||||||
const buildApi = new BuildApi();
|
const buildApi = new BuildApi();
|
||||||
|
|
||||||
function onLoadCloudBuild(options) {
|
function onLoadCloudBuild(options) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import jBox from "jbox";
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { serialShim } from "../serial_shim";
|
import { serialShim } from "../serial_shim";
|
||||||
import FileSystem from "../FileSystem";
|
import FileSystem from "../FileSystem";
|
||||||
|
import { ispConnected } from "../utils/connection";
|
||||||
|
|
||||||
const serial = serialShim();
|
const serial = serialShim();
|
||||||
|
|
||||||
|
@ -229,7 +230,7 @@ cli.initialize = function (callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
$('a.support')
|
$('a.support')
|
||||||
.toggle(navigator.onLine)
|
.toggle(ispConnected())
|
||||||
.on('click', function() {
|
.on('click', function() {
|
||||||
|
|
||||||
function submitSupportData(data) {
|
function submitSupportData(data) {
|
||||||
|
|
|
@ -18,6 +18,7 @@ import DFU from '../protocols/webusbdfu';
|
||||||
import AutoBackup from '../utils/AutoBackup.js';
|
import AutoBackup from '../utils/AutoBackup.js';
|
||||||
import AutoDetect from '../utils/AutoDetect.js';
|
import AutoDetect from '../utils/AutoDetect.js';
|
||||||
import { EventBus } from "../../components/eventBus";
|
import { EventBus } from "../../components/eventBus";
|
||||||
|
import { ispConnected } from '../utils/connection.js';
|
||||||
|
|
||||||
const firmware_flasher = {
|
const firmware_flasher = {
|
||||||
targets: null,
|
targets: null,
|
||||||
|
@ -147,7 +148,7 @@ firmware_flasher.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadTargetList(targets) {
|
function loadTargetList(targets) {
|
||||||
if (!targets || !navigator.onLine) {
|
if (!targets || !ispConnected()) {
|
||||||
$('select[name="board"]').empty().append('<option value="0">Offline</option>');
|
$('select[name="board"]').empty().append('<option value="0">Offline</option>');
|
||||||
$('select[name="firmware_version"]').empty().append('<option value="0">Offline</option>');
|
$('select[name="firmware_version"]').empty().append('<option value="0">Offline</option>');
|
||||||
|
|
||||||
|
@ -214,7 +215,7 @@ firmware_flasher.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildOptions(data) {
|
function buildOptions(data) {
|
||||||
if (!navigator.onLine) {
|
if (!ispConnected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1133,7 +1134,7 @@ firmware_flasher.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.buildApi.loadTargets(() => {
|
self.buildApi.loadTargets(() => {
|
||||||
$('#content').load("./tabs/firmware_flasher.html", onDocumentLoad);
|
$('#content').load("./tabs/firmware_flasher.html", onDocumentLoad);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1142,7 +1143,7 @@ firmware_flasher.initialize = function (callback) {
|
||||||
|
|
||||||
|
|
||||||
firmware_flasher.validateBuildKey = function() {
|
firmware_flasher.validateBuildKey = function() {
|
||||||
return this.cloudBuildKey?.length === 32 && navigator.onLine;
|
return this.cloudBuildKey?.length === 32 && ispConnected();
|
||||||
};
|
};
|
||||||
|
|
||||||
firmware_flasher.cleanup = function (callback) {
|
firmware_flasher.cleanup = function (callback) {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { mspHelper } from '../msp/MSPHelper';
|
||||||
import { updateTabList } from '../utils/updateTabList';
|
import { updateTabList } from '../utils/updateTabList';
|
||||||
import { initMap } from './map';
|
import { initMap } from './map';
|
||||||
import { fromLonLat } from "ol/proj";
|
import { fromLonLat } from "ol/proj";
|
||||||
|
import { ispConnected } from "../utils/connection";
|
||||||
|
|
||||||
const gps = {};
|
const gps = {};
|
||||||
|
|
||||||
|
@ -352,7 +353,7 @@ gps.initialize = async function (callback) {
|
||||||
|
|
||||||
let gpsFoundPosition = false;
|
let gpsFoundPosition = false;
|
||||||
|
|
||||||
if (navigator.onLine) {
|
if (ispConnected()) {
|
||||||
$('#connect').hide();
|
$('#connect').hide();
|
||||||
|
|
||||||
gpsFoundPosition = !!(lon && lat);
|
gpsFoundPosition = !!(lon && lat);
|
||||||
|
@ -382,7 +383,7 @@ gps.initialize = async function (callback) {
|
||||||
}, 75, true);
|
}, 75, true);
|
||||||
|
|
||||||
//check for internet connection on load
|
//check for internet connection on load
|
||||||
if (navigator.onLine) {
|
if (ispConnected()) {
|
||||||
console.log('Online');
|
console.log('Online');
|
||||||
set_online();
|
set_online();
|
||||||
} else {
|
} else {
|
||||||
|
@ -391,7 +392,7 @@ gps.initialize = async function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#check").on('click',function(){
|
$("#check").on('click',function(){
|
||||||
if (navigator.onLine) {
|
if (ispConnected()) {
|
||||||
console.log('Online');
|
console.log('Online');
|
||||||
set_online();
|
set_online();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { checkForConfiguratorUpdates } from '../utils/checkForConfiguratorUpdate
|
||||||
import { checkSetupAnalytics } from '../Analytics';
|
import { checkSetupAnalytics } from '../Analytics';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import NotificationManager from '../utils/notifications';
|
import NotificationManager from '../utils/notifications';
|
||||||
|
import { ispConnected } from '../utils/connection';
|
||||||
|
|
||||||
const options = {};
|
const options = {};
|
||||||
options.initialize = function (callback) {
|
options.initialize = function (callback) {
|
||||||
|
@ -30,6 +31,7 @@ options.initialize = function (callback) {
|
||||||
TABS.options.initShowDevToolsOnStartup();
|
TABS.options.initShowDevToolsOnStartup();
|
||||||
TABS.options.initShowNotifications();
|
TABS.options.initShowNotifications();
|
||||||
TABS.options.initShowWarnings();
|
TABS.options.initShowWarnings();
|
||||||
|
TABS.options.initMeteredConnection();
|
||||||
|
|
||||||
GUI.content_ready(callback);
|
GUI.content_ready(callback);
|
||||||
});
|
});
|
||||||
|
@ -228,6 +230,18 @@ options.initShowNotifications = function () {
|
||||||
.change();
|
.change();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
options.initMeteredConnection = function () {
|
||||||
|
const result = getConfig("meteredConnection");
|
||||||
|
$("div.meteredConnection input")
|
||||||
|
.prop("checked", !!result.meteredConnection)
|
||||||
|
.on('change', function () {
|
||||||
|
setConfig({ meteredConnection: $(this).is(":checked") });
|
||||||
|
// update network status
|
||||||
|
ispConnected();
|
||||||
|
})
|
||||||
|
.trigger('change');
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: remove when modules are in place
|
// TODO: remove when modules are in place
|
||||||
TABS.options = options;
|
TABS.options = options;
|
||||||
export { options };
|
export { options };
|
||||||
|
|
|
@ -11,6 +11,7 @@ import MSPCodes from '../msp/MSPCodes';
|
||||||
import { API_VERSION_1_45, API_VERSION_1_46 } from '../data_storage';
|
import { API_VERSION_1_45, API_VERSION_1_46 } from '../data_storage';
|
||||||
import { gui_log } from '../gui_log';
|
import { gui_log } from '../gui_log';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import { ispConnected } from '../utils/connection';
|
||||||
|
|
||||||
const setup = {
|
const setup = {
|
||||||
yaw_fix: 0.0,
|
yaw_fix: 0.0,
|
||||||
|
@ -411,7 +412,7 @@ setup.initialize = function (callback) {
|
||||||
const showBuildInfo = function() {
|
const showBuildInfo = function() {
|
||||||
const supported = FC.CONFIG.buildKey.length === 32;
|
const supported = FC.CONFIG.buildKey.length === 32;
|
||||||
|
|
||||||
if (supported && navigator.onLine) {
|
if (supported && ispConnected()) {
|
||||||
const buildRoot = `https://build.betaflight.com/api/builds/${FC.CONFIG.buildKey}`;
|
const buildRoot = `https://build.betaflight.com/api/builds/${FC.CONFIG.buildKey}`;
|
||||||
const buildConfig = `<span class="buildInfoBtn" title="${i18n.getMessage('initialSetupInfoBuildConfig')}: ${buildRoot}/json">
|
const buildConfig = `<span class="buildInfoBtn" title="${i18n.getMessage('initialSetupInfoBuildConfig')}: ${buildRoot}/json">
|
||||||
<a href="${buildRoot}/json" target="_blank"><strong>${i18n.getMessage('initialSetupInfoBuildConfig')}</strong></a></span>`;
|
<a href="${buildRoot}/json" target="_blank"><strong>${i18n.getMessage('initialSetupInfoBuildConfig')}</strong></a></span>`;
|
||||||
|
@ -426,7 +427,7 @@ setup.initialize = function (callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const showBuildOptions = function() {
|
const showBuildOptions = function() {
|
||||||
const supported = (semver.eq(FC.CONFIG.apiVersion, API_VERSION_1_45) && navigator.onLine || semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_46)) && FC.CONFIG.buildOptions.length;
|
const supported = (semver.eq(FC.CONFIG.apiVersion, API_VERSION_1_45) && ispConnected() || semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_46)) && FC.CONFIG.buildOptions.length;
|
||||||
|
|
||||||
if (supported) {
|
if (supported) {
|
||||||
let buildOptionList = `<div class="dialogBuildInfoGrid-container">`;
|
let buildOptionList = `<div class="dialogBuildInfoGrid-container">`;
|
||||||
|
@ -464,9 +465,33 @@ setup.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showNetworkStatus() {
|
||||||
|
const networkStatus = ispConnected();
|
||||||
|
|
||||||
|
let statusText = '';
|
||||||
|
|
||||||
|
const type = navigator.connection.effectiveType;
|
||||||
|
const downlink = navigator.connection.downlink;
|
||||||
|
const rtt = navigator.connection.rtt;
|
||||||
|
|
||||||
|
if (!networkStatus || !navigator.onLine || type === 'none') {
|
||||||
|
statusText = i18n.getMessage('initialSetupNetworkInfoStatusOffline');
|
||||||
|
} else if (type === 'slow-2g' || type === '2g' || downlink < 0.115 || rtt > 1000) {
|
||||||
|
statusText = i18n.getMessage('initialSetupNetworkInfoStatusSlow');
|
||||||
|
} else {
|
||||||
|
statusText = i18n.getMessage('initialSetupNetworkInfoStatusOnline');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.network-status').text(statusText);
|
||||||
|
$('.network-type').text(navigator.connection.effectiveType);
|
||||||
|
$('.network-downlink').text(`${navigator.connection.downlink} Mbps`);
|
||||||
|
$('.network-rtt').text(navigator.connection.rtt);
|
||||||
|
}
|
||||||
|
|
||||||
prepareDisarmFlags();
|
prepareDisarmFlags();
|
||||||
showSensorInfo();
|
showSensorInfo();
|
||||||
showFirmwareInfo();
|
showFirmwareInfo();
|
||||||
|
showNetworkStatus();
|
||||||
|
|
||||||
// Show Sonar info box if sensor exist
|
// Show Sonar info box if sensor exist
|
||||||
if (!have_sensor(FC.CONFIG.activeSensors, 'sonar')) {
|
if (!have_sensor(FC.CONFIG.activeSensors, 'sonar')) {
|
||||||
|
|
9
src/js/utils/connection.js
Normal file
9
src/js/utils/connection.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { get as getConfig } from "../ConfigStorage";
|
||||||
|
|
||||||
|
export function ispConnected() {
|
||||||
|
const connected = navigator.onLine;
|
||||||
|
const isMetered = getConfig('meteredConnection').meteredConnection;
|
||||||
|
|
||||||
|
return connected && !isMetered;
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,12 @@
|
||||||
</div>
|
</div>
|
||||||
<span class="freelabel" i18n="rememberLastTab"></span>
|
<span class="freelabel" i18n="rememberLastTab"></span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="meteredConnection margin-bottom">
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" class="toggle" />
|
||||||
|
</div>
|
||||||
|
<span class="freelabel" i18n="meteredConnection"></span>
|
||||||
|
</div>
|
||||||
<div class="analyticsOptOut margin-bottom">
|
<div class="analyticsOptOut margin-bottom">
|
||||||
<div>
|
<div>
|
||||||
<input type="checkbox" class="toggle" />
|
<input type="checkbox" class="toggle" />
|
||||||
|
|
|
@ -235,6 +235,34 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="gui_box grey">
|
||||||
|
<div class="gui_box_titlebar">
|
||||||
|
<div class="spacer_box_title" i18n="initialSetupNetworkInfo"></div>
|
||||||
|
<div class="helpicon cf_tip" i18n_title="initialSetupNetworkInfoHelp"></div>
|
||||||
|
</div>
|
||||||
|
<div class="spacer_box">
|
||||||
|
<table width="100%" border="0" cellpadding="0" cellspacing="0" class="cf_table" role="presentation">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td id="network-status" i18n="initialSetupNetworkInfoStatus"></td>
|
||||||
|
<td class="network-status"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td id="network-type" i18n="initialSetupNetworkType"></td>
|
||||||
|
<td class="network-type"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td id="network-downlink" i18n="initialSetupNetworkDownlink"></td>
|
||||||
|
<td class="network-downlink"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td id="network-rtt" i18n="initialSetupNetworkRtt"></td>
|
||||||
|
<td class="network-rtt"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue