Эх сурвалжийг харах

fix: keep unknown word on screen instead of wiping it

- submitGuess now returns boolean (true=accepted, false=invalid)
- Screen2Game only clears currentGuess when guess was valid
- Backspace dismisses message but only removes one letter, not whole row
- Player can see what they typed, backspace to fix, retry

Co-Authored-By: Claude <noreply@anthropic.com>
Oleg Panashchenko 2 долоо хоног өмнө
parent
commit
ea6104d0ea

+ 2 - 2
client/src/App.tsx

@@ -54,8 +54,8 @@ export default function App() {
 
   const handleGuess = useCallback(
     async (guess: string) => {
-      if (wordId === null) return;
-      await submitGuess(wordId, guess);
+      if (wordId === null) return false;
+      return submitGuess(wordId, guess);
     },
     [wordId, submitGuess]
   );

+ 4 - 3
client/src/hooks/useGame.ts

@@ -10,7 +10,7 @@ interface UseGameReturn {
   lastDifficulty: number | null;
   revealedWord: string | null;
   replays: SolverReplay[] | null;
-  submitGuess: (wordId: number, guess: string) => Promise<void>;
+  submitGuess: (wordId: number, guess: string) => Promise<boolean>;
   dismissMessage: () => void;
   resetForNewGame: () => void;
 }
@@ -46,14 +46,14 @@ export function useGame(initialGuesses: GuessEntry[]): UseGameReturn {
     if (!res.ok) {
       const body = await res.json().catch(() => ({}));
       setMessage((body as { error?: string }).error ?? `HTTP ${res.status}`);
-      return;
+      return false;
     }
 
     const data: GuessResponse = await res.json();
 
     if (!data.valid) {
       setMessage('Unknown word');
-      return;
+      return false;
     }
 
     const entry: GuessEntry = { guess: lowerGuess, colors: data.colors! };
@@ -68,6 +68,7 @@ export function useGame(initialGuesses: GuessEntry[]): UseGameReturn {
     if (data.replays) {
       setReplays(data.replays);
     }
+    return true;
   }, [guesses.length]);
 
   return { guesses, gameStatus, message, lastDifficulty, revealedWord, replays, submitGuess, dismissMessage, resetForNewGame };

+ 7 - 14
client/src/screens/Screen2Game.tsx

@@ -7,7 +7,7 @@ interface Screen2GameProps {
   guesses: GuessEntry[];
   letterColors: Record<string, string | undefined>;
   message: string | null;
-  onGuess: (guess: string) => Promise<void>;
+  onGuess: (guess: string) => Promise<boolean>;
   onDismissMessage: () => void;
   gameOver: boolean;
 }
@@ -24,8 +24,10 @@ export function Screen2Game({ guesses, letterColors, message, onGuess, onDismiss
 
   const submitCurrent = useCallback(async () => {
     if (currentGuess.length !== 5 || gameOver) return;
-    await onGuess(currentGuess);
-    setCurrentGuess(''); // clear on valid submission
+    const accepted = await onGuess(currentGuess);
+    if (accepted) {
+      setCurrentGuess(''); // only clear when guess was valid
+    }
   }, [currentGuess, onGuess, gameOver]);
 
   // Physical keyboard handler
@@ -38,12 +40,7 @@ export function Screen2Game({ guesses, letterColors, message, onGuess, onDismiss
         return;
       }
       if (e.key === 'Backspace') {
-        // If there's a message (invalid word), clear the whole row
-        if (message) {
-          onDismissMessage();
-          setCurrentGuess('');
-          return;
-        }
+        if (message) onDismissMessage();
         setCurrentGuess((prev) => prev.slice(0, -1));
         return;
       }
@@ -63,11 +60,7 @@ export function Screen2Game({ guesses, letterColors, message, onGuess, onDismiss
       if (key === 'Enter') {
         submitCurrent();
       } else if (key === 'Backspace') {
-        if (message) {
-          onDismissMessage();
-          setCurrentGuess('');
-          return;
-        }
+        if (message) onDismissMessage();
         setCurrentGuess((prev) => prev.slice(0, -1));
       } else if (currentGuess.length < 5) {
         setCurrentGuess((prev) => prev + key.toLowerCase());