/** * 完整示例页面 * 展示所有工具的使用方法 */ import React, { useState, useEffect } from 'react'; import { StyleSheet, View, Text, TextInput, TouchableOpacity, ScrollView, Switch, Alert, ActivityIndicator, } from 'react-native'; import { useForm, Controller } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { Image } from 'expo-image'; // 导入所有工具 import { // 工具函数 Storage, STORAGE_KEYS, formatDate, formatRelativeTime, formatChatTime, // 状态管理 useUserStore, useUser, useIsLoggedIn, useSettingsStore, useTheme, useLanguage, useHapticsEnabled, // 验证规则 loginSchema, type LoginFormData, // API 服务 authService, // 自定义 Hooks useDebounce, useThrottle, useHaptics, } from '@/src'; export default function DemoScreen() { const haptics = useHaptics(); // 状态管理示例 const user = useUser(); const isLoggedIn = useIsLoggedIn(); const login = useUserStore((state) => state.login); const logout = useUserStore((state) => state.logout); // 设置状态 const theme = useTheme(); const language = useLanguage(); const hapticsEnabled = useHapticsEnabled(); const setTheme = useSettingsStore((state) => state.setTheme); const setLanguage = useSettingsStore((state) => state.setLanguage); const setHapticsEnabled = useSettingsStore((state) => state.setHapticsEnabled); // 本地状态 const [searchText, setSearchText] = useState(''); const [searchResults, setSearchResults] = useState([]); const [loading, setLoading] = useState(false); const [counter, setCounter] = useState(0); const [storageValue, setStorageValue] = useState(''); // 表单配置 const { control, handleSubmit, formState: { errors }, } = useForm({ resolver: zodResolver(loginSchema), defaultValues: { email: '', password: '', }, }); // 防抖搜索示例 const debouncedSearch = useDebounce(async (text: string) => { if (!text.trim()) { setSearchResults([]); return; } console.log('执行搜索:', text); // 模拟 API 调用 await new Promise((resolve) => setTimeout(resolve, 500)); setSearchResults([ `结果 1: ${text}`, `结果 2: ${text}`, `结果 3: ${text}`, ]); }, 500); // 监听搜索文本变化 useEffect(() => { debouncedSearch(searchText); }, [searchText]); // 节流点击示例 const throttledClick = useThrottle(() => { haptics.light(); setCounter((prev) => prev + 1); console.log('节流点击:', counter + 1); }, 1000); // 登录处理 const onLogin = async (data: LoginFormData) => { try { setLoading(true); haptics.light(); // 模拟登录 API 调用 console.log('登录数据:', data); // 实际项目中使用: // const { user, token } = await authService.login(data); // login(user, token); // 模拟登录成功 const mockUser = { id: '1', username: data.email.split('@')[0], email: data.email, avatar: 'https://i.pravatar.cc/150?img=1', nickname: '演示用户', createdAt: new Date().toISOString(), }; login(mockUser, 'mock-token-123456'); haptics.success(); Alert.alert('成功', '登录成功!'); } catch (error: any) { haptics.error(); Alert.alert('失败', error.message || '登录失败'); } finally { setLoading(false); } }; // 登出处理 const handleLogout = () => { haptics.warning(); Alert.alert( '确认', '确定要退出登录吗?', [ { text: '取消', style: 'cancel' }, { text: '确定', onPress: () => { logout(); haptics.success(); }, }, ] ); }; // 存储示例 const handleSaveToStorage = async () => { try { haptics.light(); const testData = { message: 'Hello from AsyncStorage!', timestamp: new Date().toISOString(), counter, }; await Storage.setObject(STORAGE_KEYS.USER_PREFERENCES, testData); haptics.success(); Alert.alert('成功', '数据已保存到本地存储'); } catch (error) { haptics.error(); Alert.alert('失败', '保存失败'); } }; const handleLoadFromStorage = async () => { try { haptics.light(); const data = await Storage.getObject(STORAGE_KEYS.USER_PREFERENCES); if (data) { setStorageValue(JSON.stringify(data, null, 2)); haptics.success(); } else { setStorageValue('暂无数据'); haptics.warning(); } } catch (error) { haptics.error(); Alert.alert('失败', '读取失败'); } }; // 主题切换 const handleThemeChange = () => { haptics.selection(); const themes: Array<'light' | 'dark' | 'auto'> = ['light', 'dark', 'auto']; const currentIndex = themes.indexOf(theme); const nextTheme = themes[(currentIndex + 1) % themes.length]; setTheme(nextTheme); }; // 语言切换 const handleLanguageChange = () => { haptics.selection(); setLanguage(language === 'zh-CN' ? 'en-US' : 'zh-CN'); }; return ( {/* 标题 */} 🎯 完整功能演示 展示所有工具的使用方法 {/* 用户状态显示 */} 👤 用户状态 (Zustand) {isLoggedIn ? ( {user?.avatar && ( )} {user?.nickname} {user?.email} 注册时间: {formatRelativeTime(user?.createdAt || '')} 退出 ) : ( 未登录 )} {/* 登录表单 */} {!isLoggedIn && ( 🔐 登录表单 (React Hook Form + Zod) ( 邮箱 {errors.email && ( {errors.email.message} )} )} /> ( 密码 {errors.password && ( {errors.password.message} )} )} /> {loading ? ( ) : ( 登录 )} )} {/* 搜索示例 */} 🔍 防抖搜索 (useDebounce) {searchResults.length > 0 && ( {searchResults.map((result, index) => ( {result} ))} )} {/* 节流点击示例 */} ⏱️ 节流点击 (useThrottle) 点击次数: {counter} 快速点击测试(1秒节流) {/* 本地存储示例 */} 💾 本地存储 (AsyncStorage) 保存数据 读取数据 {storageValue && ( {storageValue} )} {/* 日期格式化示例 */} 📅 日期格式化 (Day.js) 当前时间: {formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss')} 相对时间: {formatRelativeTime(new Date())} 聊天时间: {formatChatTime(Date.now())} {/* 设置示例 */} ⚙️ 应用设置 主题: {theme} 切换 语言: {language} 切换 触觉反馈 { haptics.selection(); setHapticsEnabled(value); }} /> {/* 触觉反馈示例 */} 📳 触觉反馈 (Expo Haptics) haptics.light()} > Light haptics.medium()} > Medium haptics.heavy()} > Heavy haptics.success()} > Success haptics.warning()} > Warning haptics.error()} > Error 查看代码了解更多使用方法 📖 ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f5f5f5', }, content: { padding: 16, }, title: { fontSize: 28, fontWeight: 'bold', marginBottom: 8, color: '#333', }, subtitle: { fontSize: 16, color: '#666', marginBottom: 24, }, section: { backgroundColor: '#fff', borderRadius: 12, padding: 16, marginBottom: 16, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3, }, sectionTitle: { fontSize: 18, fontWeight: '600', marginBottom: 12, color: '#333', }, userInfo: { flexDirection: 'row', alignItems: 'center', }, avatar: { width: 60, height: 60, borderRadius: 30, marginRight: 12, }, userDetails: { flex: 1, }, userName: { fontSize: 16, fontWeight: '600', color: '#333', }, userEmail: { fontSize: 14, color: '#666', marginTop: 2, }, userDate: { fontSize: 12, color: '#999', marginTop: 4, }, inputGroup: { marginBottom: 16, }, label: { fontSize: 14, fontWeight: '500', marginBottom: 6, color: '#333', }, input: { borderWidth: 1, borderColor: '#ddd', borderRadius: 8, padding: 12, fontSize: 16, backgroundColor: '#fff', }, inputError: { borderColor: '#ff3b30', }, errorText: { color: '#ff3b30', fontSize: 12, marginTop: 4, }, button: { paddingVertical: 12, paddingHorizontal: 20, borderRadius: 8, alignItems: 'center', justifyContent: 'center', }, buttonText: { color: '#fff', fontSize: 16, fontWeight: '600', }, loginButton: { backgroundColor: '#007AFF', marginTop: 8, }, logoutButton: { backgroundColor: '#ff3b30', paddingVertical: 8, paddingHorizontal: 16, }, primaryButton: { backgroundColor: '#007AFF', }, secondaryButton: { backgroundColor: '#5856D6', }, smallButton: { backgroundColor: '#007AFF', paddingVertical: 8, paddingHorizontal: 16, }, buttonRow: { flexDirection: 'row', gap: 12, }, halfButton: { flex: 1, }, searchResults: { marginTop: 12, }, searchResult: { padding: 12, backgroundColor: '#f9f9f9', borderRadius: 8, marginBottom: 8, color: '#333', }, infoText: { fontSize: 14, color: '#666', marginBottom: 8, }, codeBlock: { backgroundColor: '#f9f9f9', borderRadius: 8, padding: 12, marginTop: 12, }, codeText: { fontFamily: 'monospace', fontSize: 12, color: '#333', }, settingRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12, }, settingLabel: { fontSize: 16, color: '#333', }, buttonGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, }, hapticsButton: { backgroundColor: '#5856D6', flex: 1, minWidth: '30%', }, successButton: { backgroundColor: '#34C759', flex: 1, minWidth: '30%', }, warningButton: { backgroundColor: '#FF9500', flex: 1, minWidth: '30%', }, errorButton: { backgroundColor: '#FF3B30', flex: 1, minWidth: '30%', }, footer: { marginTop: 24, marginBottom: 40, alignItems: 'center', }, footerText: { fontSize: 14, color: '#999', }, });