Fix frontend UX: debounce saves, Zustand selectors, init race, dialog

- Debounce project config saves: use local state + save-on-blur instead
  of firing IPC requests on every keystroke in text inputs
- Add Zustand selectors to all store consumers to prevent full-store
  re-renders on any state change
- Fix initialization race: chain checkImage after checkDocker resolves
- Fix DockerSettings setTimeout race: await checkImage after save
- Add console.error logging to all 11 empty catch blocks in ProjectCard
- Add keyboard support to AddProjectDialog: Escape to close,
  click-outside-to-close, form submit on Enter, auto-focus

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-28 20:42:40 +00:00
parent a03bdccdc7
commit 82f159d2a9
12 changed files with 370 additions and 114 deletions

View File

@@ -1,10 +1,18 @@
import { useCallback } from "react";
import { useShallow } from "zustand/react/shallow";
import { useAppState } from "../store/appState";
import * as commands from "../lib/tauri-commands";
import type { AppSettings } from "../lib/types";
export function useSettings() {
const { hasKey, setHasKey, appSettings, setAppSettings } = useAppState();
const { hasKey, setHasKey, appSettings, setAppSettings } = useAppState(
useShallow(s => ({
hasKey: s.hasKey,
setHasKey: s.setHasKey,
appSettings: s.appSettings,
setAppSettings: s.setAppSettings,
}))
);
const checkApiKey = useCallback(async () => {
try {