fix(notifications): sync mute state in chat store immediately
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit is contained in:
@@ -34,7 +34,7 @@ Legend:
|
|||||||
25. Admin Rights - `PARTIAL` (delete/pin/edit info + explicit ban API for groups/channels; integration tests cover channel member read-only, channel admin full-delete, channel message delete-for-all permissions, group profile edit permissions, and owner-only role management rules; remaining UX moderation tools limited)
|
25. Admin Rights - `PARTIAL` (delete/pin/edit info + explicit ban API for groups/channels; integration tests cover channel member read-only, channel admin full-delete, channel message delete-for-all permissions, group profile edit permissions, and owner-only role management rules; remaining UX moderation tools limited)
|
||||||
26. Channels - `PARTIAL` (create/post/edit/delete/subscribe/unsubscribe; UX edge-cases still polishing)
|
26. Channels - `PARTIAL` (create/post/edit/delete/subscribe/unsubscribe; UX edge-cases still polishing)
|
||||||
27. Channel Types - `DONE` (public/private)
|
27. Channel Types - `DONE` (public/private)
|
||||||
28. Notifications - `PARTIAL` (browser notifications + mute/settings; chat mute is now propagated in chat list payload and honored by web realtime notifications with mention override; no mobile push infra)
|
28. Notifications - `PARTIAL` (browser notifications + mute/settings; chat mute is propagated in chat list payload, honored by web realtime notifications with mention override, and mute toggle now syncs instantly in chat store; no mobile push infra)
|
||||||
29. Archive - `DONE`
|
29. Archive - `DONE`
|
||||||
30. Blacklist - `DONE`
|
30. Blacklist - `DONE`
|
||||||
31. Privacy - `PARTIAL` (avatar/last-seen/group-invites + PM policy `everyone|contacts|nobody`; group-invite `nobody` is available in API and web settings; integration tests cover PM policy matrix (`everyone/contacts/nobody`), group-invite policy matrix (`everyone/contacts/nobody`), and private chat counterpart visibility for `nobody/contacts`, remaining UX/matrix hardening)
|
31. Privacy - `PARTIAL` (avatar/last-seen/group-invites + PM policy `everyone|contacts|nobody`; group-invite `nobody` is available in API and web settings; integration tests cover PM policy matrix (`everyone/contacts/nobody`), group-invite policy matrix (`everyone/contacts/nobody`), and private chat counterpart visibility for `nobody/contacts`, remaining UX/matrix hardening)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ interface Props {
|
|||||||
export function ChatInfoPanel({ chatId, open, onClose }: Props) {
|
export function ChatInfoPanel({ chatId, open, onClose }: Props) {
|
||||||
const me = useAuthStore((s) => s.me);
|
const me = useAuthStore((s) => s.me);
|
||||||
const loadChats = useChatStore((s) => s.loadChats);
|
const loadChats = useChatStore((s) => s.loadChats);
|
||||||
|
const updateChatMuted = useChatStore((s) => s.updateChatMuted);
|
||||||
const setActiveChatId = useChatStore((s) => s.setActiveChatId);
|
const setActiveChatId = useChatStore((s) => s.setActiveChatId);
|
||||||
const setFocusedMessage = useChatStore((s) => s.setFocusedMessage);
|
const setFocusedMessage = useChatStore((s) => s.setFocusedMessage);
|
||||||
const showToast = useUiStore((s) => s.showToast);
|
const showToast = useUiStore((s) => s.showToast);
|
||||||
@@ -306,6 +307,7 @@ export function ChatInfoPanel({ chatId, open, onClose }: Props) {
|
|||||||
try {
|
try {
|
||||||
const updated = await updateChatNotificationSettings(chatId, !muted);
|
const updated = await updateChatNotificationSettings(chatId, !muted);
|
||||||
setMuted(updated.muted);
|
setMuted(updated.muted);
|
||||||
|
updateChatMuted(chatId, updated.muted);
|
||||||
} catch {
|
} catch {
|
||||||
setError("Failed to update notifications");
|
setError("Failed to update notifications");
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ interface ChatState {
|
|||||||
setReplyToMessage: (chatId: number, message: Message | null) => void;
|
setReplyToMessage: (chatId: number, message: Message | null) => void;
|
||||||
setEditingMessage: (chatId: number, message: Message | null) => void;
|
setEditingMessage: (chatId: number, message: Message | null) => void;
|
||||||
updateChatPinnedMessage: (chatId: number, pinnedMessageId: number | null) => void;
|
updateChatPinnedMessage: (chatId: number, pinnedMessageId: number | null) => void;
|
||||||
|
updateChatMuted: (chatId: number, muted: boolean) => void;
|
||||||
applyPresenceEvent: (chatId: number, userId: number, isOnline: boolean, lastSeenAt?: string) => void;
|
applyPresenceEvent: (chatId: number, userId: number, isOnline: boolean, lastSeenAt?: string) => void;
|
||||||
removeChat: (chatId: number) => void;
|
removeChat: (chatId: number) => void;
|
||||||
setDraft: (chatId: number, text: string) => void;
|
setDraft: (chatId: number, text: string) => void;
|
||||||
@@ -416,6 +417,10 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|||||||
set((state) => ({
|
set((state) => ({
|
||||||
chats: state.chats.map((chat) => (chat.id === chatId ? { ...chat, pinned_message_id: pinnedMessageId } : chat))
|
chats: state.chats.map((chat) => (chat.id === chatId ? { ...chat, pinned_message_id: pinnedMessageId } : chat))
|
||||||
})),
|
})),
|
||||||
|
updateChatMuted: (chatId, muted) =>
|
||||||
|
set((state) => ({
|
||||||
|
chats: state.chats.map((chat) => (chat.id === chatId ? { ...chat, muted } : chat))
|
||||||
|
})),
|
||||||
applyPresenceEvent: (chatId, userId, isOnline, lastSeenAt) =>
|
applyPresenceEvent: (chatId, userId, isOnline, lastSeenAt) =>
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
chats: state.chats.map((chat) => {
|
chats: state.chats.map((chat) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user