feat(ui): move game folder picker into settings

The design update moved game-folder configuration out of launcher chrome and
into Settings > Library. Follow that contract in the runtime UI without
changing the existing storage or Tauri directory commands.

The top bar now leaves its right edge for the kebab menu. Settings owns a new
Game folder row that shows a valid selected path with a neutral Change button,
or the red Not set state with a stronger Choose button when no accessible
directory is configured. Both the empty-library state and the Settings row
still use the existing native directory picker, so existing saved paths and
rescans keep their current behavior.

Keep useGameDirectory as the directory-state owner and expose the shared
hasGameDirectory boolean from that hook so the grid and Settings field agree on
what counts as configured.

Test Plan:
- git diff --cached --check
- just frontend-test
- just build

Refs: 62b409f4bfc4995c25461776107d28f52b24f30e
This commit is contained in:
2026-05-21 20:42:12 +02:00
parent eedfc0105d
commit 2e7a0cff2f
6 changed files with 128 additions and 82 deletions
@@ -45,7 +45,7 @@ const openLogsWindow = async () => {
export const MainWindow = () => {
const { settings, set: setSetting } = useSettings();
const { gameDir, gameDirExists, setGameDir, rescan } = useGameDirectory();
const { gameDir, hasGameDirectory, setGameDir, rescan } = useGameDirectory();
const games = useGames(rescan);
const actions = useGameActions(games, settings);
const thumbnails = useThumbnails();
@@ -53,8 +53,6 @@ export const MainWindow = () => {
const [openGameId, setOpenGameId] = useState<string | null>(null);
const [removeGameId, setRemoveGameId] = useState<string | null>(null);
const [settingsOpen, setSettingsOpen] = useState(false);
const hasGameDirectory = !!gameDir.trim() && gameDirExists;
const visibleGames = useMemo(
() => hasGameDirectory ? games.games : [],
[games.games, hasGameDirectory],
@@ -130,9 +128,6 @@ export const MainWindow = () => {
setQuery={setQuery}
sort={settings.sort}
setSort={(v) => setSetting('sort', v)}
gameDir={gameDir}
gameDirExists={gameDirExists}
onPickDirectory={() => void pickDirectory()}
kebabItems={kebabItems}
/>
<main className="grid-wrap">
@@ -192,6 +187,9 @@ export const MainWindow = () => {
{settingsOpen && (
<SettingsDialog
settings={settings}
gameDir={gameDir}
hasGameDirectory={hasGameDirectory}
onPickDirectory={() => void pickDirectory()}
onChange={setSetting}
onClose={() => setSettingsOpen(false)}
/>