feat: add markUnread store action and WS handler

This commit is contained in:
Jannis Braun
2026-03-20 22:13:47 +01:00
parent 2e26f98246
commit 896cb77b5c
2 changed files with 41 additions and 0 deletions
+6
View File
@@ -571,6 +571,12 @@ function handleEvent(origin: string, event: ServerEvent): void {
break; break;
} }
case 'mark_unread': {
const { onMarkUnread } = useChatStore.getState();
onMarkUnread(event.channelId, event.messageId);
break;
}
// ─── DM call events (all origins) ────────────────────────────────────── // ─── DM call events (all origins) ──────────────────────────────────────
case 'dm_call_incoming': { case 'dm_call_incoming': {
+35
View File
@@ -57,8 +57,10 @@ interface ChatState {
getTypingUsers: (channelId: string) => TypingUser[]; getTypingUsers: (channelId: string) => TypingUser[];
setReadStates: (readStates: ReadState[], channelLastMessageIds: Map<string, string>, originChannelIds?: Set<string>) => void; setReadStates: (readStates: ReadState[], channelLastMessageIds: Map<string, string>, originChannelIds?: Set<string>) => void;
markChannelUnread: (channelId: string) => void; markChannelUnread: (channelId: string) => void;
markUnread: (channelId: string, messageId: string) => void;
ackChannel: (channelId: string) => void; ackChannel: (channelId: string) => void;
onChannelAck: (channelId: string, messageId: string) => void; onChannelAck: (channelId: string, messageId: string) => void;
onMarkUnread: (channelId: string, messageId: string) => void;
removeChannelStates: (channelIds: Set<string>) => void; removeChannelStates: (channelIds: Set<string>) => void;
updateUserInMessages: (user: { id: string; [key: string]: any }) => void; updateUserInMessages: (user: { id: string; [key: string]: any }) => void;
} }
@@ -585,6 +587,25 @@ export const useChatStore = create<ChatState>((set, get) => ({
}); });
}, },
markUnread: (channelId: string, messageId: string) => {
// Optimistically update local state
set((state) => {
const newReadStates = new Map(state.readStates);
const newUnread = new Set(state.unreadChannels);
if (messageId === '0') {
newReadStates.delete(channelId);
} else {
newReadStates.set(channelId, messageId);
}
newUnread.add(channelId);
return { readStates: newReadStates, unreadChannels: newUnread };
});
// Send to the correct federated instance
const origin = getChannelOrigin(channelId);
wsSend({ type: 'mark_unread', channelId, messageId }, origin);
},
ackChannel: (channelId: string) => { ackChannel: (channelId: string) => {
const msgs = get().messages.get(channelId); const msgs = get().messages.get(channelId);
if (!msgs || msgs.length === 0) return; if (!msgs || msgs.length === 0) return;
@@ -624,6 +645,20 @@ export const useChatStore = create<ChatState>((set, get) => ({
}); });
}, },
onMarkUnread: (channelId: string, messageId: string) => {
set((state) => {
const newReadStates = new Map(state.readStates);
const newUnread = new Set(state.unreadChannels);
if (messageId === '0') {
newReadStates.delete(channelId);
} else {
newReadStates.set(channelId, messageId);
}
newUnread.add(channelId);
return { readStates: newReadStates, unreadChannels: newUnread };
});
},
removeChannelStates: (channelIds: Set<string>) => { removeChannelStates: (channelIds: Set<string>) => {
if (channelIds.size === 0) return; if (channelIds.size === 0) return;
set((state) => { set((state) => {