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

@@ -8,6 +8,7 @@ import * as Notifications from 'expo-notifications';
import { Platform, AppState, AppStateStatus } from 'react-native';
import type { WSChatMessage, WSNotificationMessage, WSAnnouncementMessage } from './sseService';
import { extractTextFromSegments } from '../types/dto';
import { getNotificationPreferencesSync } from './notificationPreferences';
// 通知渠道配置
const CHANNEL_ID = 'default';
@@ -71,17 +72,6 @@ class SystemNotificationService {
return false;
}
// 设置 notification handler确保前台也能显示通知、播放声音和震动
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: true,
shouldShowBanner: true,
shouldShowList: true,
}),
});
if (Platform.OS === 'android') {
await Notifications.setNotificationChannelAsync(CHANNEL_ID, {
name: CHANNEL_NAME,
@@ -120,15 +110,16 @@ class SystemNotificationService {
// 使用 scheduleNotificationAsync 立即显示通知
// 配合 setNotificationHandler 确保前台也能显示
const { vibrationEnabled } = getNotificationPreferencesSync();
// 构建通知内容
const content: Notifications.NotificationContentInput = {
title: options.title,
body: options.body,
data: options.data as Record<string, string | number | object> | undefined,
// 显式设置震动(仅 Android 生效)
...(Platform.OS === 'android' ? {
vibrationPattern: [0, 300, 200, 300],
} : {}),
// 显式设置震动(仅 Android 生效,且尊重「消息震动」开关
...(Platform.OS === 'android' && vibrationEnabled
? { vibrationPattern: [0, 300, 200, 300] }
: {}),
};
const notificationId = await Notifications.scheduleNotificationAsync({
@@ -179,6 +170,9 @@ class SystemNotificationService {
}
async handleWSMessage(message: WSChatMessage | WSNotificationMessage | WSAnnouncementMessage): Promise<void> {
if (!getNotificationPreferencesSync().pushEnabled) {
return;
}
// 仅在后台时显示通知,前台时不显示(用户正在使用应用,可以直接看到消息)
if (this.currentAppState !== 'active') {
// 判断是否是聊天消息(通过 segments 字段)