From d508fecfb06ead634126fd6f21cee9800f3fd358 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Sun, 10 May 2026 19:42:05 +0200 Subject: [PATCH] feat(client): dm_channel_updated WS handler + updateDmMetadata store action --- packages/web/src/hooks/useWebSocket.ts | 7 +++++++ packages/web/src/stores/spaceStore.ts | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/web/src/hooks/useWebSocket.ts b/packages/web/src/hooks/useWebSocket.ts index 8f80e91b..f2f50427 100644 --- a/packages/web/src/hooks/useWebSocket.ts +++ b/packages/web/src/hooks/useWebSocket.ts @@ -1117,6 +1117,13 @@ function handleEvent(origin: string, event: ServerEvent): void { break; } + case 'dm_channel_updated': { + if (!isHome && !activePeerOrigins.has(origin)) break; + const { dmChannelId, name, icon } = event; + useSpaceStore.getState().updateDmMetadata(dmChannelId, { name, icon }); + break; + } + // ─── Channel/space events (all origins) ───────────────────────────────── case 'channel_created': { diff --git a/packages/web/src/stores/spaceStore.ts b/packages/web/src/stores/spaceStore.ts index 4af65f05..018c4486 100644 --- a/packages/web/src/stores/spaceStore.ts +++ b/packages/web/src/stores/spaceStore.ts @@ -130,6 +130,7 @@ interface SpaceState { addDmMember: (dmChannelId: string, user: User) => void; removeDmMember: (dmChannelId: string, userId: string) => void; updateDmOwner: (dmChannelId: string, newOwnerId: string) => void; + updateDmMetadata: (dmChannelId: string, patch: { name?: string | null; icon?: string | null }) => void; closeDm: (id: string) => Promise; leaveDm: (id: string) => Promise; loadSpaces: () => Promise; @@ -326,6 +327,20 @@ export const useSpaceStore = create((set, get) => ({ ), })), + // Patches the group DM's display metadata (name + icon). Idempotent: a + // payload with only one of `name`/`icon` leaves the other field untouched. + // Mirrors `updateDmOwner` shape; called by the `dm_channel_updated` WS + // handler after a remote rename / icon change. + updateDmMetadata: (dmChannelId, patch) => set((state) => ({ + dmChannels: state.dmChannels.map(dm => { + if (dm.id !== dmChannelId) return dm; + const next = { ...dm }; + if ('name' in patch) next.name = patch.name ?? null; + if ('icon' in patch) next.icon = patch.icon ?? null; + return next; + }), + })), + closeDm: async (id) => { const origin = get().channelOriginMap.get(id) || ''; const targetApi = getApiForOrigin(origin);