feat(message): add conversation notification mute feature
Add notification mute functionality for conversations with the following changes: - Add notification_muted field to ConversationResponse and related DTOs - Add notificationMutedMap to message store for tracking mute state - Add setConversationNotificationMuted API method - Integrate mute toggle in GroupInfoScreen and PrivateChatInfoScreen - Skip system notifications for muted conversations - Suppress vibration for muted conversations in WS handler - Clean up selected mentions when @mentions are removed from text Chore changes: - Update PostCard bookmark icon from 'bookmark' to 'star' - Refine card styles across AppsScreen, MaterialsScreen, and SubjectMaterialsScreen - Improve week selector scrolling to center selected week in ScheduleScreen
This commit is contained in:
@@ -55,6 +55,9 @@ export interface MessageState {
|
||||
|
||||
// 当前用户的禁言状态 - 按群组ID存储
|
||||
mutedStatusMap: Map<string, boolean>;
|
||||
|
||||
// 会话免打扰状态 - 按会话ID存储
|
||||
notificationMutedMap: Map<string, boolean>;
|
||||
}
|
||||
|
||||
// ==================== Actions 接口 ====================
|
||||
@@ -72,6 +75,7 @@ export interface MessageActions {
|
||||
getTypingUsers: (groupId: string) => string[];
|
||||
isMuted: (groupId: string) => boolean;
|
||||
getActiveConversation: () => string | null;
|
||||
isNotificationMuted: (conversationId: string) => boolean;
|
||||
|
||||
// 设置状态
|
||||
setConversations: (conversations: Map<string, ConversationResponse>) => void;
|
||||
@@ -88,6 +92,7 @@ export interface MessageActions {
|
||||
setLoadingMessages: (conversationId: string, loading: boolean) => void;
|
||||
setTypingUsers: (groupId: string, users: string[]) => void;
|
||||
setMutedStatus: (groupId: string, isMuted: boolean) => void;
|
||||
setNotificationMuted: (conversationId: string, notificationMuted: boolean) => void;
|
||||
setInitialized: (initialized: boolean) => void;
|
||||
|
||||
// 重置
|
||||
@@ -110,6 +115,7 @@ const initialState: MessageState = {
|
||||
isInitialized: false,
|
||||
typingUsersMap: new Map(),
|
||||
mutedStatusMap: new Map(),
|
||||
notificationMutedMap: new Map(),
|
||||
};
|
||||
|
||||
// ==================== 工具函数 ====================
|
||||
@@ -177,6 +183,7 @@ export const useMessageStore = create<MessageStore>((set, get) => ({
|
||||
isInitialized: state.isInitialized,
|
||||
typingUsersMap: state.typingUsersMap,
|
||||
mutedStatusMap: state.mutedStatusMap,
|
||||
notificationMutedMap: state.notificationMutedMap,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -227,11 +234,25 @@ export const useMessageStore = create<MessageStore>((set, get) => ({
|
||||
return get().currentConversationId;
|
||||
},
|
||||
|
||||
isNotificationMuted: (conversationId: string) => {
|
||||
return get().notificationMutedMap.get(conversationId) || false;
|
||||
},
|
||||
|
||||
// ==================== 设置状态 ====================
|
||||
|
||||
setConversations: (conversations: Map<string, ConversationResponse>) => {
|
||||
const conversationList = sortConversationList(conversations);
|
||||
set({ conversations, conversationList });
|
||||
const notificationMutedMap = new Map<string, boolean>();
|
||||
conversations.forEach((conv, id) => {
|
||||
if (conv.notification_muted) {
|
||||
notificationMutedMap.set(id, true);
|
||||
}
|
||||
});
|
||||
set(state => ({
|
||||
conversations,
|
||||
conversationList,
|
||||
notificationMutedMap: new Map([...state.notificationMutedMap, ...notificationMutedMap]),
|
||||
}));
|
||||
},
|
||||
|
||||
updateConversation: (conversation: ConversationResponse) => {
|
||||
@@ -240,7 +261,13 @@ export const useMessageStore = create<MessageStore>((set, get) => ({
|
||||
const newConversations = new Map(state.conversations);
|
||||
newConversations.set(id, { ...conversation, id });
|
||||
const conversationList = sortConversationList(newConversations);
|
||||
return { conversations: newConversations, conversationList };
|
||||
const newNotificationMutedMap = new Map(state.notificationMutedMap);
|
||||
if (conversation.notification_muted) {
|
||||
newNotificationMutedMap.set(id, true);
|
||||
} else {
|
||||
newNotificationMutedMap.delete(id);
|
||||
}
|
||||
return { conversations: newConversations, conversationList, notificationMutedMap: newNotificationMutedMap };
|
||||
});
|
||||
},
|
||||
|
||||
@@ -374,6 +401,14 @@ export const useMessageStore = create<MessageStore>((set, get) => ({
|
||||
});
|
||||
},
|
||||
|
||||
setNotificationMuted: (conversationId: string, notificationMuted: boolean) => {
|
||||
set(state => {
|
||||
const newNotificationMutedMap = new Map(state.notificationMutedMap);
|
||||
newNotificationMutedMap.set(conversationId, notificationMuted);
|
||||
return { notificationMutedMap: newNotificationMutedMap };
|
||||
});
|
||||
},
|
||||
|
||||
setInitialized: (initialized: boolean) => {
|
||||
set({ isInitialized: initialized });
|
||||
},
|
||||
@@ -388,6 +423,7 @@ export const useMessageStore = create<MessageStore>((set, get) => ({
|
||||
loadingMessagesSet: new Set(),
|
||||
typingUsersMap: new Map(),
|
||||
mutedStatusMap: new Map(),
|
||||
notificationMutedMap: new Map(),
|
||||
});
|
||||
AsyncStorage.removeItem(LAST_SYSTEM_MESSAGE_AT_KEY).catch(() => {});
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user