mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-17 13:25:24 +03:00
Cordova framework integration, Android support, mobile UI & options tab
Cordova integration and android platform : - Added cordova directory with required config - Added cordova applications generation in gulpfile - Added cordova development instructions - Used cordova plugins to simulate missing chrome api plugins (chrome.serial and chrome.fileSystem) - Added cordova clipboard support - Added android operating system and Cordova gui mode - Fixed some css and js files to make them working on Android as well as on computers - Added --skipdep argument to accelerate cordova build (gulp task) - Added a webview helper to help people to update the webview app of their device New options tab : - Added options tab replacing the options dropdown - Added option to switch between phones UI and computers UI Mobile interface and global interface improvements : - Simplified the structure of the header with flex css - Made headerbar and tab container responsive (compact headerbar and side menu) - All tabs are adapted to mobile interface (except firmware flasher) - The servos and adjustments tabs are not fully adapted but are "usable" - Improved header bar animation - Improved log expandation animation - Added swipe gesture to toggle side menu Fixes during the development : - Logo position - Dark mode - Auto connection - Error messages (cordova_chromeapi.js) - Responsive grid - Testing - Disconnection - Width of boxes inside the OSD tab - Fixed cli tab - OSD tab - Motor stop switch - White spaces in boxes - Dialogs size - Connect button state - Prevent tablet with a height larger than 575px to switch to computers ui - Fixed logging tab - Fixed code smell - Fixed yarn cordova plugin install issue - Fixed content_wrapper - Fixed vibrations when scrolling - Fixed scrolling bar alignment - Fixed dialogReportProblem height - Fixed rates logo - Fixed auto connection default value (true) - Fixed D to D max - Fixed dialogs Added required messages in locales/en/messages.json file Requested changes
This commit is contained in:
parent
ea880840a8
commit
4f93e54ae6
99 changed files with 9095 additions and 3015 deletions
158
src/js/main.js
158
src/js/main.js
|
@ -4,6 +4,12 @@ window.googleAnalytics = analytics;
|
|||
window.analytics = null;
|
||||
|
||||
$(document).ready(function () {
|
||||
if (typeof cordovaApp === 'undefined') {
|
||||
appReady();
|
||||
}
|
||||
});
|
||||
|
||||
function appReady() {
|
||||
$.getJSON('version.json', function(data) {
|
||||
CONFIGURATOR.version = data.version;
|
||||
CONFIGURATOR.gitChangesetId = data.gitChangesetId;
|
||||
|
@ -29,7 +35,7 @@ $(document).ready(function () {
|
|||
initializeSerialBackend();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function checkSetupAnalytics(callback) {
|
||||
if (!analytics) {
|
||||
|
@ -143,13 +149,17 @@ function closeSerial() {
|
|||
}
|
||||
|
||||
function closeHandler() {
|
||||
this.hide();
|
||||
if (!GUI.isCordova()) {
|
||||
this.hide();
|
||||
}
|
||||
|
||||
analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'AppClose', { sessionControl: 'end' });
|
||||
|
||||
closeSerial();
|
||||
|
||||
this.close(true);
|
||||
if (!GUI.isCordova()) {
|
||||
this.close(true);
|
||||
}
|
||||
}
|
||||
|
||||
//Process to execute to real start the app
|
||||
|
@ -171,14 +181,16 @@ function startProcess() {
|
|||
GUI.nwGui.Shell.openExternal(url);
|
||||
});
|
||||
nwWindow.on('close', closeHandler);
|
||||
} else if (!GUI.isOther()) {
|
||||
} else if (GUI.isChromeApp()) {
|
||||
chrome.app.window.onClosed.addListener(closeHandler);
|
||||
// This event does not actually get fired:
|
||||
chrome.runtime.onSuspend.addListener(closeHandler);
|
||||
} else if (GUI.isCordova()) {
|
||||
window.addEventListener('beforeunload', closeHandler);
|
||||
}
|
||||
|
||||
$('.connect_b a.connect').removeClass('disabled');
|
||||
$('#logo .version').text(CONFIGURATOR.version);
|
||||
$('#logo .version, #tab_logoversion .version').text(CONFIGURATOR.version);
|
||||
updateStatusBarVersion();
|
||||
updateTopBarVersion();
|
||||
|
||||
|
@ -202,6 +214,10 @@ function startProcess() {
|
|||
);
|
||||
});
|
||||
|
||||
if (GUI.isCordova()) {
|
||||
UI_PHONES.init();
|
||||
}
|
||||
|
||||
const ui_tabs = $('#tabs > ul');
|
||||
$('a', ui_tabs).click(function () {
|
||||
if ($(this).parent().hasClass('active') === false && !GUI.tab_switch_in_progress) { // only initialize when the tab isn't already active
|
||||
|
@ -274,6 +290,9 @@ function startProcess() {
|
|||
case 'privacy_policy':
|
||||
TABS.staticTab.initialize('privacy_policy', content_ready);
|
||||
break;
|
||||
case 'options':
|
||||
TABS.options.initialize(content_ready);
|
||||
break;
|
||||
case 'firmware_flasher':
|
||||
TABS.firmware_flasher.initialize(content_ready);
|
||||
break;
|
||||
|
@ -354,117 +373,6 @@ function startProcess() {
|
|||
|
||||
$('#tabs ul.mode-disconnected li a:first').click();
|
||||
|
||||
// options
|
||||
$('a#options').click(function () {
|
||||
const el = $(this);
|
||||
|
||||
if (!el.hasClass('active')) {
|
||||
el.addClass('active');
|
||||
el.after('<div id="options-window"></div>');
|
||||
|
||||
$('div#options-window').load('./tabs/options.html', function () {
|
||||
// translate to user-selected language
|
||||
i18n.localizePage();
|
||||
|
||||
ConfigStorage.get('permanentExpertMode', function (result) {
|
||||
if (result.permanentExpertMode) {
|
||||
$('div.permanentExpertMode input').prop('checked', true);
|
||||
}
|
||||
|
||||
$('div.permanentExpertMode input').change(function () {
|
||||
const checked = $(this).is(':checked');
|
||||
|
||||
ConfigStorage.set({'permanentExpertMode': checked});
|
||||
|
||||
$('input[name="expertModeCheckbox"]').prop('checked', checked).change();
|
||||
}).change();
|
||||
});
|
||||
|
||||
ConfigStorage.get('rememberLastTab', function (result) {
|
||||
$('div.rememberLastTab input')
|
||||
.prop('checked', !!result.rememberLastTab)
|
||||
.change(function() { ConfigStorage.set({rememberLastTab: $(this).is(':checked')}); })
|
||||
.change();
|
||||
});
|
||||
|
||||
if (GUI.operating_system !== 'ChromeOS') {
|
||||
ConfigStorage.get('checkForConfiguratorUnstableVersions', function (result) {
|
||||
if (result.checkForConfiguratorUnstableVersions) {
|
||||
$('div.checkForConfiguratorUnstableVersions input').prop('checked', true);
|
||||
}
|
||||
|
||||
$('div.checkForConfiguratorUnstableVersions input').change(function () {
|
||||
const checked = $(this).is(':checked');
|
||||
|
||||
ConfigStorage.set({'checkForConfiguratorUnstableVersions': checked});
|
||||
|
||||
checkForConfiguratorUpdates();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
$('div.checkForConfiguratorUnstableVersions').hide();
|
||||
}
|
||||
|
||||
ConfigStorage.get('analyticsOptOut', function (result) {
|
||||
if (result.analyticsOptOut) {
|
||||
$('div.analyticsOptOut input').prop('checked', true);
|
||||
}
|
||||
|
||||
$('div.analyticsOptOut input').change(function () {
|
||||
const checked = $(this).is(':checked');
|
||||
|
||||
ConfigStorage.set({'analyticsOptOut': checked});
|
||||
|
||||
checkSetupAnalytics(function (analyticsService) {
|
||||
if (checked) {
|
||||
analyticsService.sendEvent(analyticsService.EVENT_CATEGORIES.APPLICATION, 'OptOut');
|
||||
}
|
||||
|
||||
analyticsService.setOptOut(checked);
|
||||
|
||||
if (!checked) {
|
||||
analyticsService.sendEvent(analyticsService.EVENT_CATEGORIES.APPLICATION, 'OptIn');
|
||||
}
|
||||
});
|
||||
}).change();
|
||||
});
|
||||
|
||||
$('div.cliAutoComplete input')
|
||||
.prop('checked', CliAutoComplete.configEnabled)
|
||||
.change(function () {
|
||||
const checked = $(this).is(':checked');
|
||||
|
||||
ConfigStorage.set({'cliAutoComplete': checked});
|
||||
CliAutoComplete.setEnabled(checked);
|
||||
}).change();
|
||||
|
||||
$('#darkThemeSelect')
|
||||
.val(DarkTheme.configEnabled)
|
||||
.change(function () {
|
||||
const value = parseInt($(this).val());
|
||||
|
||||
ConfigStorage.set({'darkTheme': value});
|
||||
setDarkTheme(value);
|
||||
}).change();
|
||||
|
||||
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);
|
||||
|
||||
$('div#options-window').slideUp(250, function () {
|
||||
el.removeClass('active');
|
||||
$(this).empty().remove();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$(document).bind('click keyup', close_and_cleanup);
|
||||
|
||||
$(this).slideDown(250);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// listen to all input change events and adjust the value within limits if necessary
|
||||
$("#content").on('focus', 'input[type="number"]', function () {
|
||||
const element = $(this);
|
||||
|
@ -535,22 +443,19 @@ function startProcess() {
|
|||
$("#showlog").on('click', function () {
|
||||
let state = $(this).data('state');
|
||||
if (state) {
|
||||
$("#log").animate({height: 27}, 200, function () {
|
||||
setTimeout(function() {
|
||||
const command_log = $('div#log');
|
||||
command_log.scrollTop($('div.wrapper', command_log).height());
|
||||
});
|
||||
}, 200);
|
||||
$("#log").removeClass('active');
|
||||
$("#content").removeClass('logopen');
|
||||
$(".tab_container").removeClass('logopen');
|
||||
$("#tab-content-container").removeClass('logopen');
|
||||
$("#scrollicon").removeClass('active');
|
||||
ConfigStorage.set({'logopen': false});
|
||||
|
||||
state = false;
|
||||
} else {
|
||||
$("#log").animate({height: 111}, 200);
|
||||
$("#log").addClass('active');
|
||||
$("#content").addClass('logopen');
|
||||
$(".tab_container").addClass('logopen');
|
||||
$("#tab-content-container").addClass('logopen');
|
||||
$("#scrollicon").addClass('active');
|
||||
ConfigStorage.set({'logopen': true});
|
||||
|
||||
|
@ -567,11 +472,12 @@ function startProcess() {
|
|||
});
|
||||
|
||||
ConfigStorage.get('permanentExpertMode', function (result) {
|
||||
const experModeCheckbox = 'input[name="expertModeCheckbox"]';
|
||||
if (result.permanentExpertMode) {
|
||||
$('input[name="expertModeCheckbox"]').prop('checked', true);
|
||||
$(experModeCheckbox).prop('checked', true);
|
||||
}
|
||||
|
||||
$('input[name="expertModeCheckbox"]').change(function () {
|
||||
$(experModeCheckbox).change(function () {
|
||||
const checked = $(this).is(':checked');
|
||||
checkSetupAnalytics(function (analyticsService) {
|
||||
analyticsService.setDimension(analyticsService.DIMENSIONS.CONFIGURATOR_EXPERT_MODE, checked ? 'On' : 'Off');
|
||||
|
@ -819,7 +725,7 @@ function updateTopBarVersion(firmwareVersion, firmwareId, hardwareId) {
|
|||
|
||||
const versionText = `${configuratorVersion}<br />${firmwareVersionAndId}<br />${targetVersion}`;
|
||||
|
||||
$('#logo .logo_text').html(versionText);
|
||||
$('#logo .logo_text, #tab_logoversion .version').html(versionText);
|
||||
}
|
||||
|
||||
function updateStatusBarVersion(firmwareVersion, firmwareId, hardwareId) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue