From 8aa171fede60a5f97462529918b2115fdcebb9bd Mon Sep 17 00:00:00 2001 From: Chewbacca Date: Tue, 13 Dec 2022 13:35:05 -0500 Subject: [PATCH 1/4] Re-order chat-list after sending messaging --- app/soapbox/queries/chats.ts | 2 ++ app/soapbox/utils/chats.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/soapbox/queries/chats.ts b/app/soapbox/queries/chats.ts index 9a119f5f1..4c377abb7 100644 --- a/app/soapbox/queries/chats.ts +++ b/app/soapbox/queries/chats.ts @@ -8,6 +8,7 @@ import { ChatWidgetScreens, useChatContext } from 'soapbox/contexts/chat-context import { useStatContext } from 'soapbox/contexts/stat-context'; import { useApi, useAppDispatch, useAppSelector, useFeatures, useOwnAccount } from 'soapbox/hooks'; import { normalizeChatMessage } from 'soapbox/normalizers'; +import { reOrderChatListItems } from 'soapbox/utils/chats'; import { flattenPages, PaginatedResult, updatePageItem } from 'soapbox/utils/queries'; import { queryClient } from './client'; @@ -280,6 +281,7 @@ const useChatActions = (chatId: string) => { onSuccess: (response, variables) => { const nextChat = { ...chat, last_message: response.data }; updatePageItem(ChatKeys.chatSearch(), nextChat, (o, n) => o.id === n.id); + reOrderChatListItems(); queryClient.invalidateQueries(ChatKeys.chatMessages(variables.chatId)); }, diff --git a/app/soapbox/utils/chats.ts b/app/soapbox/utils/chats.ts index 53676c898..e740e6b8e 100644 --- a/app/soapbox/utils/chats.ts +++ b/app/soapbox/utils/chats.ts @@ -81,4 +81,4 @@ const getUnreadChatsCount = (): number => { return sumBy(chats, chat => chat.unread); }; -export { updateChatListItem, getUnreadChatsCount }; \ No newline at end of file +export { updateChatListItem, getUnreadChatsCount, reOrderChatListItems }; \ No newline at end of file From b3a0f785d829c851b12266077ba0108f66645073 Mon Sep 17 00:00:00 2001 From: Chewbacca Date: Tue, 13 Dec 2022 14:42:18 -0500 Subject: [PATCH 2/4] Fix sorting of Chat List --- app/soapbox/utils/chats.ts | 7 +++++-- app/soapbox/utils/queries.ts | 23 +++++++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/app/soapbox/utils/chats.ts b/app/soapbox/utils/chats.ts index e740e6b8e..b7f0eb4ec 100644 --- a/app/soapbox/utils/chats.ts +++ b/app/soapbox/utils/chats.ts @@ -26,8 +26,11 @@ const updateChatInChatSearchQuery = (newChat: ChatPayload) => { */ const reOrderChatListItems = () => { sortQueryData(ChatKeys.chatSearch(), (chatA, chatB) => { - return compareDate(chatA.last_message?.created_at as string, chatB.last_message?.created_at as string); - }); + return compareDate( + chatA.last_message?.created_at as string, + chatB.last_message?.created_at as string, + ); + }, 'default'); }; /** diff --git a/app/soapbox/utils/queries.ts b/app/soapbox/utils/queries.ts index 263d2407b..e9d44210c 100644 --- a/app/soapbox/utils/queries.ts +++ b/app/soapbox/utils/queries.ts @@ -25,10 +25,21 @@ const deduplicateById = (entities: T[]): T[] => { return Array.from(map.values()); }; +export type SortOrder = 'reverse' | 'default' + /** Flatten paginated results into a single array. */ -const flattenPages = (queryData: InfiniteData> | undefined) => { +const flattenPages = ( + queryData: InfiniteData> | undefined, + order: SortOrder = 'reverse', +) => { const data = queryData?.pages.reduce( - (prev: T[], curr) => [...prev, ...curr.result], + (prev: T[], curr) => { + if (order === 'reverse') { + return [...curr.result, ...prev]; + } else { + return [...prev, ...curr.result]; + } + }, [], ); @@ -90,11 +101,15 @@ const paginateQueryData = (array: T[] | undefined) => { }, []); }; -const sortQueryData = (queryKey: QueryKey, comparator: (a: T, b: T) => number) => { +const sortQueryData = ( + queryKey: QueryKey, + comparator: (a: T, b: T) => number, + order: SortOrder = 'reverse', +) => { queryClient.setQueryData>>(queryKey, (prevResult) => { if (prevResult) { const nextResult = { ...prevResult }; - const flattenedQueryData = flattenPages(nextResult); + const flattenedQueryData = flattenPages(nextResult, order); const sortedQueryData = flattenedQueryData?.sort(comparator); const paginatedPages = paginateQueryData(sortedQueryData); const newPages = paginatedPages.map((page: T, idx: number) => ({ From 5de1c3a61d7909fd7bd4f3bb2de8df4a5750d56d Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 13 Dec 2022 15:17:58 -0600 Subject: [PATCH 3/4] Revert flattenPages order changes --- app/soapbox/utils/chats.ts | 2 +- app/soapbox/utils/queries.ts | 23 ++++------------------- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/app/soapbox/utils/chats.ts b/app/soapbox/utils/chats.ts index b7f0eb4ec..71a416562 100644 --- a/app/soapbox/utils/chats.ts +++ b/app/soapbox/utils/chats.ts @@ -30,7 +30,7 @@ const reOrderChatListItems = () => { chatA.last_message?.created_at as string, chatB.last_message?.created_at as string, ); - }, 'default'); + }); }; /** diff --git a/app/soapbox/utils/queries.ts b/app/soapbox/utils/queries.ts index e9d44210c..263d2407b 100644 --- a/app/soapbox/utils/queries.ts +++ b/app/soapbox/utils/queries.ts @@ -25,21 +25,10 @@ const deduplicateById = (entities: T[]): T[] => { return Array.from(map.values()); }; -export type SortOrder = 'reverse' | 'default' - /** Flatten paginated results into a single array. */ -const flattenPages = ( - queryData: InfiniteData> | undefined, - order: SortOrder = 'reverse', -) => { +const flattenPages = (queryData: InfiniteData> | undefined) => { const data = queryData?.pages.reduce( - (prev: T[], curr) => { - if (order === 'reverse') { - return [...curr.result, ...prev]; - } else { - return [...prev, ...curr.result]; - } - }, + (prev: T[], curr) => [...prev, ...curr.result], [], ); @@ -101,15 +90,11 @@ const paginateQueryData = (array: T[] | undefined) => { }, []); }; -const sortQueryData = ( - queryKey: QueryKey, - comparator: (a: T, b: T) => number, - order: SortOrder = 'reverse', -) => { +const sortQueryData = (queryKey: QueryKey, comparator: (a: T, b: T) => number) => { queryClient.setQueryData>>(queryKey, (prevResult) => { if (prevResult) { const nextResult = { ...prevResult }; - const flattenedQueryData = flattenPages(nextResult, order); + const flattenedQueryData = flattenPages(nextResult); const sortedQueryData = flattenedQueryData?.sort(comparator); const paginatedPages = paginateQueryData(sortedQueryData); const newPages = paginatedPages.map((page: T, idx: number) => ({ From 4204b48a40fa98aa61f2245761caedbc4955df86 Mon Sep 17 00:00:00 2001 From: Chewbacca Date: Wed, 14 Dec 2022 08:42:14 -0500 Subject: [PATCH 4/4] Remove mocks --- app/soapbox/queries/__tests__/chats.test.ts | 2 - app/soapbox/utils/__mocks__/queries.ts | 55 --------------------- 2 files changed, 57 deletions(-) delete mode 100644 app/soapbox/utils/__mocks__/queries.ts diff --git a/app/soapbox/queries/__tests__/chats.test.ts b/app/soapbox/queries/__tests__/chats.test.ts index 7640fd511..3d72b9c0f 100644 --- a/app/soapbox/queries/__tests__/chats.test.ts +++ b/app/soapbox/queries/__tests__/chats.test.ts @@ -11,8 +11,6 @@ import { flattenPages } from 'soapbox/utils/queries'; import { IAccount } from '../accounts'; import { ChatKeys, IChat, IChatMessage, isLastMessage, useChat, useChatActions, useChatMessages, useChats } from '../chats'; -jest.mock('soapbox/utils/queries'); - const chat: IChat = { accepted: true, account: { diff --git a/app/soapbox/utils/__mocks__/queries.ts b/app/soapbox/utils/__mocks__/queries.ts deleted file mode 100644 index efc7447a3..000000000 --- a/app/soapbox/utils/__mocks__/queries.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { InfiniteData, QueryKey, UseInfiniteQueryResult } from '@tanstack/react-query'; - -import { queryClient } from 'soapbox/jest/test-helpers'; - -import { PaginatedResult } from '../queries'; - -const flattenPages = (queryData: UseInfiniteQueryResult>['data']) => { - return queryData?.pages.reduce( - (prev: T[], curr) => [...curr.result, ...prev], - [], - ); -}; - -const updatePageItem = (queryKey: QueryKey, newItem: T, isItem: (item: T, newItem: T) => boolean) => { - queryClient.setQueriesData>>(queryKey, (data) => { - if (data) { - const pages = data.pages.map(page => { - const result = page.result.map(item => isItem(item, newItem) ? newItem : item); - return { ...page, result }; - }); - return { ...data, pages }; - } - }); -}; - -/** Insert the new item at the beginning of the first page. */ -const appendPageItem = (queryKey: QueryKey, newItem: T) => { - queryClient.setQueryData>>(queryKey, (data) => { - if (data) { - const pages = [...data.pages]; - pages[0] = { ...pages[0], result: [...pages[0].result, newItem] }; - return { ...data, pages }; - } - }); -}; - -/** Remove an item inside if found. */ -const removePageItem = (queryKey: QueryKey, itemToRemove: T, isItem: (item: T, newItem: T) => boolean) => { - queryClient.setQueriesData>>(queryKey, (data) => { - if (data) { - const pages = data.pages.map(page => { - const result = page.result.filter(item => !isItem(item, itemToRemove)); - return { ...page, result }; - }); - return { ...data, pages }; - } - }); -}; - -export { - flattenPages, - updatePageItem, - appendPageItem, - removePageItem, -}; \ No newline at end of file