2026-04-27 23:21:08 +08:00
|
|
|
import { useEffect, useRef } from 'react';
|
|
|
|
|
import { Platform } from 'react-native';
|
2026-03-24 14:21:31 +08:00
|
|
|
import { Redirect } from 'expo-router';
|
|
|
|
|
|
|
|
|
|
import { AppRouteStack } from '../../src/app-navigation/AppRouteStack';
|
|
|
|
|
import { messageManager, useAuthStore } from '../../src/stores';
|
2026-04-27 23:21:08 +08:00
|
|
|
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()}`;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-24 14:21:31 +08:00
|
|
|
|
|
|
|
|
export default function AppLayout() {
|
|
|
|
|
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
|
2026-04-27 23:21:08 +08:00
|
|
|
const userID = useAuthStore((s) => s.currentUser?.id);
|
|
|
|
|
const deviceRegistered = useRef(false);
|
2026-03-24 14:21:31 +08:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
messageManager.initialize();
|
|
|
|
|
}, []);
|
|
|
|
|
|
2026-04-27 23:21:08 +08:00
|
|
|
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]);
|
|
|
|
|
|
2026-03-24 14:21:31 +08:00
|
|
|
if (!isAuthenticated) {
|
|
|
|
|
return <Redirect href="/login" />;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return <AppRouteStack />;
|
2026-04-27 23:21:08 +08:00
|
|
|
}
|