Reset state on failure

alex-chats
Justin 2022-08-31 13:20:37 -04:00
rodzic 7535862a40
commit c63fdec916
3 zmienionych plików z 23 dodań i 17 usunięć

Wyświetl plik

@ -14,7 +14,7 @@ import { Avatar, Button, HStack, Icon, IconButton, Input, Stack, Text, Textarea
import UploadProgress from 'soapbox/components/upload-progress'; import UploadProgress from 'soapbox/components/upload-progress';
import UploadButton from 'soapbox/features/compose/components/upload_button'; import UploadButton from 'soapbox/features/compose/components/upload_button';
import { useAppSelector, useAppDispatch, useOwnAccount } from 'soapbox/hooks'; import { useAppSelector, useAppDispatch, useOwnAccount } from 'soapbox/hooks';
import { IChat, useChat } from 'soapbox/queries/chats'; import { IChat, IChatMessage, useChat } from 'soapbox/queries/chats';
import { queryClient } from 'soapbox/queries/client'; import { queryClient } from 'soapbox/queries/client';
import { truncateFilename } from 'soapbox/utils/media'; import { truncateFilename } from 'soapbox/utils/media';
@ -56,22 +56,23 @@ const ChatBox: React.FC<IChatBox> = ({ chat, onSetInputRef, autosize, inputRef }
const isSubmitDisabled = content.length === 0 && !attachment; const isSubmitDisabled = content.length === 0 && !attachment;
const submitMessage = useMutation(({ chatId, content }: any) => { const submitMessage = useMutation(({ chatId, content }: any) => createChatMessage(chatId, content), {
return createChatMessage(chatId, content); retry: false,
}, { onMutate: async(newMessage: any) => {
onMutate: async (newMessage) => {
clearState();
// Cancel any outgoing refetches (so they don't overwrite our optimistic update) // Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await queryClient.cancelQueries(['chats', 'messages', chat.id]); await queryClient.cancelQueries(['chats', 'messages', chat.id]);
// Snapshot the previous value // Snapshot the previous value
const previousChatMessages = queryClient.getQueryData(['chats', 'messages', chat.id]); const prevChatMessages = queryClient.getQueryData(['chats', 'messages', chat.id]);
const prevContent = content;
// Clear state (content, attachment, etc)
clearState();
// Optimistically update to the new value // Optimistically update to the new value
queryClient.setQueryData(['chats', 'messages', chat.id], (prevResult: any) => { queryClient.setQueryData(['chats', 'messages', chat.id], (prevResult: any) => {
const newResult = prevResult; const newResult = { ...prevResult };
newResult.pages = prevResult.pages.map((page: any, idx: number) => { newResult.pages = newResult.pages.map((page: any, idx: number) => {
if (idx === 0) { if (idx === 0) {
return { return {
...page, ...page,
@ -92,14 +93,15 @@ const ChatBox: React.FC<IChatBox> = ({ chat, onSetInputRef, autosize, inputRef }
}); });
// Return a context object with the snapshotted value // Return a context object with the snapshotted value
return { previousChatMessages }; return { prevChatMessages, prevContent };
}, },
// If the mutation fails, use the context returned from onMutate to roll back // If the mutation fails, use the context returned from onMutate to roll back
onError: (err, newTodo, context: any) => { onError: (_error: any, _newData: any, context: any) => {
queryClient.setQueryData(['chats', 'messages', chat.id], context.previousChatMessages); setContent(context.prevContent);
queryClient.setQueryData(['chats', 'messages', chat.id], context.prevChatMessages);
}, },
// Always refetch after error or success: // Always refetch after error or success:
onSettled: () => { onSuccess: () => {
queryClient.invalidateQueries(['chats', 'messages', chat.id]); queryClient.invalidateQueries(['chats', 'messages', chat.id]);
}, },
}); });
@ -120,7 +122,9 @@ const ChatBox: React.FC<IChatBox> = ({ chat, onSetInputRef, autosize, inputRef }
}; };
submitMessage.mutate({ chatId: chat.id, content }); submitMessage.mutate({ chatId: chat.id, content });
acceptChat.mutate(); if (!chat.accepted) {
acceptChat.mutate();
}
} }
}; };

Wyświetl plik

@ -359,9 +359,10 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, autosize }) => {
}, [formattedChatMessages.length]); }, [formattedChatMessages.length]);
useEffect(() => { useEffect(() => {
const lastMessageId = formattedChatMessages.pop()?.id; const lastMessage = formattedChatMessages.pop();
const lastMessageId = lastMessage?.id;
if (lastMessageId) { if (lastMessageId && !lastMessage.pending) {
markChatAsRead(lastMessageId); markChatAsRead(lastMessageId);
} }
}, [formattedChatMessages.length]); }, [formattedChatMessages.length]);

Wyświetl plik

@ -34,6 +34,7 @@ export interface IChatMessage {
created_at: Date created_at: Date
id: string id: string
unread: boolean unread: boolean
pending?: boolean
} }
const reverseOrder = (a: IChat, b: IChat): number => { const reverseOrder = (a: IChat, b: IChat): number => {