File size: 3,956 Bytes
8725cc4
 
 
0ce34cb
8725cc4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ce34cb
 
8725cc4
0ce34cb
 
 
 
 
 
 
 
8725cc4
 
 
 
 
 
0ce34cb
 
 
 
 
 
 
 
 
8725cc4
 
 
769c038
 
 
 
 
 
 
 
0ce34cb
8725cc4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ce34cb
 
 
 
 
 
 
 
 
8725cc4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
769c038
8725cc4
0ce34cb
8725cc4
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { motion } from "framer-motion";
import { KeyboardEvent, useRef, useEffect, useState } from "react";

interface SentenceBuilderProps {
  currentWord: string;
  successfulRounds: number;
  sentence: string[];
  playerInput: string;
  isAiThinking: boolean;
  onInputChange: (value: string) => void;
  onSubmitWord: (e: React.FormEvent) => void;
  onMakeGuess: () => void;
}

export const SentenceBuilder = ({
  currentWord,
  successfulRounds,
  sentence,
  playerInput,
  isAiThinking,
  onInputChange,
  onSubmitWord,
  onMakeGuess,
}: SentenceBuilderProps) => {
  const inputRef = useRef<HTMLInputElement>(null);
  const [imageLoaded, setImageLoaded] = useState(false);
  const imagePath = `/think_in_sync_assets/${currentWord.toLowerCase()}.jpg`;

  useEffect(() => {
    const img = new Image();
    img.onload = () => setImageLoaded(true);
    img.src = imagePath;
    console.log("Attempting to load image:", imagePath);
  }, [imagePath]);

  // Focus input on initial render
  useEffect(() => {
    setTimeout(() => {
      inputRef.current?.focus();
    }, 100);
  }, []);

  // Focus input after AI finishes thinking
  useEffect(() => {
    if (!isAiThinking && sentence.length > 0 && sentence.length % 2 === 0) {
      setTimeout(() => {
        inputRef.current?.focus();
      }, 100);
    }
  }, [isAiThinking, sentence.length]);

  const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
    if (e.shiftKey && e.key === 'Enter') {
      e.preventDefault();
      if (playerInput.trim()) {
        // Create a synthetic form event to add the current word
        const syntheticEvent = {
          preventDefault: () => {},
        } as React.FormEvent;
        onSubmitWord(syntheticEvent);
      }
      // Make the guess immediately without waiting for AI response
      onMakeGuess();
    }
  };

  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      className="text-center"
    >
      <h2 className="mb-4 text-2xl font-semibold text-gray-900">
        Build a Description
      </h2>
      <p className="mb-6 text-sm text-gray-600">
        Take turns with AI to describe your word without using the word itself!
      </p>
      <div className="mb-4 overflow-hidden rounded-lg bg-secondary/10">
        {imageLoaded && (
          <img
            src={imagePath}
            alt={currentWord}
            className="mx-auto h-48 w-full object-cover"
          />
        )}
        <p className="p-4 text-2xl font-bold tracking-wider text-secondary">
          {currentWord}
        </p>
      </div>
      <div className="mb-6 rounded-lg bg-gray-50 p-4">
        <p className="text-lg text-gray-800">
          {sentence.length > 0 ? sentence.join(" ") : "Start your sentence..."}
        </p>
      </div>
      <form onSubmit={onSubmitWord} className="mb-4">
        <Input
          ref={inputRef}
          type="text"
          value={playerInput}
          onChange={(e) => onInputChange(e.target.value.replace(/\s/g, ''))}
          onKeyDown={handleKeyDown}
          placeholder="Enter your word..."
          className="mb-4"
          disabled={isAiThinking}
        />
        <div className="flex gap-4">
          <Button
            type="submit"
            className="flex-1 bg-primary text-lg hover:bg-primary/90"
            disabled={!playerInput.trim() || isAiThinking}
          >
            {isAiThinking ? "AI is thinking..." : "Add Word ⏎"}
          </Button>
          <Button
            type="button"
            onClick={onMakeGuess}
            className="flex-1 bg-secondary text-lg hover:bg-secondary/90"
            disabled={(!sentence.length && !playerInput.trim()) || isAiThinking}
          >
            {isAiThinking ? "AI is thinking..." : "Make AI Guess ⇧⏎"}
          </Button>
        </div>
      </form>
    </motion.div>
  );
};