2026-01-20 18:26:58 +02:00
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
import { useShape } from "@electric-sql/react";
|
2026-01-22 19:04:23 +02:00
|
|
|
import { useSetAtom } from "jotai";
|
|
|
|
|
import { useEffect } from "react";
|
|
|
|
|
import { chatSessionStateAtom } from "@/atoms/chat/chat-session-state.atom";
|
2026-01-20 18:26:58 +02:00
|
|
|
import type { ChatSessionState } from "@/contracts/types/chat-session-state.types";
|
|
|
|
|
|
|
|
|
|
const ELECTRIC_URL = process.env.NEXT_PUBLIC_ELECTRIC_URL || "http://localhost:5133";
|
|
|
|
|
|
2026-01-20 19:48:28 +02:00
|
|
|
/**
|
2026-01-22 19:04:23 +02:00
|
|
|
* Syncs chat session state for a thread via Electric SQL.
|
|
|
|
|
* Call once per thread (in page.tsx). Updates global atom.
|
2026-01-20 19:48:28 +02:00
|
|
|
*/
|
2026-01-22 19:04:23 +02:00
|
|
|
export function useChatSessionStateSync(threadId: number | null) {
|
|
|
|
|
const setSessionState = useSetAtom(chatSessionStateAtom);
|
|
|
|
|
|
|
|
|
|
const { data } = useShape<ChatSessionState>({
|
2026-01-20 18:26:58 +02:00
|
|
|
url: `${ELECTRIC_URL}/v1/shape`,
|
|
|
|
|
params: {
|
|
|
|
|
table: "chat_session_state",
|
2026-01-22 19:04:23 +02:00
|
|
|
where: `thread_id = ${threadId ?? -1}`,
|
2026-01-20 18:26:58 +02:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
2026-01-22 19:04:23 +02:00
|
|
|
useEffect(() => {
|
|
|
|
|
if (!threadId) {
|
|
|
|
|
setSessionState(null);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-01-20 18:26:58 +02:00
|
|
|
|
2026-01-22 19:04:23 +02:00
|
|
|
const row = data?.[0];
|
|
|
|
|
setSessionState({
|
|
|
|
|
threadId,
|
|
|
|
|
isAiResponding: !!row?.ai_responding_to_user_id,
|
|
|
|
|
respondingToUserId: row?.ai_responding_to_user_id ?? null,
|
|
|
|
|
});
|
|
|
|
|
}, [threadId, data, setSessionState]);
|
2026-01-20 18:26:58 +02:00
|
|
|
}
|