From c8eba28e7a131c0a29be85a3be93048053344f2b Mon Sep 17 00:00:00 2001 From: ZhenYi <434836402@qq.com> Date: Sun, 26 Apr 2026 23:58:59 +0800 Subject: [PATCH] feat(frontend): add repo type to mention autocomplete system Add 'repo' to MentionType across all editor types, include repos in the @ trigger pool, add repo badge (green chip), Repos section in the mention dropdown, and MentionBadge styles. Wire projectRepos from room context into IMEditor mentionItems. --- src/components/room/message/MessageInput.tsx | 12 +++++++++--- src/components/room/message/editor/IMEditor.tsx | 8 ++++++-- src/components/room/message/editor/types.ts | 2 +- src/components/shared/MentionBadge.tsx | 5 +++++ src/lib/mention.ts | 7 +++++++ 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/components/room/message/MessageInput.tsx b/src/components/room/message/MessageInput.tsx index 2276468..a1a8aea 100644 --- a/src/components/room/message/MessageInput.tsx +++ b/src/components/room/message/MessageInput.tsx @@ -76,7 +76,7 @@ export const MessageInput = forwardRef(fu {roomName, onSend, replyingTo, onCancelReply}, ref, ) { - const {members, activeRoomId, roomAiConfigs, wsClient} = useRoom(); + const {members, activeRoomId, roomAiConfigs, projectRepos, wsClient} = useRoom(); // Ref passed to the inner IMEditor const innerEditorRef = useRef(null); @@ -147,12 +147,18 @@ export const MessageInput = forwardRef(fu channels: [] as { id: string; label: string; type: 'channel'; avatar?: string }[], ai: roomAiConfigs.map((cfg) => ({ id: cfg.model, - label: cfg.modelName ?? cfg.model, + label: cfg.modelName || 'Unknown AI', type: 'ai' as const, })), + repos: projectRepos.map((r) => ({ + id: r.repo_name, + label: r.repo_name, + type: 'repo' as const, + description: r.description ?? undefined, + })), commands: SLASH_COMMANDS, specialMentions: SPECIAL_MENTIONS, - }), [members, roomAiConfigs]); + }), [members, roomAiConfigs, projectRepos]); // File upload handler — POST to /rooms/{room_id}/upload const handleUploadFile = async (file: File): Promise<{ id: string; url: string }> => { diff --git a/src/components/room/message/editor/IMEditor.tsx b/src/components/room/message/editor/IMEditor.tsx index 0a2cd0c..5533229 100644 --- a/src/components/room/message/editor/IMEditor.tsx +++ b/src/components/room/message/editor/IMEditor.tsx @@ -26,6 +26,7 @@ export interface IMEditorProps { users: MentionItem[]; channels: MentionItem[]; ai: MentionItem[]; + repos: MentionItem[]; commands: MentionItem[]; specialMentions?: MentionItem[]; }; @@ -151,6 +152,7 @@ function getBadge(type: MentionType): { label: string; cls: string } | null { if (type === 'ai') return {label: 'AI', cls: 'bg-blue-50 text-blue-600'}; if (type === 'channel') return {label: '#', cls: 'bg-gray-100 text-gray-500'}; if (type === 'command') return {label: 'cmd', cls: 'bg-amber-50 text-amber-600'}; + if (type === 'repo') return {label: 'repo', cls: 'bg-green-50 text-green-600'}; return null; } @@ -173,12 +175,13 @@ function serializeAstNode(node: EditorNode): string { // ─── Mention Dropdown (sectioned by type) ──────────────────────────────────── -const SECTION_ORDER = ['special_here', 'special_channel', 'ai', 'user', 'channel', 'command'] as const; +const SECTION_ORDER = ['special_here', 'special_channel', 'ai', 'user', 'repo', 'channel', 'command'] as const; const SECTION_LABELS: Record = { special_here: 'Notify', special_channel: 'Notify', ai: 'AI', user: 'Members', + repo: 'Repositories', channel: 'Channels', command: 'Commands', }; @@ -356,7 +359,8 @@ export const IMEditor = forwardRef(function IMEdi ...(mentionItems.specialMentions ?? []), ...mentionItems.ai, ...mentionItems.users, - ], [mentionItems.specialMentions, mentionItems.ai, mentionItems.users]); + ...mentionItems.repos, + ], [mentionItems.specialMentions, mentionItems.ai, mentionItems.users, mentionItems.repos]); const hashPool = useMemo(() => [...mentionItems.channels], [mentionItems.channels]); diff --git a/src/components/room/message/editor/types.ts b/src/components/room/message/editor/types.ts index e07a1ff..eef297b 100644 --- a/src/components/room/message/editor/types.ts +++ b/src/components/room/message/editor/types.ts @@ -2,7 +2,7 @@ * Core types for the IM editor (mentions, files, emojis). */ -export type MentionType = 'user' | 'channel' | 'ai' | 'command' | 'special_here' | 'special_channel'; +export type MentionType = 'user' | 'channel' | 'ai' | 'repo' | 'command' | 'special_here' | 'special_channel'; export interface MentionItem { id: string; diff --git a/src/components/shared/MentionBadge.tsx b/src/components/shared/MentionBadge.tsx index f60bc38..88c9b20 100644 --- a/src/components/shared/MentionBadge.tsx +++ b/src/components/shared/MentionBadge.tsx @@ -42,6 +42,11 @@ const TYPE_STYLE: Record