import { Ionicons } from '@expo/vector-icons'; import { useRouter } from 'expo-router'; import { useState } from 'react'; import { ActivityIndicator, KeyboardAvoidingView, Platform, Pressable, ScrollView, StyleSheet, Text, TextInput, View, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useLegalData } from '../../src/hooks'; import { colors } from '../../src/theme'; import type { LegalMessage } from '../../src/types'; /* ===================== 子组件:顶部导航 ===================== */ function Header({ onBack }: { onBack: () => void }) { return ( 阿布阿诺法律咨询 ); } /* ===================== 子组件:消息气泡 ===================== */ function MessageBubble({ message }: { message: LegalMessage }) { const isUser = message.role === 'user'; return ( {!isUser && ( 诺 )} {message.content} ); } /* ===================== 页面 ===================== */ export default function LegalChatScreen() { const router = useRouter(); const { conversation, loading, error, refresh, sendMessage } = useLegalData(); const [input, setInput] = useState(''); const [sending, setSending] = useState(false); const handleSend = async () => { const text = input.trim(); if (!text || sending) return; setSending(true); setInput(''); try { await sendMessage(text); } finally { setSending(false); } }; return (
router.back()} /> {loading ? ( ) : error ? ( 加载失败,请重试 重试 ) : ( 阿布阿诺 AI 法律助手仅供参考,复杂问题建议升级到一对一律师咨询。 {conversation?.messages.map((message) => ( ))} )} ); } const styles = StyleSheet.create({ safeArea: { flex: 1, backgroundColor: colors.pageBg, }, flex: { flex: 1, }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 8, height: 48, backgroundColor: colors.white, borderBottomWidth: 1, borderBottomColor: colors.borderLight, }, headerBtn: { width: 40, height: 40, alignItems: 'center', justifyContent: 'center', }, headerTitle: { fontSize: 17, fontWeight: '700', color: colors.textPrimary, }, scroll: { flex: 1, }, scrollContent: { padding: 8, paddingBottom: 16, }, tipCard: { flexDirection: 'row', alignItems: 'center', gap: 8, backgroundColor: colors.infoLight, borderRadius: 8, padding: 10, marginBottom: 8, }, tipText: { flex: 1, fontSize: 12, lineHeight: 17, color: colors.infoText, }, bubbleWrap: { flexDirection: 'row', alignItems: 'flex-end', marginBottom: 10, }, bubbleWrapLeft: { justifyContent: 'flex-start', }, bubbleWrapRight: { justifyContent: 'flex-end', }, avatar: { width: 32, height: 32, borderRadius: 16, backgroundColor: colors.primary, alignItems: 'center', justifyContent: 'center', marginRight: 8, }, avatarText: { fontSize: 13, fontWeight: '700', color: colors.white, }, bubble: { maxWidth: '76%', paddingHorizontal: 12, paddingVertical: 10, borderRadius: 12, }, bubbleUser: { backgroundColor: colors.primary, borderBottomRightRadius: 4, }, bubbleAssistant: { backgroundColor: colors.white, borderBottomLeftRadius: 4, }, bubbleText: { fontSize: 14, lineHeight: 20, }, bubbleTextUser: { color: colors.white, }, bubbleTextAssistant: { color: colors.textPrimary, }, inputBar: { flexDirection: 'row', alignItems: 'center', gap: 8, paddingHorizontal: 8, paddingVertical: 10, backgroundColor: colors.white, borderTopWidth: 1, borderTopColor: colors.borderLight, }, input: { flex: 1, maxHeight: 100, minHeight: 40, borderRadius: 20, borderWidth: 1, borderColor: colors.border, paddingHorizontal: 14, paddingVertical: 8, fontSize: 14, color: colors.textPrimary, backgroundColor: colors.pageBg, }, sendBtn: { width: 40, height: 40, borderRadius: 20, alignItems: 'center', justifyContent: 'center', backgroundColor: colors.primaryBtn, }, sendBtnDisabled: { opacity: 0.5, }, stateBox: { flex: 1, alignItems: 'center', justifyContent: 'center', }, stateText: { marginTop: 12, fontSize: 14, color: colors.textSecondary, }, retryBtn: { marginTop: 16, paddingHorizontal: 24, paddingVertical: 8, borderRadius: 18, backgroundColor: colors.primaryBtn, }, retryText: { fontSize: 13, fontWeight: '600', color: colors.white, }, });