From c0bf99557868735881697572355cc56d41985c93 Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Mon, 22 Nov 2021 10:58:46 +0100 Subject: [PATCH] Reworked board selection dialog ordering --- .../src/browser/boards/boards-config.tsx | 70 ++++++++++++++++-- .../src/common/protocol/boards-service.ts | 74 +++---------------- 2 files changed, 76 insertions(+), 68 deletions(-) diff --git a/arduino-ide-extension/src/browser/boards/boards-config.tsx b/arduino-ide-extension/src/browser/boards/boards-config.tsx index 083fa6124..f511ffaa7 100644 --- a/arduino-ide-extension/src/browser/boards/boards-config.tsx +++ b/arduino-ide-extension/src/browser/boards/boards-config.tsx @@ -10,8 +10,12 @@ import { BoardWithPackage, } from '../../common/protocol/boards-service'; import { NotificationCenter } from '../notification-center'; -import { BoardsServiceProvider } from './boards-service-provider'; +import { + AvailableBoard, + BoardsServiceProvider, +} from './boards-service-provider'; import { nls } from '@theia/core/lib/browser/nls'; +import { naturalCompare } from '../../common/utils'; export namespace BoardsConfig { export interface Config { @@ -184,11 +188,50 @@ export class BoardsConfig extends React.Component< .filter(notEmpty); } + protected get availableBoards(): AvailableBoard[] { + return this.props.boardsServiceProvider.availableBoards; + } + protected queryPorts = async ( availablePorts: MaybePromise = this.availablePorts ) => { - const ports = await availablePorts; - return { knownPorts: ports.sort(Port.compare) }; + // Available ports must be sorted in this order: + // 1. Serial with recognized boards + // 2. Serial with guessed boards + // 3. Serial with incomplete boards + // 4. Network with recognized boards + // 5. Other protocols with recognized boards + const ports = (await availablePorts).sort((left: Port, right: Port) => { + if (left.protocol === 'serial' && right.protocol !== 'serial') { + return -1; + } else if (left.protocol !== 'serial' && right.protocol === 'serial') { + return 1; + } else if (left.protocol === 'network' && right.protocol !== 'network') { + return -1; + } else if (left.protocol !== 'network' && right.protocol === 'network') { + return 1; + } else if (left.protocol === right.protocol) { + // We show ports, including those that have guessed + // or unrecognized boards, so we must sort those too. + const leftBoard = this.availableBoards.find((board) => + Port.sameAs(board.port, left) + ); + const rightBoard = this.availableBoards.find((board) => + Port.sameAs(board.port, right) + ); + if (leftBoard && !rightBoard) { + return -1; + } else if (!leftBoard && rightBoard) { + return 1; + } else if (leftBoard?.state! < rightBoard?.state!) { + return -1; + } else if (leftBoard?.state! > rightBoard?.state!) { + return 1; + } + } + return naturalCompare(left.address, right.address); + }); + return { knownPorts: ports }; }; protected toggleFilterPorts = () => { @@ -281,8 +324,25 @@ export class BoardsConfig extends React.Component< } protected renderPorts(): React.ReactNode { - const filter = this.state.showAllPorts ? () => true : Port.isBoardPort; - const ports = this.state.knownPorts.filter(filter); + let ports = [] as Port[]; + debugger; + if (this.state.showAllPorts) { + ports = this.state.knownPorts; + } else { + ports = this.state.knownPorts.filter((port) => { + if (port.protocol === 'serial') { + return true; + } + // All other ports with different protocol are + // only shown if there is a recognized board + // connected + for (const board of this.availableBoards) { + if (board.port?.address === port.address) { + return true; + } + } + }); + } return !ports.length ? (
No ports discovered
) : ( diff --git a/arduino-ide-extension/src/common/protocol/boards-service.ts b/arduino-ide-extension/src/common/protocol/boards-service.ts index 5435dc797..714b00374 100644 --- a/arduino-ide-extension/src/common/protocol/boards-service.ts +++ b/arduino-ide-extension/src/common/protocol/boards-service.ts @@ -1,4 +1,3 @@ -import { isWindows, isOSX } from '@theia/core/lib/common/os'; import { naturalCompare } from './../utils'; import { Searchable } from './searchable'; import { Installable } from './installable'; @@ -176,25 +175,20 @@ export namespace Port { } export function compare(left: Port, right: Port): number { - // Board ports have higher priorities, they come first. - if (isBoardPort(left) && !isBoardPort(right)) { + // Ports must be sorted in this order: + // 1. Serial + // 2. Network + // 3. Other protocols + if (left.protocol === "serial" && right.protocol !== "serial") { return -1; - } - if (!isBoardPort(left) && isBoardPort(right)) { + } else if (left.protocol !== "serial" && right.protocol === "serial") { + return 1; + } else if (left.protocol === "network" && right.protocol !== "network") { + return -1; + } else if (left.protocol !== "network" && right.protocol === "network") { return 1; } - let result = naturalCompare( - left.protocol.toLocaleLowerCase(), - right.protocol.toLocaleLowerCase() - ); - if (result !== 0) { - return result; - } - result = naturalCompare(left.address, right.address); - if (result !== 0) { - return result; - } - return naturalCompare(left.label || '', right.label || ''); + return naturalCompare(left.address!, right.address!); } export function equals( @@ -211,52 +205,6 @@ export namespace Port { return left === right; } - // Based on: https://github.com/arduino/Arduino/blob/93581b03d723e55c60caedb4729ffc6ea808fe78/arduino-core/src/processing/app/SerialPortList.java#L48-L74 - export function isBoardPort(port: Port): boolean { - const address = port.address.toLocaleLowerCase(); - if (isWindows) { - // `COM1` seems to be the default serial port on Windows. - return address !== 'COM1'.toLocaleLowerCase(); - } - // On macOS and Linux, the port should start with `/dev/`. - if (!address.startsWith('/dev/')) { - return false; - } - if (isOSX) { - // Example: `/dev/cu.usbmodem14401` - if (/(tty|cu)\..*/i.test(address.substring('/dev/'.length))) { - return [ - '/dev/cu.MALS', - '/dev/cu.SOC', - '/dev/cu.Bluetooth-Incoming-Port', - ] - .map((a) => a.toLocaleLowerCase()) - .every((a) => a !== address); - } - } - - // Example: `/dev/ttyACM0` - if ( - /(ttyS|ttyUSB|ttyACM|ttyAMA|rfcomm|ttyO)[0-9]{1,3}/i.test( - address.substring('/dev/'.length) - ) - ) { - // Default ports were `/dev/ttyS0` -> `/dev/ttyS31` on Ubuntu 16.04.2. - if (address.startsWith('/dev/ttyS')) { - const index = Number.parseInt( - address.substring('/dev/ttyS'.length), - 10 - ); - if (!Number.isNaN(index) && 0 <= index && 31 >= index) { - return false; - } - } - return true; - } - - return false; - } - export function sameAs( left: Port | undefined, right: Port | string | undefined