Skip to content

Commit

Permalink
Reworked board selection dialog ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
silvanocerza committed Nov 22, 2021
1 parent 374afe0 commit e2bbcb1
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 68 deletions.
69 changes: 64 additions & 5 deletions arduino-ide-extension/src/browser/boards/boards-config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<Port[]> = 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 = () => {
Expand Down Expand Up @@ -281,8 +324,24 @@ 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[];
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 ? (
<div className="loading noselect">No ports discovered</div>
) : (
Expand Down
74 changes: 11 additions & 63 deletions arduino-ide-extension/src/common/protocol/boards-service.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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(
Expand All @@ -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
Expand Down

0 comments on commit e2bbcb1

Please sign in to comment.