From 6c734b0bed90fd2c5f2fa4ca24a431dc24b7f8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Inka=20Soko=C5=82owska?= Date: Tue, 27 Jun 2023 15:29:11 +0200 Subject: [PATCH] [web] Fix message search results for old query appearing Summary: If the user searched for "first query", and then before the results had the chance to appear, search for "second query", the results for "first query" would still be appended to the results array. This diff fixes that by using an id for each server call, and after the results get fetched, the id of the server call is compared with the most recent id. Test Plan: Checked that flow is not broken in web and native that both use `useSearchMessages`. checked that the above scenario doesn't happen anymore (I used network dev tools to ensure the messages didn't get fetched before the query was changed). Checked that it is still possible to fetch messages, and more messages for the same query. Reviewers: kamil, kuba, michal Reviewed By: michal Subscribers: ashoat, tomek Differential Revision: https://phab.comm.dev/D8327 --- lib/shared/search-utils.js | 8 +++--- native/search/message-search.react.js | 25 +++++++++++++++---- .../message-search-state-provider.react.js | 8 ++++++ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/lib/shared/search-utils.js b/lib/shared/search-utils.js index cc1817c955..3030b2b256 100644 --- a/lib/shared/search-utils.js +++ b/lib/shared/search-utils.js @@ -229,18 +229,20 @@ function useSearchMessages(): ( onResultsReceived: ( messages: $ReadOnlyArray, endReached: boolean, + queryID: number, threadID: string, ) => mixed, + queryID: number, cursor?: string, ) => void { const callSearchMessages = useServerCall(searchMessages); const dispatchActionPromise = useDispatchActionPromise(); return React.useCallback( - (query, threadID, onResultsReceived, cursor) => { + (query, threadID, onResultsReceived, queryID, cursor) => { const searchMessagesPromise = (async () => { if (query === '') { - onResultsReceived([], true, threadID); + onResultsReceived([], true, queryID, threadID); return; } const { messages, endReached } = await callSearchMessages({ @@ -248,7 +250,7 @@ function useSearchMessages(): ( threadID, cursor, }); - onResultsReceived(messages, endReached, threadID); + onResultsReceived(messages, endReached, queryID, threadID); })(); dispatchActionPromise(searchMessagesActionTypes, searchMessagesPromise); diff --git a/native/search/message-search.react.js b/native/search/message-search.react.js index d39ca880c0..68e6bf4cb5 100644 --- a/native/search/message-search.react.js +++ b/native/search/message-search.react.js @@ -47,7 +47,14 @@ function MessageSearch(props: MessageSearchProps): React.Node { const [endReached, setEndReached] = React.useState(false); const appendSearchResults = React.useCallback( - (newMessages: $ReadOnlyArray, end: boolean) => { + ( + newMessages: $ReadOnlyArray, + end: boolean, + queryID: number, + ) => { + if (queryID !== queryIDRef.current) { + return; + } setSearchResults(oldMessages => [...oldMessages, ...newMessages]); setEndReached(end); }, @@ -56,16 +63,24 @@ function MessageSearch(props: MessageSearchProps): React.Node { const searchMessages = useSearchMessages(); + const queryIDRef = React.useRef(0); + React.useEffect(() => { setSearchResults([]); setLastID(undefined); setEndReached(false); }, [query, searchMessages]); - React.useEffect( - () => searchMessages(query, threadInfo.id, appendSearchResults, lastID), - [appendSearchResults, lastID, query, searchMessages, threadInfo.id], - ); + React.useEffect(() => { + queryIDRef.current += 1; + searchMessages( + query, + threadInfo.id, + appendSearchResults, + queryIDRef.current, + lastID, + ); + }, [appendSearchResults, lastID, query, searchMessages, threadInfo.id]); const userInfos = useSelector(state => state.userStore.userInfos); diff --git a/web/search/message-search-state-provider.react.js b/web/search/message-search-state-provider.react.js index 2b48e57b4d..7e29efddc2 100644 --- a/web/search/message-search-state-provider.react.js +++ b/web/search/message-search-state-provider.react.js @@ -114,13 +114,19 @@ function MessageSearchStateProvider(props: Props): React.Node { const searchMessagesCall = useSearchMessages(); const loading = React.useRef(false); + const queryIDRef = React.useRef(0); const appendResults = React.useCallback( ( newMessages: $ReadOnlyArray, end: boolean, + queryID: number, threadID: string, ) => { + if (queryID !== queryIDRef.current) { + return; + } + appendResult(newMessages, threadID); if (end) { setEndReached(threadID); @@ -135,11 +141,13 @@ function MessageSearchStateProvider(props: Props): React.Node { if (loading.current || endsReached.current.has(threadID)) { return; } + queryIDRef.current += 1; loading.current = true; searchMessagesCall( queries.current[threadID], threadID, appendResults, + queryIDRef.current, lastIDs.current[threadID], ); },