feat(realtime): sync message edits and deletes instantly

This commit is contained in:
2026-03-08 13:17:09 +03:00
parent eda84d4d82
commit 13b5f5b855
5 changed files with 70 additions and 1 deletions

View File

@@ -112,6 +112,24 @@ export function useRealtime() {
scheduleReloadChats();
}
}
if (event.event === "message_updated") {
const chatId = Number(event.payload.chat_id);
const message = event.payload.message as Message;
if (!Number.isFinite(chatId) || !message?.id) {
return;
}
chatStore.upsertMessage(chatId, message);
scheduleReloadChats();
}
if (event.event === "message_deleted") {
const chatId = Number(event.payload.chat_id);
const messageId = Number(event.payload.message_id);
if (!Number.isFinite(chatId) || !Number.isFinite(messageId)) {
return;
}
chatStore.removeMessage(chatId, messageId);
scheduleReloadChats();
}
if (event.event === "chat_updated") {
const chatId = Number(event.payload.chat_id);
if (Number.isFinite(chatId)) {

View File

@@ -85,6 +85,7 @@ interface ChatState {
status: DeliveryStatus,
senderId: number
) => void;
upsertMessage: (chatId: number, message: Message) => void;
removeMessage: (chatId: number, messageId: number) => void;
restoreMessages: (chatId: number, messages: Message[]) => void;
clearChatMessages: (chatId: number) => void;
@@ -299,6 +300,30 @@ export const useChatStore = create<ChatState>((set, get) => ({
messagesByChat: { ...state.messagesByChat, [chatId]: next }
}));
},
upsertMessage: (chatId, message) => {
const old = get().messagesByChat[chatId] ?? [];
if (!old.length) {
set((state) => ({
messagesByChat: { ...state.messagesByChat, [chatId]: [message] }
}));
return;
}
const idx = old.findIndex((m) => m.id === message.id);
if (idx === -1) {
const next = [...old, message].sort((a, b) => a.id - b.id);
set((state) => ({
messagesByChat: { ...state.messagesByChat, [chatId]: next }
}));
return;
}
const next = [...old];
const existing = next[idx];
const deliveryStatus = mergeDeliveryStatus(message.delivery_status, existing.delivery_status);
next[idx] = deliveryStatus ? { ...message, delivery_status: deliveryStatus } : message;
set((state) => ({
messagesByChat: { ...state.messagesByChat, [chatId]: next }
}));
},
removeMessage: (chatId, messageId) => {
const old = get().messagesByChat[chatId] ?? [];
set((state) => ({