feat: add nutrition and mood reminder settings
- Implemented nutrition and mood reminder toggles in notification settings screen. - Added corresponding utility functions for managing nutrition and mood reminder preferences. - Updated user preferences interface to include nutrition and mood reminder states. - Enhanced localization for new reminder settings and alerts. - Incremented iOS app version to 1.0.30.
This commit is contained in:
@@ -3,9 +3,13 @@ import { useI18n } from '@/hooks/useI18n';
|
||||
import { useNotifications } from '@/hooks/useNotifications';
|
||||
import {
|
||||
getMedicationReminderEnabled,
|
||||
getMoodReminderEnabled,
|
||||
getNotificationEnabled,
|
||||
getNutritionReminderEnabled,
|
||||
setMedicationReminderEnabled,
|
||||
setNotificationEnabled
|
||||
setMoodReminderEnabled,
|
||||
setNotificationEnabled,
|
||||
setNutritionReminderEnabled
|
||||
} from '@/utils/userPreferences';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { GlassView, isLiquidGlassAvailable } from 'expo-glass-effect';
|
||||
@@ -24,17 +28,23 @@ export default function NotificationSettingsScreen() {
|
||||
// 通知设置状态
|
||||
const [notificationEnabled, setNotificationEnabledState] = useState(false);
|
||||
const [medicationReminderEnabled, setMedicationReminderEnabledState] = useState(false);
|
||||
const [nutritionReminderEnabled, setNutritionReminderEnabledState] = useState(false);
|
||||
const [moodReminderEnabled, setMoodReminderEnabledState] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
// 加载通知设置
|
||||
const loadNotificationSettings = useCallback(async () => {
|
||||
try {
|
||||
const [notification, medicationReminder] = await Promise.all([
|
||||
const [notification, medicationReminder, nutritionReminder, moodReminder] = await Promise.all([
|
||||
getNotificationEnabled(),
|
||||
getMedicationReminderEnabled(),
|
||||
getNutritionReminderEnabled(),
|
||||
getMoodReminderEnabled(),
|
||||
]);
|
||||
setNotificationEnabledState(notification);
|
||||
setMedicationReminderEnabledState(medicationReminder);
|
||||
setNutritionReminderEnabledState(nutritionReminder);
|
||||
setMoodReminderEnabledState(moodReminder);
|
||||
} catch (error) {
|
||||
console.error('Failed to load notification settings:', error);
|
||||
} finally {
|
||||
@@ -87,9 +97,13 @@ export default function NotificationSettingsScreen() {
|
||||
// 关闭推送,保存用户偏好设置
|
||||
await setNotificationEnabled(false);
|
||||
setNotificationEnabledState(false);
|
||||
// 关闭总开关时,也关闭药品提醒
|
||||
// 关闭总开关时,也关闭所有提醒
|
||||
await setMedicationReminderEnabled(false);
|
||||
setMedicationReminderEnabledState(false);
|
||||
await setNutritionReminderEnabled(false);
|
||||
setNutritionReminderEnabledState(false);
|
||||
await setMoodReminderEnabled(false);
|
||||
setMoodReminderEnabledState(false);
|
||||
} catch (error) {
|
||||
console.error('Failed to disable push notifications:', error);
|
||||
Alert.alert(t('notificationSettings.alerts.error.title'), t('notificationSettings.alerts.error.saveFailed'));
|
||||
@@ -118,6 +132,48 @@ export default function NotificationSettingsScreen() {
|
||||
}
|
||||
};
|
||||
|
||||
// 处理营养通知提醒开关变化
|
||||
const handleNutritionReminderToggle = async (value: boolean) => {
|
||||
try {
|
||||
await setNutritionReminderEnabled(value);
|
||||
setNutritionReminderEnabledState(value);
|
||||
|
||||
if (value) {
|
||||
// 发送测试通知
|
||||
await sendNotification({
|
||||
title: t('notificationSettings.alerts.nutritionReminderEnabled.title'),
|
||||
body: t('notificationSettings.alerts.nutritionReminderEnabled.body'),
|
||||
sound: true,
|
||||
priority: 'high',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to set nutrition reminder:', error);
|
||||
Alert.alert(t('notificationSettings.alerts.error.title'), t('notificationSettings.alerts.error.nutritionReminderFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
// 处理心情通知提醒开关变化
|
||||
const handleMoodReminderToggle = async (value: boolean) => {
|
||||
try {
|
||||
await setMoodReminderEnabled(value);
|
||||
setMoodReminderEnabledState(value);
|
||||
|
||||
if (value) {
|
||||
// 发送测试通知
|
||||
await sendNotification({
|
||||
title: t('notificationSettings.alerts.moodReminderEnabled.title'),
|
||||
body: t('notificationSettings.alerts.moodReminderEnabled.body'),
|
||||
sound: true,
|
||||
priority: 'high',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to set mood reminder:', error);
|
||||
Alert.alert(t('notificationSettings.alerts.error.title'), t('notificationSettings.alerts.error.moodReminderFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
// 返回按钮
|
||||
const BackButton = () => (
|
||||
<TouchableOpacity
|
||||
@@ -247,6 +303,34 @@ export default function NotificationSettingsScreen() {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 营养提醒部分 */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>{t('notificationSettings.sections.nutritionReminder')}</Text>
|
||||
<View style={styles.card}>
|
||||
<SwitchItem
|
||||
title={t('notificationSettings.items.nutritionReminder.title')}
|
||||
description={t('notificationSettings.items.nutritionReminder.description')}
|
||||
value={nutritionReminderEnabled}
|
||||
onValueChange={handleNutritionReminderToggle}
|
||||
disabled={!notificationEnabled}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 心情提醒部分 */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>{t('notificationSettings.sections.moodReminder')}</Text>
|
||||
<View style={styles.card}>
|
||||
<SwitchItem
|
||||
title={t('notificationSettings.items.moodReminder.title')}
|
||||
description={t('notificationSettings.items.moodReminder.description')}
|
||||
value={moodReminderEnabled}
|
||||
onValueChange={handleMoodReminderToggle}
|
||||
disabled={!notificationEnabled}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 说明部分 */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>{t('notificationSettings.sections.description')}</Text>
|
||||
|
||||
Reference in New Issue
Block a user