Initial commit: OmniAI Web Frontend
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Shared mention trigger detection.
|
||||
*
|
||||
* Detects when the user has typed "@" followed by an optional query
|
||||
* at the cursor position, and returns the match info for opening
|
||||
* a mention panel.
|
||||
*/
|
||||
|
||||
/** Characters that BLOCK @ trigger (only @ itself, to prevent @@). */
|
||||
const BLOCKED_BEFORE_AT = /[@]/;
|
||||
|
||||
export interface MentionTriggerMatch {
|
||||
/** Index of the @ character in the full text. */
|
||||
atIndex: number;
|
||||
/** The query text after @ (may be empty). */
|
||||
query: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the text before the cursor contains an active @ mention trigger.
|
||||
*
|
||||
* Rules:
|
||||
* - @ must be at position 0, or preceded by a boundary character
|
||||
* (whitespace, Chinese/English punctuation, brackets).
|
||||
* - The query (text after @ up to the cursor) must not contain
|
||||
* any boundary character or space.
|
||||
* - Returns null if no trigger is found.
|
||||
*/
|
||||
export function detectMentionTrigger(textBeforeCursor: string): MentionTriggerMatch | null {
|
||||
const atIdx = textBeforeCursor.lastIndexOf("@");
|
||||
if (atIdx < 0) return null;
|
||||
|
||||
// @ must be at start or not preceded by another @
|
||||
if (atIdx > 0 && BLOCKED_BEFORE_AT.test(textBeforeCursor[atIdx - 1])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const query = textBeforeCursor.slice(atIdx + 1);
|
||||
|
||||
// Query must not contain spaces or punctuation that would break a mention token
|
||||
if (/[\s,。、;:!??!.,;:(){}\[\]<>""''《》【】@]/.test(query)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { atIndex: atIdx, query };
|
||||
}
|
||||
|
||||
/** Token pattern for @图片1, @视频1, @文本1, @音频1, @附件1, @素材1, etc. */
|
||||
export const MENTION_TOKEN_RE = /@(?:图片|视频|文本|音频|附件|素材)\d+/g;
|
||||
Reference in New Issue
Block a user