修复了课表周数硬编码
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
TouchableOpacity,
|
||||
RefreshControl,
|
||||
ActivityIndicator,
|
||||
Dimensions,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useIsFocused } from '@react-navigation/native';
|
||||
@@ -25,7 +26,6 @@ import { messageService } from '../../services/messageService';
|
||||
import { commentService } from '../../services/commentService';
|
||||
import { SystemMessageItem } from '../../components/business';
|
||||
import { Text, EmptyState, ResponsiveContainer } from '../../components/common';
|
||||
import { useResponsive, useBreakpointGTE } from '../../hooks/useResponsive';
|
||||
import { RootStackParamList } from '../../navigation/types';
|
||||
import { useMessageManagerSystemUnreadCount, useUserStore } from '../../stores';
|
||||
|
||||
@@ -48,9 +48,27 @@ export const NotificationsScreen: React.FC<{ onBack?: () => void }> = ({ onBack
|
||||
const { setSystemUnreadCount, decrementSystemUnreadCount } = useMessageManagerSystemUnreadCount();
|
||||
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
|
||||
|
||||
// 响应式布局
|
||||
const { isDesktop, isTablet } = useResponsive();
|
||||
const isWideScreen = useBreakpointGTE('lg');
|
||||
// 修复竞态条件:使用本地状态管理窗口尺寸,避免 hydration 问题
|
||||
const [windowSize, setWindowSize] = useState({ width: 0, height: 0 });
|
||||
const [isHydrated, setIsHydrated] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// 延迟设置窗口尺寸,确保在客户端完全加载后再获取
|
||||
const timer = setTimeout(() => {
|
||||
const { width, height } = Dimensions.get('window');
|
||||
setWindowSize({ width, height });
|
||||
setIsHydrated(true);
|
||||
}, 100);
|
||||
return () => clearTimeout(timer);
|
||||
}, []);
|
||||
|
||||
// 使用本地尺寸状态计算断点 (lg = 768)
|
||||
const isWideScreen = windowSize.width >= 768;
|
||||
const isDesktop = windowSize.width >= 1024;
|
||||
const isTablet = windowSize.width >= 768 && windowSize.width < 1024;
|
||||
|
||||
// Web端使用更大的容器宽度
|
||||
const containerMaxWidth = isDesktop ? 1200 : isTablet ? 1000 : 900;
|
||||
|
||||
const [messages, setMessages] = useState<SystemMessageResponse[]>([]);
|
||||
const [activeType, setActiveType] = useState('all');
|
||||
@@ -320,7 +338,7 @@ export const NotificationsScreen: React.FC<{ onBack?: () => void }> = ({ onBack
|
||||
const shouldShowBackButton = onBack && !isWideScreen;
|
||||
|
||||
return (
|
||||
<View style={[styles.header, isWideScreen && styles.headerWide]}>
|
||||
<View style={[styles.header, isWideScreen ? styles.headerWide : null]}>
|
||||
{shouldShowBackButton ? (
|
||||
<TouchableOpacity
|
||||
style={styles.backButton}
|
||||
@@ -342,21 +360,34 @@ export const NotificationsScreen: React.FC<{ onBack?: () => void }> = ({ onBack
|
||||
|
||||
// 渲染空状态
|
||||
const renderEmpty = () => (
|
||||
<EmptyState
|
||||
title="暂无通知"
|
||||
description="关注一些用户来获取通知吧"
|
||||
icon="bell-outline"
|
||||
/>
|
||||
<View style={[styles.emptyContainer, isWideScreen && styles.emptyContainerWeb]}>
|
||||
<EmptyState
|
||||
title="暂无通知"
|
||||
description="关注一些用户来获取通知吧"
|
||||
icon="bell-outline"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
// 如果还未hydrated,显示加载占位符,避免竞态条件导致的渲染问题
|
||||
if (!isHydrated) {
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={[]}>
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color={colors.primary.main} />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={[]}>
|
||||
{isWideScreen ? (
|
||||
<ResponsiveContainer maxWidth={900}>
|
||||
<ResponsiveContainer maxWidth={containerMaxWidth}>
|
||||
{/* 头部 - 大屏模式下隐藏返回按钮 */}
|
||||
{renderHeader()}
|
||||
{/* 分类筛选 */}
|
||||
<View style={[styles.filterContainer, isWideScreen && styles.filterContainerWide]}>
|
||||
<View style={[styles.filterContainer, isWideScreen && styles.filterContainerWideWeb]}>
|
||||
{MESSAGE_TYPES.map(type => {
|
||||
const count = type.key === 'all'
|
||||
? displayMessages.length
|
||||
@@ -518,10 +549,11 @@ const styles = StyleSheet.create({
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.divider,
|
||||
},
|
||||
filterContainerWide: {
|
||||
filterContainerWideWeb: {
|
||||
paddingHorizontal: spacing.xl,
|
||||
paddingVertical: spacing.md,
|
||||
justifyContent: 'center',
|
||||
backgroundColor: colors.background.paper,
|
||||
},
|
||||
filterTag: {
|
||||
flexDirection: 'row',
|
||||
@@ -596,4 +628,14 @@ const styles = StyleSheet.create({
|
||||
loadingMoreText: {
|
||||
marginLeft: spacing.sm,
|
||||
},
|
||||
emptyContainer: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
emptyContainerWeb: {
|
||||
minHeight: 500,
|
||||
justifyContent: 'center',
|
||||
paddingTop: 100,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user