refactor(App, navigation): migrate to Expo Router and clean up navigation structure
- 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:
@@ -1,16 +1,13 @@
|
||||
import React from 'react';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, Alert, ScrollView, Pressable } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { RouteProp, useNavigation, useRoute } from '@react-navigation/native';
|
||||
import { useRouter, useLocalSearchParams } from 'expo-router';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
|
||||
import type { ScheduleStackParamList } from '../../navigation/types';
|
||||
import { colors, spacing, borderRadius, fontSizes, shadows } from '../../theme';
|
||||
import { routePayloadCache } from '../../stores/routePayloadCache';
|
||||
import { scheduleService } from '../../services/scheduleService';
|
||||
|
||||
type CourseDetailRouteProp = RouteProp<ScheduleStackParamList, 'CourseDetail'>;
|
||||
|
||||
const WEEKDAY_NAMES = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
|
||||
const getMergedSectionIndex = (section: number) => Math.ceil(section / 2);
|
||||
|
||||
@@ -36,13 +33,17 @@ const formatWeekRanges = (weeks: number[]) => {
|
||||
};
|
||||
|
||||
const CourseDetailScreen: React.FC = () => {
|
||||
const route = useRoute<CourseDetailRouteProp>();
|
||||
const navigation = useNavigation<NativeStackNavigationProp<ScheduleStackParamList>>();
|
||||
const { course, relatedCourses } = route.params;
|
||||
const router = useRouter();
|
||||
const { courseId } = useLocalSearchParams<{ courseId?: string }>();
|
||||
const cached = courseId ? routePayloadCache.getCourseDetail(courseId) : undefined;
|
||||
const course = cached?.course;
|
||||
const relatedCourses = cached?.relatedCourses ?? [];
|
||||
|
||||
const timeLines = relatedCourses.length > 0 ? relatedCourses : [course];
|
||||
const timeLines =
|
||||
relatedCourses.length > 0 ? relatedCourses : course ? [course] : [];
|
||||
|
||||
const handleDeleteCourse = () => {
|
||||
if (!course) return;
|
||||
Alert.alert('删除课程', '确认删除这条课程安排吗?', [
|
||||
{ text: '取消', style: 'cancel' },
|
||||
{
|
||||
@@ -52,7 +53,7 @@ const CourseDetailScreen: React.FC = () => {
|
||||
try {
|
||||
await scheduleService.deleteCourse(course.id);
|
||||
Alert.alert('删除成功', '课程已删除');
|
||||
navigation.goBack();
|
||||
router.back();
|
||||
} catch (error) {
|
||||
console.error('删除课程失败:', error);
|
||||
Alert.alert('删除失败', '删除课程失败,请稍后重试');
|
||||
@@ -62,10 +63,20 @@ const CourseDetailScreen: React.FC = () => {
|
||||
]);
|
||||
};
|
||||
|
||||
if (!course) {
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.mask}>
|
||||
<Pressable style={StyleSheet.absoluteFillObject} onPress={() => router.back()} />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.mask}>
|
||||
<Pressable style={StyleSheet.absoluteFillObject} onPress={() => navigation.goBack()} />
|
||||
<Pressable style={StyleSheet.absoluteFillObject} onPress={() => router.back()} />
|
||||
<View style={styles.card}>
|
||||
<View style={styles.header}>
|
||||
<View style={styles.headerLeft}>
|
||||
@@ -74,7 +85,7 @@ const CourseDetailScreen: React.FC = () => {
|
||||
</View>
|
||||
<Text style={styles.title}>课程详情</Text>
|
||||
</View>
|
||||
<TouchableOpacity onPress={() => navigation.goBack()} style={styles.closeButton} hitSlop={10}>
|
||||
<TouchableOpacity onPress={() => router.back()} style={styles.closeButton} hitSlop={10}>
|
||||
<MaterialCommunityIcons name="close" size={18} color={colors.text.secondary} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
@@ -21,8 +21,8 @@ import { PanGestureHandler, State } from 'react-native-gesture-handler';
|
||||
import type { PanGestureHandlerStateChangeEvent } from 'react-native-gesture-handler';
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
import { useFocusEffect, useNavigation } from '@react-navigation/native';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { useFocusEffect } from '@react-navigation/native';
|
||||
import { useRouter } from 'expo-router';
|
||||
import { colors, fontSizes, spacing, borderRadius, shadows } from '../../theme';
|
||||
import { useResponsive } from '../../hooks/useResponsive';
|
||||
import {
|
||||
@@ -32,7 +32,8 @@ import {
|
||||
getCourseColor,
|
||||
hasCourseInWeek,
|
||||
} from '../../types/schedule';
|
||||
import type { ScheduleStackParamList } from '../../navigation/types';
|
||||
import * as hrefs from '../../navigation/hrefs';
|
||||
import { routePayloadCache } from '../../stores/routePayloadCache';
|
||||
import { scheduleService } from '../../services/scheduleService';
|
||||
|
||||
const { width: SCREEN_WIDTH } = Dimensions.get('window');
|
||||
@@ -147,7 +148,7 @@ const getWeekDates = (weekOffset: number = 0) => {
|
||||
const INITIAL_WEEK = getCurrentWeekNumber();
|
||||
|
||||
export const ScheduleScreen: React.FC = () => {
|
||||
const navigation = useNavigation<NativeStackNavigationProp<ScheduleStackParamList>>();
|
||||
const router = useRouter();
|
||||
// 使用响应式 hook 检测屏幕尺寸
|
||||
const { width: screenWidth, height: screenHeight, isMobile, platform } = useResponsive();
|
||||
const insets = useSafeAreaInsets();
|
||||
@@ -616,12 +617,11 @@ export const ScheduleScreen: React.FC = () => {
|
||||
width: cardWidth,
|
||||
},
|
||||
]}
|
||||
onPress={() =>
|
||||
navigation.navigate('CourseDetail', {
|
||||
course,
|
||||
relatedCourses: getRelatedCourses(course),
|
||||
})
|
||||
}
|
||||
onPress={() => {
|
||||
const related = getRelatedCourses(course);
|
||||
routePayloadCache.stashCourseDetail(course, related);
|
||||
router.push(hrefs.hrefScheduleCourse(String(course.id)));
|
||||
}}
|
||||
onLongPress={() => handleCourseLongPress(course)}
|
||||
delayLongPress={500}
|
||||
activeOpacity={0.82}
|
||||
|
||||
Reference in New Issue
Block a user