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
@@ -14,7 +14,7 @@ import { wsSend } from '../../hooks/useWebSocket';
import { getActiveRoom } from '../../hooks/useLiveKit';
import { AudioManager } from '../../audio/AudioManager';
import { hasPermissionBit, PermissionBits } from '../../utils/permissions';
import { parseFederatedUsername } from '../../utils/identity';
import { parseFederatedUsername, isSelf } from '../../utils/identity';
export function ChannelSidebar() {
const servers = useServerStore((s) => s.servers);
@@ -189,7 +189,7 @@ export function ChannelSidebar() {
<div className="space-y-[2px]">
{dmChannels.map((dm) => {
const otherMembers = dm.members.filter(m => m.id !== user?.id);
const otherMembers = dm.members.filter(m => !isSelf(m, user));
if (otherMembers.length === 0) return null;
const isGroup = dm.members.length > 2;
const isDmUnread = unreadChannels.has(dm.id) && currentChannelId !== dm.id;