Expose Cloud Build Options and hide tabs and features (#3332)
Expose Cloud Build Options Add cloud build options to auto-detectmaster
parent
65d0ab3796
commit
584e672c4d
|
@ -549,6 +549,9 @@
|
|||
"buildServerSupportRequestSubmission": {
|
||||
"message": "<br>*** Support data submitted *** <br>Id: $1<br><br><br># copy ID and provide to the betaflight team."
|
||||
},
|
||||
"buildKey": {
|
||||
"message": "Build Key: <strong>$1</strong>"
|
||||
},
|
||||
"supportWarningDialogTitle": {
|
||||
"message": "Confirm Data Submission"
|
||||
},
|
||||
|
|
|
@ -149,6 +149,18 @@ export default class BuildApi {
|
|||
});
|
||||
}
|
||||
|
||||
requestBuildOptions(key, onSuccess, onFailure) {
|
||||
|
||||
const url = `${this._url}/api/builds/${key}/json`;
|
||||
$.get(url, function (data) {
|
||||
onSuccess(data);
|
||||
}).fail(xhr => {
|
||||
if (onFailure !== undefined) {
|
||||
onFailure();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadOptions(onSuccess, onFailure) {
|
||||
|
||||
const url = `${this._url}/api/options`;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { bit_check, bit_set, bit_clear } from "./bit";
|
||||
import { API_VERSION_1_44 } from './data_storage';
|
||||
import { API_VERSION_1_44, API_VERSION_1_45 } from './data_storage';
|
||||
import semver from "semver";
|
||||
import { tracking } from "./Analytics";
|
||||
|
||||
|
@ -11,21 +11,22 @@ const Features = function (config) {
|
|||
{bit: 2, group: 'other', name: 'INFLIGHT_ACC_CAL'},
|
||||
{bit: 3, group: 'rxMode', mode: 'select', name: 'RX_SERIAL'},
|
||||
{bit: 4, group: 'escMotorStop', name: 'MOTOR_STOP'},
|
||||
{bit: 5, group: 'other', name: 'SERVO_TILT', haveTip: true},
|
||||
{bit: 5, group: 'other', name: 'SERVO_TILT', haveTip: true, dependsOn: 'SERVOS'},
|
||||
{bit: 6, group: 'other', name: 'SOFTSERIAL', haveTip: true},
|
||||
{bit: 7, group: 'gps', name: 'GPS', haveTip: true},
|
||||
{bit: 9, group: 'other', name: 'SONAR'},
|
||||
{bit: 10, group: 'telemetry', name: 'TELEMETRY'},
|
||||
{bit: 7, group: 'other', name: 'GPS', haveTip: true, dependsOn: 'GPS'},
|
||||
{bit: 9, group: 'other', name: 'SONAR', dependsOn: 'RANGEFINDER'},
|
||||
{bit: 10, group: 'telemetry', name: 'TELEMETRY', dependsOn: 'TELEMETRY'},
|
||||
{bit: 12, group: '3D', name: '3D'},
|
||||
{bit: 13, group: 'rxMode', mode: 'select', name: 'RX_PARALLEL_PWM'},
|
||||
{bit: 14, group: 'rxMode', mode: 'select', name: 'RX_MSP'},
|
||||
{bit: 15, group: 'rssi', name: 'RSSI_ADC'},
|
||||
{bit: 16, group: 'other', name: 'LED_STRIP'},
|
||||
{bit: 17, group: 'other', name: 'DISPLAY', haveTip: true},
|
||||
{bit: 18, group: 'other', name: 'OSD'},
|
||||
{bit: 20, group: 'other', name: 'CHANNEL_FORWARDING'},
|
||||
{bit: 21, group: 'other', name: 'TRANSPONDER', haveTip: true},
|
||||
{bit: 16, group: 'other', name: 'LED_STRIP', dependsOn: 'LED_STRIP'},
|
||||
{bit: 17, group: 'other', name: 'DISPLAY', haveTip: true, dependsOn: 'DASHBOARD'},
|
||||
{bit: 18, group: 'other', name: 'OSD', dependsOn: 'OSD'},
|
||||
{bit: 20, group: 'other', name: 'CHANNEL_FORWARDING', dependsOn: 'SERVOS'},
|
||||
{bit: 21, group: 'other', name: 'TRANSPONDER', haveTip: true, dependsOn: 'TRANSPONDER'},
|
||||
{bit: 22, group: 'other', name: 'AIRMODE'},
|
||||
{bit: 24, group: 'vtx', name: 'VTX', dependsOn: 'VTX'},
|
||||
{bit: 25, group: 'rxMode', mode: 'select', name: 'RX_SPI'},
|
||||
{bit: 27, group: 'escSensor', name: 'ESC_SENSOR'},
|
||||
{bit: 28, group: 'antiGravity', name: 'ANTI_GRAVITY', haveTip: true, hideName: true},
|
||||
|
@ -37,7 +38,19 @@ const Features = function (config) {
|
|||
);
|
||||
}
|
||||
|
||||
self._features = features.sort((a, b) => a.name.localeCompare(b.name, window.navigator.language, { ignorePunctuation: true }));
|
||||
self._features = features;
|
||||
|
||||
if (semver.gte(config.apiVersion, API_VERSION_1_45) && config.buildKey.length === 32) {
|
||||
self._features = [];
|
||||
|
||||
for (const feature of features) {
|
||||
if (config.buildOptions.some(opt => opt.includes(feature.dependsOn)) || feature.dependsOn === undefined) {
|
||||
self._features.push(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self._features.sort((a, b) => a.name.localeCompare(b.name, window.navigator.language, { ignorePunctuation: true }));
|
||||
self._featureMask = 0;
|
||||
|
||||
self._analyticsChanges = {};
|
||||
|
|
|
@ -6,12 +6,13 @@ export const API_VERSION_1_42 = '1.42.0';
|
|||
export const API_VERSION_1_43 = '1.43.0';
|
||||
export const API_VERSION_1_44 = '1.44.0';
|
||||
export const API_VERSION_1_45 = '1.45.0';
|
||||
export const API_VERSION_1_46 = '1.46.0';
|
||||
|
||||
const CONFIGURATOR = {
|
||||
// all versions are specified and compared using semantic versioning http://semver.org/
|
||||
API_VERSION_ACCEPTED: API_VERSION_1_41,
|
||||
API_VERSION_MIN_SUPPORTED_BACKUP_RESTORE: API_VERSION_1_41,
|
||||
API_VERSION_MAX_SUPPORTED: API_VERSION_1_45,
|
||||
API_VERSION_MAX_SUPPORTED: API_VERSION_1_46,
|
||||
|
||||
connectionValid: false,
|
||||
connectionValidCliOnly: false,
|
||||
|
|
|
@ -8,6 +8,8 @@ const INITIAL_CONFIG = {
|
|||
flightControllerVersion: '',
|
||||
version: 0,
|
||||
buildInfo: '',
|
||||
buildKey: '',
|
||||
buildOptions: [],
|
||||
multiType: 0,
|
||||
msp_version: 0, // not specified using semantic versioning
|
||||
capability: 0,
|
||||
|
|
|
@ -33,19 +33,16 @@ class GuiControl {
|
|||
'options',
|
||||
'help',
|
||||
];
|
||||
this.defaultAllowedFCTabsWhenConnected = [
|
||||
|
||||
this.defaultAllowedTabsCloudBuild = [
|
||||
'setup',
|
||||
'failsafe',
|
||||
'transponder',
|
||||
'osd',
|
||||
'power',
|
||||
'adjustments',
|
||||
'auxiliary',
|
||||
'presets',
|
||||
'cli',
|
||||
'configuration',
|
||||
'gps',
|
||||
'led_strip',
|
||||
'logging',
|
||||
'onboard_logging',
|
||||
'modes',
|
||||
|
@ -54,10 +51,19 @@ class GuiControl {
|
|||
'ports',
|
||||
'receiver',
|
||||
'sensors',
|
||||
];
|
||||
|
||||
this.defaultCloudBuildTabOptions = [
|
||||
'gps',
|
||||
'led_strip',
|
||||
'osd',
|
||||
'servos',
|
||||
'transponder',
|
||||
'vtx',
|
||||
];
|
||||
|
||||
this.defaultAllowedFCTabsWhenConnected = [ ...this.defaultAllowedTabsCloudBuild, ...this.defaultCloudBuildTabOptions];
|
||||
|
||||
this.allowedTabs = this.defaultAllowedTabsWhenDisconnected;
|
||||
|
||||
// check which operating system is user running
|
||||
|
|
|
@ -202,6 +202,7 @@ const MSPCodes = {
|
|||
CRAFT_NAME: 2,
|
||||
PID_PROFILE_NAME: 3,
|
||||
RATE_PROFILE_NAME: 4,
|
||||
BUILD_KEY: 5,
|
||||
};
|
||||
|
||||
export default MSPCodes;
|
||||
|
|
|
@ -851,6 +851,9 @@ MspHelper.prototype.process_data = function(dataHandler) {
|
|||
case MSPCodes.RATE_PROFILE_NAME:
|
||||
FC.CONFIG.rateProfileNames[FC.CONFIG.rateProfile] = self.getText(data);
|
||||
break;
|
||||
case MSPCodes.BUILD_KEY:
|
||||
FC.CONFIG.buildKey = self.getText(data);
|
||||
break;
|
||||
default:
|
||||
console.log('Unsupport text type');
|
||||
break;
|
||||
|
|
|
@ -23,6 +23,7 @@ import { get as getConfig, set as setConfig } from "./ConfigStorage";
|
|||
import { tracking } from "./Analytics";
|
||||
import semver from 'semver';
|
||||
import CryptoES from "crypto-es";
|
||||
import BuildApi from "./BuildApi";
|
||||
|
||||
let mspHelper;
|
||||
let connectionTimestamp;
|
||||
|
@ -458,17 +459,39 @@ function checkReportProblems() {
|
|||
});
|
||||
}
|
||||
|
||||
function processUid() {
|
||||
MSP.send_message(MSPCodes.MSP_UID, false, false, function () {
|
||||
const deviceIdentifier = FC.CONFIG.deviceIdentifier;
|
||||
|
||||
tracking.setFlightControllerData(tracking.DATA.MCU_ID, CryptoES.SHA1(deviceIdentifier));
|
||||
tracking.sendEvent(tracking.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'Connected');
|
||||
connectionTimestamp = Date.now();
|
||||
gui_log(i18n.getMessage('uniqueDeviceIdReceived', [deviceIdentifier]));
|
||||
async function processBuildConfiguration() {
|
||||
const buildApi = new BuildApi();
|
||||
|
||||
function onLoadCloudBuild(options) {
|
||||
FC.CONFIG.buildOptions = options.Request.Options;
|
||||
processCraftName();
|
||||
});
|
||||
}
|
||||
|
||||
await MSP.promise(MSPCodes.MSP2_GET_TEXT, mspHelper.crunch(MSPCodes.MSP2_GET_TEXT, MSPCodes.BUILD_KEY));
|
||||
|
||||
if (FC.CONFIG.buildKey.length === 32 && navigator.onLine) {
|
||||
gui_log(i18n.getMessage('buildKey', FC.CONFIG.buildKey));
|
||||
buildApi.requestBuildOptions(FC.CONFIG.buildKey, onLoadCloudBuild, processCraftName);
|
||||
} else {
|
||||
processCraftName();
|
||||
}
|
||||
}
|
||||
|
||||
async function processUid() {
|
||||
await MSP.promise(MSPCodes.MSP_UID);
|
||||
|
||||
tracking.setFlightControllerData(tracking.DATA.MCU_ID, CryptoES.SHA1(FC.CONFIG.deviceIdentifier));
|
||||
tracking.sendEvent(tracking.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'Connected');
|
||||
|
||||
connectionTimestamp = Date.now();
|
||||
|
||||
gui_log(i18n.getMessage('uniqueDeviceIdReceived', FC.CONFIG.deviceIdentifier));
|
||||
|
||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_45)) {
|
||||
processBuildConfiguration();
|
||||
} else {
|
||||
processCraftName();
|
||||
}
|
||||
}
|
||||
|
||||
async function processCraftName() {
|
||||
|
@ -494,7 +517,19 @@ function setRtc() {
|
|||
|
||||
function finishOpen() {
|
||||
CONFIGURATOR.connectionValid = true;
|
||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_45) && FC.CONFIG.buildKey.length === 32) {
|
||||
|
||||
GUI.allowedTabs = GUI.defaultAllowedTabsCloudBuild;
|
||||
|
||||
for (const tab of GUI.defaultCloudBuildTabOptions) {
|
||||
if (FC.CONFIG.buildOptions.some(opt => opt.toLowerCase().includes(tab))) {
|
||||
GUI.allowedTabs.push(tab);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
GUI.allowedTabs = GUI.defaultAllowedFCTabsWhenConnected.slice();
|
||||
}
|
||||
|
||||
if (GUI.isCordova()) {
|
||||
UI_PHONES.reset();
|
||||
|
|
|
@ -11,7 +11,7 @@ import FC from '../fc';
|
|||
import MSP from '../msp';
|
||||
import MSPCodes from '../msp/MSPCodes';
|
||||
import PortHandler, { usbDevices } from '../port_handler';
|
||||
import CONFIGURATOR, { API_VERSION_1_39 } from '../data_storage';
|
||||
import CONFIGURATOR, { API_VERSION_1_39, API_VERSION_1_45 } from '../data_storage';
|
||||
import serial from '../serial';
|
||||
import STM32DFU from '../protocols/stm32usbdfu';
|
||||
import { gui_log } from '../gui_log';
|
||||
|
@ -165,11 +165,9 @@ firmware_flasher.initialize = function (callback) {
|
|||
|
||||
TABS.firmware_flasher.targets = targets;
|
||||
|
||||
result = getStorage('selected_board');
|
||||
if (result.selected_board) {
|
||||
const selected = targets.find(t => t.target === result.selected_board);
|
||||
$('select[name="board"]').val(selected ? result.selected_board : 0).trigger('change');
|
||||
}
|
||||
|
||||
// For discussion. Rather remove build configuration and let user use auto-detect. Often I think already had pressed the button.
|
||||
$('div.build_configuration').slideUp();
|
||||
}
|
||||
|
||||
function buildOptionsList(select_e, options) {
|
||||
|
@ -399,10 +397,6 @@ firmware_flasher.initialize = function (callback) {
|
|||
}
|
||||
|
||||
if (!GUI.connect_lock) {
|
||||
if (target !== '0') {
|
||||
setStorage({'selected_board': target});
|
||||
}
|
||||
|
||||
self.selectedBoard = target;
|
||||
console.log('board changed to', target);
|
||||
|
||||
|
@ -535,6 +529,8 @@ firmware_flasher.initialize = function (callback) {
|
|||
function verifyBoard() {
|
||||
if (!$('option:selected', portPickerElement).data().isDFU) {
|
||||
|
||||
let mspHelper;
|
||||
|
||||
function onFinishClose() {
|
||||
MSP.clearListeners();
|
||||
}
|
||||
|
@ -561,38 +557,91 @@ firmware_flasher.initialize = function (callback) {
|
|||
if (board !== target) {
|
||||
boardSelect.val(board).trigger('change');
|
||||
}
|
||||
|
||||
gui_log(i18n.getMessage(targetAvailable ? 'firmwareFlasherBoardVerificationSuccess' : 'firmwareFlasherBoardVerficationTargetNotAvailable',
|
||||
{ boardName: board }));
|
||||
} else {
|
||||
gui_log(i18n.getMessage('firmwareFlasherBoardVerificationFail'));
|
||||
}
|
||||
|
||||
onClose();
|
||||
}
|
||||
|
||||
function getBoard() {
|
||||
function getBoardInfo() {
|
||||
MSP.send_message(MSPCodes.MSP_BOARD_INFO, false, false, onFinish);
|
||||
}
|
||||
|
||||
function presetBuildOptions(data) {
|
||||
const newOptions = [];
|
||||
|
||||
newOptions.generalOptions = [];
|
||||
newOptions.motorProtocols = [];
|
||||
newOptions.radioProtocols = [];
|
||||
newOptions.telemetryProtocols = [];
|
||||
|
||||
for (const option of data.generalOptions) {
|
||||
option.default = FC.CONFIG.buildOptions.some(opt => opt.includes(option.value));
|
||||
newOptions.generalOptions.push(option);
|
||||
}
|
||||
|
||||
for (const option of data.motorProtocols) {
|
||||
option.default = FC.CONFIG.buildOptions.some(opt => opt.includes(option.value));
|
||||
newOptions.motorProtocols.push(option);
|
||||
}
|
||||
|
||||
for (const option of data.radioProtocols) {
|
||||
option.default = FC.CONFIG.buildOptions.some(opt => opt.includes(option.value));
|
||||
newOptions.radioProtocols.push(option);
|
||||
}
|
||||
|
||||
for (const option of data.telemetryProtocols) {
|
||||
option.default = FC.CONFIG.buildOptions.some(opt => opt.includes(option.value));
|
||||
newOptions.telemetryProtocols.push(option);
|
||||
}
|
||||
|
||||
buildOptions(newOptions);
|
||||
}
|
||||
|
||||
function getBuildInfo() {
|
||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_45) && navigator.onLine) {
|
||||
|
||||
function onLoadCloudBuild(options) {
|
||||
if (FC.CONFIG.buildKey.length === 32) {
|
||||
FC.CONFIG.buildOptions = options.Request.Options;
|
||||
self.releaseLoader.loadOptions(presetBuildOptions);
|
||||
}
|
||||
getBoardInfo();
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP2_GET_TEXT, mspHelper.crunch(MSPCodes.MSP2_GET_TEXT, MSPCodes.BUILD_KEY), false, () => {
|
||||
self.releaseLoader.requestBuildOptions(FC.CONFIG.buildKey, onLoadCloudBuild, getBoardInfo);
|
||||
});
|
||||
} else {
|
||||
getBoardInfo();
|
||||
}
|
||||
}
|
||||
|
||||
function detectBoard() {
|
||||
console.log(`Requesting board information`);
|
||||
MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, () => {
|
||||
if (!FC.CONFIG.apiVersion || FC.CONFIG.apiVersion === 'null.null.0') {
|
||||
FC.CONFIG.apiVersion = '0.0.0';
|
||||
}
|
||||
console.log(FC.CONFIG.apiVersion);
|
||||
MSP.send_message(MSPCodes.MSP_UID, false, false, () => {
|
||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_39)) {
|
||||
MSP.send_message(MSPCodes.MSP_BOARD_INFO, false, false, onFinish);
|
||||
|
||||
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_39)) {
|
||||
onClose(); // not supported
|
||||
} else {
|
||||
console.log('Firmware version not supported for reading board information');
|
||||
onClose();
|
||||
MSP.send_message(MSPCodes.MSP_UID, false, false, getBuildInfo);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onConnect(openInfo) {
|
||||
if (openInfo) {
|
||||
serial.onReceive.addListener(data => MSP.read(data));
|
||||
const mspHelper = new MspHelper();
|
||||
mspHelper = new MspHelper();
|
||||
MSP.listen(mspHelper.process_data.bind(mspHelper));
|
||||
getBoard();
|
||||
detectBoard();
|
||||
} else {
|
||||
gui_log(i18n.getMessage('serialPortOpenFail'));
|
||||
}
|
||||
|
@ -1219,7 +1268,6 @@ firmware_flasher.showDialogVerifyBoard = function (selected, verified, onAbort,
|
|||
if (!dialogVerifyBoard.hasAttribute('open')) {
|
||||
dialogVerifyBoard.showModal();
|
||||
$('#dialog-verify-board-abort-confirmbtn').click(function() {
|
||||
setStorage({'selected_board': FC.CONFIG.boardName});
|
||||
dialogVerifyBoard.close();
|
||||
onAbort();
|
||||
});
|
||||
|
|
|
@ -28,25 +28,16 @@ ports.initialize = function (callback) {
|
|||
{ name: 'TELEMETRY_SMARTPORT', groups: ['telemetry'], maxPorts: 1 },
|
||||
{ name: 'RX_SERIAL', groups: ['rx'], maxPorts: 1 },
|
||||
{ name: 'BLACKBOX', groups: ['peripherals'], sharableWith: ['msp'], notSharableWith: ['telemetry'], maxPorts: 1 },
|
||||
{ name: 'TELEMETRY_LTM', groups: ['telemetry'], sharableWith: ['msp'], notSharableWith: ['peripherals'], maxPorts: 1 },
|
||||
{ name: 'TELEMETRY_MAVLINK', groups: ['telemetry'], sharableWith: ['msp'], notSharableWith: ['peripherals'], maxPorts: 1 },
|
||||
{ name: 'IRC_TRAMP', groups: ['peripherals'], maxPorts: 1 },
|
||||
{ name: 'ESC_SENSOR', groups: ['sensors'], maxPorts: 1 },
|
||||
{ name: 'TBS_SMARTAUDIO', groups: ['peripherals'], maxPorts: 1 },
|
||||
{ name: 'TELEMETRY_IBUS', groups: ['telemetry'], maxPorts: 1 },
|
||||
{ name: 'RUNCAM_DEVICE_CONTROL', groups: ['peripherals'], maxPorts: 1 },
|
||||
{ name: 'LIDAR_TF', groups: ['peripherals'], maxPorts: 1 },
|
||||
];
|
||||
|
||||
const ltmFunctionRule = {name: 'TELEMETRY_LTM', groups: ['telemetry'], sharableWith: ['msp'], notSharableWith: ['peripherals'], maxPorts: 1};
|
||||
functionRules.push(ltmFunctionRule);
|
||||
|
||||
const mavlinkFunctionRule = {name: 'TELEMETRY_MAVLINK', groups: ['telemetry'], sharableWith: ['msp'], notSharableWith: ['peripherals'], maxPorts: 1};
|
||||
functionRules.push(mavlinkFunctionRule);
|
||||
|
||||
functionRules.push({ name: 'IRC_TRAMP', groups: ['peripherals'], maxPorts: 1 });
|
||||
|
||||
functionRules.push({ name: 'ESC_SENSOR', groups: ['sensors'], maxPorts: 1 });
|
||||
functionRules.push({ name: 'TBS_SMARTAUDIO', groups: ['peripherals'], maxPorts: 1 });
|
||||
|
||||
functionRules.push({ name: 'TELEMETRY_IBUS', groups: ['telemetry'], maxPorts: 1 });
|
||||
|
||||
functionRules.push({ name: 'RUNCAM_DEVICE_CONTROL', groups: ['peripherals'], maxPorts: 1 });
|
||||
|
||||
functionRules.push({ name: 'LIDAR_TF', groups: ['peripherals'], maxPorts: 1 });
|
||||
|
||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_43)) {
|
||||
functionRules.push({ name: 'FRSKY_OSD', groups: ['peripherals'], maxPorts: 1 });
|
||||
}
|
||||
|
@ -424,6 +415,7 @@ ports.initialize = function (callback) {
|
|||
let enableBlackbox = false;
|
||||
let enableEsc = false;
|
||||
let enableGps = false;
|
||||
let enableVtx = false;
|
||||
|
||||
for (const port of FC.SERIAL_CONFIG.ports) {
|
||||
const func = port.functions;
|
||||
|
@ -447,6 +439,10 @@ ports.initialize = function (callback) {
|
|||
if (func.includes('GPS')) {
|
||||
enableGps = true;
|
||||
}
|
||||
|
||||
if (func.includes('IRC_TRAMP') || func.includes('TBS_SMARTAUDIO')) {
|
||||
enableVtx = true;
|
||||
}
|
||||
}
|
||||
|
||||
const featureConfig = FC.FEATURE_CONFIG.features;
|
||||
|
@ -479,6 +475,12 @@ ports.initialize = function (callback) {
|
|||
featureConfig.disable('GPS');
|
||||
}
|
||||
|
||||
if (enableVtx) {
|
||||
featureConfig.enable('VTX');
|
||||
} else {
|
||||
featureConfig.disable('VTX');
|
||||
}
|
||||
|
||||
mspHelper.sendSerialConfig(save_features);
|
||||
|
||||
function save_features() {
|
||||
|
|
|
@ -1,53 +1,22 @@
|
|||
import semver from "semver";
|
||||
import { API_VERSION_1_42 } from "../data_storage";
|
||||
import { API_VERSION_1_42, API_VERSION_1_45 } from "../data_storage";
|
||||
import FC from "../fc";
|
||||
import { isExpertModeEnabled } from "./isExportModeEnabled";
|
||||
|
||||
export function updateTabList(features) {
|
||||
const isExpertModeEnabled = $('input[name="expertModeCheckbox"]').is(':checked');
|
||||
|
||||
if (isExpertModeEnabled()) {
|
||||
$('#tabs ul.mode-connected li.tab_failsafe').show();
|
||||
$('#tabs ul.mode-connected li.tab_adjustments').show();
|
||||
$('#tabs ul.mode-connected li.tab_servos').show();
|
||||
$('#tabs ul.mode-connected li.tab_sensors').show();
|
||||
$('#tabs ul.mode-connected li.tab_logging').show();
|
||||
} else {
|
||||
$('#tabs ul.mode-connected li.tab_failsafe').hide();
|
||||
$('#tabs ul.mode-connected li.tab_adjustments').hide();
|
||||
$('#tabs ul.mode-connected li.tab_servos').hide();
|
||||
$('#tabs ul.mode-connected li.tab_sensors').hide();
|
||||
$('#tabs ul.mode-connected li.tab_logging').hide();
|
||||
}
|
||||
$('#tabs ul.mode-connected li.tab_failsafe').toggle(isExpertModeEnabled);
|
||||
$('#tabs ul.mode-connected li.tab_adjustments').toggle(isExpertModeEnabled);
|
||||
$('#tabs ul.mode-connected li.tab_servos').toggle(isExpertModeEnabled);
|
||||
$('#tabs ul.mode-connected li.tab_sensors').toggle(isExpertModeEnabled);
|
||||
$('#tabs ul.mode-connected li.tab_logging').toggle(isExpertModeEnabled);
|
||||
|
||||
if (features.isEnabled('GPS') && isExpertModeEnabled()) {
|
||||
$('#tabs ul.mode-connected li.tab_gps').show();
|
||||
} else {
|
||||
$('#tabs ul.mode-connected li.tab_gps').hide();
|
||||
}
|
||||
|
||||
if (features.isEnabled('LED_STRIP')) {
|
||||
$('#tabs ul.mode-connected li.tab_led_strip').show();
|
||||
} else {
|
||||
$('#tabs ul.mode-connected li.tab_led_strip').hide();
|
||||
}
|
||||
|
||||
if (features.isEnabled('TRANSPONDER')) {
|
||||
$('#tabs ul.mode-connected li.tab_transponder').show();
|
||||
} else {
|
||||
$('#tabs ul.mode-connected li.tab_transponder').hide();
|
||||
}
|
||||
|
||||
if (features.isEnabled('OSD')) {
|
||||
$('#tabs ul.mode-connected li.tab_osd').show();
|
||||
} else {
|
||||
$('#tabs ul.mode-connected li.tab_osd').hide();
|
||||
}
|
||||
|
||||
$('#tabs ul.mode-connected li.tab_power').show();
|
||||
|
||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_42)) {
|
||||
$('#tabs ul.mode-connected li.tab_vtx').show();
|
||||
} else {
|
||||
$('#tabs ul.mode-connected li.tab_vtx').hide();
|
||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_45 || FC.CONFIG.buildKey.length !== 32)) {
|
||||
$('#tabs ul.mode-connected li.tab_gps').toggle(features.isEnabled('GPS'));
|
||||
$('#tabs ul.mode-connected li.tab_led_strip').toggle(features.isEnabled('LED_STRIP'));
|
||||
$('#tabs ul.mode-connected li.tab_servos').toggle(features.isEnabled('CHANNEL_FORWARDING') || features.isEnabled('SERVO_TILT'));
|
||||
$('#tabs ul.mode-connected li.tab_transponder').toggle(features.isEnabled('TRANSPONDER'));
|
||||
$('#tabs ul.mode-connected li.tab_osd').toggle(features.isEnabled('OSD'));
|
||||
$('#tabs ul.mode-connected li.tab_vtx').toggle(features.isEnabled('VTX') && semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_42));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
<th i18n="configurationFeatureName"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="features gps other" id="noline">
|
||||
<tbody class="features other" id="noline">
|
||||
<!-- table generated here -->
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
Loading…
Reference in New Issue