Refactor chat functions
This commit is contained in:
parent
b5aca1649d
commit
5816659a09
|
@ -1,11 +1,9 @@
|
||||||
import { InfiniteData } from '@tanstack/react-query';
|
|
||||||
|
|
||||||
import { getSettings } from 'soapbox/actions/settings';
|
import { getSettings } from 'soapbox/actions/settings';
|
||||||
import messages from 'soapbox/locales/messages';
|
import messages from 'soapbox/locales/messages';
|
||||||
import { normalizeChatMessage } from 'soapbox/normalizers';
|
|
||||||
import { ChatKeys, IChat, isLastMessage } from 'soapbox/queries/chats';
|
import { ChatKeys, IChat, isLastMessage } from 'soapbox/queries/chats';
|
||||||
import { queryClient } from 'soapbox/queries/client';
|
import { queryClient } from 'soapbox/queries/client';
|
||||||
import { updatePageItem, appendPageItem, removePageItem, flattenPages, PaginatedResult, sortQueryData } from 'soapbox/utils/queries';
|
import { updateChatListItem } from 'soapbox/utils/chats';
|
||||||
|
import { removePageItem } from 'soapbox/utils/queries';
|
||||||
// import { play, soundCache } from 'soapbox/utils/sounds';
|
// import { play, soundCache } from 'soapbox/utils/sounds';
|
||||||
|
|
||||||
import { connectStream } from '../stream';
|
import { connectStream } from '../stream';
|
||||||
|
@ -30,7 +28,7 @@ import {
|
||||||
} from './timelines';
|
} from './timelines';
|
||||||
|
|
||||||
import type { AppDispatch, RootState } from 'soapbox/store';
|
import type { AppDispatch, RootState } from 'soapbox/store';
|
||||||
import type { APIEntity, Chat, ChatMessage } from 'soapbox/types/entities';
|
import type { APIEntity, Chat } from 'soapbox/types/entities';
|
||||||
|
|
||||||
const STREAMING_CHAT_UPDATE = 'STREAMING_CHAT_UPDATE';
|
const STREAMING_CHAT_UPDATE = 'STREAMING_CHAT_UPDATE';
|
||||||
const STREAMING_FOLLOW_RELATIONSHIPS_UPDATE = 'STREAMING_FOLLOW_RELATIONSHIPS_UPDATE';
|
const STREAMING_FOLLOW_RELATIONSHIPS_UPDATE = 'STREAMING_FOLLOW_RELATIONSHIPS_UPDATE';
|
||||||
|
@ -52,43 +50,6 @@ const updateFollowRelationships = (relationships: APIEntity) =>
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ChatPayload extends Omit<Chat, 'last_message'> {
|
|
||||||
last_message: ChatMessage | null,
|
|
||||||
}
|
|
||||||
|
|
||||||
const dateComparator = (chatA: IChat, chatB: IChat): number => {
|
|
||||||
const chatADate = new Date(chatA.last_message?.created_at as string);
|
|
||||||
const chatBDate = new Date(chatB.last_message?.created_at as string);
|
|
||||||
|
|
||||||
if (chatBDate < chatADate) return -1;
|
|
||||||
if (chatBDate > chatADate) return 1;
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateChat = (payload: ChatPayload) => {
|
|
||||||
const { id: chatId, last_message: lastMessage } = payload;
|
|
||||||
|
|
||||||
const currentChats = flattenPages(
|
|
||||||
queryClient.getQueryData<InfiniteData<PaginatedResult<IChat>>>(ChatKeys.chatSearch()),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (currentChats?.find((chat: any) => chat.id === chatId)) {
|
|
||||||
// If the chat exists in the client, let's update it.
|
|
||||||
updatePageItem<Chat>(ChatKeys.chatSearch(), payload as any, (o, n) => o.id === n.id);
|
|
||||||
// Now that we have the new chat loaded, let's re-sort to put
|
|
||||||
// the most recent on top.
|
|
||||||
sortQueryData<IChat>(ChatKeys.chatSearch(), dateComparator);
|
|
||||||
} else {
|
|
||||||
// If this is a brand-new chat, let's invalid the queries.
|
|
||||||
queryClient.invalidateQueries(ChatKeys.chatSearch());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastMessage) {
|
|
||||||
// Update the Chat Messages query data.
|
|
||||||
appendPageItem(ChatKeys.chatMessages(payload.id), normalizeChatMessage(lastMessage));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeChatMessage = (payload: string) => {
|
const removeChatMessage = (payload: string) => {
|
||||||
const data = JSON.parse(payload);
|
const data = JSON.parse(payload);
|
||||||
const chatId = data.chat_id;
|
const chatId = data.chat_id;
|
||||||
|
@ -178,7 +139,7 @@ const connectTimelineStream = (
|
||||||
|
|
||||||
// Don't update own messages from streaming
|
// Don't update own messages from streaming
|
||||||
if (!messageOwned) {
|
if (!messageOwned) {
|
||||||
updateChat(chat);
|
updateChatListItem(chat);
|
||||||
// Temp disable until we support disabling/enabling.
|
// Temp disable until we support disabling/enabling.
|
||||||
// play(soundCache.chat);
|
// play(soundCache.chat);
|
||||||
}
|
}
|
||||||
|
|
|
@ -434,7 +434,7 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat }) => {
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<div className='flex-grow flex flex-col justify-end'>
|
<div className='flex-grow flex flex-col justify-end pb-4'>
|
||||||
<div className='px-4'>
|
<div className='px-4'>
|
||||||
<PlaceholderChatMessage isMyMessage />
|
<PlaceholderChatMessage isMyMessage />
|
||||||
<PlaceholderChatMessage />
|
<PlaceholderChatMessage />
|
||||||
|
|
|
@ -446,10 +446,6 @@ const UI: React.FC = ({ children }) => {
|
||||||
|
|
||||||
dispatch(fetchAnnouncements());
|
dispatch(fetchAnnouncements());
|
||||||
|
|
||||||
if (features.chats) {
|
|
||||||
// dispatch(fetchChats());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (account.staff) {
|
if (account.staff) {
|
||||||
dispatch(fetchReports({ resolved: false }));
|
dispatch(fetchReports({ resolved: false }));
|
||||||
dispatch(fetchUsers(['local', 'need_approval']));
|
dispatch(fetchUsers(['local', 'need_approval']));
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
import { InfiniteData } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { normalizeChatMessage } from 'soapbox/normalizers';
|
||||||
|
import { ChatKeys } from 'soapbox/queries/chats';
|
||||||
|
import { queryClient } from 'soapbox/queries/client';
|
||||||
|
import { Chat, ChatMessage } from 'soapbox/types/entities';
|
||||||
|
|
||||||
|
import { compareDate } from './comparators';
|
||||||
|
import { appendPageItem, flattenPages, PaginatedResult, sortQueryData, updatePageItem } from './queries';
|
||||||
|
|
||||||
|
interface ChatPayload extends Omit<Chat, 'last_message'> {
|
||||||
|
last_message: ChatMessage | null,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the Chat entity inside the ChatSearch query.
|
||||||
|
* @param newChat - Chat entity.
|
||||||
|
*/
|
||||||
|
const updateChatInChatSearchQuery = (newChat: ChatPayload) => {
|
||||||
|
updatePageItem<ChatPayload>(ChatKeys.chatSearch(), newChat as any, (o, n) => o.id === n.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-order the ChatSearch query by the last message timestamp.
|
||||||
|
*/
|
||||||
|
const reOrderChatListItems = () => {
|
||||||
|
sortQueryData<ChatPayload>(ChatKeys.chatSearch(), (chatA, chatB) => {
|
||||||
|
return compareDate(chatA.last_message?.created_at as string, chatB.last_message?.created_at as string);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a Chat entity exists within the cached ChatSearch query.
|
||||||
|
* @param chatId - String
|
||||||
|
* @returns Boolean
|
||||||
|
*/
|
||||||
|
const checkIfChatExists = (chatId: string) => {
|
||||||
|
const currentChats = flattenPages(
|
||||||
|
queryClient.getQueryData<InfiniteData<PaginatedResult<Chat>>>(ChatKeys.chatSearch()),
|
||||||
|
);
|
||||||
|
|
||||||
|
return currentChats?.find((chat: Chat) => chat.id === chatId);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force a re-fetch of ChatSearch.
|
||||||
|
*/
|
||||||
|
const invalidateChatSearchQuery = () => {
|
||||||
|
queryClient.invalidateQueries(ChatKeys.chatSearch());
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateChatListItem = (newChat: ChatPayload) => {
|
||||||
|
const { id: chatId, last_message: lastMessage } = newChat;
|
||||||
|
|
||||||
|
const isChatAlreadyLoaded = checkIfChatExists(chatId);
|
||||||
|
|
||||||
|
if (isChatAlreadyLoaded) {
|
||||||
|
// If the chat exists in the client, let's update it.
|
||||||
|
updateChatInChatSearchQuery(newChat);
|
||||||
|
// Now that we have the new chat loaded, let's re-sort to put
|
||||||
|
// the most recent on top.
|
||||||
|
reOrderChatListItems();
|
||||||
|
} else {
|
||||||
|
// If this is a brand-new chat, let's invalid the queries.
|
||||||
|
invalidateChatSearchQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastMessage) {
|
||||||
|
// Update the Chat Messages query data.
|
||||||
|
appendPageItem(ChatKeys.chatMessages(newChat.id), normalizeChatMessage(lastMessage));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { updateChatListItem };
|
|
@ -20,4 +20,20 @@ function compareId(id1: string, id2: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { compareId };
|
/**
|
||||||
|
* Compare by dates, where most recent date is returned first.
|
||||||
|
*
|
||||||
|
* @param dateString1 - string that is parsable by Date
|
||||||
|
* @param dateString2 - string that is parsable by Date
|
||||||
|
* @returns 1 | -1 | 0
|
||||||
|
*/
|
||||||
|
function compareDate(dateString1: string, dateString2: string) {
|
||||||
|
const date1 = new Date(dateString1);
|
||||||
|
const date2 = new Date(dateString2);
|
||||||
|
|
||||||
|
if (date2 < date1) return -1;
|
||||||
|
if (date2 > date1) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { compareId, compareDate };
|
Loading…
Reference in New Issue