mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-10-26 03:28:32 +00:00
Rework listing of discovered ports (#614)
* Removed Protocol type * Reworked function that groups ports by protocol * Remove useless protocol check in Port sameAs function * Reworked port selection menu ordering Now ports are shown in this order: 1. Serial with recognized boards 2. Serial with unrecognized boards 3. Network with recognized boards 4. Network with unrecognized boards 5. Other protocols with recognized boards 6. Other protocols with unrecognized boards * Fix ports shown multiple times in menu * Reworked board selection dropdown ordering Ordering is now: 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 * Localize some strings * Fix bug selecting board in boards selector dropdown * Reworked board selection dialog ordering * Fix Tools > Port menu not refreshing * Move Select other board button to bottom of Board selector dropdown and change its style * Updated arduino-cli to 0.20.0 and generated protocol files
This commit is contained in:
@@ -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';
|
||||
@@ -6,26 +5,18 @@ import { ArduinoComponent } from './arduino-component';
|
||||
|
||||
export type AvailablePorts = Record<string, [Port, Array<Board>]>;
|
||||
export namespace AvailablePorts {
|
||||
export function groupByProtocol(availablePorts: AvailablePorts): {
|
||||
serial: AvailablePorts;
|
||||
network: AvailablePorts;
|
||||
unknown: AvailablePorts;
|
||||
} {
|
||||
const serial: AvailablePorts = {};
|
||||
const network: AvailablePorts = {};
|
||||
const unknown: AvailablePorts = {};
|
||||
for (const key of Object.keys(availablePorts)) {
|
||||
const [port, boards] = availablePorts[key];
|
||||
const { protocol } = port;
|
||||
if (protocol === 'serial') {
|
||||
serial[key] = [port, boards];
|
||||
} else if (protocol === 'network') {
|
||||
network[key] = [port, boards];
|
||||
} else {
|
||||
unknown[key] = [port, boards];
|
||||
export function byProtocol(availablePorts: AvailablePorts): Map<string, AvailablePorts> {
|
||||
const grouped = new Map<string, AvailablePorts>();
|
||||
for (const address of Object.keys(availablePorts)) {
|
||||
const [port, boards] = availablePorts[address];
|
||||
let ports = grouped.get(port.protocol);
|
||||
if (!ports) {
|
||||
ports = {} as AvailablePorts;
|
||||
}
|
||||
ports[address] = [port, boards];
|
||||
grouped.set(port.protocol, ports);
|
||||
}
|
||||
return { serial, network, unknown };
|
||||
return grouped;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +125,7 @@ export const BoardsServicePath = '/services/boards-service';
|
||||
export const BoardsService = Symbol('BoardsService');
|
||||
export interface BoardsService
|
||||
extends Installable<BoardsPackage>,
|
||||
Searchable<BoardsPackage> {
|
||||
Searchable<BoardsPackage> {
|
||||
/**
|
||||
* Deprecated. `getState` should be used to correctly map a board with a port.
|
||||
* @deprecated
|
||||
@@ -156,26 +147,13 @@ export interface BoardsService
|
||||
|
||||
export interface Port {
|
||||
readonly address: string;
|
||||
readonly protocol: Port.Protocol;
|
||||
readonly protocol: string;
|
||||
/**
|
||||
* Optional label for the protocol. For example: `Serial Port (USB)`.
|
||||
*/
|
||||
readonly label?: string;
|
||||
}
|
||||
export namespace Port {
|
||||
export type Protocol = 'serial' | 'network' | 'unknown';
|
||||
export namespace Protocol {
|
||||
export function toProtocol(protocol: string | undefined): Protocol {
|
||||
if (protocol === 'serial') {
|
||||
return 'serial';
|
||||
} else if (protocol === 'network') {
|
||||
return 'network';
|
||||
} else {
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function is(arg: any): arg is Port {
|
||||
return (
|
||||
!!arg &&
|
||||
@@ -197,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(
|
||||
@@ -232,78 +205,14 @@ 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
|
||||
) {
|
||||
if (left && right) {
|
||||
if (left.protocol !== 'serial') {
|
||||
console.log(
|
||||
`Unexpected protocol for 'left' port: ${JSON.stringify(
|
||||
left
|
||||
)}. Ignoring 'protocol', comparing 'addresses' with ${JSON.stringify(
|
||||
right
|
||||
)}.`
|
||||
);
|
||||
}
|
||||
if (typeof right === 'string') {
|
||||
return left.address === right;
|
||||
}
|
||||
if (right.protocol !== 'serial') {
|
||||
console.log(
|
||||
`Unexpected protocol for 'right' port: ${JSON.stringify(
|
||||
right
|
||||
)}. Ignoring 'protocol', comparing 'addresses' with ${JSON.stringify(
|
||||
left
|
||||
)}.`
|
||||
);
|
||||
}
|
||||
return left.address === right.address;
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user