feat: 实现目标通知功能及相关组件
- 新增目标通知功能,支持根据用户创建目标时选择的频率和开始时间自动创建本地定时推送通知 - 实现每日、每周和每月的重复类型,用户可自定义选择提醒时间和重复规则 - 集成目标通知测试组件,方便开发者测试不同类型的通知 - 更新相关文档,详细描述目标通知功能的实现和使用方法 - 优化目标页面,确保用户体验和界面一致性
This commit is contained in:
195
components/GoalNotificationTest.tsx
Normal file
195
components/GoalNotificationTest.tsx
Normal file
@@ -0,0 +1,195 @@
|
||||
import { GoalNotificationHelpers } from '@/utils/notificationHelpers';
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { ThemedText } from './ThemedText';
|
||||
import { ThemedView } from './ThemedView';
|
||||
|
||||
export const GoalNotificationTest: React.FC = () => {
|
||||
const [testResults, setTestResults] = useState<string[]>([]);
|
||||
|
||||
const addResult = (result: string) => {
|
||||
setTestResults(prev => [...prev, `${new Date().toLocaleTimeString()}: ${result}`]);
|
||||
};
|
||||
|
||||
const testDailyGoalNotification = async () => {
|
||||
try {
|
||||
const notificationIds = await GoalNotificationHelpers.scheduleGoalNotifications(
|
||||
{
|
||||
title: '每日运动目标',
|
||||
repeatType: 'daily',
|
||||
frequency: 1,
|
||||
hasReminder: true,
|
||||
reminderTime: '09:00',
|
||||
},
|
||||
'测试用户'
|
||||
);
|
||||
addResult(`每日目标通知创建成功,ID: ${notificationIds.join(', ')}`);
|
||||
} catch (error) {
|
||||
addResult(`每日目标通知创建失败: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
const testWeeklyGoalNotification = async () => {
|
||||
try {
|
||||
const notificationIds = await GoalNotificationHelpers.scheduleGoalNotifications(
|
||||
{
|
||||
title: '每周运动目标',
|
||||
repeatType: 'weekly',
|
||||
frequency: 1,
|
||||
hasReminder: true,
|
||||
reminderTime: '10:00',
|
||||
customRepeatRule: {
|
||||
weekdays: [1, 3, 5], // 周一、三、五
|
||||
},
|
||||
},
|
||||
'测试用户'
|
||||
);
|
||||
addResult(`每周目标通知创建成功,ID: ${notificationIds.join(', ')}`);
|
||||
} catch (error) {
|
||||
addResult(`每周目标通知创建失败: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
const testMonthlyGoalNotification = async () => {
|
||||
try {
|
||||
const notificationIds = await GoalNotificationHelpers.scheduleGoalNotifications(
|
||||
{
|
||||
title: '每月运动目标',
|
||||
repeatType: 'monthly',
|
||||
frequency: 1,
|
||||
hasReminder: true,
|
||||
reminderTime: '11:00',
|
||||
customRepeatRule: {
|
||||
dayOfMonth: [1, 15], // 每月1号和15号
|
||||
},
|
||||
},
|
||||
'测试用户'
|
||||
);
|
||||
addResult(`每月目标通知创建成功,ID: ${notificationIds.join(', ')}`);
|
||||
} catch (error) {
|
||||
addResult(`每月目标通知创建失败: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
const testGoalAchievementNotification = async () => {
|
||||
try {
|
||||
await GoalNotificationHelpers.sendGoalAchievementNotification('测试用户', '每日运动目标');
|
||||
addResult('目标达成通知发送成功');
|
||||
} catch (error) {
|
||||
addResult(`目标达成通知发送失败: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
const testCancelGoalNotifications = async () => {
|
||||
try {
|
||||
await GoalNotificationHelpers.cancelGoalNotifications('每日运动目标');
|
||||
addResult('目标通知取消成功');
|
||||
} catch (error) {
|
||||
addResult(`目标通知取消失败: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
const clearResults = () => {
|
||||
setTestResults([]);
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemedView style={styles.container}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
<ThemedText style={styles.title}>目标通知测试</ThemedText>
|
||||
|
||||
<View style={styles.buttonContainer}>
|
||||
<TouchableOpacity style={styles.button} onPress={testDailyGoalNotification}>
|
||||
<ThemedText style={styles.buttonText}>测试每日目标通知</ThemedText>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={styles.button} onPress={testWeeklyGoalNotification}>
|
||||
<ThemedText style={styles.buttonText}>测试每周目标通知</ThemedText>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={styles.button} onPress={testMonthlyGoalNotification}>
|
||||
<ThemedText style={styles.buttonText}>测试每月目标通知</ThemedText>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={styles.button} onPress={testGoalAchievementNotification}>
|
||||
<ThemedText style={styles.buttonText}>测试目标达成通知</ThemedText>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={styles.button} onPress={testCancelGoalNotifications}>
|
||||
<ThemedText style={styles.buttonText}>取消目标通知</ThemedText>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={styles.clearButton} onPress={clearResults}>
|
||||
<ThemedText style={styles.buttonText}>清除结果</ThemedText>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<View style={styles.resultsContainer}>
|
||||
<ThemedText style={styles.resultsTitle}>测试结果:</ThemedText>
|
||||
{testResults.map((result, index) => (
|
||||
<ThemedText key={index} style={styles.resultText}>
|
||||
{result}
|
||||
</ThemedText>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</ThemedView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
padding: 20,
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
},
|
||||
title: {
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
marginBottom: 20,
|
||||
textAlign: 'center',
|
||||
},
|
||||
buttonContainer: {
|
||||
gap: 10,
|
||||
marginBottom: 20,
|
||||
},
|
||||
button: {
|
||||
backgroundColor: '#6366F1',
|
||||
padding: 15,
|
||||
borderRadius: 10,
|
||||
alignItems: 'center',
|
||||
},
|
||||
clearButton: {
|
||||
backgroundColor: '#EF4444',
|
||||
padding: 15,
|
||||
borderRadius: 10,
|
||||
alignItems: 'center',
|
||||
},
|
||||
buttonText: {
|
||||
color: '#FFFFFF',
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
},
|
||||
resultsContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
resultsTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
marginBottom: 10,
|
||||
},
|
||||
resultText: {
|
||||
fontSize: 14,
|
||||
marginBottom: 5,
|
||||
padding: 10,
|
||||
backgroundColor: '#F3F4F6',
|
||||
borderRadius: 5,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user