import { useState, useEffect, useCallback } from "react"; import Sidebar from "./components/Sidebar"; import ChatView from "./components/ChatView"; import SettingsPage from "./features/settings/SettingsPage"; import { useDB } from "./hooks/useDB"; import { useModels } from "./hooks/useModels"; import { useRuntimeManager } from "./features/runtime/useRuntimeManager"; import { useRuntimeReadyModelRefresh } from "./features/runtime/useRuntimeReadyModelRefresh"; import type { Chat } from "./lib/types"; import "./App.css"; export default function App() { const { db, ready } = useDB(); const [currentChatId, setCurrentChatId] = useState(null); const [chats, setChats] = useState([]); const [sidebarOpen, setSidebarOpen] = useState(false); const [view, setView] = useState<"chat" | "settings">("chat"); const runtime = useRuntimeManager(); const { models, selectedModel, setSelectedModel, status, refresh: refreshModels } = useModels( runtime.connection.serverUrl, runtime.connection.apiKey, Boolean(runtime.connection.serverUrl), ); useRuntimeReadyModelRefresh(runtime.snapshot.status, refreshModels); const loadChats = useCallback(() => { if (!db) return; const rows = db.query("SELECT * FROM chats ORDER BY updated_at DESC"); setChats(rows); }, [db]); useEffect(() => { loadChats(); }, [loadChats]); const newChat = useCallback(() => { if (!db) return; const id = db.insert("INSERT INTO chats (title) VALUES ('New Chat')"); if (id > 0) { setCurrentChatId(id); setSidebarOpen(false); loadChats(); } }, [db, loadChats]); const deleteChat = useCallback((id: number) => { if (!db) return; if (!window.confirm("Delete this conversation and all of its messages?")) return; db.run("DELETE FROM chats WHERE id = ?", [id]); if (currentChatId === id) setCurrentChatId(null); setSidebarOpen(false); loadChats(); }, [db, currentChatId, loadChats]); const handleSelectChat = useCallback((id: number) => { setCurrentChatId(id); setSidebarOpen(false); }, []); if (!ready) { return (
Initializing…
); } return (
{view !== "settings" && ( setView("settings")} onCloseMobile={() => setSidebarOpen(false)} /> )} {view !== "settings" && sidebarOpen && (
); }