Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Commit b9e9b1d

Browse files
Fix bug: Search path for Library Manager is incomplete
1 parent cf1ac62 commit b9e9b1d

File tree

6 files changed

+149
-73
lines changed

6 files changed

+149
-73
lines changed

html/app/components/LibraryItemView.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,13 @@ export default class LibraryItemView extends React.Component<ILibraryProps, ILib
127127
this.state.isUninstalling && (<div className="toolbar-mask theme-bgcolor">Removing</div>)
128128
}
129129
{
130-
lib.version && (
130+
lib.installed && (
131131
<div className="right-side">
132-
<Button className="operation-btn" onClick={() => this.addLibPath(lib.srcPath)}>Add to Include Path</Button>
132+
{
133+
lib.supported && (
134+
<Button className="operation-btn" onClick={() => this.addLibPath(lib.srcPath)}>Add to Include Path</Button>
135+
)
136+
}
133137
{
134138
lib.versions && lib.versions.length && util.versionCompare(lib.versions[0], lib.version) > 0 && (
135139
<Button className="operation-btn" onClick={() => this.installLibrary(lib.name, lib.versions[0])}>Update</Button>

html/app/components/LibraryManager.tsx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*-------------------------------------------------------------------------------------------*/
55

66
import * as React from "react";
7-
import { Button, DropdownButton, MenuItem } from "react-bootstrap";
7+
import { Button, Checkbox, DropdownButton, MenuItem } from "react-bootstrap";
88
import { connect } from "react-redux";
99
import SearchInput, { createFilter } from "react-search-input";
1010
import * as actions from "../actions";
@@ -28,6 +28,7 @@ interface ILibraryManagerState extends React.Props<any> {
2828
searchTerm: string;
2929
type: string;
3030
topic: string;
31+
checked: boolean;
3132
}
3233

3334
const mapStateToProps = (store) => {
@@ -72,10 +73,12 @@ class LibraryManager extends React.Component<ILibraryManagerProps, ILibraryManag
7273
searchTerm: "",
7374
type: "All",
7475
topic: "All",
76+
checked: false,
7577
};
7678
this.typeUpdate = this.typeUpdate.bind(this);
7779
this.topicUpdate = this.topicUpdate.bind(this);
7880
this.searchUpdate = this.searchUpdate.bind(this);
81+
this.handleCheck = this.handleCheck.bind(this);
7982
}
8083

8184
public componentWillMount() {
@@ -103,8 +106,8 @@ class LibraryManager extends React.Component<ILibraryManagerProps, ILibraryManag
103106
switch (topic) {
104107
case "All":
105108
return true;
106-
case "Uncatogorized":
107-
return !element.category;
109+
case "Uncategorized":
110+
return !element.category || element.category === topic;
108111
default:
109112
return element.category === topic;
110113
}
@@ -114,7 +117,8 @@ class LibraryManager extends React.Component<ILibraryManagerProps, ILibraryManag
114117
const filterSearch = createFilter(this.state.searchTerm, SEARCH_KEYS);
115118
let totalCount = 0;
116119
this.props.libraries.forEach((element) => {
117-
if (filterType(element, this.state.type) && filterTopic(element, this.state.topic) && filterSearch(element)) {
120+
const filterSupported = this.state.checked ? element.supported : true;
121+
if (filterSupported && filterType(element, this.state.type) && filterTopic(element, this.state.topic) && filterSearch(element)) {
118122
element.shouldBeDisplayed = true;
119123
totalCount++;
120124
} else {
@@ -154,6 +158,7 @@ class LibraryManager extends React.Component<ILibraryManagerProps, ILibraryManag
154158
})}
155159
</DropdownButton>
156160
<SearchInput className="search-input" placeholder="Filter your search..." onChange={this.searchUpdate} />
161+
<Checkbox className="supported-checkbox" onChange={this.handleCheck}>Only show libraries supported by current board</Checkbox>
157162
</div>
158163
<div className="arduinomanager-container">
159164
{
@@ -187,6 +192,12 @@ class LibraryManager extends React.Component<ILibraryManagerProps, ILibraryManag
187192
searchTerm: term,
188193
});
189194
}
195+
196+
private handleCheck() {
197+
this.setState({
198+
checked: !this.state.checked,
199+
});
200+
}
190201
}
191202

192203
export default connect(mapStateToProps, mapDispatchToProps)(LibraryManager);

html/app/reducers/libraryManagerReducer.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ export function libraryManagerReducer(state = initalState, action) {
3030
return item.category || "Uncategorized";
3131
});
3232
// Sorting versions in descending order.
33-
action.libraries.forEach((element) => {
33+
// for loop is faster than forEach iterator.
34+
for (let element of action.libraries) {
3435
element.versions = element.versions ? element.versions.sort(util.versionCompare).reverse() : element.versions;
35-
});
36+
}
3637
return {
3738
...state,
3839
libraries: action.libraries,

html/app/styles/board.scss

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
}
2020

2121
.arduinomanager-toolbar {
22-
height: 60px;
22+
min-height: 60px;
2323
padding: 15px 10px;
2424
position: fixed;
2525
width: 100%;
@@ -162,6 +162,20 @@ a {
162162
}
163163

164164
.librarymanager {
165+
.arduinomanager-toolbar {
166+
min-height: 80px;
167+
}
168+
169+
.supported-checkbox {
170+
margin-top: -5px;
171+
margin-bottom: 0px;
172+
padding-left: 5px;
173+
}
174+
175+
.arduinomanager-container {
176+
padding-top: 80px;
177+
}
178+
165179
.search-input {
166180
margin-left: 380px;
167181
padding-top: 0px;

src/arduino/boardManager.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -283,12 +283,9 @@ export class BoardManager {
283283
const arduinoPath = this._settings.arduinoPath;
284284
const packageName = "arduino";
285285
const archName = "avr";
286-
let defaultPlatformPath = path.join(arduinoPath, "hardware");
287-
const platform = os.platform();
288-
if (platform === "darwin") {
286+
let defaultPlatformPath = path.join(arduinoPath, "hardware"); // linux and win32.
287+
if (os.platform() === "darwin") {
289288
defaultPlatformPath = path.join(arduinoPath, "Arduino.app/Contents/Java/hardware");
290-
} else if (platform === "linux") {
291-
// TODO Check default platform path at linux.
292289
}
293290
try {
294291
let packageBundled = fs.readFileSync(path.join(defaultPlatformPath, "package_index_bundled.json"), "utf8");
@@ -378,7 +375,6 @@ export class BoardManager {
378375
}
379376

380377
private loadInstalledBoards(): void {
381-
// let boards: Map<string, IBoard> = new Map<string, IBoard>();
382378
this._boards = new Map<string, IBoard>();
383379
this.installedPlatforms.forEach((plat) => {
384380
let dir = plat.rootBoardPath;

src/arduino/libraryManager.ts

Lines changed: 108 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*-------------------------------------------------------------------------------------------*/
55

66
import * as fs from "fs";
7+
import * as os from "os";
78
import * as path from "path";
89

910
import * as util from "../common/util";
@@ -27,24 +28,24 @@ export interface ILibrary {
2728
architectures: string[];
2829
types: string[];
2930
builtIn: boolean;
31+
supported: boolean;
3032
}
3133

3234
export class LibraryManager {
33-
private _libraries: Map<string, ILibrary>;
35+
private _libraryMap: Map<string, ILibrary>;
3436

35-
// Sorted library group by board type, then alphabetically.
36-
private _sortedLibrary: ILibrary[];
37+
private _libraries: ILibrary[];
3738

3839
constructor(private _settings: IArduinoSettings, private _arduinoApp: ArduinoApp) {
3940
}
4041

4142
public get libraries(): ILibrary[] {
42-
return this._sortedLibrary;
43+
return this._libraries;
4344
}
4445

4546
public async loadLibraries() {
46-
this._libraries = new Map<string, ILibrary>();
47-
this._sortedLibrary = [];
47+
this._libraryMap = new Map<string, ILibrary>();
48+
this._libraries = [];
4849

4950
await this._arduinoApp.boardManager.loadPackages();
5051

@@ -55,102 +56,151 @@ export class LibraryManager {
5556
let packageContent = fs.readFileSync(libraryIndexFilePath, "utf8");
5657
this.parseLibraryIndex(JSON.parse(packageContent));
5758

59+
await this.loadIdeLibraries();
5860
await this.loadInstalledLibraries();
59-
await this.sortLibraries();
61+
const builtinLibs = await this.loadBoardLibraries();
62+
this._libraries = Array.from(this._libraryMap.values());
63+
this._libraries = this._libraries.concat(builtinLibs);
64+
this.tagSupportedLibraries();
6065
}
6166

6267
private parseLibraryIndex(rawModel: any) {
6368
rawModel.libraries.forEach((library: ILibrary) => {
6469
// Arduino install-library program will replace the blank space of the library folder name with underscore,
6570
// here format library name consistently for better parsing at the next steps.
6671
const formattedName = library.name.replace(/\s+/g, "_");
67-
let existingLib = this._libraries.get(formattedName);
72+
let existingLib = this._libraryMap.get(formattedName);
6873
if (existingLib) {
6974
existingLib.versions.push(library.version);
7075
} else {
7176
library.versions = [library.version];
7277
library.builtIn = false;
7378
library.version = "";
74-
this._libraries.set(formattedName, library);
79+
this._libraryMap.set(formattedName, library);
7580
}
7681
});
7782
}
7883

79-
private async loadInstalledLibraries() {
80-
let libRoot = this._settings.libPath;
84+
private async loadIdeLibraries() {
85+
const arduinoPath = this._settings.arduinoPath;
86+
let ideLibraryPath = path.join(arduinoPath, "libraries"); // linux and win32
87+
if (os.platform() === "darwin") {
88+
ideLibraryPath = path.join(arduinoPath, "Arduino.app/Contents/Java/libraries");
89+
}
90+
const ideLibraries = util.filterJunk(fs.readdirSync(ideLibraryPath));
91+
for (let libDir of ideLibraries) {
92+
if (util.fileExistsSync(path.join(ideLibraryPath, libDir, "library.properties"))) {
93+
const properties = <any>await util.parseProperties(path.join(ideLibraryPath, libDir, "library.properties"));
94+
const formattedName = properties.name.replace(/\s+/g, "_");
95+
let sourceLib = this._libraryMap.get(formattedName);
96+
if (sourceLib) {
97+
sourceLib.version = util.formatVersion(properties.version);
98+
sourceLib.builtIn = true;
99+
sourceLib.installed = true;
100+
sourceLib.installedPath = path.join(ideLibraryPath, libDir);
101+
sourceLib.srcPath = path.join(ideLibraryPath, libDir, "src");
102+
// If lib src folder doesn't exist, then fallback to the lib root path as source folder.
103+
sourceLib.srcPath = util.directoryExistsSync(sourceLib.srcPath) ? sourceLib.srcPath : path.join(ideLibraryPath, libDir);
104+
}
105+
}
106+
}
107+
}
81108

109+
private async loadInstalledLibraries() {
110+
const libRoot = this._settings.libPath;
82111
if (!util.directoryExistsSync(this._settings.libPath)) {
83112
return;
84113
}
85114

86115
let installedLibDirs = util.filterJunk(fs.readdirSync(libRoot));
87116
for (let libDir of installedLibDirs) {
88-
let sourceLib = this._libraries.get(libDir);
89-
if (sourceLib && util.fileExistsSync(path.join(libRoot, libDir, "library.properties"))) {
117+
if (util.fileExistsSync(path.join(libRoot, libDir, "library.properties"))) {
90118
const properties = <any>await util.parseProperties(path.join(libRoot, libDir, "library.properties"));
91-
sourceLib.version = util.formatVersion(properties.version);
92-
sourceLib.installed = true;
93-
sourceLib.installedPath = path.join(libRoot, libDir);
94-
sourceLib.srcPath = path.join(libRoot, libDir, "src");
95-
// If lib src folder doesn't exist, then fallback to the lib root path as source folder.
96-
sourceLib.srcPath = util.directoryExistsSync(sourceLib.srcPath) ? sourceLib.srcPath : path.join(libRoot, libDir);
119+
const formattedName = properties.name.replace(/\s+/g, "_");
120+
let sourceLib = this._libraryMap.get(formattedName);
121+
if (sourceLib) {
122+
sourceLib.version = util.formatVersion(properties.version);
123+
sourceLib.builtIn = false;
124+
sourceLib.installed = true;
125+
sourceLib.installedPath = path.join(libRoot, libDir);
126+
sourceLib.srcPath = path.join(libRoot, libDir, "src");
127+
// If lib src folder doesn't exist, then fallback to the lib root path as source folder.
128+
sourceLib.srcPath = util.directoryExistsSync(sourceLib.srcPath) ? sourceLib.srcPath : path.join(libRoot, libDir);
129+
}
97130
}
98131
}
99132
}
100133

101-
private async sortLibraries() {
102-
if (!this._arduinoApp.boardManager.currentBoard) {
103-
return;
134+
private async loadBoardLibraries() {
135+
let builtinLibs = [];
136+
const librarySet = new Set(this._libraryMap.keys());
137+
for (let board of this._arduinoApp.boardManager.platforms) {
138+
if (board.installedVersion) {
139+
const libs = await this.parseBoardLibraries(board.rootBoardPath, board.architecture, librarySet);
140+
builtinLibs = builtinLibs.concat(libs);
141+
}
104142
}
105-
this._libraries.forEach((_lib) => {
106-
this._sortedLibrary.push(_lib);
107-
});
108-
109-
// Filter out not supported library according to the selected board type.
110-
let targetArch = this._arduinoApp.boardManager.currentBoard.platform.architecture;
111-
this._sortedLibrary = this._sortedLibrary.filter((_lib) => {
112-
let supportedArch = (<string[]>_lib.architectures).find((arch) => {
113-
return arch.indexOf(targetArch) >= 0 || arch.indexOf("*") >= 0;
114-
});
115-
return supportedArch && supportedArch.length > 0;
116-
});
117-
118-
this._sortedLibrary.sort((a, b) => {
119-
return a.name > b.name ? 1 : -1;
120-
});
121-
await this.addBuiltInLibs();
143+
return builtinLibs;
122144
}
123145

124-
private async addBuiltInLibs() {
125-
let currentBoard = this._arduinoApp.boardManager.currentBoard;
126-
if (!currentBoard) {
127-
return;
128-
}
129-
let rootBoardPath = currentBoard.platform.rootBoardPath;
146+
private async parseBoardLibraries(rootBoardPath, architecture, librarySet: Set<any>) {
130147
let builtInLib = [];
131148
let builtInLibPath = path.join(rootBoardPath, "libraries");
132149
if (util.directoryExistsSync(builtInLibPath)) {
133150
let libDirs = util.filterJunk(fs.readdirSync(builtInLibPath));
134151
if (!libDirs || !libDirs.length) {
135-
return;
152+
return builtInLib;
136153
}
137154
for (let libDir of libDirs) {
138155
if (!util.fileExistsSync(path.join(builtInLibPath, libDir, "library.properties"))) {
139-
continue;
156+
const properties = <ILibrary>{};
157+
properties.name = libDir;
158+
properties.builtIn = true;
159+
properties.installedPath = path.join(builtInLibPath, libDir);
160+
properties.srcPath = path.join(builtInLibPath, libDir, "src");
161+
// If lib src folder doesn't exist, then fallback to lib root path as source folder.
162+
properties.srcPath = util.directoryExistsSync(properties.srcPath) ? properties.srcPath : path.join(builtInLibPath, libDir);
163+
properties.installed = true;
164+
properties.architectures = [architecture];
165+
// For libraries with the same name, append architecture info to name to avoid duplication.
166+
if (librarySet.has(properties.name)) {
167+
properties.name = properties.name + "(" + architecture + ")";
168+
}
169+
librarySet.add(properties.name);
170+
builtInLib.push(properties);
171+
} else {
172+
let properties = <any>await util.parseProperties(path.join(builtInLibPath, libDir, "library.properties"));
173+
properties.version = util.formatVersion(properties.version);
174+
properties.builtIn = true;
175+
properties.installedPath = path.join(builtInLibPath, libDir);
176+
properties.srcPath = path.join(builtInLibPath, libDir, "src");
177+
// If lib src folder doesn't exist, then fallback to lib root path as source folder.
178+
properties.srcPath = util.directoryExistsSync(properties.srcPath) ? properties.srcPath : path.join(builtInLibPath, libDir);
179+
properties.installed = true;
180+
properties.website = properties.url;
181+
properties.architectures = [architecture];
182+
// For libraries with the same name, append architecture info to name to avoid duplication.
183+
if (librarySet.has(properties.name)) {
184+
properties.name = properties.name + "(" + architecture + ")";
185+
}
186+
librarySet.add(properties.name);
187+
builtInLib.push(properties);
140188
}
141-
let properties = <any>await util.parseProperties(path.join(builtInLibPath, libDir, "library.properties"));
142-
properties.version = util.formatVersion(properties.version);
143-
properties.builtIn = true;
144-
properties.installedPath = path.join(builtInLibPath, libDir);
145-
properties.srcPath = path.join(builtInLibPath, libDir, "src");
146-
// If lib src folder doesn't exist, then fallback to lib root path as source folder.
147-
properties.srcPath = util.directoryExistsSync(properties.srcPath) ? properties.srcPath : path.join(builtInLibPath, libDir);
148-
properties.installed = true;
149-
properties.website = properties.url;
150-
builtInLib.push(properties);
151189
}
152190
}
191+
return builtInLib;
192+
}
153193

154-
this._sortedLibrary = builtInLib.concat(this._sortedLibrary);
194+
private tagSupportedLibraries() {
195+
const currentBoard = this._arduinoApp.boardManager.currentBoard;
196+
if (!currentBoard) {
197+
return;
198+
}
199+
let targetArch = currentBoard.platform.architecture;
200+
this._libraries.forEach((library) => {
201+
library.supported = !!(<string[]>library.architectures).find((arch) => {
202+
return arch.indexOf(targetArch) >= 0 || arch.indexOf("*") >= 0;
203+
});
204+
});
155205
}
156206
}

0 commit comments

Comments
 (0)