refactor(web): unify DM sorting with sortDmChannels across all triggers

This commit is contained in:
Jannis Braun
2026-04-02 17:56:26 +02:00
parent afa583df1d
commit b77aad61eb
3 changed files with 28 additions and 15 deletions
+15 -6
View File
@@ -4,6 +4,7 @@ import { wsSend } from '../hooks/useWebSocket';
import { isDmChannel, getChannelOrigin, getApiForOrigin, useSpaceStore } from './spaceStore';
import { useAuthStore } from './authStore';
import { normalizeMessageAssets } from '../utils/assetUrls';
import { sortDmChannels } from '../utils/dmSorting';
const MAX_MESSAGES_PER_CHANNEL = 200;
const MAX_CACHED_CHANNELS = 20;
@@ -285,12 +286,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
? { ...dm, lastMessage: { id: tempId, dmChannelId: channelId, userId: currentUser.id, content, createdAt: Date.now() } }
: dm
);
updatedDms.sort((a, b) => {
const aTime = a.lastMessage?.createdAt ?? a.createdAt;
const bTime = b.lastMessage?.createdAt ?? b.createdAt;
return bTime - aTime;
});
setDmChannels(updatedDms);
setDmChannels(sortDmChannels(updatedDms, get().unreadChannels, get().currentChannelId));
}
}
@@ -589,6 +585,13 @@ export const useChatStore = create<ChatState>((set, get) => ({
}
set({ readStates: rsMap, unreadChannels: unread });
// Re-sort DM list now that unread state is known (handles initial load
// where populateFromReady runs before read states are processed)
const { dmChannels, setDmChannels } = useSpaceStore.getState();
if (dmChannels.length > 0) {
setDmChannels(sortDmChannels(dmChannels, unread, currentChannelId));
}
},
markChannelUnread: (channelId: string) => {
@@ -652,6 +655,12 @@ export const useChatStore = create<ChatState>((set, get) => ({
return { readStates: newReadStates, unreadChannels: newUnread };
});
// Re-sort DM list when a DM is marked as read (moves from unread to read group)
if (isDmChannel(channelId)) {
const { dmChannels, setDmChannels } = useSpaceStore.getState();
setDmChannels(sortDmChannels(dmChannels, get().unreadChannels, channelId));
}
// Send to the correct instance
const origin = getChannelOrigin(channelId);
wsSend({ type: 'channel_ack', channelId, messageId }, origin);
+8 -1
View File
@@ -3,6 +3,7 @@ import type { Space, Channel, ChannelCategory, MemberWithUser, SpaceWithChannels
import { api, BackspaceApiClient } from '../api/client';
import { resolveAssetUrl, normalizeUserAssets } from '../utils/assetUrls';
import { isSelf } from '../utils/identity';
import { sortDmChannels } from '../utils/dmSorting';
import { useAuthStore } from './authStore';
import { useChatStore } from './chatStore';
@@ -670,9 +671,15 @@ export const useSpaceStore = create<SpaceState>((set, get) => ({
});
const mergedDms = [...existingDmsFromOtherOrigins, ...incomingDms];
// Sort DMs using unread-first ordering. On initial load, unreadChannels may
// still be empty (read states are processed after populateFromReady); the
// safety-net re-sort in setReadStates handles that case.
const { unreadChannels, currentChannelId } = useChatStore.getState();
const sortedDms = sortDmChannels(mergedDms, unreadChannels, currentChannelId);
const update: Partial<SpaceState> = {
spaces: mergedSpaces,
dmChannels: mergedDms,
dmChannels: sortedDms,
channelToSpaceMap,
channelLastMessageIds,
spacePermissions,