import { ThemedText } from '@/components/ThemedText'; import { ThemedView } from '@/components/ThemedView'; import { getTokenStatusDescription, isPushNotificationAvailable, usePushNotifications } from '@/hooks/usePushNotifications'; import { useThemeColor } from '@/hooks/useThemeColor'; import { TokenStatus } from '@/services/pushNotificationManager'; import React, { useEffect, useState } from 'react'; import { ActivityIndicator, Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; export default function PushNotificationSettingsScreen() { const backgroundColor = useThemeColor({}, 'background'); const textColor = useThemeColor({}, 'text'); const borderColor = useThemeColor({}, 'border'); const primaryColor = useThemeColor({}, 'primary'); const { isInitialized, tokenStatus, isLoading, registerToken, getCurrentToken, updateTokenStatus, clearAllData, } = usePushNotifications(); const [isRegistering, setIsRegistering] = useState(false); const [currentToken, setCurrentToken] = useState(null); useEffect(() => { updateTokenStatus(); setCurrentToken(getCurrentToken()); }, [isInitialized, tokenStatus]); const handleRegisterToken = async () => { setIsRegistering(true); try { const success = await registerToken(); if (success) { Alert.alert('成功', '设备令牌注册成功'); } else { Alert.alert('失败', '设备令牌注册失败,请检查网络连接和权限设置'); } } catch (error) { console.error('注册设备令牌失败:', error); Alert.alert('错误', '注册设备令牌时发生错误'); } finally { setIsRegistering(false); } }; const handleClearData = () => { Alert.alert( '确认清除', '这将清除所有本地推送通知数据,包括设备令牌。确定要继续吗?', [ { text: '取消', style: 'cancel' }, { text: '确定', style: 'destructive', onPress: async () => { try { await clearAllData(); Alert.alert('成功', '推送通知数据已清除'); } catch (error) { console.error('清除数据失败:', error); Alert.alert('错误', '清除数据时发生错误'); } }, }, ] ); }; const copyTokenToClipboard = () => { if (currentToken) { // 这里可以使用 Clipboard API 复制到剪贴板 Alert.alert('令牌已复制', '设备令牌已复制到剪贴板(功能待实现)'); } }; const getStatusColor = () => { switch (tokenStatus) { case TokenStatus.REGISTERED: return '#4CAF50'; case TokenStatus.GRANTED: return '#2196F3'; case TokenStatus.DENIED: return '#F44336'; case TokenStatus.FAILED: return '#FF9800'; default: return '#9E9E9E'; } }; if (isLoading) { return ( 加载推送通知设置... ); } return ( 推送通知设置 管理您的推送通知权限和设备令牌 状态信息 初始化状态: {isInitialized ? '已初始化' : '未初始化'} 令牌状态: {getTokenStatusDescription(tokenStatus)} 推送可用: {isPushNotificationAvailable(tokenStatus) ? '是' : '否'} {currentToken && ( 设备令牌 {currentToken.substring(0, 20)}...{currentToken.substring(currentToken.length - 10)} 复制 )} 操作 {isRegistering ? ( ) : ( 注册设备令牌 )} updateTokenStatus()} > 刷新状态 清除所有数据 说明 • 推送通知需要在真实iOS设备上使用{'\n'} • 设备令牌用于接收远程推送通知{'\n'} • 如果令牌状态显示"权限被拒绝",请在系统设置中开启通知权限{'\n'} • 清除数据后需要重新初始化推送通知 ); } const styles = StyleSheet.create({ container: { flex: 1, }, scrollView: { flex: 1, padding: 16, }, loadingContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', }, loadingText: { marginTop: 16, fontSize: 16, }, header: { marginBottom: 24, }, title: { fontSize: 28, fontWeight: 'bold', marginBottom: 8, }, subtitle: { fontSize: 16, opacity: 0.7, }, card: { backgroundColor: 'rgba(255, 255, 255, 0.1)', borderRadius: 12, padding: 16, marginBottom: 16, borderWidth: 1, }, cardTitle: { fontSize: 18, fontWeight: '600', marginBottom: 12, }, statusRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8, }, statusLabel: { fontSize: 16, flex: 1, }, statusValue: { flex: 1, alignItems: 'flex-end', }, statusText: { fontSize: 16, fontWeight: '500', }, tokenContainer: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', }, tokenText: { fontSize: 14, fontFamily: 'monospace', flex: 1, marginRight: 12, }, copyButton: { paddingHorizontal: 12, paddingVertical: 6, borderRadius: 6, borderWidth: 1, }, copyButtonText: { fontSize: 14, fontWeight: '500', }, actionButton: { borderRadius: 8, paddingVertical: 12, paddingHorizontal: 16, alignItems: 'center', marginBottom: 12, }, actionButtonText: { color: '#ffffff', fontSize: 16, fontWeight: '600', }, secondaryButton: { backgroundColor: 'transparent', borderWidth: 1, }, secondaryButtonText: { fontSize: 16, fontWeight: '600', }, dangerButton: { backgroundColor: '#F44336', }, dangerButtonText: { color: '#ffffff', fontSize: 16, fontWeight: '600', }, description: { fontSize: 14, lineHeight: 20, }, });