feat(CommentItem, PostDetailScreen, ReportDialog): integrate report functionality
Some checks failed
Frontend CI / build-and-push-web (push) Successful in 2m54s
Frontend CI / build-android-apk (push) Has been cancelled
Frontend CI / ota-android (push) Has been cancelled

- Added report button to CommentItem for reporting comments and replies.
- Integrated ReportDialog into PostDetailScreen for handling report submissions.
- Enhanced ReportDialog with detailed report reasons and improved UI interactions.
- Updated styles across various components for a more modern look and feel.

Made-with: Cursor
This commit is contained in:
lafay
2026-03-30 17:53:30 +08:00
parent e0ee29caf8
commit 774b5c4b47
14 changed files with 793 additions and 373 deletions

View File

@@ -39,7 +39,7 @@ import { useCurrentUser } from '../../stores/authStore';
import { postService, commentService, uploadService, authService, showPrompt, voteService } from '../../services';
import { processPostUseCase } from '../../core/usecases/ProcessPostUseCase';
import { useCursorPagination } from '../../hooks/useCursorPagination';
import { CommentItem, VoteCard } from '../../components/business';
import { CommentItem, VoteCard, ReportDialog } from '../../components/business';
import { Avatar, Button, Loading, EmptyState, Text, ImageGallery, ImageGrid, ImageGridItem, AdaptiveLayout, AppBackButton } from '../../components/common';
import { useResponsive, useResponsiveValue, useResponsiveSpacing } from '../../hooks/useResponsive';
import * as hrefs from '../../navigation/hrefs';
@@ -177,6 +177,10 @@ export const PostDetailScreen: React.FC = () => {
const flatListRef = useRef<FlatList>(null);
const hasRecordedView = useRef(false); // 是否已记录浏览量
// 举报相关状态
const [reportDialogVisible, setReportDialogVisible] = useState(false);
const [reportTarget, setReportTarget] = useState<{ type: 'post' | 'comment'; id: string } | null>(null);
// 投票相关状态
const [voteResult, setVoteResult] = useState<VoteResultDTO | null>(null);
const [isVoteLoading, setIsVoteLoading] = useState(false);
@@ -1243,6 +1247,25 @@ export const PostDetailScreen: React.FC = () => {
</TouchableOpacity>
</View>
)}
{/* 举报按钮 - 只对非帖子作者显示 */}
{currentUser?.id !== post.author?.id && (
<TouchableOpacity
style={styles.reportButtonInline}
onPress={() => {
setReportTarget({ type: 'post', id: post.id });
setReportDialogVisible(true);
}}
>
<MaterialCommunityIcons
name="flag-outline"
size={14}
color={colors.text.hint}
/>
<Text variant="caption" color={colors.text.hint} style={styles.reportButtonText}>
</Text>
</TouchableOpacity>
)}
</View>
{/* 底部操作栏 - QQ频道风格 */}
@@ -1347,6 +1370,12 @@ export const PostDetailScreen: React.FC = () => {
}
};
// 处理举报评论
const handleReportComment = useCallback((comment: Comment) => {
setReportTarget({ type: 'comment', id: comment.id });
setReportDialogVisible(true);
}, []);
// 渲染评论 - 带楼层号
const commentKeyExtractor = useCallback((item: Comment) => item.id, []);
@@ -1372,9 +1401,10 @@ export const PostDetailScreen: React.FC = () => {
onDelete={handleDeleteComment}
onImagePress={handleImagePress}
currentUserId={currentUser?.id}
onReport={handleReportComment}
/>
);
}, [currentUser?.id, handleDeleteComment, handleImagePress, handleLikeComment, handleLoadMoreReplies, post?.user_id]);
}, [currentUser?.id, handleDeleteComment, handleImagePress, handleLikeComment, handleLoadMoreReplies, post?.user_id, handleReportComment]);
// 渲染空评论 - 现代化设计
const renderEmptyComments = useCallback(() => (
@@ -1696,6 +1726,20 @@ export const PostDetailScreen: React.FC = () => {
onClose={() => setShowImageModal(false)}
enableSave
/>
{/* 举报对话框 */}
<ReportDialog
visible={reportDialogVisible}
targetType={reportTarget?.type || 'post'}
targetId={reportTarget?.id || ''}
onClose={() => {
setReportDialogVisible(false);
setReportTarget(null);
}}
onSuccess={() => {
setReportTarget(null);
}}
/>
</SafeAreaView>
);
};
@@ -1858,7 +1902,13 @@ function createPostDetailStyles(colors: AppColors) {
alignItems: 'center',
padding: spacing.xs,
},
editButtonText: {
reportButtonInline: {
flexDirection: 'row',
alignItems: 'center',
marginLeft: spacing.sm,
padding: spacing.xs,
},
reportButtonText: {
marginLeft: 2,
fontSize: fontSizes.sm,
},