feat(ui): redesign system message item with card-style layout and add title validation
- Refactor SystemMessageItem with modern card design, gradient colors, and improved visual hierarchy - Add unread indicator, status badges, and enhanced avatar badges for message types - Update CreatePostScreen to require title input and improve placeholder text - Add Android back button handling for notification screens in embedded mode - Replace manual shadow styles with theme shadow utilities across message screens
This commit is contained in:
@@ -337,6 +337,11 @@ export const CreatePostScreen: React.FC<CreatePostScreenProps> = (props) => {
|
||||
// 防止重复点击
|
||||
if (posting) return;
|
||||
|
||||
if (!title.trim()) {
|
||||
Alert.alert('错误', '请输入帖子标题');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!content.trim()) {
|
||||
Alert.alert('错误', '请输入帖子内容');
|
||||
return;
|
||||
@@ -365,7 +370,7 @@ export const CreatePostScreen: React.FC<CreatePostScreenProps> = (props) => {
|
||||
|
||||
// 创建投票帖子
|
||||
await voteService.createVotePost({
|
||||
title: title.trim() || '无标题',
|
||||
title: title.trim(),
|
||||
content: content.trim(),
|
||||
images: imageUrls,
|
||||
vote_options: validOptions,
|
||||
@@ -383,7 +388,7 @@ export const CreatePostScreen: React.FC<CreatePostScreenProps> = (props) => {
|
||||
} else {
|
||||
if (isEditMode && editPostID) {
|
||||
const updated = await postService.updatePost(editPostID, {
|
||||
title: title.trim() || '无标题',
|
||||
title: title.trim(),
|
||||
content: content.trim(),
|
||||
images: imageUrls,
|
||||
});
|
||||
@@ -403,7 +408,7 @@ export const CreatePostScreen: React.FC<CreatePostScreenProps> = (props) => {
|
||||
} else {
|
||||
// 创建普通帖子
|
||||
await postService.createPost({
|
||||
title: title.trim() || '无标题',
|
||||
title: title.trim(),
|
||||
content: content.trim(),
|
||||
images: imageUrls,
|
||||
});
|
||||
@@ -562,7 +567,7 @@ export const CreatePostScreen: React.FC<CreatePostScreenProps> = (props) => {
|
||||
]}
|
||||
value={title}
|
||||
onChangeText={setTitle}
|
||||
placeholder="添加标题(可选)"
|
||||
placeholder="请输入标题(必填)"
|
||||
placeholderTextColor={colors.text.hint}
|
||||
maxLength={MAX_TITLE_LENGTH}
|
||||
/>
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
Animated,
|
||||
TextInput,
|
||||
Keyboard,
|
||||
BackHandler,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useNavigation, useIsFocused } from '@react-navigation/native';
|
||||
@@ -283,6 +284,19 @@ export const MessageListScreen: React.FC = () => {
|
||||
}
|
||||
}, [isFocused]);
|
||||
|
||||
// 处理 Android 物理返回键 - 当显示通知页面时,返回键关闭通知页面
|
||||
useEffect(() => {
|
||||
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
|
||||
if (showNotifications) {
|
||||
setShowNotifications(false);
|
||||
return true; // 阻止默认行为
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return () => backHandler.remove();
|
||||
}, [showNotifications]);
|
||||
|
||||
// 下拉刷新
|
||||
const onRefresh = useCallback(async () => {
|
||||
setRefreshing(true);
|
||||
|
||||
@@ -14,13 +14,14 @@ import {
|
||||
RefreshControl,
|
||||
ActivityIndicator,
|
||||
Dimensions,
|
||||
BackHandler,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useIsFocused } from '@react-navigation/native';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
import { colors, spacing, borderRadius } from '../../theme';
|
||||
import { colors, spacing, borderRadius, shadows } from '../../theme';
|
||||
import { SystemMessageResponse } from '../../types/dto';
|
||||
import { messageService } from '../../services/messageService';
|
||||
import { commentService } from '../../services/commentService';
|
||||
@@ -182,6 +183,21 @@ export const NotificationsScreen: React.FC<{ onBack?: () => void }> = ({ onBack
|
||||
}
|
||||
}, [isFocused, onBack]);
|
||||
|
||||
// 处理 Android 物理返回键 - 当 onBack 存在时(内嵌模式),拦截返回键
|
||||
useEffect(() => {
|
||||
if (!onBack) return;
|
||||
|
||||
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
|
||||
if (isFocused) {
|
||||
onBack();
|
||||
return true; // 阻止默认行为
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return () => backHandler.remove();
|
||||
}, [isFocused, onBack]);
|
||||
|
||||
// 筛选消息
|
||||
const filteredMessages = activeType === 'all'
|
||||
? displayMessages
|
||||
@@ -558,12 +574,7 @@ const styles = StyleSheet.create({
|
||||
paddingHorizontal: spacing.lg,
|
||||
paddingVertical: spacing.md,
|
||||
backgroundColor: colors.background.paper,
|
||||
// 移除底部边框,使用更柔和的分隔方式
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 2,
|
||||
elevation: 2,
|
||||
...shadows.sm,
|
||||
},
|
||||
headerWide: {
|
||||
paddingHorizontal: spacing.xl,
|
||||
@@ -613,7 +624,6 @@ const styles = StyleSheet.create({
|
||||
paddingHorizontal: spacing.md,
|
||||
paddingVertical: spacing.sm,
|
||||
backgroundColor: colors.background.paper,
|
||||
// 移除底部边框,让界面更简洁
|
||||
},
|
||||
filterContainerWideWeb: {
|
||||
paddingHorizontal: spacing.xl,
|
||||
@@ -629,6 +639,8 @@ const styles = StyleSheet.create({
|
||||
marginRight: spacing.xs,
|
||||
borderRadius: borderRadius.lg,
|
||||
backgroundColor: colors.background.default,
|
||||
borderWidth: 1,
|
||||
borderColor: 'transparent',
|
||||
},
|
||||
filterTagWide: {
|
||||
paddingHorizontal: spacing.lg,
|
||||
@@ -637,6 +649,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
filterTagActive: {
|
||||
backgroundColor: colors.primary.main,
|
||||
borderColor: colors.primary.main,
|
||||
},
|
||||
filterTagTextActive: {
|
||||
fontWeight: '600',
|
||||
@@ -655,7 +668,8 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
listContent: {
|
||||
flexGrow: 1,
|
||||
paddingTop: spacing.sm,
|
||||
paddingTop: spacing.md,
|
||||
paddingBottom: spacing.lg,
|
||||
},
|
||||
listContentWide: {
|
||||
paddingHorizontal: spacing.xl,
|
||||
@@ -679,6 +693,7 @@ const styles = StyleSheet.create({
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
paddingTop: spacing['3xl'],
|
||||
},
|
||||
emptyContainerWeb: {
|
||||
minHeight: 500,
|
||||
|
||||
Reference in New Issue
Block a user