Files
GMW/frontend/src/hooks/useMessages.ts
T

55 lines
1.8 KiB
TypeScript
Raw Normal View History

import { useCallback, useEffect, useState } from "react";
import { listMessages, reanalyzeMessage } from "../api/messages";
import type { MessageRecord } from "../types/messages";
export function mergeMessages(current: MessageRecord[], incoming: MessageRecord[]): MessageRecord[] {
const byId = new Map(current.map((message) => [message.id, message]));
for (const message of incoming) {
byId.set(message.id, { ...byId.get(message.id), ...message });
}
return Array.from(byId.values())
.sort((a, b) => b.created_at - a.created_at || b.id.localeCompare(a.id))
.slice(0, 200);
}
export function useMessages() {
const [messages, setMessages] = useState<MessageRecord[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetchMessages = useCallback(async (channelId?: string) => {
setLoading(true);
setError(null);
try {
const params = new URLSearchParams({ limit: "80" });
if (channelId) params.set("channel", channelId);
const result = await listMessages(params);
setMessages(result.data);
return result.data;
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
setError(message);
throw err;
} finally {
setLoading(false);
}
}, []);
const reanalyze = useCallback(async (id: string) => {
setMessages((prev) =>
prev.map((message) =>
message.id === id
? { ...message, ai_status: "pending", ai_error: null, ai_analysis: null }
: message,
),
);
await reanalyzeMessage(id);
}, []);
useEffect(() => {
fetchMessages().catch(() => undefined);
}, [fetchMessages]);
return { messages, setMessages, loading, error, fetchMessages, reanalyze };
}