fix(web): robust date parsing and merge strategy in conversation store
This commit is contained in:
@@ -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)),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user