fix(web): normalize channel and server IDs across channel store and auto-select default channel

This commit is contained in:
2026-07-27 11:56:39 -04:00
parent 13e3aec2d5
commit 5eeb659b70
3 changed files with 51 additions and 17 deletions
+13 -1
View File
@@ -117,9 +117,21 @@ export function ChannelList() {
}, [fetchNotifSettings, fetchReadStates]);
const channels = useMemo(() => {
return activeServerId ? channelsByServer[activeServerId] || [] : [];
return activeServerId ? channelsByServer[activeServerId.toLowerCase()] || [] : [];
}, [activeServerId, channelsByServer]);
useEffect(() => {
if (channels.length > 0) {
const activeExists = activeChannelId && channels.some((c) => c.id === activeChannelId);
if (!activeExists) {
const defaultChannel = channels.find((c) => c.type === 'text') || channels[0];
if (defaultChannel) {
setActiveChannel(defaultChannel.id);
}
}
}
}, [channels, activeChannelId, setActiveChannel]);
const activeServer = useMemo(() => {
if (!activeServerId) return null;
return servers.find((s) => s.id === activeServerId) || null;
+2 -2
View File
@@ -332,8 +332,8 @@ export function ChatArea() {
);
const canBulkDelete = true;
const channels = activeServerId ? channelsByServer[activeServerId] || [] : [];
const activeChannel = channels.find((c) => c.id === activeChannelId);
const channels = activeServerId ? channelsByServer[activeServerId.toLowerCase()] || [] : [];
const activeChannel = channels.find((c) => c.id.toLowerCase() === activeChannelId);
const members = activeServerId ? membersByServer[activeServerId] || [] : [];
// Humans only for mentions / nickname lookup (bots live in member list separately).
const humanMembers = useMemo(() => members.filter((m) => !m.is_bot), [members]);
+36 -14
View File
@@ -33,11 +33,18 @@ export const useChannelStore = create<ChannelState>((set) => ({
error: null,
fetchChannels: async (serverId) => {
const srvId = serverId.toLowerCase();
set({ isLoading: true, error: null });
try {
const channels = await api.get<Channel[]>(`/servers/${serverId}/channels`);
const channels = await api.get<Channel[]>(`/servers/${srvId}/channels`);
const list = Array.isArray(channels) ? channels : [];
const normalized = list.map((c) => ({
...c,
id: c.id.toLowerCase(),
server_id: c.server_id.toLowerCase(),
}));
set((state) => ({
channelsByServer: { ...state.channelsByServer, [serverId]: channels },
channelsByServer: { ...state.channelsByServer, [srvId]: normalized },
isLoading: false,
}));
} catch (error) {
@@ -63,37 +70,52 @@ export const useChannelStore = create<ChannelState>((set) => ({
}
},
addChannel: (channel) =>
addChannel: (channel) => {
const norm = {
...channel,
id: channel.id.toLowerCase(),
server_id: channel.server_id.toLowerCase(),
};
set((state) => {
const list = state.channelsByServer[channel.server_id] || [];
const list = state.channelsByServer[norm.server_id] || [];
if (list.some((c) => c.id === norm.id)) return state;
return {
channelsByServer: {
...state.channelsByServer,
[channel.server_id]: [...list, channel],
[norm.server_id]: [...list, norm],
},
};
}),
});
},
updateChannel: (channel) =>
updateChannel: (channel) => {
const norm = {
...channel,
id: channel.id.toLowerCase(),
server_id: channel.server_id.toLowerCase(),
};
set((state) => {
const list = state.channelsByServer[channel.server_id] || [];
const list = state.channelsByServer[norm.server_id] || [];
return {
channelsByServer: {
...state.channelsByServer,
[channel.server_id]: list.map((c) => (c.id === channel.id ? channel : c)),
[norm.server_id]: list.map((c) => (c.id === norm.id ? norm : c)),
},
};
}),
});
},
removeChannel: (id) =>
removeChannel: (id) => {
const chId = id.toLowerCase();
set((state) => {
const next: Record<string, Channel[]> = {};
for (const serverId of Object.keys(state.channelsByServer)) {
next[serverId] = state.channelsByServer[serverId].filter((c) => c.id !== id);
next[serverId] = state.channelsByServer[serverId].filter((c) => c.id !== chId);
}
return {
channelsByServer: next,
activeChannelId: state.activeChannelId === id ? null : state.activeChannelId,
activeChannelId: state.activeChannelId === chId ? null : state.activeChannelId,
};
}),
});
},
}));