1- import { useCallback , useEffect , useMemo , useRef , useState } from 'react'
1+ import { useCallback , useMemo , useState } from 'react'
22import type { WatchlistItem } from '../types/market'
3- import { research } from '../api/client'
4- import { hitToWatchlistItem , normalizeWatchlistItem , watchlistItemKey } from '../market/instrument'
3+ import { normalizeWatchlistItem , watchlistItemKey } from '../market/instrument'
4+ import {
5+ useInstrumentSearchWithUniversePrep ,
6+ type UniversePrepUi ,
7+ } from '../market/useInstrumentSearchWithUniversePrep'
58
69export interface StockMentionState {
710 open : boolean
@@ -29,33 +32,24 @@ function findMentionTrigger(text: string, cursor: number) {
2932
3033export function useStockMention ( items : WatchlistItem [ ] ) {
3134 const [ state , setState ] = useState < StockMentionState > ( CLOSED )
32- const [ remote , setRemote ] = useState < WatchlistItem [ ] > ( [ ] )
33- const searchGen = useRef ( 0 )
3435
35- useEffect ( ( ) => {
36- if ( ! state . open ) {
37- setRemote ( [ ] )
38- return
39- }
40- const q = state . query . trim ( )
41- if ( q . length < 2 && ! q . includes ( ':' ) ) {
42- setRemote ( [ ] )
43- return
44- }
45- const gen = ++ searchGen . current
46- const timer = window . setTimeout ( ( ) => {
47- void research . searchInstruments ( q , 12 )
48- . then ( resp => {
49- if ( gen !== searchGen . current ) return
50- const hits = resp . data ?. items ?? [ ]
51- setRemote ( hits . map ( hitToWatchlistItem ) )
52- } )
53- . catch ( ( ) => {
54- if ( gen === searchGen . current ) setRemote ( [ ] )
55- } )
56- } , 220 )
57- return ( ) => window . clearTimeout ( timer )
58- } , [ state . open , state . query ] )
36+ const searchEnabled = state . open && (
37+ state . query . trim ( ) . length >= 2 || state . query . includes ( ':' )
38+ )
39+ const searchKeyword = searchEnabled ? state . query . trim ( ) : ''
40+
41+ const {
42+ hits : remote ,
43+ searching : remoteSearching ,
44+ universePrep,
45+ refreshingAfterPrep,
46+ } = useInstrumentSearchWithUniversePrep ( {
47+ keyword : searchKeyword ,
48+ limit : 12 ,
49+ minLength : state . query . includes ( ':' ) ? 1 : 2 ,
50+ debounceMs : 220 ,
51+ enabled : searchEnabled ,
52+ } )
5953
6054 const syncFromInput = useCallback ( ( text : string , cursor : number ) => {
6155 const trigger = findMentionTrigger ( text , cursor )
@@ -75,7 +69,6 @@ export function useStockMention(items: WatchlistItem[]) {
7569
7670 const close = useCallback ( ( ) => {
7771 setState ( CLOSED )
78- setRemote ( [ ] )
7972 } , [ ] )
8073
8174 const matches = useMemo ( ( ) => {
@@ -85,10 +78,8 @@ export function useStockMention(items: WatchlistItem[]) {
8578 if ( ! q ) return true
8679 const normalized = normalizeWatchlistItem ( item )
8780 const code = normalized . code . toLowerCase ( )
88- const label = code
8981 return item . name . toLowerCase ( ) . includes ( q )
9082 || code . includes ( q )
91- || label . includes ( q )
9283 || ( item . industry ?. toLowerCase ( ) . includes ( q ) ?? false )
9384 } )
9485 const merged = new Map < string , WatchlistItem > ( )
@@ -116,7 +107,6 @@ export function useStockMention(items: WatchlistItem[]) {
116107 const nextText = `${ before } ${ after } `
117108 const nextCursor = before . length
118109 setState ( CLOSED )
119- setRemote ( [ ] )
120110 return { nextText, nextCursor }
121111 } , [ state . startIndex ] )
122112
@@ -152,5 +142,8 @@ export function useStockMention(items: WatchlistItem[]) {
152142 clampActiveIndex,
153143 setActiveIndex,
154144 setMentionActiveIndex : setActiveIndex ,
145+ universePrep : universePrep as UniversePrepUi ,
146+ remoteSearching,
147+ refreshingAfterPrep,
155148 }
156149}
0 commit comments