fix: prevent duplicate DMs at creation time, clean up corrupted read states

Replace the unreliable client-side DM dedup loop in populateFromReady with
a creation-time guard (findExistingDmForUser) that checks all instances
before opening a new DM. Guards added to FriendsPage, NewDmModal, and
UserProfilePopout.

Also fixes: corrupted read_states from temp_ optimistic message IDs (server
migration + client-side validation), federation-aware closeDm/addDmMember
API routing, isSelf-based DM member filtering in sidebar/header, and WS
event error isolation.
This commit is contained in:
Jannis Braun
2026-03-04 20:04:15 +01:00
parent 33ae79bae9
commit 65e9ee5203
12 changed files with 108 additions and 12 deletions
+12 -1
View File
@@ -478,7 +478,16 @@ export const useChatStore = create<ChatState>((set, get) => ({
const unread = new Set<string>();
for (const [channelId, lastMsgId] of channelLastMessageIds) {
const lastRead = rsMap.get(channelId);
if (!lastRead || BigInt(lastMsgId) > BigInt(lastRead)) {
if (!lastRead) {
unread.add(channelId);
continue;
}
try {
if (BigInt(lastMsgId) > BigInt(lastRead)) {
unread.add(channelId);
}
} catch {
// Corrupted read state (e.g. temp_ ID) — treat as unread
unread.add(channelId);
}
}
@@ -500,6 +509,8 @@ export const useChatStore = create<ChatState>((set, get) => ({
const lastMsg = msgs[msgs.length - 1];
if (!lastMsg) return;
const messageId = lastMsg.id;
// Don't ack optimistic/temp messages — wait for the real server ID
if (messageId.startsWith('temp_')) return;
// Update local state immediately
set((state) => {