Skip to content

Commit c0bf995

Browse files
committed
Reworked board selection dialog ordering
1 parent 374afe0 commit c0bf995

File tree

2 files changed

+76
-68
lines changed

2 files changed

+76
-68
lines changed

Diff for: arduino-ide-extension/src/browser/boards/boards-config.tsx

+65-5
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ import {
1010
BoardWithPackage,
1111
} from '../../common/protocol/boards-service';
1212
import { NotificationCenter } from '../notification-center';
13-
import { BoardsServiceProvider } from './boards-service-provider';
13+
import {
14+
AvailableBoard,
15+
BoardsServiceProvider,
16+
} from './boards-service-provider';
1417
import { nls } from '@theia/core/lib/browser/nls';
18+
import { naturalCompare } from '../../common/utils';
1519

1620
export namespace BoardsConfig {
1721
export interface Config {
@@ -184,11 +188,50 @@ export class BoardsConfig extends React.Component<
184188
.filter(notEmpty);
185189
}
186190

191+
protected get availableBoards(): AvailableBoard[] {
192+
return this.props.boardsServiceProvider.availableBoards;
193+
}
194+
187195
protected queryPorts = async (
188196
availablePorts: MaybePromise<Port[]> = this.availablePorts
189197
) => {
190-
const ports = await availablePorts;
191-
return { knownPorts: ports.sort(Port.compare) };
198+
// Available ports must be sorted in this order:
199+
// 1. Serial with recognized boards
200+
// 2. Serial with guessed boards
201+
// 3. Serial with incomplete boards
202+
// 4. Network with recognized boards
203+
// 5. Other protocols with recognized boards
204+
const ports = (await availablePorts).sort((left: Port, right: Port) => {
205+
if (left.protocol === 'serial' && right.protocol !== 'serial') {
206+
return -1;
207+
} else if (left.protocol !== 'serial' && right.protocol === 'serial') {
208+
return 1;
209+
} else if (left.protocol === 'network' && right.protocol !== 'network') {
210+
return -1;
211+
} else if (left.protocol !== 'network' && right.protocol === 'network') {
212+
return 1;
213+
} else if (left.protocol === right.protocol) {
214+
// We show ports, including those that have guessed
215+
// or unrecognized boards, so we must sort those too.
216+
const leftBoard = this.availableBoards.find((board) =>
217+
Port.sameAs(board.port, left)
218+
);
219+
const rightBoard = this.availableBoards.find((board) =>
220+
Port.sameAs(board.port, right)
221+
);
222+
if (leftBoard && !rightBoard) {
223+
return -1;
224+
} else if (!leftBoard && rightBoard) {
225+
return 1;
226+
} else if (leftBoard?.state! < rightBoard?.state!) {
227+
return -1;
228+
} else if (leftBoard?.state! > rightBoard?.state!) {
229+
return 1;
230+
}
231+
}
232+
return naturalCompare(left.address, right.address);
233+
});
234+
return { knownPorts: ports };
192235
};
193236

194237
protected toggleFilterPorts = () => {
@@ -281,8 +324,25 @@ export class BoardsConfig extends React.Component<
281324
}
282325

283326
protected renderPorts(): React.ReactNode {
284-
const filter = this.state.showAllPorts ? () => true : Port.isBoardPort;
285-
const ports = this.state.knownPorts.filter(filter);
327+
let ports = [] as Port[];
328+
debugger;
329+
if (this.state.showAllPorts) {
330+
ports = this.state.knownPorts;
331+
} else {
332+
ports = this.state.knownPorts.filter((port) => {
333+
if (port.protocol === 'serial') {
334+
return true;
335+
}
336+
// All other ports with different protocol are
337+
// only shown if there is a recognized board
338+
// connected
339+
for (const board of this.availableBoards) {
340+
if (board.port?.address === port.address) {
341+
return true;
342+
}
343+
}
344+
});
345+
}
286346
return !ports.length ? (
287347
<div className="loading noselect">No ports discovered</div>
288348
) : (

Diff for: arduino-ide-extension/src/common/protocol/boards-service.ts

+11-63
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { isWindows, isOSX } from '@theia/core/lib/common/os';
21
import { naturalCompare } from './../utils';
32
import { Searchable } from './searchable';
43
import { Installable } from './installable';
@@ -176,25 +175,20 @@ export namespace Port {
176175
}
177176

178177
export function compare(left: Port, right: Port): number {
179-
// Board ports have higher priorities, they come first.
180-
if (isBoardPort(left) && !isBoardPort(right)) {
178+
// Ports must be sorted in this order:
179+
// 1. Serial
180+
// 2. Network
181+
// 3. Other protocols
182+
if (left.protocol === "serial" && right.protocol !== "serial") {
181183
return -1;
182-
}
183-
if (!isBoardPort(left) && isBoardPort(right)) {
184+
} else if (left.protocol !== "serial" && right.protocol === "serial") {
185+
return 1;
186+
} else if (left.protocol === "network" && right.protocol !== "network") {
187+
return -1;
188+
} else if (left.protocol !== "network" && right.protocol === "network") {
184189
return 1;
185190
}
186-
let result = naturalCompare(
187-
left.protocol.toLocaleLowerCase(),
188-
right.protocol.toLocaleLowerCase()
189-
);
190-
if (result !== 0) {
191-
return result;
192-
}
193-
result = naturalCompare(left.address, right.address);
194-
if (result !== 0) {
195-
return result;
196-
}
197-
return naturalCompare(left.label || '', right.label || '');
191+
return naturalCompare(left.address!, right.address!);
198192
}
199193

200194
export function equals(
@@ -211,52 +205,6 @@ export namespace Port {
211205
return left === right;
212206
}
213207

214-
// Based on: https://github.com/arduino/Arduino/blob/93581b03d723e55c60caedb4729ffc6ea808fe78/arduino-core/src/processing/app/SerialPortList.java#L48-L74
215-
export function isBoardPort(port: Port): boolean {
216-
const address = port.address.toLocaleLowerCase();
217-
if (isWindows) {
218-
// `COM1` seems to be the default serial port on Windows.
219-
return address !== 'COM1'.toLocaleLowerCase();
220-
}
221-
// On macOS and Linux, the port should start with `/dev/`.
222-
if (!address.startsWith('/dev/')) {
223-
return false;
224-
}
225-
if (isOSX) {
226-
// Example: `/dev/cu.usbmodem14401`
227-
if (/(tty|cu)\..*/i.test(address.substring('/dev/'.length))) {
228-
return [
229-
'/dev/cu.MALS',
230-
'/dev/cu.SOC',
231-
'/dev/cu.Bluetooth-Incoming-Port',
232-
]
233-
.map((a) => a.toLocaleLowerCase())
234-
.every((a) => a !== address);
235-
}
236-
}
237-
238-
// Example: `/dev/ttyACM0`
239-
if (
240-
/(ttyS|ttyUSB|ttyACM|ttyAMA|rfcomm|ttyO)[0-9]{1,3}/i.test(
241-
address.substring('/dev/'.length)
242-
)
243-
) {
244-
// Default ports were `/dev/ttyS0` -> `/dev/ttyS31` on Ubuntu 16.04.2.
245-
if (address.startsWith('/dev/ttyS')) {
246-
const index = Number.parseInt(
247-
address.substring('/dev/ttyS'.length),
248-
10
249-
);
250-
if (!Number.isNaN(index) && 0 <= index && 31 >= index) {
251-
return false;
252-
}
253-
}
254-
return true;
255-
}
256-
257-
return false;
258-
}
259-
260208
export function sameAs(
261209
left: Port | undefined,
262210
right: Port | string | undefined

0 commit comments

Comments
 (0)