feat(web): add telegram-like message status indicators
All checks were successful
CI / test (push) Successful in 21s
All checks were successful
CI / test (push) Successful in 21s
- optimistic sending state with pending clock icon - transition statuses sent -> delivered -> read via realtime events - render checkmarks next to outgoing message timestamps
This commit is contained in:
@@ -14,6 +14,8 @@ export function useRealtime() {
|
||||
const accessToken = useAuthStore((s) => s.accessToken);
|
||||
const me = useAuthStore((s) => s.me);
|
||||
const prependMessage = useChatStore((s) => s.prependMessage);
|
||||
const confirmMessageByClientId = useChatStore((s) => s.confirmMessageByClientId);
|
||||
const setMessageDeliveryStatus = useChatStore((s) => s.setMessageDeliveryStatus);
|
||||
const loadChats = useChatStore((s) => s.loadChats);
|
||||
const chats = useChatStore((s) => s.chats);
|
||||
const activeChatId = useChatStore((s) => s.activeChatId);
|
||||
@@ -34,7 +36,12 @@ export function useRealtime() {
|
||||
if (event.event === "receive_message") {
|
||||
const chatId = Number(event.payload.chat_id);
|
||||
const message = event.payload.message as Message;
|
||||
prependMessage(chatId, message);
|
||||
const clientMessageId = event.payload.client_message_id as string | undefined;
|
||||
if (clientMessageId && message.sender_id === me?.id) {
|
||||
confirmMessageByClientId(chatId, clientMessageId, message);
|
||||
} else {
|
||||
prependMessage(chatId, message);
|
||||
}
|
||||
if (message.sender_id !== me?.id) {
|
||||
ws.send(JSON.stringify({ event: "message_delivered", payload: { chat_id: chatId, message_id: message.id } }));
|
||||
if (chatId === activeChatId) {
|
||||
@@ -63,10 +70,26 @@ export function useRealtime() {
|
||||
typingByChat.current[chatId]?.delete(userId);
|
||||
useChatStore.getState().setTypingUsers(chatId, [...(typingByChat.current[chatId] ?? [])]);
|
||||
}
|
||||
if (event.event === "message_delivered") {
|
||||
const chatId = Number(event.payload.chat_id);
|
||||
const messageId = Number(event.payload.message_id);
|
||||
const userId = Number(event.payload.user_id);
|
||||
if (userId !== me?.id) {
|
||||
setMessageDeliveryStatus(chatId, messageId, "delivered");
|
||||
}
|
||||
}
|
||||
if (event.event === "message_read") {
|
||||
const chatId = Number(event.payload.chat_id);
|
||||
const messageId = Number(event.payload.message_id);
|
||||
const userId = Number(event.payload.user_id);
|
||||
if (userId !== me?.id) {
|
||||
setMessageDeliveryStatus(chatId, messageId, "read");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return () => ws.close();
|
||||
}, [wsUrl, prependMessage, loadChats, chats, me?.id, activeChatId]);
|
||||
}, [wsUrl, prependMessage, confirmMessageByClientId, setMessageDeliveryStatus, loadChats, chats, me?.id, activeChatId]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user