fix: closing DM switches to next DM or channels, resolve DM recipient name for header

This commit is contained in:
jevb
2026-03-27 14:46:09 +01:00
parent 9dfd12f4bb
commit bd11642ffc
2 changed files with 37 additions and 3 deletions
+12 -2
View File
@@ -18,6 +18,7 @@ import { authStore, clearAuth, updateUser } from "@stores/auth.store";
import { closeSettings } from "@stores/ui.store";
import { updatePresence } from "@stores/members.store";
import { channelsStore, getActiveChannel } from "@stores/channels.store";
import { dmStore } from "@stores/dm.store";
import { voiceStore } from "@stores/voice.store";
import {
leaveVoice as voiceSessionLeave,
@@ -110,6 +111,15 @@ export function createMainPage(options: MainPageOptions): MountableComponent {
return authStore.getState().user?.id ?? 0;
}
/** Resolve display name for a channel — for DMs, use recipient username from DM store. */
function resolveChannelName(channelId: number, channelName: string, channelType?: string): string {
if (channelType === "dm" && (!channelName || channelName === "")) {
const dm = dmStore.getState().channels.find((c) => c.channelId === channelId);
if (dm !== undefined) return dm.recipient.username;
}
return channelName;
}
// ---------------------------------------------------------------------------
// Mount / Destroy
// ---------------------------------------------------------------------------
@@ -350,7 +360,7 @@ export function createMainPage(options: MainPageOptions): MountableComponent {
if (active.type === "text") {
videoModeCtrl?.showChat();
}
channelCtrl!.mountChannel(active.id, active.name, active.type);
channelCtrl!.mountChannel(active.id, resolveChannelName(active.id, active.name, active.type), active.type);
}
} catch (err) {
log.error("Channel mount failed", err);
@@ -361,7 +371,7 @@ export function createMainPage(options: MainPageOptions): MountableComponent {
const active = getActiveChannel();
if (active !== null) {
channelCtrl!.mountChannel(active.id, active.name, active.type);
channelCtrl!.mountChannel(active.id, resolveChannelName(active.id, active.name, active.type), active.type);
}
}
@@ -267,7 +267,10 @@ export function createSidebarArea(opts: SidebarAreaOptions): SidebarAreaResult {
/** Ensure a DM channel exists in channelsStore so ChannelController can switch to it. */
function addDmToChannelsStore(dmChannel: DmChannel): void {
const existing = channelsStore.getState().channels.get(dmChannel.channelId);
if (existing !== undefined) return;
// If the channel exists but has an empty name (server sends DMs with name=''),
// update it with the recipient's username
if (existing !== undefined && existing.name !== "") return;
const newChannel: Channel = {
id: dmChannel.channelId,
@@ -414,9 +417,30 @@ export function createSidebarArea(opts: SidebarAreaOptions): SidebarAreaResult {
onCloseDm: (userId) => {
const dmChannel = dmChannels.find((c) => c.recipient.id === userId);
if (dmChannel !== undefined) {
const wasActive = channelsStore.getState().activeChannelId === dmChannel.channelId;
// Remove from store immediately (optimistic), then call API
removeDmChannel(dmChannel.channelId);
void api.closeDm(dmChannel.channelId);
// If the closed DM was the active chat, switch away
if (wasActive) {
const remaining = dmStore.getState().channels;
if (remaining.length > 0) {
// Switch to the next DM
selectDmConversation(remaining[0]!);
} else {
// No DMs left — go back to channels
setSidebarMode("channels");
if (channelBeforeDm !== null) {
setActiveChannel(channelBeforeDm);
} else {
const channels = channelsStore.getState().channels;
for (const ch of channels.values()) {
if (ch.type === "text") { setActiveChannel(ch.id); break; }
}
}
}
}
}
},
onNewDm: () => {