diff --git a/extensions/matrix/src/matrix/monitor/mentions.ts b/extensions/matrix/src/matrix/monitor/mentions.ts index 70349a0a72a..38a99cfc712 100644 --- a/extensions/matrix/src/matrix/monitor/mentions.ts +++ b/extensions/matrix/src/matrix/monitor/mentions.ts @@ -66,25 +66,36 @@ function escapeRegExp(value: string): string { return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } -function appendUniqueMentionCandidate( - candidates: string[], - seen: Set, - candidate?: string | null, -) { - const trimmed = candidate?.trim(); - if (!trimmed) { - return; - } - const normalized = normalizeLowercaseStringOrEmpty(trimmed); - if (seen.has(normalized)) { - return; - } - seen.add(normalized); - candidates.push(trimmed); +function resolveMatrixMentionPrefixCandidates(params: { + userId?: string | null; + displayName?: string | null; +}): string[] { + const candidates: string[] = []; + const seen = new Set(); + + const append = (candidate?: string | null) => { + const trimmed = candidate?.trim(); + if (!trimmed) { + return; + } + const normalized = normalizeLowercaseStringOrEmpty(trimmed); + if (seen.has(normalized)) { + return; + } + seen.add(normalized); + candidates.push(trimmed); + }; + + append(params.userId); + const localpart = params.userId ? resolveMatrixUserLocalpart(params.userId) : null; + append(localpart ? `@${localpart}` : null); + append(params.displayName); + append(params.displayName ? `@${params.displayName}` : null); + + return candidates; } -function stripNativeMatrixMentionPrefix(text: string, candidate: string): string | null { - const pattern = new RegExp(`^\\s*${escapeRegExp(candidate)}(?:\\s*[:,])?(?:\\s+|$)`, "i"); +function stripMatchedMatrixMentionPrefix(text: string, pattern: RegExp): string | null { const match = text.match(pattern); if (!match) { return null; @@ -92,14 +103,15 @@ function stripNativeMatrixMentionPrefix(text: string, candidate: string): string return text.slice(match[0].length).trimStart(); } +function stripNativeMatrixMentionPrefix(text: string, candidate: string): string | null { + const pattern = new RegExp(`^\\s*${escapeRegExp(candidate)}(?:\\s*[:,])?(?:\\s+|$)`, "i"); + return stripMatchedMatrixMentionPrefix(text, pattern); +} + function stripRegexMatrixMentionPrefix(text: string, pattern: RegExp): string | null { const flags = pattern.flags.replace(/[gy]/g, ""); const anchored = new RegExp(`^\\s*(?:${pattern.source})(?:\\s*[:,])?(?:\\s+|$)`, flags); - const match = text.match(anchored); - if (!match) { - return null; - } - return text.slice(match[0].length).trimStart(); + return stripMatchedMatrixMentionPrefix(text, anchored); } export function stripMatrixMentionPrefix(params: { @@ -113,19 +125,7 @@ export function stripMatrixMentionPrefix(params: { return text; } - const candidates: string[] = []; - const seen = new Set(); - appendUniqueMentionCandidate(candidates, seen, params.userId); - const localpart = params.userId ? resolveMatrixUserLocalpart(params.userId) : null; - appendUniqueMentionCandidate(candidates, seen, localpart ? `@${localpart}` : null); - appendUniqueMentionCandidate(candidates, seen, params.displayName); - appendUniqueMentionCandidate( - candidates, - seen, - params.displayName ? `@${params.displayName}` : null, - ); - - for (const candidate of candidates) { + for (const candidate of resolveMatrixMentionPrefixCandidates(params)) { const stripped = stripNativeMatrixMentionPrefix(text, candidate); if (stripped !== null) { return stripped;