import { Show, createSignal, onSettled } from "solid-js"; import History from "./components/History"; import OpenRepository from "./components/OpenRepository"; import RepositoryNav from "./components/RepositoryNav"; import StatusBar from "./components/StatusBar"; import Welcome from "./components/Welcome"; import { openRepository } from "./lib/api"; import { isGigitError, type OpenedRepository } from "./lib/bindings"; import { createGraphView } from "./lib/graph"; import { createRecents } from "./lib/recents"; /** What to call a repository: its working tree's folder, or the git directory. */ function nameOf(repository: OpenedRepository): string { const path = repository.summary.workdir ?? repository.summary.gitDir; return path.replace(/\/+$/u, "").split("/").pop() ?? path; } /** How the current HEAD reads in the title bar. */ function headOf(repository: OpenedRepository): string { const head = repository.summary.head; switch (head.state) { case "branch": return head.shorthand; case "detached": return `detached at ${head.id.slice(0, 7)}`; case "unborn": return `${head.shorthand} (no commits yet)`; } } export default function App() { const [repository, setRepository] = createSignal(); const [opening, setOpening] = createSignal(false); const [error, setError] = createSignal(); const graph = createGraphView(); const recents = createRecents(); onSettled(() => void recents.refresh()); async function open(path: string) { setOpening(true); setError(undefined); try { const opened = await openRepository(path); setRepository(opened); // Opening promotes the repository to the front of the list, so the // welcome pane is right when it is next seen. void recents.refresh(); await graph.show(opened.id); } catch (failure) { setRepository(undefined); setError(isGigitError(failure) ? failure.message : String(failure)); } finally { setOpening(false); } } return (
{/* A button rather than a link to `#history`, which is the conventional shape for this. WebKit leaves links out of the tab order unless the system's keyboard navigation setting is turned on, and it is off by default — so on macOS, where the app runs in WKWebView, a skip link is a skip link nobody can reach. A button is tabbable in every engine. Verified in tests/e2e/accessibility.spec.ts against both. */}

gigit

No repository open

} > {(current) => (

{nameOf(current())} · {headOf(current())}

)}
{/* tabindex="-1" so the skip button actually moves focus here */}
} >

History

); }