Replace expo-notifications with JPush for push notifications across the app. This includes adding JPush native module dependencies, configuring the JPush plugin in app.json, implementing jpushService wrapper, and updating notification services to use JPush APIs. Also adds device registration on token refresh for both mobile and web platforms. BREAKING CHANGE: expo-notifications removed in favor of JPush for push notifications
83 lines
2.5 KiB
TypeScript
83 lines
2.5 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
import { Platform } from 'react-native';
|
|
import { Redirect } from 'expo-router';
|
|
|
|
import { AppRouteStack } from '../../src/app-navigation/AppRouteStack';
|
|
import { messageManager, useAuthStore } from '../../src/stores';
|
|
import { jpushService } from '../../src/services/notification/jpushService';
|
|
|
|
function getDeviceType(): 'ios' | 'android' | 'web' {
|
|
switch (Platform.OS) {
|
|
case 'ios': return 'ios';
|
|
case 'android': return 'android';
|
|
default: return 'web';
|
|
}
|
|
}
|
|
|
|
async function getOrCreateDeviceID(): Promise<string> {
|
|
try {
|
|
const AsyncStorage = require('@react-native-async-storage/async-storage').default;
|
|
const DEVICE_ID_KEY = 'withyou_device_id';
|
|
let deviceId = await AsyncStorage.getItem(DEVICE_ID_KEY);
|
|
if (deviceId) return deviceId;
|
|
const timestamp = Date.now().toString(36);
|
|
const random = Math.random().toString(36).substring(2, 8);
|
|
deviceId = `${Platform.OS}_${timestamp}_${random}`;
|
|
await AsyncStorage.setItem(DEVICE_ID_KEY, deviceId);
|
|
return deviceId;
|
|
} catch {
|
|
return `${Platform.OS}_${Date.now()}`;
|
|
}
|
|
}
|
|
|
|
export default function AppLayout() {
|
|
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
|
|
const userID = useAuthStore((s) => s.currentUser?.id);
|
|
const deviceRegistered = useRef(false);
|
|
|
|
useEffect(() => {
|
|
messageManager.initialize();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!isAuthenticated || !userID) return;
|
|
|
|
if (!deviceRegistered.current) {
|
|
deviceRegistered.current = true;
|
|
|
|
if (Platform.OS === 'web') {
|
|
// Web: register device without push_token (JPush not available on web)
|
|
getOrCreateDeviceID().then((deviceId) => {
|
|
const { pushService } = require('../../src/services/notification/pushService');
|
|
pushService.registerDevice({
|
|
device_id: deviceId,
|
|
device_type: 'web',
|
|
device_name: 'Web Browser',
|
|
}).catch((err: any) => {
|
|
console.warn('[Push] web device register failed:', err?.message);
|
|
});
|
|
});
|
|
} else {
|
|
// Mobile: JPush handles registration internally in initialize()
|
|
jpushService.initialize().then((ok) => {
|
|
if (ok && userID) {
|
|
jpushService.setAliasForUser(userID);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
return () => {
|
|
if (!isAuthenticated) {
|
|
deviceRegistered.current = false;
|
|
jpushService.cleanup();
|
|
}
|
|
};
|
|
}, [isAuthenticated, userID]);
|
|
|
|
if (!isAuthenticated) {
|
|
return <Redirect href="/login" />;
|
|
}
|
|
|
|
return <AppRouteStack />;
|
|
} |