fix(mobile): Chat startet bei neuester Nachricht und Chats nach letzter Aktivität sortieren
Der Verlauf nutzt eine invertierte Liste und öffnet dadurch immer ganz unten. Raumlisten liefern lastActivityAt; die App sortiert alle Chats danach und zieht einen Chat nach dem Senden sofort nach oben. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ export type MobileChatRoom = {
|
||||
key: string; id?: string; name: string; topic?: string | null;
|
||||
source: 'internal' | 'collaboration'; group: string; exists: boolean;
|
||||
type?: string; projectId?: number; projectNumber?: string | null; userId?: string; email?: string | null;
|
||||
ownerName?: string; remote?: boolean; status?: string; unread?: number;
|
||||
ownerName?: string; remote?: boolean; status?: string; unread?: number; lastActivityAt?: string | null;
|
||||
};
|
||||
export type ChatInvitation = {
|
||||
id: string; name: string; ownerName?: string; role: string;
|
||||
@@ -45,6 +45,11 @@ export const chatEndpoint = (room: MobileChatRoom, suffix = '') => room.source =
|
||||
? `/api/collaboration/rooms/${encodeURIComponent(room.id!)}${suffix}`
|
||||
: `/api/communication/chat/rooms/${encodeURIComponent(room.key)}${suffix}`;
|
||||
export const visibleChatRooms = (directory: ChatDirectory) => directory.rooms.filter(room => !directory.hiddenRoomKeys.includes(room.key));
|
||||
const activity = (room: MobileChatRoom) => (room.lastActivityAt && Date.parse(room.lastActivityAt)) || 0;
|
||||
// Most recently used chats first; rooms without activity keep their server order at the end.
|
||||
export const sortChatRooms = (rooms: MobileChatRoom[]) => [...rooms].sort((a, b) => activity(b) - activity(a));
|
||||
export const touchChatRoom = (rooms: MobileChatRoom[], key: string, at = new Date().toISOString()) =>
|
||||
sortChatRooms(rooms.map(room => room.key === key ? { ...room, lastActivityAt: at } : room));
|
||||
export const chatCursor = (room: MobileChatRoom, messages: MobileChatMessage[]) => Math.max(0,
|
||||
...messages.map(message => room.source === 'collaboration' ? message.seq || 0 : Number(message.id)));
|
||||
export function mergeChatMessages(current: MobileChatMessage[], incoming: MobileChatMessage[], collaboration: boolean) {
|
||||
@@ -98,9 +103,9 @@ export function createChatApi(request: Request) {
|
||||
...room, source: 'internal', group, unread: unread.rooms?.[room.key]?.count || 0,
|
||||
}));
|
||||
return {
|
||||
rooms: [...decorate(base.rooms, 'Räume'), ...decorate(projects.rooms, 'Projekte'), ...decorate(direct.rooms, 'Direkt'),
|
||||
rooms: sortChatRooms([...decorate(base.rooms, 'Räume'), ...decorate(projects.rooms, 'Projekte'), ...decorate(direct.rooms, 'Direkt'),
|
||||
...collaboration.rooms.map(room => ({ ...room, key: collaborationKey(room.id),
|
||||
source: 'collaboration' as const, group: 'Zusammenarbeit', exists: true }))],
|
||||
source: 'collaboration' as const, group: 'Zusammenarbeit', exists: true }))]),
|
||||
hiddenRoomKeys: hidden.hiddenRoomKeys, invitations: collaboration.invitations,
|
||||
canManage: collaboration.canManage === true, projects: collaboration.projects || [],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user