(position?: number[])
| 366 | * @see https://linear.app/dailydotdev/issue/ENG-228 |
| 367 | */ |
| 368 | const checkMention = (position?: number[]) => { |
| 369 | const current = [textarea.selectionStart, textarea.selectionEnd]; |
| 370 | const selection = position ?? current; |
| 371 | const [word] = getCloseWord(textarea, selection); |
| 372 | const mention = word.substring(1); |
| 373 | const isValid = |
| 374 | word.charAt(0) === '@' && |
| 375 | (mention.length === 0 || handleRegex.test(mention)); |
| 376 | |
| 377 | if (!isValid) { |
| 378 | return updateQuery(undefined); |
| 379 | } |
| 380 | |
| 381 | // Skip mention detection if @ is inside a markdown link |
| 382 | if (isSelectionInMarkdownLink(textarea, selection[0], selection[1])) { |
| 383 | return updateQuery(undefined); |
| 384 | } |
| 385 | |
| 386 | // Skip mention detection if @ is part of a URL |
| 387 | // Check if the word containing @ is a URL (with or without protocol) |
| 388 | // This regex matches: |
| 389 | // - URLs starting with www. |
| 390 | // - URLs with http:// or https:// |
| 391 | // - Domain-like patterns (e.g., example.com, sub.domain.com) |
| 392 | const looksLikeUrl = |
| 393 | isValidHttpUrl(word) || |
| 394 | word.startsWith('www.') || |
| 395 | /^[a-zA-Z0-9-]+\.[a-zA-Z0-9-]+/i.test(word); |
| 396 | |
| 397 | if (looksLikeUrl) { |
| 398 | return updateQuery(undefined); |
| 399 | } |
| 400 | |
| 401 | if (isNullOrUndefined(query)) { |
| 402 | return updateQuery(mention ?? ''); |
| 403 | } |
| 404 | |
| 405 | return updateQuery(mention); |
| 406 | }; |
| 407 | |
| 408 | const checkEmoji = (position?: number[]) => { |
| 409 | const current = [textarea.selectionStart, textarea.selectionEnd]; |
no test coverage detected