UNPKG

stream-chat

Version:

JS SDK for the Stream Chat API

109 lines (96 loc) 2.82 kB
import type { TextSelection } from './types'; import { escapeCommandRegExp } from './commandUtils'; /** * For commands, we want to match all patterns except: * 1. Text not starting with trigger * 2. Trigger in middle of text */ export const getTriggerCharWithToken = ({ trigger, text, isCommand = false, acceptTrailingSpaces = true, }: { trigger: string; text: string; isCommand?: boolean; acceptTrailingSpaces?: boolean; }) => { const escapedTrigger = escapeCommandRegExp(trigger); const triggerNorWhitespace = `[^\\s${escapedTrigger}]*`; const match = text.match( new RegExp( isCommand ? `^[${escapedTrigger}]${triggerNorWhitespace}$` : acceptTrailingSpaces ? `(?!^|\\W)?[${escapedTrigger}]${triggerNorWhitespace}\\s?${triggerNorWhitespace}$` : `(?!^|\\W)?[${escapedTrigger}]${triggerNorWhitespace}$`, 'g', ), ); return match && match[match.length - 1].trim(); }; export const insertItemWithTrigger = ({ insertText, selection, text, trigger, }: { insertText: string; selection: TextSelection; text: string; trigger: string; }) => { const beforeCursor = text.slice(0, selection.end); const afterCursor = text.slice(selection.end); // Replace the trigger and query with the user mention const lastIndex = beforeCursor.lastIndexOf(trigger); const newText = beforeCursor.slice(0, lastIndex) + insertText + afterCursor; return { text: newText, selection: { start: lastIndex + insertText.length, end: lastIndex + insertText.length, }, }; }; export const replaceWordWithEntity = async ({ caretPosition, getEntityString, text, }: { caretPosition: number; getEntityString: (word: string) => Promise<string | null> | string | null; text: string; }): Promise<string> => { const lastWordRegex = /([^\s]+)(\s*)$/; const match = lastWordRegex.exec(text.slice(0, caretPosition)); if (!match) return text; const lastWord = match[1]; if (!lastWord) return text; const spaces = match[2]; const newWord = await getEntityString(lastWord); if (newWord == null) return text; const textBeforeWord = text.slice(0, caretPosition - match[0].length); const textAfterCaret = text.slice(caretPosition, -1); return textBeforeWord + newWord + spaces + textAfterCaret; }; export type TokenizationPayload = { tokenizedDisplayName: { token: string; parts: string[] }; }; export const getTokenizedSuggestionDisplayName = ({ displayName, searchToken, }: { displayName: string; searchToken: string; }): TokenizationPayload => ({ tokenizedDisplayName: { token: searchToken, parts: searchToken ? displayName .split(new RegExp(`(${escapeCommandRegExp(searchToken)})`, 'gi')) .filter(Boolean) : [displayName], }, });