refactor(App, navigation): migrate to Expo Router and clean up navigation structure
All checks were successful
Frontend CI / build-and-push-web (push) Successful in 4m27s
Frontend CI / ota-android (push) Successful in 11m6s
Frontend CI / build-android-apk (push) Successful in 1h16m45s

- Updated App entry point to utilize Expo Router, simplifying the navigation setup.
- Removed legacy navigation components and services to streamline the codebase.
- Adjusted package.json to reflect the new entry point and updated dependencies for compatibility.
- Enhanced overall application structure by consolidating navigation logic and improving maintainability.
This commit is contained in:
lafay
2026-03-24 14:21:31 +08:00
parent b91e78c921
commit 2ddb9cadd8
111 changed files with 1829 additions and 3214 deletions

View File

@@ -1,25 +1,38 @@
import React, { useEffect, useMemo, useState } from 'react';
import { View, StyleSheet, TouchableOpacity, Alert, ScrollView } from 'react-native';
import { useNavigation, useRoute, RouteProp } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useRouter, useLocalSearchParams } from 'expo-router';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { SafeAreaView } from 'react-native-safe-area-context';
import { colors, spacing, borderRadius, shadows } from '../../theme';
import { Avatar, Text } from '../../components/common';
import { RootStackParamList } from '../../navigation/types';
import * as hrefs from '../../navigation/hrefs';
import { routePayloadCache } from '../../stores/routePayloadCache';
import { groupService } from '../../services/groupService';
import { groupManager } from '../../stores/groupManager';
import { userManager } from '../../stores/userManager';
import { GroupInfoSummaryCard, DecisionFooter } from './components/GroupRequestShared';
type Route = RouteProp<RootStackParamList, 'GroupRequestDetail'>;
type Navigation = NativeStackNavigationProp<RootStackParamList>;
const GroupRequestDetailScreen: React.FC = () => {
const route = useRoute<Route>();
const navigation = useNavigation<Navigation>();
const { message } = route.params;
const router = useRouter();
const { messageId } = useLocalSearchParams<{ messageId?: string }>();
const message = messageId ? routePayloadCache.getSystemMessage(messageId) : undefined;
if (!message) {
return (
<SafeAreaView style={styles.container} edges={['bottom']}>
<View style={styles.emptyWrap}>
<Text variant="body" color="secondary">
</Text>
<TouchableOpacity onPress={() => router.back()} style={styles.backBtn}>
<Text variant="body"></Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
const { extra_data } = message;
const [submitting, setSubmitting] = useState(false);
const [memberCount, setMemberCount] = useState<number | null>(null);
@@ -64,7 +77,7 @@ const GroupRequestDetailScreen: React.FC = () => {
if (!extra_data?.group_id) return;
setLoadingGroup(true);
try {
const group = await groupManager.getGroup(extra_data.group_id);
const group = await groupManager.getGroup(String(extra_data.group_id));
setMemberCount(group.member_count ?? null);
} catch {
setMemberCount(null);
@@ -90,18 +103,18 @@ const GroupRequestDetailScreen: React.FC = () => {
setSubmitting(true);
try {
if (message.system_type === 'group_invite') {
await groupService.respondInvite(groupId, {
await groupService.respondInvite(String(groupId), {
flag,
approve,
});
} else {
await groupService.reviewJoinRequest(groupId, {
await groupService.reviewJoinRequest(String(groupId), {
flag,
approve,
});
}
Alert.alert('成功', approve ? '已同意申请' : '已拒绝申请', [
{ text: '确定', onPress: () => navigation.goBack() },
{ text: '确定', onPress: () => router.back() },
]);
} catch (error) {
Alert.alert('操作失败', '请稍后重试');
@@ -114,7 +127,7 @@ const GroupRequestDetailScreen: React.FC = () => {
if (!applicantId) return;
const user = await userManager.getUserById(applicantId);
if (user?.id) {
navigation.navigate('UserProfile', { userId: String(user.id) });
router.push(hrefs.hrefUserProfile(String(user.id)));
}
};
@@ -124,7 +137,7 @@ const GroupRequestDetailScreen: React.FC = () => {
<GroupInfoSummaryCard
groupName={extra_data?.group_name}
groupAvatar={extra_data?.group_avatar}
groupNo={extra_data?.group_id}
groupNo={String(extra_data?.group_id ?? '')}
groupDescription={extra_data?.group_description}
memberCountText={loadingGroup ? '人数加载中...' : `${memberCount ?? '-'}`}
/>
@@ -166,6 +179,16 @@ const styles = StyleSheet.create({
flex: 1,
backgroundColor: colors.background.default,
},
emptyWrap: {
flex: 1,
padding: spacing.lg,
justifyContent: 'center',
alignItems: 'center',
gap: spacing.md,
},
backBtn: {
padding: spacing.sm,
},
scrollView: {
flex: 1,
},