@@ -14,7 +14,6 @@ import type {SearchKey} from '@libs/SearchUIUtils';
1414import CONST from '@src/CONST' ;
1515import ONYXKEYS from '@src/ONYXKEYS' ;
1616import type { ReportActions , SearchResults , Transaction } from '@src/types/onyx' ;
17- import { isEmptyObject } from '@src/types/utils/EmptyObject' ;
1817import useNetwork from './useNetwork' ;
1918import useOnyx from './useOnyx' ;
2019import usePrevious from './usePrevious' ;
@@ -227,40 +226,23 @@ function useSearchHighlightAndScroll({
227226 }
228227
229228 const newKeys = new Set < string > ( ) ;
229+ const consumedManualIDs : string [ ] = [ ] ;
230230 for ( const id of newTransactionIDs ) {
231231 const newTransactionKey = `${ ONYXKEYS . COLLECTION . TRANSACTION } ${ id } ` ;
232232 highlightedIDs . current . add ( newTransactionKey ) ;
233233 newKeys . add ( newTransactionKey ) ;
234+ if ( manualHighlightTransactionIDs . has ( id ) ) {
235+ consumedManualIDs . push ( id ) ;
236+ }
234237 }
235238 setNewSearchResultKeys ( newKeys ) ;
236- }
237- } , [ searchResults ?. data , previousSearchResults , isChat , transactionIDsToHighlight ] ) ;
238239
239- // Reset transactionIDsToHighlight after they have been highlighted
240- useEffect ( ( ) => {
241- if ( isEmptyObject ( transactionIDsToHighlight ) || newSearchResultKeys === null ) {
242- return ;
240+ // Clear consumed manual highlight flags so subsequent detect runs don't re-highlight the same IDs.
241+ if ( consumedManualIDs . length > 0 ) {
242+ mergeTransactionIdsHighlightOnSearchRoute ( queryJSON . type , Object . fromEntries ( consumedManualIDs . map ( ( id ) => [ id , false ] ) ) ) ;
243+ }
243244 }
244-
245- const highlightedTransactionIDs = Object . keys ( transactionIDsToHighlight ) . filter (
246- ( id ) => transactionIDsToHighlight [ id ] && newSearchResultKeys ?. has ( `${ ONYXKEYS . COLLECTION . TRANSACTION } ${ id } ` ) ,
247- ) ;
248-
249- // We need to use requestAnimationFrame here to ensure that setTimeout actually starts
250- // only after the user has navigated to the "Reports > Expenses" page.
251- // Otherwise, there is still a chance we might miss the timing because setTimeout runs too early,
252- // causing the highlight not to appear.
253- let timer : NodeJS . Timeout ;
254- const animation = requestAnimationFrame ( ( ) => {
255- timer = setTimeout ( ( ) => {
256- mergeTransactionIdsHighlightOnSearchRoute ( queryJSON . type , Object . fromEntries ( highlightedTransactionIDs . map ( ( id ) => [ id , false ] ) ) ) ;
257- } , CONST . ANIMATED_HIGHLIGHT_START_DURATION ) ;
258- } ) ;
259- return ( ) => {
260- clearTimeout ( timer ) ;
261- cancelAnimationFrame ( animation ) ;
262- } ;
263- } , [ transactionIDsToHighlight , queryJSON . type , newSearchResultKeys ] ) ;
245+ } , [ searchResults ?. data , previousSearchResults , isChat , transactionIDsToHighlight , queryJSON . type ] ) ;
264246
265247 // Remove transactionIDsToHighlight when the user leaves the current search type
266248 useEffect (
@@ -329,7 +311,9 @@ function useSearchHighlightAndScroll({
329311 triggeredByHookRef . current = false ;
330312 } ;
331313
332- return { newSearchResultKeys, handleSelectionListScroll, newTransactions} ;
314+ const hasQueuedHighlights = newSearchResultKeys !== null && newSearchResultKeys . size > 0 ;
315+
316+ return { newSearchResultKeys, handleSelectionListScroll, newTransactions, hasQueuedHighlights} ;
333317}
334318
335319/**
0 commit comments