feat(Notification): implement notification preferences management and enhance notification handling
- 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:
@@ -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 字段)
|
||||
|
||||
Reference in New Issue
Block a user