Skip to content

Commit d91f8e5

Browse files
committed
feat: improve search state title, show matches count
1 parent 899ffad commit d91f8e5

File tree

3 files changed

+72
-20
lines changed

3 files changed

+72
-20
lines changed

src/extension.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ import {
1010
getCommandToRun,
1111
getCompatibilityList,
1212
getEntryTypeLabel,
13+
getMatchesCountLabel,
1314
getPlatformsList,
1415
invertObject,
1516
numberFormatter,
16-
openListWithSearch
17+
openListWithSearch,
18+
pluralize
1719
} from './utils';
1820

1921
export async function activate(context: ExtensionContext) {
@@ -46,14 +48,30 @@ export async function activate(context: ExtensionContext) {
4648
.filter((keyword): keyword is ValidKeyword => keyword in VALID_KEYWORDS_MAP)
4749
.map((keyword) => VALID_KEYWORDS_MAP[keyword] as ValidKeyword);
4850

51+
const { libraries, total } = await fetchData(searchString, validKeywords);
52+
packagesPick.items = libraries;
53+
4954
if (validKeywords.length > 0) {
50-
packagesPick.title = `Active filters: ${validKeywords.join(', ')}`;
55+
if (searchString.trim().length > 0) {
56+
packagesPick.title = `Query: ${searchString} • Filters: ${validKeywords.join(', ')}${getMatchesCountLabel(total)}`;
57+
} else {
58+
packagesPick.title = `Filters: ${validKeywords.join(', ')}${getMatchesCountLabel(total)}`;
59+
}
5160
} else {
52-
packagesPick.title = STRINGS.DEFAULT_TITLE;
61+
if (searchString.trim().length > 0) {
62+
packagesPick.title = `Query: ${searchString}${getMatchesCountLabel(total)}`;
63+
} else {
64+
packagesPick.title = STRINGS.DEFAULT_TITLE;
65+
}
5366
}
54-
packagesPick.items = await fetchData(searchString, validKeywords);
5567
} else {
56-
packagesPick.items = await fetchData(value);
68+
const { libraries, total } = await fetchData(value);
69+
packagesPick.items = libraries;
70+
if (value.trim().length > 0) {
71+
packagesPick.title = `Query: ${value}${getMatchesCountLabel(total)}`;
72+
} else {
73+
packagesPick.title = STRINGS.DEFAULT_TITLE;
74+
}
5775
}
5876

5977
packagesPick.busy = false;
@@ -111,7 +129,7 @@ export async function activate(context: ExtensionContext) {
111129
},
112130
selectedEntry.github.stats.dependencies !== undefined && {
113131
label: ENTRY_OPTION.VIEW_DEPENDENCIES,
114-
description: `$(package) ${numberFormatter.format(selectedEntry.github.stats.dependencies)} ${selectedEntry.github.stats.dependencies === 1 ? 'dependency' : 'dependencies'}`
132+
description: `$(package) ${numberFormatter.format(selectedEntry.github.stats.dependencies)} ${pluralize('dependency', selectedEntry.github.stats.dependencies)}`
115133
},
116134
!selectedEntry.template && { label: ENTRY_OPTION.VIEW_BUNDLEPHOBIA },
117135
selectedEntry.nightlyProgram && { label: ENTRY_OPTION.VIEW_NIGHTLY_RESULTS },

src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ export type PackageData = {
9292
nightlyProgram?: boolean;
9393
};
9494

95+
export type APIResponseData = {
96+
libraries: DirectoryEntry[];
97+
total?: number;
98+
};
99+
95100
export type NpmRegistryData = {
96101
'dist-tags': Record<string, string>;
97102
versions: Record<

src/utils.ts

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { QuickPick, window } from 'vscode';
22

3-
import { DirectoryEntry, PackageData, ValidKeyword } from './types';
3+
import { APIResponseData, DirectoryEntry, PackageData, ValidKeyword } from './types';
44
import { BASE_API_URL, STRINGS } from './constants';
55

66
export const numberFormatter = new Intl.NumberFormat('en-EN', { notation: 'compact' });
@@ -37,7 +37,12 @@ export function getCommandToRun({ dev, npmPkg }: DirectoryEntry, preferredManage
3737
}
3838
}
3939

40-
export async function fetchData(query?: string, keywords?: ValidKeyword[]): Promise<DirectoryEntry[]> {
40+
const EMPTY_RESULT = {
41+
libraries: [],
42+
total: 0
43+
};
44+
45+
export async function fetchData(query?: string, keywords?: ValidKeyword[]): Promise<APIResponseData> {
4146
try {
4247
const apiUrl = new URL(BASE_API_URL);
4348

@@ -53,26 +58,29 @@ export async function fetchData(query?: string, keywords?: ValidKeyword[]): Prom
5358
const response = await fetch(apiUrl.href);
5459

5560
if (response.ok) {
56-
const data = (await response.json()) as object;
61+
const data = (await response.json()) as APIResponseData;
5762

5863
if ('libraries' in data && Array.isArray(data.libraries)) {
59-
return data.libraries.map((item: PackageData) => ({
60-
label: item.npmPkg,
61-
description: item.github.description ?? 'No description',
62-
detail: getDetailLabel(item),
63-
alwaysShow: true,
64-
...item
65-
}));
64+
return {
65+
libraries: data.libraries.map((item: PackageData) => ({
66+
label: item.npmPkg,
67+
description: item.github.description ?? 'No description',
68+
detail: getDetailLabel(item),
69+
alwaysShow: true,
70+
...item
71+
})),
72+
total: data.total ?? 0
73+
};
6674
}
6775
window.showErrorMessage(`Invalid React Native Directory API response content`);
68-
return [];
76+
return EMPTY_RESULT;
6977
}
7078
window.showErrorMessage(`Invalid React Native Directory API response: ${response.status}`);
71-
return [];
79+
return EMPTY_RESULT;
7280
} catch (error) {
7381
console.error(error);
7482
window.showErrorMessage('Failed to fetch data from React Native Directory API');
75-
return [];
83+
return EMPTY_RESULT;
7684
}
7785
}
7886

@@ -122,9 +130,10 @@ export async function openListWithSearch(
122130
}
123131

124132
packagesPick.show();
125-
packagesPick.items = await fetchData(query);
133+
packagesPick.items = (await fetchData(query)).libraries;
126134

127135
packagesPick.placeholder = STRINGS.PACKAGES_PLACEHOLDER;
136+
packagesPick.title = STRINGS.DEFAULT_TITLE;
128137
packagesPick.busy = false;
129138
}
130139

@@ -137,6 +146,26 @@ export function getEntryTypeLabel(entry: DirectoryEntry): string {
137146
return 'library';
138147
}
139148

149+
export function getMatchesCountLabel(count: number = 0): string {
150+
return `${numberFormatter.format(count)} ${pluralize('match', count)}`;
151+
}
152+
140153
export function invertObject(obj: Record<string, string>): Record<string, string> {
141154
return Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]));
142155
}
156+
157+
export function pluralize(word: string, count: number) {
158+
if (count === 1) {
159+
return word;
160+
}
161+
162+
if (/[^aeiou]y$/i.test(word)) {
163+
return word.replace(/y$/i, 'ies');
164+
}
165+
166+
if (/(s|sh|ch|x|z)$/i.test(word)) {
167+
return `${word}es`;
168+
}
169+
170+
return `${word}s`;
171+
}

0 commit comments

Comments
 (0)