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: 8,
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,
},
});