fix(web): robust date parsing and merge strategy in conversation store

This commit is contained in:
2026-07-27 08:49:57 -04:00
parent 4e48815b91
commit f53cd49803
+46 -23
View File
@@ -2,6 +2,13 @@ import { create } from "zustand";
import { api } from "../lib/api.ts";
import { type Reaction } from "./message.ts";
function parseDate(iso: string): number {
if (!iso) return 0;
const normalized = iso.includes("T") ? iso : iso.replace(" ", "T");
const t = new Date(normalized).getTime();
return isNaN(t) ? 0 : t;
}
export interface ConversationMember {
id: string;
username: string;
@@ -89,17 +96,26 @@ export const useConversationStore = create<ConversationState>((set, get) => ({
`/conversations/${conversationId}/messages${params}`,
);
const list = Array.isArray(messages) ? messages : [];
set((state) => ({
messagesByConversation: {
...state.messagesByConversation,
[conversationId]: list,
},
hasMoreByConversation: {
...state.hasMoreByConversation,
[conversationId]: list.length >= 50,
},
isLoading: false,
}));
set((state) => {
const existing = state.messagesByConversation[conversationId] || [];
const map = new Map<string, ConversationMessage>();
existing.forEach((m) => map.set(m.id, m));
list.forEach((m) => map.set(m.id, m));
const merged = Array.from(map.values()).sort(
(a, b) => parseDate(a.created_at) - parseDate(b.created_at)
);
return {
messagesByConversation: {
...state.messagesByConversation,
[conversationId]: merged,
},
hasMoreByConversation: {
...state.hasMoreByConversation,
[conversationId]: list.length >= 50,
},
isLoading: false,
};
});
} catch (error) {
set({ isLoading: false, error: error instanceof Error ? error.message : "Failed" });
}
@@ -118,17 +134,24 @@ export const useConversationStore = create<ConversationState>((set, get) => ({
`/conversations/${conversationId}/messages?before=${encodeURIComponent(oldestId)}`,
);
const list = Array.isArray(older) ? older : [];
set((state) => ({
messagesByConversation: {
...state.messagesByConversation,
[conversationId]: [...list, ...existing],
},
hasMoreByConversation: {
...state.hasMoreByConversation,
[conversationId]: list.length >= 50,
},
isLoadingOlder: false,
}));
set((state) => {
const map = new Map<string, ConversationMessage>();
[...list, ...existing].forEach((m) => map.set(m.id, m));
const merged = Array.from(map.values()).sort(
(a, b) => parseDate(a.created_at) - parseDate(b.created_at)
);
return {
messagesByConversation: {
...state.messagesByConversation,
[conversationId]: merged,
},
hasMoreByConversation: {
...state.hasMoreByConversation,
[conversationId]: list.length >= 50,
},
isLoadingOlder: false,
};
});
} catch {
set({ isLoadingOlder: false });
}
@@ -156,7 +179,7 @@ export const useConversationStore = create<ConversationState>((set, get) => ({
messagesByConversation: {
...state.messagesByConversation,
[message.conversation_id]: [...existing, message]
.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()),
.sort((a, b) => parseDate(a.created_at) - parseDate(b.created_at)),
},
};
});