feat(core): clear saved chat and add message deletion scopes
Some checks failed
CI / test (push) Failing after 26s

backend:

- add message_hidden table for per-user message hiding

- support DELETE /messages/{id}?for_all=true|false

- implement delete-for-me vs delete-for-all logic by chat type/permissions

- add POST /chats/{chat_id}/clear and route saved chat deletion to clear

web:

- saved messages action changed from delete to clear

- message context menu now supports delete modal: for me / for everyone

- add local store helpers removeMessage/clearChatMessages

- include realtime stability improvements and app error boundary
This commit is contained in:
2026-03-08 01:13:20 +03:00
parent a42f97962b
commit 7f15edcb4e
15 changed files with 486 additions and 77 deletions

View File

@@ -22,6 +22,8 @@ interface ChatState {
confirmMessageByClientId: (chatId: number, clientMessageId: string, message: Message) => void;
removeOptimisticMessage: (chatId: number, clientMessageId: string) => void;
setMessageDeliveryStatus: (chatId: number, messageId: number, status: DeliveryStatus) => void;
removeMessage: (chatId: number, messageId: number) => void;
clearChatMessages: (chatId: number) => void;
setTypingUsers: (chatId: number, userIds: number[]) => void;
setReplyToMessage: (chatId: number, message: Message | null) => void;
updateChatPinnedMessage: (chatId: number, pinnedMessageId: number | null) => void;
@@ -137,6 +139,22 @@ export const useChatStore = create<ChatState>((set, get) => ({
messagesByChat: { ...state.messagesByChat, [chatId]: next }
}));
},
removeMessage: (chatId, messageId) => {
const old = get().messagesByChat[chatId] ?? [];
set((state) => ({
messagesByChat: {
...state.messagesByChat,
[chatId]: old.filter((m) => m.id !== messageId)
}
}));
},
clearChatMessages: (chatId) =>
set((state) => ({
messagesByChat: {
...state.messagesByChat,
[chatId]: []
}
})),
setTypingUsers: (chatId, userIds) =>
set((state) => ({ typingByChat: { ...state.typingByChat, [chatId]: userIds } })),
setReplyToMessage: (chatId, message) =>