| .. | .. |
|---|
| 1 | 1 | import React, { useState } from "react"; |
|---|
| 2 | | -import { Pressable, ScrollView, Text, View } from "react-native"; |
|---|
| 3 | | - |
|---|
| 4 | | -interface Command { |
|---|
| 5 | | - label: string; |
|---|
| 6 | | - value: string; |
|---|
| 7 | | -} |
|---|
| 8 | | - |
|---|
| 9 | | -const DEFAULT_COMMANDS: Command[] = [ |
|---|
| 10 | | - { label: "/s", value: "/s" }, |
|---|
| 11 | | - { label: "/ss", value: "/ss" }, |
|---|
| 12 | | - { label: "/clear", value: "/clear" }, |
|---|
| 13 | | - { label: "/help", value: "/help" }, |
|---|
| 14 | | - { label: "/status", value: "/status" }, |
|---|
| 15 | | -]; |
|---|
| 2 | +import { Pressable, Text, View, useWindowDimensions } from "react-native"; |
|---|
| 3 | +import * as Haptics from "expo-haptics"; |
|---|
| 16 | 4 | |
|---|
| 17 | 5 | interface CommandBarProps { |
|---|
| 18 | | - onCommand: (command: string) => void; |
|---|
| 19 | | - commands?: Command[]; |
|---|
| 6 | + onSessions: () => void; |
|---|
| 7 | + onScreenshot: () => void; |
|---|
| 8 | + onHelp: () => void; |
|---|
| 20 | 9 | } |
|---|
| 21 | 10 | |
|---|
| 22 | | -export function CommandBar({ |
|---|
| 23 | | - onCommand, |
|---|
| 24 | | - commands = DEFAULT_COMMANDS, |
|---|
| 25 | | -}: CommandBarProps) { |
|---|
| 26 | | - const [activeCommand, setActiveCommand] = useState<string | null>(null); |
|---|
| 11 | +export function CommandBar({ onSessions, onScreenshot, onHelp }: CommandBarProps) { |
|---|
| 12 | + return ( |
|---|
| 13 | + <View |
|---|
| 14 | + style={{ |
|---|
| 15 | + flexDirection: "row", |
|---|
| 16 | + paddingHorizontal: 12, |
|---|
| 17 | + paddingVertical: 6, |
|---|
| 18 | + gap: 8, |
|---|
| 19 | + }} |
|---|
| 20 | + > |
|---|
| 21 | + <CmdBtn icon="📋" label="Sessions" bg="#1A2744" border="#2E4A7A" onPress={onSessions} /> |
|---|
| 22 | + <CmdBtn icon="📸" label="Screen" bg="#1A3A2A" border="#2E6A4A" onPress={onScreenshot} /> |
|---|
| 23 | + <CmdBtn icon="❓" label="Help" bg="#3A1A2A" border="#6A2E4A" onPress={onHelp} /> |
|---|
| 24 | + </View> |
|---|
| 25 | + ); |
|---|
| 26 | +} |
|---|
| 27 | 27 | |
|---|
| 28 | | - function handlePress(command: Command) { |
|---|
| 29 | | - setActiveCommand(command.value); |
|---|
| 30 | | - onCommand(command.value); |
|---|
| 31 | | - setTimeout(() => setActiveCommand(null), 200); |
|---|
| 32 | | - } |
|---|
| 28 | +interface TextModeCommandBarProps { |
|---|
| 29 | + onSessions: () => void; |
|---|
| 30 | + onScreenshot: () => void; |
|---|
| 31 | + onNavigate: () => void; |
|---|
| 32 | + onClear: () => void; |
|---|
| 33 | +} |
|---|
| 34 | + |
|---|
| 35 | +export function TextModeCommandBar({ |
|---|
| 36 | + onSessions, |
|---|
| 37 | + onScreenshot, |
|---|
| 38 | + onNavigate, |
|---|
| 39 | + onClear, |
|---|
| 40 | +}: TextModeCommandBarProps) { |
|---|
| 41 | + return ( |
|---|
| 42 | + <View |
|---|
| 43 | + style={{ |
|---|
| 44 | + flexDirection: "row", |
|---|
| 45 | + paddingHorizontal: 12, |
|---|
| 46 | + paddingVertical: 6, |
|---|
| 47 | + gap: 8, |
|---|
| 48 | + }} |
|---|
| 49 | + > |
|---|
| 50 | + <CmdBtn icon="📋" label="Sessions" bg="#1A2744" border="#2E4A7A" onPress={onSessions} /> |
|---|
| 51 | + <CmdBtn icon="📸" label="Screen" bg="#1A3A2A" border="#2E6A4A" onPress={onScreenshot} /> |
|---|
| 52 | + <CmdBtn icon="🧭" label="Navigate" bg="#2A2A1A" border="#5A5A2E" onPress={onNavigate} /> |
|---|
| 53 | + <CmdBtn icon="🗑" label="Clear" bg="#3A1A1A" border="#6A2E2E" onPress={onClear} /> |
|---|
| 54 | + </View> |
|---|
| 55 | + ); |
|---|
| 56 | +} |
|---|
| 57 | + |
|---|
| 58 | +function CmdBtn({ |
|---|
| 59 | + icon, |
|---|
| 60 | + label, |
|---|
| 61 | + bg, |
|---|
| 62 | + border, |
|---|
| 63 | + onPress, |
|---|
| 64 | +}: { |
|---|
| 65 | + icon: string; |
|---|
| 66 | + label: string; |
|---|
| 67 | + bg: string; |
|---|
| 68 | + border: string; |
|---|
| 69 | + onPress: () => void; |
|---|
| 70 | +}) { |
|---|
| 71 | + const [pressed, setPressed] = useState(false); |
|---|
| 72 | + const { width } = useWindowDimensions(); |
|---|
| 33 | 73 | |
|---|
| 34 | 74 | return ( |
|---|
| 35 | | - <View className="border-t border-pai-border"> |
|---|
| 36 | | - <ScrollView |
|---|
| 37 | | - horizontal |
|---|
| 38 | | - showsHorizontalScrollIndicator={false} |
|---|
| 39 | | - contentContainerStyle={{ paddingHorizontal: 12, paddingVertical: 8, gap: 8 }} |
|---|
| 75 | + <View style={{ flex: 1 }}> |
|---|
| 76 | + <Pressable |
|---|
| 77 | + onPressIn={() => setPressed(true)} |
|---|
| 78 | + onPressOut={() => setPressed(false)} |
|---|
| 79 | + onPress={() => { |
|---|
| 80 | + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); |
|---|
| 81 | + onPress(); |
|---|
| 82 | + }} |
|---|
| 40 | 83 | > |
|---|
| 41 | | - {commands.map((cmd) => ( |
|---|
| 42 | | - <Pressable |
|---|
| 43 | | - key={cmd.value} |
|---|
| 44 | | - onPress={() => handlePress(cmd)} |
|---|
| 45 | | - className="rounded-full px-4 py-2" |
|---|
| 46 | | - style={({ pressed }) => ({ |
|---|
| 47 | | - backgroundColor: |
|---|
| 48 | | - activeCommand === cmd.value || pressed |
|---|
| 49 | | - ? "#4A9EFF" |
|---|
| 50 | | - : "#1E1E2E", |
|---|
| 51 | | - })} |
|---|
| 52 | | - > |
|---|
| 53 | | - <Text |
|---|
| 54 | | - className="text-sm font-medium" |
|---|
| 55 | | - style={{ |
|---|
| 56 | | - color: |
|---|
| 57 | | - activeCommand === cmd.value ? "#FFFFFF" : "#9898B0", |
|---|
| 58 | | - }} |
|---|
| 59 | | - > |
|---|
| 60 | | - {cmd.label} |
|---|
| 61 | | - </Text> |
|---|
| 62 | | - </Pressable> |
|---|
| 63 | | - ))} |
|---|
| 64 | | - </ScrollView> |
|---|
| 84 | + <View |
|---|
| 85 | + style={{ |
|---|
| 86 | + height: 68, |
|---|
| 87 | + borderRadius: 16, |
|---|
| 88 | + alignItems: "center", |
|---|
| 89 | + justifyContent: "center", |
|---|
| 90 | + backgroundColor: pressed ? "#4A9EFF" : bg, |
|---|
| 91 | + borderWidth: 1.5, |
|---|
| 92 | + borderColor: pressed ? "#4A9EFF" : border, |
|---|
| 93 | + }} |
|---|
| 94 | + > |
|---|
| 95 | + <Text style={{ fontSize: 26, marginBottom: 2 }}>{icon}</Text> |
|---|
| 96 | + <Text style={{ color: "#C8C8E0", fontSize: 13, fontWeight: "700" }}> |
|---|
| 97 | + {label} |
|---|
| 98 | + </Text> |
|---|
| 99 | + </View> |
|---|
| 100 | + </Pressable> |
|---|
| 65 | 101 | </View> |
|---|
| 66 | 102 | ); |
|---|
| 67 | 103 | } |
|---|