import { useGameMeta } from "../state/gameMeta.tsx"; import type { LaneId } from "../../shared/custom.ts"; /** * One game at a time. * * The settings panel already lets a reader switch games on and off, but that is * a different job: it says which games they play, and it is set once. This is * the thing a reader does *while reading* — clear the deck down to one game, * finish it, move to the next. Doing that with the on/off switches means two * taps per game and a settings panel that no longer describes what they play. * * So focus is a lens, not a setting: it never changes which games are switched * on, "All" is always one tap away, and the rotation ends by returning to All * rather than looping forever. */ export function GameFocus({ games, focus, counts, total, next, onFocus, onAdvance, }: { /** Games the reader has switched on, in feed order. */ games: LaneId[]; focus: LaneId | null; /** Outstanding rows per game, so a chip says whether it is worth a visit. */ counts: Partial>; total: number; /** Where "next" goes — null means back to all games. */ next: LaneId | null; onFocus: (game: LaneId | null) => void; onAdvance: () => void; }) { const gameMeta = useGameMeta(); // With one game there is nothing to focus down to, and the bar would just be // a chip that does nothing. if (games.length < 2) return null; return (

Focus

{/* A scrolling strip where the bar is as wide as the page, wrapped rows where it is a 20rem rail: a thirteen-game reader would otherwise get four chips and a hairline scrollbar, and a game you cannot see is a game you will not focus. The rail is short and the list beside it is long, so the rows cost nothing that column was using. */}
onFocus(null)} /> {games.map((id) => { const game = gameMeta(id); return ( onFocus(focus === id ? null : id)} /> ); })}
); } /** * A game chip. * * Carries its hue whether or not it is selected — dimmer when it is not — so * the row reads as a set of games at a glance rather than as one coloured chip * among a row of grey ones. The count is what makes it worth tapping: a game * with nothing outstanding says so before you visit it. */ function Chip({ label, ariaLabel, count, on, hue, onClick, }: { label: string; ariaLabel?: string | undefined; count: number; on: boolean; hue: string; onClick: () => void; }) { return ( ); }