2026-06-01 22:56:37 +08:00
|
|
|
import '../src/polyfills';
|
2026-06-16 19:03:26 +08:00
|
|
|
import React, { useEffect, useRef } from 'react';
|
2026-03-25 05:16:54 +08:00
|
|
|
import { AppState, AppStateStatus, Platform, View, ActivityIndicator } from 'react-native';
|
2026-03-24 14:21:31 +08:00
|
|
|
import { Stack, useRouter } from 'expo-router';
|
|
|
|
|
import { StatusBar } from 'expo-status-bar';
|
|
|
|
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
|
|
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
|
|
|
import { PaperProvider } from 'react-native-paper';
|
|
|
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
2026-03-25 05:16:54 +08:00
|
|
|
import * as SystemUI from 'expo-system-ui';
|
2026-04-26 17:13:43 +08:00
|
|
|
import { useFonts } from 'expo-font';
|
2026-03-24 14:21:31 +08:00
|
|
|
|
2026-04-13 01:30:37 +08:00
|
|
|
import { registerNotificationPresentationHandler } from '@/services/notification';
|
2026-04-12 18:14:29 +08:00
|
|
|
import { EventSubscriber } from '../src/infrastructure/EventSubscriber';
|
2026-03-25 05:16:54 +08:00
|
|
|
import {
|
|
|
|
|
ThemeBootstrap,
|
|
|
|
|
useAppColors,
|
|
|
|
|
usePaperThemeFromStore,
|
|
|
|
|
useResolvedColorScheme,
|
|
|
|
|
} from '../src/theme';
|
2026-05-03 22:01:43 +08:00
|
|
|
|
2026-03-24 14:21:31 +08:00
|
|
|
import AppPromptBar from '../src/components/common/AppPromptBar';
|
|
|
|
|
import AppDialogHost from '../src/components/common/AppDialogHost';
|
2026-04-13 01:30:37 +08:00
|
|
|
import { installAlertOverride } from '@/services/ui';
|
|
|
|
|
import { checkForAPKUpdate } from '@/services/platform';
|
2026-03-27 17:12:19 +08:00
|
|
|
import { CallScreen, IncomingCallModal, FloatingCallWindow } from '../src/components/call';
|
2026-04-27 23:21:08 +08:00
|
|
|
import { jpushService } from '@/services/notification/jpushService';
|
2026-06-03 01:56:02 +08:00
|
|
|
import { callKeepService } from '@/services/callkeep';
|
|
|
|
|
import { callStore } from '@/stores/call';
|
2026-06-12 23:42:09 +08:00
|
|
|
import * as hrefs from '../src/navigation/hrefs';
|
2026-03-24 14:21:31 +08:00
|
|
|
|
2026-03-25 01:30:00 +08:00
|
|
|
registerNotificationPresentationHandler();
|
2026-03-24 14:21:31 +08:00
|
|
|
|
|
|
|
|
const queryClient = new QueryClient({
|
|
|
|
|
defaultOptions: {
|
|
|
|
|
queries: {
|
|
|
|
|
retry: 2,
|
|
|
|
|
staleTime: 5 * 60 * 1000,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
installAlertOverride();
|
|
|
|
|
|
|
|
|
|
if (Platform.OS === 'web' && typeof document !== 'undefined') {
|
|
|
|
|
const style = document.createElement('style');
|
|
|
|
|
style.textContent = `
|
|
|
|
|
input:focus, textarea:focus, select:focus {
|
|
|
|
|
outline: none !important;
|
|
|
|
|
outline-width: 0 !important;
|
|
|
|
|
box-shadow: none !important;
|
|
|
|
|
}
|
|
|
|
|
input:focus-visible, textarea:focus-visible {
|
|
|
|
|
outline: none !important;
|
|
|
|
|
}
|
|
|
|
|
*:focus { outline: none !important; }
|
|
|
|
|
*:focus-visible { outline: none !important; }
|
2026-04-14 02:12:53 +08:00
|
|
|
/* 修复移动端滑动问题 - 仅对根容器限制 */
|
<think>Let me analyze the staged changes to generate a proper conventional commit message.
Looking at the changes:
1. **New files**:
- `app/(app)/(tabs)/profile/account-deletion.tsx` - account deletion screen
- `app/(app)/(tabs)/profile/privacy-settings.tsx` - privacy settings screen
- `src/screens/profile/AccountDeletionScreen.tsx` - account deletion implementation
- `src/screens/profile/PrivacySettingsScreen.tsx` - privacy settings implementation
2. **Modified files**:
- Database changes: `LocalDataSource.ts`, `DatabaseManager.ts`, `DatabaseConfig.ts`, `MigrationManager.ts` - refactoring database layer (removing LockManager, simplified initialization, added retry logic)
- Auth store: `authStore.ts` - changed `initDatabase` to `switchDatabase`
- Auth service: `authService.ts` - added privacy settings and account deletion methods
- DTOs: `dto.ts` - added PrivacySettingsDTO, DeletionStatusDTO, VoteOptionDTO, VoteResultDTO types
- Navigation: `hrefs.ts` - added new href functions for privacy settings and account deletion
- Profile screens: `SettingsScreen.tsx`, `index.ts`, `_layout.tsx` - added new menu items and routes
- Various message screens - added keyboard handling props
- `app/_layout.tsx` - added CSS for mobile touch handling
- `CreatePostScreen.tsx` - fixed vote_options format
- `PostDetailScreen.tsx` - added type annotations for vote handling
- `MediaCacheManager.ts` - updated to use new expo-file-system API
- `VerificationSettingsScreen.tsx` - fixed type safety
- `AccountSecurityScreen.tsx` - styling refactoring
This is a multi-faceted change involving:
Database refactoring, new privacy/account deletion features, bug fixes, and UI improvements. The database changes appear to be refactoring without new functionality. The most significant changes are the privacy settings and account deletion features, plus bug fixes like the vote options format and mobile touch handling.
</think>
feat(profile): add privacy settings and account deletion screens
Add privacy settings and account deletion functionality with new screens and APIs. Refactor database initialization to use switchDatabase for user switching. Fix vote options format in post creation and add type safety to vote handling. Improve mobile touch handling in layout and message screens. Update media cache to use new expo-file-system API.
BREAKING CHANGE: Database initialization now uses switchDatabase instead of initDatabase for user switching
2026-04-08 16:48:19 +08:00
|
|
|
html, body {
|
|
|
|
|
overscroll-behavior: none;
|
2026-04-14 02:12:53 +08:00
|
|
|
touch-action: manipulation;
|
|
|
|
|
-webkit-overflow-scrolling: touch;
|
<think>Let me analyze the staged changes to generate a proper conventional commit message.
Looking at the changes:
1. **New files**:
- `app/(app)/(tabs)/profile/account-deletion.tsx` - account deletion screen
- `app/(app)/(tabs)/profile/privacy-settings.tsx` - privacy settings screen
- `src/screens/profile/AccountDeletionScreen.tsx` - account deletion implementation
- `src/screens/profile/PrivacySettingsScreen.tsx` - privacy settings implementation
2. **Modified files**:
- Database changes: `LocalDataSource.ts`, `DatabaseManager.ts`, `DatabaseConfig.ts`, `MigrationManager.ts` - refactoring database layer (removing LockManager, simplified initialization, added retry logic)
- Auth store: `authStore.ts` - changed `initDatabase` to `switchDatabase`
- Auth service: `authService.ts` - added privacy settings and account deletion methods
- DTOs: `dto.ts` - added PrivacySettingsDTO, DeletionStatusDTO, VoteOptionDTO, VoteResultDTO types
- Navigation: `hrefs.ts` - added new href functions for privacy settings and account deletion
- Profile screens: `SettingsScreen.tsx`, `index.ts`, `_layout.tsx` - added new menu items and routes
- Various message screens - added keyboard handling props
- `app/_layout.tsx` - added CSS for mobile touch handling
- `CreatePostScreen.tsx` - fixed vote_options format
- `PostDetailScreen.tsx` - added type annotations for vote handling
- `MediaCacheManager.ts` - updated to use new expo-file-system API
- `VerificationSettingsScreen.tsx` - fixed type safety
- `AccountSecurityScreen.tsx` - styling refactoring
This is a multi-faceted change involving:
Database refactoring, new privacy/account deletion features, bug fixes, and UI improvements. The database changes appear to be refactoring without new functionality. The most significant changes are the privacy settings and account deletion features, plus bug fixes like the vote options format and mobile touch handling.
</think>
feat(profile): add privacy settings and account deletion screens
Add privacy settings and account deletion functionality with new screens and APIs. Refactor database initialization to use switchDatabase for user switching. Fix vote options format in post creation and add type safety to vote handling. Improve mobile touch handling in layout and message screens. Update media cache to use new expo-file-system API.
BREAKING CHANGE: Database initialization now uses switchDatabase instead of initDatabase for user switching
2026-04-08 16:48:19 +08:00
|
|
|
}
|
2026-04-14 02:12:53 +08:00
|
|
|
/* React Native Web 生成的滚动容器 - 允许双向滑动 */
|
|
|
|
|
[class*="css-view"] {
|
|
|
|
|
touch-action: auto;
|
|
|
|
|
-webkit-overflow-scrolling: touch;
|
<think>Let me analyze the staged changes to generate a proper conventional commit message.
Looking at the changes:
1. **New files**:
- `app/(app)/(tabs)/profile/account-deletion.tsx` - account deletion screen
- `app/(app)/(tabs)/profile/privacy-settings.tsx` - privacy settings screen
- `src/screens/profile/AccountDeletionScreen.tsx` - account deletion implementation
- `src/screens/profile/PrivacySettingsScreen.tsx` - privacy settings implementation
2. **Modified files**:
- Database changes: `LocalDataSource.ts`, `DatabaseManager.ts`, `DatabaseConfig.ts`, `MigrationManager.ts` - refactoring database layer (removing LockManager, simplified initialization, added retry logic)
- Auth store: `authStore.ts` - changed `initDatabase` to `switchDatabase`
- Auth service: `authService.ts` - added privacy settings and account deletion methods
- DTOs: `dto.ts` - added PrivacySettingsDTO, DeletionStatusDTO, VoteOptionDTO, VoteResultDTO types
- Navigation: `hrefs.ts` - added new href functions for privacy settings and account deletion
- Profile screens: `SettingsScreen.tsx`, `index.ts`, `_layout.tsx` - added new menu items and routes
- Various message screens - added keyboard handling props
- `app/_layout.tsx` - added CSS for mobile touch handling
- `CreatePostScreen.tsx` - fixed vote_options format
- `PostDetailScreen.tsx` - added type annotations for vote handling
- `MediaCacheManager.ts` - updated to use new expo-file-system API
- `VerificationSettingsScreen.tsx` - fixed type safety
- `AccountSecurityScreen.tsx` - styling refactoring
This is a multi-faceted change involving:
Database refactoring, new privacy/account deletion features, bug fixes, and UI improvements. The database changes appear to be refactoring without new functionality. The most significant changes are the privacy settings and account deletion features, plus bug fixes like the vote options format and mobile touch handling.
</think>
feat(profile): add privacy settings and account deletion screens
Add privacy settings and account deletion functionality with new screens and APIs. Refactor database initialization to use switchDatabase for user switching. Fix vote options format in post creation and add type safety to vote handling. Improve mobile touch handling in layout and message screens. Update media cache to use new expo-file-system API.
BREAKING CHANGE: Database initialization now uses switchDatabase instead of initDatabase for user switching
2026-04-08 16:48:19 +08:00
|
|
|
}
|
2026-04-14 02:12:53 +08:00
|
|
|
/* 水平滚动容器 */
|
|
|
|
|
[data-horizontal-scroll="true"],
|
|
|
|
|
div[style*="overflow-x"],
|
|
|
|
|
div[style*="overflow: scroll"],
|
|
|
|
|
div[style*="overflow: auto"] {
|
|
|
|
|
touch-action: pan-x pan-y;
|
|
|
|
|
-webkit-overflow-scrolling: touch;
|
<think>Let me analyze the staged changes to generate a proper conventional commit message.
Looking at the changes:
1. **New files**:
- `app/(app)/(tabs)/profile/account-deletion.tsx` - account deletion screen
- `app/(app)/(tabs)/profile/privacy-settings.tsx` - privacy settings screen
- `src/screens/profile/AccountDeletionScreen.tsx` - account deletion implementation
- `src/screens/profile/PrivacySettingsScreen.tsx` - privacy settings implementation
2. **Modified files**:
- Database changes: `LocalDataSource.ts`, `DatabaseManager.ts`, `DatabaseConfig.ts`, `MigrationManager.ts` - refactoring database layer (removing LockManager, simplified initialization, added retry logic)
- Auth store: `authStore.ts` - changed `initDatabase` to `switchDatabase`
- Auth service: `authService.ts` - added privacy settings and account deletion methods
- DTOs: `dto.ts` - added PrivacySettingsDTO, DeletionStatusDTO, VoteOptionDTO, VoteResultDTO types
- Navigation: `hrefs.ts` - added new href functions for privacy settings and account deletion
- Profile screens: `SettingsScreen.tsx`, `index.ts`, `_layout.tsx` - added new menu items and routes
- Various message screens - added keyboard handling props
- `app/_layout.tsx` - added CSS for mobile touch handling
- `CreatePostScreen.tsx` - fixed vote_options format
- `PostDetailScreen.tsx` - added type annotations for vote handling
- `MediaCacheManager.ts` - updated to use new expo-file-system API
- `VerificationSettingsScreen.tsx` - fixed type safety
- `AccountSecurityScreen.tsx` - styling refactoring
This is a multi-faceted change involving:
Database refactoring, new privacy/account deletion features, bug fixes, and UI improvements. The database changes appear to be refactoring without new functionality. The most significant changes are the privacy settings and account deletion features, plus bug fixes like the vote options format and mobile touch handling.
</think>
feat(profile): add privacy settings and account deletion screens
Add privacy settings and account deletion functionality with new screens and APIs. Refactor database initialization to use switchDatabase for user switching. Fix vote options format in post creation and add type safety to vote handling. Improve mobile touch handling in layout and message screens. Update media cache to use new expo-file-system API.
BREAKING CHANGE: Database initialization now uses switchDatabase instead of initDatabase for user switching
2026-04-08 16:48:19 +08:00
|
|
|
}
|
2026-04-14 02:12:53 +08:00
|
|
|
/* 手势区域 - 允许滑动手势 */
|
|
|
|
|
[data-gesture-area="true"] {
|
|
|
|
|
touch-action: pan-x pan-y;
|
|
|
|
|
}
|
|
|
|
|
/* 图片查看器手势区域 */
|
|
|
|
|
.react-native-image-viewer,
|
|
|
|
|
[data-image-viewer="true"] {
|
|
|
|
|
touch-action: pinch-zoom pan-x pan-y;
|
<think>Let me analyze the staged changes to generate a proper conventional commit message.
Looking at the changes:
1. **New files**:
- `app/(app)/(tabs)/profile/account-deletion.tsx` - account deletion screen
- `app/(app)/(tabs)/profile/privacy-settings.tsx` - privacy settings screen
- `src/screens/profile/AccountDeletionScreen.tsx` - account deletion implementation
- `src/screens/profile/PrivacySettingsScreen.tsx` - privacy settings implementation
2. **Modified files**:
- Database changes: `LocalDataSource.ts`, `DatabaseManager.ts`, `DatabaseConfig.ts`, `MigrationManager.ts` - refactoring database layer (removing LockManager, simplified initialization, added retry logic)
- Auth store: `authStore.ts` - changed `initDatabase` to `switchDatabase`
- Auth service: `authService.ts` - added privacy settings and account deletion methods
- DTOs: `dto.ts` - added PrivacySettingsDTO, DeletionStatusDTO, VoteOptionDTO, VoteResultDTO types
- Navigation: `hrefs.ts` - added new href functions for privacy settings and account deletion
- Profile screens: `SettingsScreen.tsx`, `index.ts`, `_layout.tsx` - added new menu items and routes
- Various message screens - added keyboard handling props
- `app/_layout.tsx` - added CSS for mobile touch handling
- `CreatePostScreen.tsx` - fixed vote_options format
- `PostDetailScreen.tsx` - added type annotations for vote handling
- `MediaCacheManager.ts` - updated to use new expo-file-system API
- `VerificationSettingsScreen.tsx` - fixed type safety
- `AccountSecurityScreen.tsx` - styling refactoring
This is a multi-faceted change involving:
Database refactoring, new privacy/account deletion features, bug fixes, and UI improvements. The database changes appear to be refactoring without new functionality. The most significant changes are the privacy settings and account deletion features, plus bug fixes like the vote options format and mobile touch handling.
</think>
feat(profile): add privacy settings and account deletion screens
Add privacy settings and account deletion functionality with new screens and APIs. Refactor database initialization to use switchDatabase for user switching. Fix vote options format in post creation and add type safety to vote handling. Improve mobile touch handling in layout and message screens. Update media cache to use new expo-file-system API.
BREAKING CHANGE: Database initialization now uses switchDatabase instead of initDatabase for user switching
2026-04-08 16:48:19 +08:00
|
|
|
}
|
2026-03-24 14:21:31 +08:00
|
|
|
`;
|
|
|
|
|
document.head.appendChild(style);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 05:16:54 +08:00
|
|
|
function SystemChrome() {
|
|
|
|
|
const colors = useAppColors();
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
void SystemUI.setBackgroundColorAsync(colors.background.default);
|
|
|
|
|
if (Platform.OS === 'web' && typeof document !== 'undefined') {
|
|
|
|
|
const meta = document.querySelector('meta[name="theme-color"]');
|
|
|
|
|
if (meta) {
|
|
|
|
|
meta.setAttribute('content', colors.background.default);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, [colors.background.default]);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-24 14:21:31 +08:00
|
|
|
function NotificationBootstrap() {
|
|
|
|
|
const appState = useRef<AppStateStatus>(AppState.currentState);
|
2026-04-28 00:20:07 +08:00
|
|
|
const permissionRequested = useRef(false);
|
|
|
|
|
const router = useRouter();
|
2026-03-24 14:21:31 +08:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const initNotifications = async () => {
|
2026-04-13 01:30:37 +08:00
|
|
|
const { loadNotificationPreferences } = await import('@/services/notification');
|
2026-03-25 01:30:00 +08:00
|
|
|
await loadNotificationPreferences();
|
2026-04-13 01:30:37 +08:00
|
|
|
const { systemNotificationService } = await import('@/services/notification');
|
2026-03-24 14:21:31 +08:00
|
|
|
await systemNotificationService.initialize();
|
2026-04-13 01:30:37 +08:00
|
|
|
const { initBackgroundService } = await import('@/services/background');
|
2026-06-15 20:43:15 +08:00
|
|
|
// 默认静默模式,不会注册后台任务,不会触发自启动
|
2026-03-24 14:21:31 +08:00
|
|
|
await initBackgroundService();
|
|
|
|
|
|
|
|
|
|
const subscription = AppState.addEventListener('change', (nextAppState) => {
|
|
|
|
|
if (appState.current.match(/inactive|background/) && nextAppState === 'active') {
|
|
|
|
|
systemNotificationService.clearBadge();
|
|
|
|
|
}
|
|
|
|
|
appState.current = nextAppState;
|
|
|
|
|
});
|
|
|
|
|
|
2026-04-28 00:20:07 +08:00
|
|
|
// Listen for JPush notification taps — navigate to the relevant screen
|
2026-04-27 23:21:08 +08:00
|
|
|
jpushService.onNotification((message) => {
|
2026-04-28 00:20:07 +08:00
|
|
|
console.log('[NotificationBootstrap] JPush notification:', message.notificationEventType, message);
|
|
|
|
|
if (message.notificationEventType !== 'notificationOpened') return;
|
|
|
|
|
|
|
|
|
|
const extras = message.extras || {};
|
|
|
|
|
const notifType = extras.notification_type || message.notificationType;
|
|
|
|
|
|
2026-04-28 14:53:32 +08:00
|
|
|
if (notifType === 'chat_message' || notifType === 'chat') {
|
|
|
|
|
const conversationId = extras.conversation_id || extras.conversationId;
|
|
|
|
|
const senderId = extras.sender_id || extras.senderId;
|
|
|
|
|
const conversationType = extras.conversation_type || extras.conversationType;
|
|
|
|
|
const groupId = extras.group_id || extras.groupId;
|
|
|
|
|
const groupName = extras.group_name || extras.groupName;
|
2026-05-13 00:31:44 +08:00
|
|
|
const groupAvatar = extras.group_avatar || extras.groupAvatar;
|
2026-04-28 14:53:32 +08:00
|
|
|
|
|
|
|
|
if (conversationId) {
|
|
|
|
|
const isGroup = conversationType === 'group';
|
2026-06-12 23:42:09 +08:00
|
|
|
router.push(
|
|
|
|
|
hrefs.hrefChat({
|
|
|
|
|
conversationId,
|
|
|
|
|
userId: isGroup ? undefined : senderId,
|
|
|
|
|
isGroupChat: isGroup,
|
|
|
|
|
groupId: isGroup ? groupId : undefined,
|
|
|
|
|
groupName: isGroup ? groupName : undefined,
|
|
|
|
|
groupAvatar: isGroup ? groupAvatar : undefined,
|
|
|
|
|
})
|
|
|
|
|
);
|
2026-04-28 14:53:32 +08:00
|
|
|
} else {
|
2026-06-12 23:42:09 +08:00
|
|
|
router.push(hrefs.hrefNotifications());
|
2026-04-28 14:53:32 +08:00
|
|
|
}
|
2026-04-28 00:20:07 +08:00
|
|
|
} else {
|
2026-06-12 23:42:09 +08:00
|
|
|
router.push(hrefs.hrefNotifications());
|
2026-04-28 00:20:07 +08:00
|
|
|
}
|
2026-04-27 23:21:08 +08:00
|
|
|
});
|
2026-03-24 14:21:31 +08:00
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
subscription.remove();
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-28 00:20:07 +08:00
|
|
|
const requestPermissionOnLaunch = async () => {
|
|
|
|
|
if (permissionRequested.current) return;
|
|
|
|
|
permissionRequested.current = true;
|
|
|
|
|
|
|
|
|
|
if (Platform.OS === 'web') return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const hasPermission = await jpushService.checkNotificationPermission();
|
|
|
|
|
if (!hasPermission) {
|
|
|
|
|
await jpushService.requestNotificationPermission();
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.warn('[NotificationBootstrap] request permission on launch failed:', error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-24 14:21:31 +08:00
|
|
|
initNotifications();
|
2026-04-28 00:20:07 +08:00
|
|
|
requestPermissionOnLaunch();
|
2026-03-24 14:21:31 +08:00
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 03:41:43 +08:00
|
|
|
function APKUpdateBootstrap() {
|
|
|
|
|
const hasChecked = useRef(false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (hasChecked.current) return;
|
|
|
|
|
hasChecked.current = true;
|
|
|
|
|
|
|
|
|
|
// 延迟执行,避免与启动流程冲突
|
|
|
|
|
const timer = setTimeout(() => {
|
|
|
|
|
checkForAPKUpdate().catch((error) => {
|
|
|
|
|
console.error('APK update check failed:', error);
|
|
|
|
|
});
|
|
|
|
|
}, 3000);
|
|
|
|
|
|
|
|
|
|
return () => clearTimeout(timer);
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-03 01:56:02 +08:00
|
|
|
function CallKeepBootstrap() {
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (Platform.OS === 'web') return;
|
|
|
|
|
|
|
|
|
|
callKeepService.initialize({
|
|
|
|
|
onSystemAnswered: () => {
|
|
|
|
|
callStore.getState().handleSystemAnswer();
|
|
|
|
|
},
|
|
|
|
|
onSystemEnded: () => {
|
|
|
|
|
callStore.getState().endCall('ended');
|
|
|
|
|
},
|
|
|
|
|
onSystemMuted: (muted: boolean) => {
|
|
|
|
|
callStore.getState().handleSystemMuted(muted);
|
|
|
|
|
},
|
|
|
|
|
onIncomingCallFromPush: (session) => {
|
|
|
|
|
callStore.getState().handleIncomingFromPush(session);
|
|
|
|
|
},
|
|
|
|
|
onOutgoingStarted: () => {
|
|
|
|
|
// Outgoing call accepted by system — no action needed,
|
|
|
|
|
// the WS call_invited / call_accepted flow handles everything
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
callKeepService.dispose();
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 05:16:54 +08:00
|
|
|
function ThemedStack() {
|
2026-03-24 14:21:31 +08:00
|
|
|
const router = useRouter();
|
2026-03-25 05:16:54 +08:00
|
|
|
const resolved = useResolvedColorScheme();
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<StatusBar style={resolved === 'dark' ? 'light' : 'dark'} />
|
|
|
|
|
<SystemChrome />
|
2026-04-12 18:14:29 +08:00
|
|
|
<EventSubscriber />
|
2026-06-16 19:03:26 +08:00
|
|
|
<NotificationBootstrap />
|
|
|
|
|
<APKUpdateBootstrap />
|
|
|
|
|
<CallKeepBootstrap />
|
|
|
|
|
<Stack screenOptions={{ headerShown: false }}>
|
|
|
|
|
<Stack.Screen name="index" options={{ headerShown: false }} />
|
|
|
|
|
<Stack.Screen name="(auth)" options={{ headerShown: false }} />
|
|
|
|
|
<Stack.Screen name="(app)" options={{ headerShown: false }} />
|
|
|
|
|
<Stack.Screen name="privacy" options={{ headerShown: false }} />
|
|
|
|
|
<Stack.Screen name="terms" options={{ headerShown: false }} />
|
|
|
|
|
</Stack>
|
2026-03-25 05:16:54 +08:00
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ThemedProviders({ children }: { children: React.ReactNode }) {
|
|
|
|
|
const theme = usePaperThemeFromStore();
|
|
|
|
|
return <PaperProvider theme={theme}>{children}</PaperProvider>;
|
|
|
|
|
}
|
2026-03-24 14:21:31 +08:00
|
|
|
|
2026-03-25 05:16:54 +08:00
|
|
|
export default function RootLayout() {
|
2026-04-26 17:13:43 +08:00
|
|
|
const [fontsLoaded] = useFonts({});
|
|
|
|
|
|
|
|
|
|
if (!fontsLoaded) {
|
|
|
|
|
return (
|
|
|
|
|
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
|
|
|
|
<ActivityIndicator />
|
|
|
|
|
</View>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-24 14:21:31 +08:00
|
|
|
return (
|
|
|
|
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
|
|
|
<SafeAreaProvider>
|
2026-03-25 05:16:54 +08:00
|
|
|
<ThemedProviders>
|
2026-03-24 14:21:31 +08:00
|
|
|
<QueryClientProvider client={queryClient}>
|
2026-03-25 05:16:54 +08:00
|
|
|
<ThemeBootstrap />
|
|
|
|
|
<ThemedStack />
|
2026-03-24 14:21:31 +08:00
|
|
|
<AppPromptBar />
|
|
|
|
|
<AppDialogHost />
|
2026-03-27 17:12:19 +08:00
|
|
|
<IncomingCallModal />
|
|
|
|
|
<CallScreen />
|
|
|
|
|
<FloatingCallWindow />
|
2026-03-24 14:21:31 +08:00
|
|
|
</QueryClientProvider>
|
2026-03-25 05:16:54 +08:00
|
|
|
</ThemedProviders>
|
2026-03-24 14:21:31 +08:00
|
|
|
</SafeAreaProvider>
|
|
|
|
|
</GestureHandlerRootView>
|
|
|
|
|
);
|
|
|
|
|
}
|