Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 15 additions & 22 deletions src/hooks/useSearchHighlightAndScroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,18 +237,23 @@ function useSearchHighlightAndScroll({
return;
}

// As we depend on newSearchResultKeys to determine which transactionIDs to reset from transactionIDsToHighlight,
// we need to ensure that newSearchResultKeys is not cleared before we reset transactionIDsToHighlight
const highlightedTransactionIDs = Object.keys(transactionIDsToHighlight).filter(
(id) => transactionIDsToHighlight[id] && newSearchResultKeys?.has(`${ONYXKEYS.COLLECTION.TRANSACTION}${id}`),
);

const timer = setTimeout(() => {
mergeTransactionIdsHighlightOnSearchRoute(queryJSON.type, Object.fromEntries(highlightedTransactionIDs.map((id) => [id, false])));
}, CONST.ANIMATED_HIGHLIGHT_START_DURATION);

// We need to use requestAnimationFrame here to ensure that setTimeout actually starts
// only after the user has navigated to the "Reports > Expenses" page.
// Otherwise, there is still a chance we might miss the timing because setTimeout runs too early,
// causing the highlight not to appear.
let timer: NodeJS.Timeout;
const animation = requestAnimationFrame(() => {
timer = setTimeout(() => {
mergeTransactionIdsHighlightOnSearchRoute(queryJSON.type, Object.fromEntries(highlightedTransactionIDs.map((id) => [id, false])));
}, CONST.ANIMATED_HIGHLIGHT_START_DURATION);
Comment on lines +249 to +252
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Start highlight-reset timer before clearing result keys

By starting mergeTransactionIdsHighlightOnSearchRoute(...false) inside requestAnimationFrame, this timeout is scheduled about one frame later than the setNewSearchResultKeys(null) timeout (which now starts immediately with the same delay). In the common case, newSearchResultKeys becomes null first, this effect re-runs because it depends on newSearchResultKeys, and the cleanup clears the pending timeout before it executes, so transactionIDsToHighlight is never reset and the same expense gets highlighted again on later opens.

Useful? React with 👍 / 👎.

});
return () => {
clearTimeout(timer);
cancelAnimationFrame(animation);
};
}, [transactionIDsToHighlight, queryJSON.type, newSearchResultKeys]);

Expand All @@ -266,23 +271,11 @@ function useSearchHighlightAndScroll({
return;
}

// We need to use requestAnimationFrame here to ensure that setTimeout actually starts
// only after "Reports > Expenses" pages finishes the current rendering cycle and the user sees the highlight,
// which is when we want to start the timer to remove the highlight.
// Otherwise, there is still a chance we might miss the timing because setTimeout runs too early,
// causing the highlight not to appear.

let timer: NodeJS.Timeout;
const animation = requestAnimationFrame(() => {
timer = setTimeout(() => {
setNewSearchResultKeys(null);
}, CONST.ANIMATED_HIGHLIGHT_START_DURATION);
});
const timer = setTimeout(() => {
setNewSearchResultKeys(null);
}, CONST.ANIMATED_HIGHLIGHT_START_DURATION);

return () => {
clearTimeout(timer);
cancelAnimationFrame(animation);
};
return () => clearTimeout(timer);
}, [newSearchResultKeys]);

/**
Expand Down
Loading