/** * The recents list as the UI sees it. * * Kept beside the graph store rather than inside it: what a repository's * history looks like and which repositories are worth offering are unrelated * concerns that happen to appear on the same screen. */ import { createSignal } from "solid-js"; import { forgetRecentRepository, listRecentRepositories } from "./api"; import { isGigitError, type RecentRepository, type RepositoryId } from "./bindings"; function describe(error: unknown): string { return isGigitError(error) ? error.message : String(error); } export function createRecents() { const [entries, setEntries] = createSignal([]); const [message, setMessage] = createSignal(); /** Fetch the list. Safe to call whenever the list may have changed. */ async function refresh() { try { setEntries(await listRecentRepositories()); } catch (error) { // A recents list that cannot be read is a nuisance, not a failure worth // blocking the app over — the picker still works. setMessage(describe(error)); } } /** Drop one, removing it from the list straight away. */ async function forget(id: RepositoryId) { // Removed locally first: the list is the user's own and waiting on a round // trip to see their own click take effect would feel broken. const before = entries(); setEntries(before.filter((entry) => entry.id !== id)); try { await forgetRecentRepository(id); } catch (error) { setEntries(before); setMessage(describe(error)); } } return { entries, message, refresh, forget }; } export type Recents = ReturnType;