import { useEffect } from "react"; import { useConnectionStore } from "./stores/connectionStore"; import { useSettingsStore } from "./stores/settingsStore"; import { useUiStore } from "./stores/uiStore"; import { useBackupStore } from "./stores/backupStore"; import { HomeScreen } from "./components/layout/HomeScreen"; import { SettingsPage } from "./components/settings/SettingsPage"; import { NewConnectionScreen } from "./components/connections/NewConnectionScreen"; import { ErrorBanner } from "./components/ui/ErrorBanner"; import { ToastContainer } from "./components/ui/Toast"; import { DbViewerScreen } from "./components/db-viewer/DbViewerScreen"; import { useAppearance } from "./hooks/useAppearance"; import { isMacOS } from "./lib/platform"; import { getCurrentWindow } from "@tauri-apps/api/window"; const VIEW_TITLES: Record = { home: "Gridline", settings: "Settings", "new-connection": "New Connection", "db-viewer": "", }; export default function App() { const activeView = useUiStore((s) => s.activeView); const setActiveView = useUiStore((s) => s.setActiveView); const settingsReturnView = useUiStore((s) => s.settingsReturnView); const openSettings = useUiStore((s) => s.openSettings); const loadConnections = useConnectionStore((s) => s.loadAll); const loadSettings = useSettingsStore((s) => s.load); const settings = useSettingsStore((s) => s.settings); const connectionError = useConnectionStore((s) => s.error); const activeFolderId = useUiStore((s) => s.activeFolderId); const folders = useConnectionStore((s) => s.folders); const tags = useConnectionStore((s) => s.tags); const prefilledConnectionString = useUiStore((s) => s.prefilledConnectionString); const clearPrefilledConnectionString = useUiStore((s) => s.clearPrefilledConnectionString); useAppearance(settings?.theme ?? "system", settings?.font_size ?? "medium", settings?.accent_color ?? "#2563EB"); useEffect(() => { loadConnections(); loadSettings(); // Init backup event listener (noop outside Tauri) useBackupStore.getState().initListener().catch(() => {}); }, [loadConnections, loadSettings]); // If the user hasn't navigated anywhere yet, start in the configured default folder const setActiveFolderId = useUiStore((s) => s.setActiveFolderId); const defaultFolderId = settings?.default_folder_id; useEffect(() => { if (defaultFolderId && useUiStore.getState().activeFolderId === null) { setActiveFolderId(defaultFolderId); } }, [defaultFolderId, setActiveFolderId]); useEffect(() => { let title = VIEW_TITLES[activeView] ?? "Gridline"; if (activeView === "db-viewer") { const conn = useConnectionStore.getState().connections.find( (c) => c.id === useUiStore.getState().activeConnectionId ); if (conn) title = conn.name; } document.title = title; try { getCurrentWindow().setTitle(title).catch(() => { // Ignore environments where the Tauri API is unavailable (tests, browser) }); } catch { // getCurrentWindow can throw outside of a Tauri runtime } }, [activeView]); const keepDbViewerMounted = activeView === "db-viewer" || (activeView === "settings" && settingsReturnView === "db-viewer"); const dbViewerVisible = activeView === "db-viewer"; return (
{typeof window !== "undefined" && "__TAURI_INTERNALS__" in window && isMacOS() && ( // macOS "Overlay" title bar: in-flow strip the window can be // dragged by; traffic lights float over it. Only in Tauri.
)}
{connectionError && (
)} {activeView === "settings" && } {activeView === "new-connection" && ( { clearPrefilledConnectionString(); setActiveView("home"); }} onCancel={() => { clearPrefilledConnectionString(); setActiveView("home"); }} /> )} {activeView === "home" && } {keepDbViewerMounted && (
setActiveView("home")} onSettings={openSettings} />
)}
); }