kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
Reset state on failure
rodzic
7535862a40
commit
c63fdec916
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
Ładowanie…
Reference in New Issue