Skip to content

Commit cb96f2b

Browse files
Fix search to include description
Fixes #178
1 parent bd99023 commit cb96f2b

File tree

2 files changed

+181
-143
lines changed

2 files changed

+181
-143
lines changed

src/pages/extensions.tsx

Lines changed: 93 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import Layout from "../components/Layout";
44
import getAppProps, { AppProps } from "../components/WithAppProps";
55
import Link from "next/link";
66
import { AwesomeArcadeExtensionsList } from "@/components/AwesomeArcadeList";
7-
import { debounce } from "@/scripts/Utils/Timers";
87
import { AnalyticEvents } from "@/components/Analytics";
98
import { useSession } from "next-auth/react";
109
import Tippy from "@tippyjs/react";
@@ -27,7 +26,9 @@ export function Extensions({
2726
}: ExtensionsProps): React.ReactNode {
2827
const { data: session } = useSession();
2928

30-
const [search, setSearch] = React.useState("");
29+
const [disableSearch, setDisableSearch] = React.useState(false);
30+
const [searchParamsChanged, setSearchParamsChanged] = React.useState(false);
31+
const [searchQuery, setSearchQuery] = React.useState("");
3132
const [showJSOnlyExts, setShowJSOnlyExts] = React.useState(false);
3233
const [filteredList, setFilteredList] = React.useState(list);
3334
const [resultCount, setResultCount] = React.useState<number | undefined>(
@@ -40,84 +41,83 @@ export function Extensions({
4041
React.useEffect(() => {
4142
const q = new URLSearchParams(window.location.search).get(searchParam);
4243
if (q !== null) {
43-
setSearch(q);
44+
setSearchQuery(q);
4445
}
4546
const showJSOnly = new URLSearchParams(window.location.search).get(
4647
showJSOnlyParam,
4748
);
4849
if (showJSOnly !== null) {
4950
setShowJSOnlyExts(stringToBool(showJSOnly));
5051
}
52+
runSearch(q, showJSOnly != null ? stringToBool(showJSOnly) : null);
5153
if (window.location.hash.length > 0) {
5254
smoothScrollToID(window.location.hash.replace("#", ""));
5355
}
56+
// eslint-disable-next-line
5457
}, []);
5558

56-
React.useEffect(() => {
57-
const url = new URL(window.location.toString());
58-
if (search === "") {
59-
url.searchParams.delete(searchParam);
60-
} else {
61-
url.searchParams.set(searchParam, search);
62-
}
63-
if (showJSOnlyExts) {
64-
url.searchParams.set(showJSOnlyParam, "true");
65-
} else {
66-
url.searchParams.delete(showJSOnlyParam);
67-
}
68-
window.history.replaceState({}, "", url.toString());
69-
}, [search, showJSOnlyExts]);
70-
71-
// React.useEffect(() => {
72-
// document.addEventListener("keydown", (e) => {
73-
// if (e.keyCode === 114 || ((e.ctrlKey || e.metaKey) && e.keyCode === 70)) {
74-
// e.preventDefault();
75-
// }
76-
// if ((e.ctrlKey || e.metaKey) && e.code == "KeyF") {
77-
// setTimeout(() => {
78-
// console.log("FOCUS FIND");
79-
// const searchBar = getElement("searchBar") as HTMLInputElement;
80-
// searchBar.focus();
81-
// }, 1000);
82-
// }
83-
// });
84-
// }, []);
85-
86-
React.useEffect(() => {
87-
if (search.length > 0 || showJSOnlyExts) {
88-
const filtered = structuredClone(list);
89-
let extCount = 0;
90-
const group = filtered;
91-
const normalizeString = (s: string): string => {
92-
return s.trim().toLowerCase();
93-
};
94-
const normalizedSearch = normalizeString(search);
95-
for (let i = group.length - 1; i >= 0; i--) {
96-
const ext = group[i];
97-
if (
98-
!(
99-
normalizeString(ext.repo).includes(normalizedSearch) ||
100-
normalizeString(ext.url).includes(normalizedSearch) ||
101-
// normalizeString(ext.description).includes(normalizedSearch) ||
102-
normalizeString(ext.author).includes(normalizedSearch)
103-
) ||
104-
(!showJSOnlyExts && ext.javascriptOnly)
105-
) {
106-
group.splice(i, 1);
59+
const runSearch = (
60+
query: string | null = null,
61+
showJSOnly: boolean | null = null,
62+
) => {
63+
setDisableSearch(true);
64+
setTimeout(() => {
65+
const q = query ?? searchQuery;
66+
const showJS = showJSOnly ?? showJSOnlyExts;
67+
setSearchQuery(q);
68+
setShowJSOnlyExts(showJS);
69+
if (q.length > 0 || showJS) {
70+
const filtered = structuredClone(list);
71+
let extCount = 0;
72+
const group = filtered;
73+
const normalizeString = (s: string): string => {
74+
return s.trim().toLowerCase();
75+
};
76+
const normalizedSearch = normalizeString(q);
77+
for (let i = group.length - 1; i >= 0; i--) {
78+
const ext = group[i];
79+
if (
80+
!(
81+
normalizeString(ext.repo).includes(normalizedSearch) ||
82+
normalizeString(ext.url).includes(normalizedSearch) ||
83+
normalizeString(
84+
JSON.stringify(ext["description"]["children"]),
85+
).includes(normalizedSearch) ||
86+
normalizeString(ext.author).includes(normalizedSearch)
87+
) ||
88+
(!showJS && ext.javascriptOnly)
89+
) {
90+
group.splice(i, 1);
91+
}
10792
}
93+
extCount += group.length;
94+
setFilteredList(filtered);
95+
setResultCount(extCount);
96+
} else {
97+
setFilteredList(
98+
list.filter((ext) => {
99+
return !ext.javascriptOnly;
100+
}),
101+
);
102+
setResultCount(undefined);
108103
}
109-
extCount += group.length;
110-
setFilteredList(filtered);
111-
setResultCount(extCount);
112-
} else {
113-
setFilteredList(
114-
list.filter((ext) => {
115-
return !ext.javascriptOnly;
116-
}),
117-
);
118-
setResultCount(undefined);
119-
}
120-
}, [search, showJSOnlyExts, list]);
104+
const url = new URL(window.location.toString());
105+
if (q === "") {
106+
url.searchParams.delete(searchParam);
107+
} else {
108+
url.searchParams.set(searchParam, q);
109+
}
110+
if (showJS) {
111+
url.searchParams.set(showJSOnlyParam, "true");
112+
} else {
113+
url.searchParams.delete(showJSOnlyParam);
114+
}
115+
window.history.replaceState({}, "", url.toString());
116+
AnalyticEvents.sendSearch(q);
117+
setDisableSearch(false);
118+
setSearchParamsChanged(false);
119+
});
120+
};
121121

122122
return (
123123
<Layout
@@ -164,36 +164,49 @@ export function Extensions({
164164
}
165165
`}
166166
</style>
167-
<Tippy content="Search extensions by author, name, or URL!">
167+
<Tippy content="Search extensions by author, name, description, or URL!">
168168
<input
169169
id="searchBar"
170170
type="search"
171171
className="form-control"
172-
placeholder="Search extensions by author, name, or URL!"
173-
defaultValue={search}
174-
onChange={(event) => {
175-
const v = event.target.value;
176-
setSearch(v);
177-
debounce(
178-
"extensionSearchChange",
179-
() => {
180-
AnalyticEvents.sendSearch(v);
181-
},
182-
1000,
183-
);
172+
placeholder="Search extensions by author, name, description, or URL!"
173+
// disabled={disableSearch}
174+
value={searchQuery}
175+
onChange={(e) => {
176+
setSearchQuery(e.target.value);
177+
setSearchParamsChanged(true);
178+
}}
179+
onKeyDown={(e) => {
180+
if (e.key === "Enter") {
181+
runSearch();
182+
e.currentTarget.focus();
183+
}
184184
}}
185185
aria-label="Search query"
186186
/>
187187
</Tippy>
188188
</div>
189+
<div className="col-auto">
190+
<button
191+
type="button"
192+
className="btn btn-primary"
193+
disabled={disableSearch || !searchParamsChanged}
194+
onClick={() => {
195+
runSearch();
196+
}}
197+
>
198+
Search
199+
</button>
200+
</div>
189201
<div className="col-auto">
190202
<div className="form-check">
191203
<input
192204
className="form-check-input"
193205
type="checkbox"
194-
defaultChecked={showJSOnlyExts}
206+
checked={showJSOnlyExts}
195207
onChange={(e) => {
196208
setShowJSOnlyExts(e.target.checked);
209+
setSearchParamsChanged(true);
197210
}}
198211
id="showJSOnlyExtsCheckInput"
199212
/>

0 commit comments

Comments
 (0)