feat(Notification): implement notification preferences management and enhance notification handling
All checks were successful
Frontend CI / build-and-push-web (push) Successful in 8m28s
Frontend CI / ota-android (push) Successful in 11m6s
Frontend CI / build-android-apk (push) Successful in 1h3m35s

- Introduced a new service for managing notification preferences, including push notifications, sound, and vibration settings.
- Updated the notification handling logic to respect user preferences, ensuring notifications are displayed according to user settings.
- Refactored the App and various screens to integrate the new notification preferences, improving user experience and consistency.
- Enhanced the HomeScreen and NotificationSettingsScreen to load and update notification settings seamlessly.
- Implemented a mechanism to hide the bottom tab bar based on scroll events, improving navigation usability.
This commit is contained in:
lafay
2026-03-25 01:30:00 +08:00
parent cedb8284ba
commit 583ac64dfd
19 changed files with 666 additions and 396 deletions

View File

@@ -13,14 +13,16 @@ import {
} from 'react-native';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { colors, spacing, fontSizes, borderRadius } from '../../theme';
import { Text, ResponsiveContainer } from '../../components/common';
import { setVibrationEnabled } from '../../services/backgroundService';
import {
loadNotificationPreferences,
setPushNotificationsPreference,
setSoundPreference,
setVibrationPreference,
} from '../../services/notificationPreferences';
import { useResponsive } from '../../hooks';
const VIBRATION_ENABLED_KEY = 'vibration_enabled';
interface NotificationSettingItem {
key: string;
title: string;
@@ -40,34 +42,48 @@ export const NotificationSettingsScreen: React.FC = () => {
// 底部间距,避免被 TabBar 遮挡
const scrollBottomInset = isMobile ? 64 + 24 + insets.bottom + spacing.md : spacing.md;
// 加载设置
// 加载设置(与启动时 hydrate 一致,避免从其它入口进页时 UI 与内存不一致)
useEffect(() => {
const loadSettings = async () => {
try {
const vibrationStored = await AsyncStorage.getItem(VIBRATION_ENABLED_KEY);
if (vibrationStored !== null) {
const enabled = JSON.parse(vibrationStored);
setVibrationEnabledState(enabled);
setVibrationEnabled(enabled);
}
const prefs = await loadNotificationPreferences();
setVibrationEnabledState(prefs.vibrationEnabled);
setPushEnabled(prefs.pushEnabled);
setSoundEnabled(prefs.soundEnabled);
} catch (error) {
console.error('加载震动设置失败:', error);
console.error('加载通知设置失败:', error);
}
};
loadSettings();
}, []);
// 切换震动
const toggleVibration = async (value: boolean) => {
try {
setVibrationEnabledState(value);
setVibrationEnabled(value);
await AsyncStorage.setItem(VIBRATION_ENABLED_KEY, JSON.stringify(value));
await setVibrationPreference(value);
} catch (error) {
console.error('保存震动设置失败:', error);
}
};
const togglePush = async (value: boolean) => {
try {
setPushEnabled(value);
await setPushNotificationsPreference(value);
} catch (error) {
console.error('保存推送开关失败:', error);
}
};
const toggleSound = async (value: boolean) => {
try {
setSoundEnabled(value);
await setSoundPreference(value);
} catch (error) {
console.error('保存提示音设置失败:', error);
}
};
const settings: NotificationSettingItem[] = [
{
key: 'push',
@@ -75,7 +91,7 @@ export const NotificationSettingsScreen: React.FC = () => {
subtitle: '接收新消息、点赞、评论等推送',
icon: 'bell-outline',
value: pushEnabled,
onValueChange: setPushEnabled,
onValueChange: togglePush,
},
{
key: 'vibration',
@@ -91,7 +107,7 @@ export const NotificationSettingsScreen: React.FC = () => {
subtitle: '收到新消息时播放提示音',
icon: 'volume-high',
value: soundEnabled,
onValueChange: setSoundEnabled,
onValueChange: toggleSound,
},
];