Skip to content

Commit dc886dc

Browse files
authored
Gate virtual and manual connect options behind expert mode (betaflight#5049)
* Gate virtual and manual connect options behind expert mode The Virtual and Manual entries in the sidebar connect menu now require expert mode in addition to the existing showVirtualMode / showManualMode toggles, keeping the casual connect flow free of dev-only options. * Close virtual/manual bypass and simplify connect menu - Reset a persisted or auto-selected virtual/manual port to noselection on connect when expert mode is off, so the gate can't be bypassed via a previously stored selection - Skip virtual/manual fallbacks in PortHandler.selectActivePort unless expert mode is enabled - Extract buildDeviceItems and buildPermissionItems helpers from the menuItems computed to bring cognitive complexity back under the SonarCloud limit * Unify connect menu helper signatures buildDeviceItems now calls isExpertModeEnabled itself so both it and buildPermissionItems rely purely on closed-over state — no caller plumbing required.
1 parent 86755d4 commit dc886dc

2 files changed

Lines changed: 27 additions & 15 deletions

File tree

src/components/port-picker/ConnectButton.vue

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import PortHandler from "../../js/port_handler";
6060
import { connectDisconnect, disconnect } from "../../js/serial_backend";
6161
import { i18n } from "../../js/localization";
6262
import { set as setConfig } from "../../js/ConfigStorage";
63+
import { isExpertModeEnabled } from "../../js/utils/isExpertModeEnabled";
6364
import ConnectOptionsDialog from "./ConnectOptionsDialog.vue";
6465
6566
function selectAndConnect(path) {
@@ -124,10 +125,9 @@ export default defineComponent({
124125
dialogOpen.value = true;
125126
}
126127
127-
const menuItems = computed(() => {
128-
const items = [];
128+
function buildDeviceItems() {
129+
const expertMode = isExpertModeEnabled();
129130
const devices = [];
130-
131131
if (PortHandler.showSerialOption) {
132132
for (const d of serialPorts.value) {
133133
devices.push({
@@ -155,26 +155,25 @@ export default defineComponent({
155155
});
156156
}
157157
}
158-
159-
if (PortHandler.showVirtualMode) {
158+
if (expertMode && PortHandler.showVirtualMode) {
160159
devices.push({
161160
label: i18n.getMessage("portsSelectVirtual"),
162161
icon: "i-lucide-flask-conical",
163162
onSelect: () => openConnectDialog("virtual"),
164163
});
165164
}
166-
if (PortHandler.showManualMode) {
165+
if (expertMode && PortHandler.showManualMode) {
167166
devices.push({
168167
label: i18n.getMessage("portsSelectManual"),
169168
icon: "i-lucide-keyboard",
170169
onSelect: () => openConnectDialog("manual"),
171170
});
172171
}
172+
return devices;
173+
}
173174
174-
if (devices.length) {
175-
items.push(...devices, { type: "separator" });
176-
}
177-
175+
function buildPermissionItems() {
176+
const items = [];
178177
if (PortHandler.showSerialOption) {
179178
items.push({
180179
label: i18n.getMessage("portsSelectPermission"),
@@ -196,8 +195,14 @@ export default defineComponent({
196195
onSelect: () => PortHandler.requestDevicePermission("usb"),
197196
});
198197
}
198+
return items;
199+
}
199200
201+
const menuItems = computed(() => {
202+
const devices = buildDeviceItems();
203+
const items = devices.length ? [...devices, { type: "separator" }] : [];
200204
items.push(
205+
...buildPermissionItems(),
201206
{ type: "separator" },
202207
{
203208
type: "checkbox",
@@ -207,7 +212,6 @@ export default defineComponent({
207212
onSelect: (e) => e.preventDefault(),
208213
},
209214
);
210-
211215
return items;
212216
});
213217
@@ -216,6 +220,12 @@ export default defineComponent({
216220
return;
217221
}
218222
223+
// Guard against a persisted virtual/manual selection when expert mode is off.
224+
const gatedModes = ["virtual", "manual"];
225+
if (!isExpertModeEnabled() && gatedModes.includes(selectedPort.value)) {
226+
PortHandler.portPicker.selectedPort = "noselection";
227+
}
228+
219229
if (selectedPort.value === "noselection") {
220230
PortHandler.selectActivePort();
221231
if (PortHandler.portPicker.selectedPort !== "noselection") {

src/js/port_handler.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { EventBus } from "../components/eventBus";
33
import { serial } from "./serial.js";
44
import defaultDfu, { UsbDfuProtocol } from "./protocols/usbdfu";
55
import CapacitorDfuTransport from "./protocols/CapacitorDfuTransport";
6+
import { isExpertModeEnabled } from "./utils/isExpertModeEnabled";
67
import { reactive } from "vue";
78
import {
89
checkCompatibility,
@@ -283,13 +284,14 @@ PortHandler.selectActivePort = function (suggestedDevice = false) {
283284
}
284285
}
285286

286-
// Return the virtual port
287-
if (!selectedPort && this.showVirtualMode) {
287+
// Expert-only fallbacks: only surface virtual/manual when expert mode is on.
288+
const expertMode = isExpertModeEnabled();
289+
290+
if (!selectedPort && expertMode && this.showVirtualMode) {
288291
selectedPort = "virtual";
289292
}
290293

291-
// Return the manual port
292-
if (!selectedPort && this.showManualMode) {
294+
if (!selectedPort && expertMode && this.showManualMode) {
293295
selectedPort = "manual";
294296
}
295297

0 commit comments

Comments
 (0)