Matthias Nott
2026-03-02 aca79f31767ae6f03f47a284f3d0e80850c5fb02
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
import React, { useCallback } from "react";
import { Pressable, Text, View } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { router } from "expo-router";
import { useChat } from "../contexts/ChatContext";
import { useConnection } from "../contexts/ConnectionContext";
import { MessageList } from "../components/chat/MessageList";
import { InputBar } from "../components/chat/InputBar";
import { CommandBar } from "../components/chat/CommandBar";
import { StatusDot } from "../components/ui/StatusDot";
export default function ChatScreen() {
  const { messages, sendTextMessage, sendVoiceMessage, clearMessages } =
    useChat();
  const { status } = useConnection();
  const handleCommand = useCallback(
    (command: string) => {
      if (command === "/clear") {
        clearMessages();
        return;
      }
      sendTextMessage(command);
    },
    [sendTextMessage, clearMessages]
  );
  const handleSendVoice = useCallback(
    (audioUri: string, durationMs: number) => {
      sendVoiceMessage(audioUri, durationMs);
    },
    [sendVoiceMessage]
  );
  return (
    <SafeAreaView className="flex-1 bg-pai-bg" edges={["top", "bottom"]}>
      {/* Header */}
      <View className="flex-row items-center justify-between px-4 py-3 border-b border-pai-border">
        <Text className="text-pai-text text-xl font-bold tracking-tight">
          PAILot
        </Text>
        <View className="flex-row items-center gap-3">
          <StatusDot status={status} size={10} />
          <Text className="text-pai-text-secondary text-xs">
            {status === "connected"
              ? "Connected"
              : status === "connecting"
              ? "Connecting..."
              : "Offline"}
          </Text>
          <Pressable
            onPress={() => router.push("/settings")}
            className="w-9 h-9 items-center justify-center rounded-full bg-pai-bg-tertiary"
            hitSlop={{ top: 4, bottom: 4, left: 4, right: 4 }}
          >
            <Text className="text-base">⚙️</Text>
          </Pressable>
        </View>
      </View>
      {/* Message list */}
      <View className="flex-1">
        {messages.length === 0 ? (
          <View className="flex-1 items-center justify-center gap-3">
            <Text className="text-5xl">🛩</Text>
            <Text className="text-pai-text text-xl font-semibold">
              PAILot
            </Text>
            <Text className="text-pai-text-muted text-sm text-center px-8">
              Voice-first AI communicator.{"\n"}Hold the mic button to talk.
            </Text>
          </View>
        ) : (
          <MessageList messages={messages} />
        )}
      </View>
      {/* Command bar */}
      <CommandBar onCommand={handleCommand} />
      {/* Input bar */}
      <InputBar onSendText={sendTextMessage} onSendVoice={handleSendVoice} />
    </SafeAreaView>
  );
}