|
1 | | -import { Text, View } from "react-native"; |
| 1 | +import { useState } from "react"; |
| 2 | +import { |
| 3 | + KeyboardAvoidingView, |
| 4 | + Platform, |
| 5 | + Text, |
| 6 | + TextInput, |
| 7 | + TouchableOpacity, |
| 8 | + View, |
| 9 | +} from "react-native"; |
2 | 10 | import { SafeAreaView } from "react-native-safe-area-context"; |
3 | | -import { type Message, MessagesList } from "../components/MessagesList"; |
4 | | - |
5 | | -// Sample messages for demo |
6 | | -const SAMPLE_MESSAGES: Message[] = [ |
7 | | - { id: "1", text: "Hello!" }, |
8 | | - { id: "2", text: "How can I help you today?" }, |
9 | | - { id: "3", text: "Welcome to the chat." }, |
10 | | -]; |
| 11 | +import { MessagesList } from "../components/MessagesList"; |
| 12 | +import { useMaxStore } from "../stores/maxStore"; |
11 | 13 |
|
12 | 14 | export default function ChatScreen() { |
| 15 | + const [inputText, setInputText] = useState(""); |
| 16 | + const { thread, streamingActive, askMax, stopGeneration, resetThread } = |
| 17 | + useMaxStore(); |
| 18 | + |
| 19 | + const handleSend = async () => { |
| 20 | + const trimmed = inputText.trim(); |
| 21 | + if (!trimmed || streamingActive) return; |
| 22 | + |
| 23 | + setInputText(""); |
| 24 | + await askMax(trimmed); |
| 25 | + }; |
| 26 | + |
| 27 | + const handleStop = () => { |
| 28 | + stopGeneration(); |
| 29 | + }; |
| 30 | + |
13 | 31 | return ( |
14 | | - <SafeAreaView className="flex-1 bg-dark-bg"> |
15 | | - {/* Header */} |
16 | | - <View className="border-dark-border border-b px-6 pt-4 pb-2"> |
17 | | - <Text className="font-bold text-white text-xl">Chat</Text> |
18 | | - </View> |
| 32 | + <SafeAreaView |
| 33 | + className="flex-1 bg-dark-bg" |
| 34 | + edges={["top", "left", "right"]} |
| 35 | + > |
| 36 | + <KeyboardAvoidingView |
| 37 | + behavior={Platform.OS === "ios" ? "padding" : "height"} |
| 38 | + className="flex-1" |
| 39 | + keyboardVerticalOffset={0} |
| 40 | + > |
| 41 | + {/* Header */} |
| 42 | + <View className="flex-row items-center justify-between border-dark-border border-b px-6 pt-4 pb-2"> |
| 43 | + <Text className="font-bold text-white text-xl">Max</Text> |
| 44 | + {thread.length > 0 && ( |
| 45 | + <TouchableOpacity onPress={resetThread}> |
| 46 | + <Text className="text-blue-500">New chat</Text> |
| 47 | + </TouchableOpacity> |
| 48 | + )} |
| 49 | + </View> |
| 50 | + |
| 51 | + {/* Messages */} |
| 52 | + <View className="flex-1"> |
| 53 | + <MessagesList messages={thread} isLoading={streamingActive} /> |
| 54 | + </View> |
19 | 55 |
|
20 | | - {/* Messages */} |
21 | | - <View className="flex-1"> |
22 | | - <MessagesList messages={SAMPLE_MESSAGES} /> |
23 | | - </View> |
| 56 | + {/* Input area */} |
| 57 | + <View className="border-dark-border border-t px-4 py-3"> |
| 58 | + <View className="flex-row items-end gap-2"> |
| 59 | + <TextInput |
| 60 | + className="max-h-[120px] min-h-[44px] flex-1 rounded-2xl bg-dark-border px-4 py-3 text-base text-white" |
| 61 | + placeholder="Ask Max..." |
| 62 | + placeholderTextColor="#6B7280" |
| 63 | + value={inputText} |
| 64 | + onChangeText={setInputText} |
| 65 | + onSubmitEditing={handleSend} |
| 66 | + multiline |
| 67 | + editable={!streamingActive} |
| 68 | + returnKeyType="send" |
| 69 | + blurOnSubmit={false} |
| 70 | + /> |
| 71 | + {streamingActive ? ( |
| 72 | + <TouchableOpacity |
| 73 | + onPress={handleStop} |
| 74 | + className="h-11 w-11 items-center justify-center rounded-full bg-red-600" |
| 75 | + > |
| 76 | + <View className="h-4 w-4 rounded-sm bg-white" /> |
| 77 | + </TouchableOpacity> |
| 78 | + ) : ( |
| 79 | + <TouchableOpacity |
| 80 | + onPress={handleSend} |
| 81 | + disabled={!inputText.trim()} |
| 82 | + className={`h-11 w-11 items-center justify-center rounded-full ${ |
| 83 | + inputText.trim() ? "bg-blue-600" : "bg-dark-border" |
| 84 | + }`} |
| 85 | + > |
| 86 | + <Text className="text-lg text-white">↑</Text> |
| 87 | + </TouchableOpacity> |
| 88 | + )} |
| 89 | + </View> |
| 90 | + </View> |
| 91 | + </KeyboardAvoidingView> |
24 | 92 | </SafeAreaView> |
25 | 93 | ); |
26 | 94 | } |
0 commit comments