feat(post): add post reference functionality with inline cards and suggestion search
Some checks failed
Frontend CI / build-and-push-web (push) Failing after 2m42s
Frontend CI / build-android-apk (push) Has been cancelled
Frontend CI / ota-android (push) Has been cancelled

Add support for referencing/quoting other posts within post content. Includes:
- New `post_ref` segment type with `PostRefSegmentData` interface for post references
- New `PostRefCard` component to display referenced posts inline
- Post suggestion search triggered by `#` in `PostMentionInput`
- Updated `PostContentRenderer` to render post reference segments
- Add `suggestPosts` and `recordRefClick` API methods in postService

Additional improvements:
- Add image gallery preview for user profile covers and avatars
- Make text selectable across CommentItem, PostContentRenderer, and PostDetailScreen
- Migrate FlatList to FlashList in PostDetailScreen and UserProfileScreen
- Add nestedScrollEnabled to CreatePostScreen
- Add clickable member avatars in GroupMembersScreen
This commit is contained in:
lafay
2026-04-26 01:11:30 +08:00
parent 5fa5403d6a
commit 2dc6936aac
11 changed files with 554 additions and 193 deletions

View File

@@ -150,7 +150,7 @@ export type MessageStatus = 'normal' | 'recalled' | 'deleted';
// ==================== Message Segment Types ====================
// Segment类型
export type SegmentType = 'text' | 'image' | 'voice' | 'video' | 'file' | 'at' | 'reply' | 'face' | 'link' | 'vote';
export type SegmentType = 'text' | 'image' | 'voice' | 'video' | 'file' | 'at' | 'reply' | 'face' | 'link' | 'vote' | 'post_ref';
// 文本Segment数据
export interface TextSegmentData {
@@ -232,6 +232,20 @@ export interface VoteSegmentData {
is_multi_choice?: boolean;
}
// 帖子内链Segment数据
export interface PostRefSegmentData {
post_id: string;
title?: string;
author?: {
id: string;
nickname: string;
avatar?: string;
};
status?: string;
accessible?: boolean;
click_count?: number;
}
// MessageSegment 联合类型 - 使用 discriminated union
export type MessageSegment =
| { type: 'text'; data: TextSegmentData }
@@ -243,7 +257,8 @@ export type MessageSegment =
| { type: 'reply'; data: ReplySegmentData }
| { type: 'face'; data: FaceSegmentData }
| { type: 'link'; data: LinkSegmentData }
| { type: 'vote'; data: VoteSegmentData };
| { type: 'vote'; data: VoteSegmentData }
| { type: 'post_ref'; data: PostRefSegmentData };
// 消息响应
export interface MessageResponse {
@@ -787,6 +802,10 @@ export function extractTextFromSegments(segments?: MessageSegment[], memberMap?:
case 'reply':
// 回复不显示在预览中
break;
case 'post_ref':
const refData = segment.data as PostRefSegmentData;
result += refData.title ? `[帖子: ${refData.title}]` : '[帖子引用]';
break;
}
}
@@ -967,6 +986,10 @@ export async function extractTextFromSegmentsAsync(
case 'reply':
// 回复不显示在预览中
break;
case 'post_ref':
const refDataAsync = segment.data as PostRefSegmentData;
result += refDataAsync.title ? `[帖子: ${refDataAsync.title}]` : '[帖子引用]';
break;
}
}