diff --git a/src/services/notification/jpushService.ts b/src/services/notification/jpushService.ts index e40ac83..3413d60 100644 --- a/src/services/notification/jpushService.ts +++ b/src/services/notification/jpushService.ts @@ -1,6 +1,8 @@ -import { Platform, NativeModules } from 'react-native'; +import { Platform, NativeModules, AppState } from 'react-native'; import { pushService } from './pushService'; import * as Notifications from 'expo-notifications'; +import { getNotificationPreferencesSync } from './notificationPreferences'; +import { vibrateOnMessage } from '../platform/messageVibrationService'; type JPushNotificationMessage = { messageID: string; @@ -68,6 +70,12 @@ class JPushService { JPush!.addNotificationListener((result: any) => { console.log('[JPush] notification:', result); + if (result.notificationEventType === 'notificationArrived') { + const prefs = getNotificationPreferencesSync(); + if (prefs.vibrationEnabled && AppState.currentState === 'active') { + vibrateOnMessage('notification').catch(() => {}); + } + } if (this.notificationCallback) { this.notificationCallback({ messageID: result.messageID || '', @@ -111,6 +119,10 @@ class JPushService { production: !__DEV__, }); + if (Platform.OS === 'android') { + this._setupAndroidNotificationChannel(); + } + console.log('[JPush] init called, waiting for registration...'); // 轮询获取 RegistrationID,间隔逐渐增大 @@ -136,11 +148,37 @@ class JPushService { } private _onConnected(): void { - if (this.registrationID) return; // Already have registrationID, skip + if (this.registrationID) return; console.log('[JPush] connected, fetching registrationID...'); this._fetchRegistrationID(); } + private _setupAndroidNotificationChannel(): void { + if (!JPush) return; + try { + (JPush as any).setChannelAndSound({ + channel: '推送通知', + channelId: 'jpush_notification', + }); + console.log('[JPush] Android notification channel configured'); + } catch (error) { + console.warn('[JPush] setChannelAndSound failed:', error); + } + + try { + Notifications.setNotificationChannelAsync('jpush_notification', { + name: '推送通知', + importance: Notifications.AndroidImportance.HIGH, + vibrationPattern: [0, 250, 250, 250], + sound: 'default', + enableLights: true, + showBadge: true, + }); + } catch (error) { + console.warn('[JPush] expo-notifications channel setup failed:', error); + } + } + private _fetchRegistrationID(): void { if (!JPush) return; JPush.getRegistrationID((result: any) => { @@ -282,7 +320,15 @@ class JPushService { }): void { if (!JPush || !this.isInitialized) return; try { - JPush.addLocalNotification(params); + if (Platform.OS === 'android') { + const localParams = { + ...params, + priority: 1, + }; + JPush.addLocalNotification(localParams); + } else { + JPush.addLocalNotification(params); + } } catch (error) { console.error('[JPush] addLocalNotification failed:', error); } diff --git a/src/services/notification/notificationPreferences.ts b/src/services/notification/notificationPreferences.ts index 8dd9fb1..8628a20 100644 --- a/src/services/notification/notificationPreferences.ts +++ b/src/services/notification/notificationPreferences.ts @@ -1,4 +1,6 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; +import { Platform } from 'react-native'; +import * as Notifications from 'expo-notifications'; import { setVibrationEnabled } from '../platform/messageVibrationService'; export const NOTIFICATION_PREF_KEYS = { @@ -70,6 +72,18 @@ export async function setSoundPreference(enabled: boolean): Promise { } export function registerNotificationPresentationHandler(): void { - // JPush handles notification presentation natively. - // Preferences are read from getNotificationPreferencesSync() when needed. + if (Platform.OS === 'web') return; + + Notifications.setNotificationHandler({ + handleNotification: async () => { + const prefs = getNotificationPreferencesSync(); + return { + shouldShowAlert: prefs.pushEnabled, + shouldPlaySound: prefs.soundEnabled, + shouldSetBadge: true, + shouldShowBanner: prefs.pushEnabled, + shouldShowList: prefs.pushEnabled, + }; + }, + }); } diff --git a/src/services/notification/systemNotificationService.ts b/src/services/notification/systemNotificationService.ts index 04c1d27..1b6dfc6 100644 --- a/src/services/notification/systemNotificationService.ts +++ b/src/services/notification/systemNotificationService.ts @@ -191,6 +191,18 @@ class SystemNotificationService { vibrateOnMessage('notification').catch(() => {}); await this.showWSNotification(notifMsg); } + } else { + // App is in foreground: trigger vibration feedback + if ('segments' in message) { + const chatMsg = message as WSChatMessage; + const conversationId = normalizeConversationId(chatMsg.conversation_id); + const isNotificationMuted = useMessageStore.getState().isNotificationMuted(conversationId); + if (!isNotificationMuted) { + vibrateOnMessage('chat').catch(() => {}); + } + } else { + vibrateOnMessage('notification').catch(() => {}); + } } }