@@ -10,8 +10,8 @@ import { SearchInput } from "@pythnetwork/component-library/SearchInput";
10
10
import { SingleToggleGroup } from "@pythnetwork/component-library/SingleToggleGroup" ;
11
11
import { Skeleton } from "@pythnetwork/component-library/Skeleton" ;
12
12
import {
13
- Virtualizer ,
14
13
ListLayout ,
14
+ Virtualizer ,
15
15
} from "@pythnetwork/component-library/Virtualizer" ;
16
16
import type { Button as UnstyledButton } from "@pythnetwork/component-library/unstyled/Button" ;
17
17
import {
@@ -20,16 +20,17 @@ import {
20
20
} from "@pythnetwork/component-library/unstyled/ListBox" ;
21
21
import { useDrawer } from "@pythnetwork/component-library/useDrawer" ;
22
22
import { useLogger } from "@pythnetwork/component-library/useLogger" ;
23
+ import { matchSorter } from "match-sorter" ;
23
24
import type { ReactNode } from "react" ;
24
- import { useMemo , useCallback , useEffect , useState } from "react" ;
25
- import { useIsSSR , useCollator , useFilter } from "react-aria" ;
25
+ import { useCallback , useEffect , useMemo , useState } from "react" ;
26
+ import { useIsSSR } from "react-aria" ;
26
27
27
- import styles from "./search-button.module.scss" ;
28
28
import { Cluster , ClusterToName } from "../../services/pyth" ;
29
29
import { AssetClassBadge } from "../AssetClassBadge" ;
30
30
import { PriceFeedTag } from "../PriceFeedTag" ;
31
31
import { PublisherTag } from "../PublisherTag" ;
32
32
import { Score } from "../Score" ;
33
+ import styles from "./search-button.module.scss" ;
33
34
34
35
const INPUTS = new Set ( [ "input" , "select" , "button" , "textarea" ] ) ;
35
36
@@ -50,6 +51,7 @@ type ResolvedSearchButtonProps = {
50
51
displaySymbol : string ;
51
52
assetClass : string ;
52
53
description : string ;
54
+ priceAccount : string ;
53
55
icon : ReactNode ;
54
56
} [ ] ;
55
57
publishers : ( {
@@ -170,58 +172,38 @@ const SearchDialogContents = ({
170
172
const logger = useLogger ( ) ;
171
173
const [ search , setSearch ] = useState ( "" ) ;
172
174
const [ type , setType ] = useState < ResultType | "" > ( "" ) ;
173
- const collator = useCollator ( ) ;
174
- const filter = useFilter ( { sensitivity : "base" , usage : "search" } ) ;
175
175
const closeDrawer = useCallback ( ( ) => {
176
176
drawer . close ( ) . catch ( ( error : unknown ) => {
177
177
logger . error ( error ) ;
178
178
} ) ;
179
179
} , [ drawer , logger ] ) ;
180
- const results = useMemo (
181
- ( ) =>
182
- [
183
- ...( type === ResultType . Publisher
184
- ? [ ]
185
- : // This is inefficient but Safari doesn't support `Iterator.filter`,
186
- // see https://bugs.webkit.org/show_bug.cgi?id=248650
187
- [ ...feeds . entries ( ) ]
188
- . filter ( ( [ , { displaySymbol } ] ) =>
189
- filter . contains ( displaySymbol , search ) ,
190
- )
191
- . map ( ( [ symbol , feed ] ) => ( {
192
- type : ResultType . PriceFeed as const ,
193
- id : symbol ,
194
- ...feed ,
195
- } ) ) ) ,
196
- ...( type === ResultType . PriceFeed
197
- ? [ ]
198
- : publishers
199
- . filter (
200
- ( publisher ) =>
201
- filter . contains ( publisher . publisherKey , search ) ||
202
- ( publisher . name && filter . contains ( publisher . name , search ) ) ,
203
- )
204
- . map ( ( publisher ) => ( {
205
- type : ResultType . Publisher as const ,
206
- id : [
207
- ClusterToName [ publisher . cluster ] ,
208
- publisher . publisherKey ,
209
- ] . join ( ":" ) ,
210
- ...publisher ,
211
- } ) ) ) ,
212
- ] . sort ( ( a , b ) =>
213
- collator . compare (
214
- a . type === ResultType . PriceFeed
215
- ? a . displaySymbol
216
- : ( a . name ?? a . publisherKey ) ,
217
- b . type === ResultType . PriceFeed
218
- ? b . displaySymbol
219
- : ( b . name ?? b . publisherKey ) ,
220
- ) ,
221
- ) ,
222
- [ feeds , publishers , collator , filter , search , type ] ,
223
- ) ;
224
180
181
+ const results = useMemo ( ( ) => {
182
+ const filteredFeeds = matchSorter ( feeds , search , {
183
+ keys : [ "displaySymbol" , "symbol" , "description" , "priceAccount" ] ,
184
+ } ) . map ( ( { symbol, ...feed } ) => ( {
185
+ type : ResultType . PriceFeed as const ,
186
+ id : symbol ,
187
+ symbol,
188
+ ...feed ,
189
+ } ) ) ;
190
+
191
+ const filteredPublishers = matchSorter ( publishers , search , {
192
+ keys : [ "publisherKey" , "name" ] ,
193
+ } ) . map ( ( publisher ) => ( {
194
+ type : ResultType . Publisher as const ,
195
+ id : [ ClusterToName [ publisher . cluster ] , publisher . publisherKey ] . join ( ":" ) ,
196
+ ...publisher ,
197
+ } ) ) ;
198
+
199
+ if ( type === ResultType . PriceFeed ) {
200
+ return filteredFeeds ;
201
+ }
202
+ if ( type === ResultType . Publisher ) {
203
+ return filteredPublishers ;
204
+ }
205
+ return [ ...filteredFeeds , ...filteredPublishers ] ;
206
+ } , [ feeds , publishers , search , type ] ) ;
225
207
return (
226
208
< div className = { styles . searchDialogContents } >
227
209
< div className = { styles . searchBar } >
0 commit comments