2023-06-12 21:15:23 +10:00
|
|
|
import { BaseRange, Editor } from 'slate';
|
|
|
|
|
|
|
|
|
|
export enum AutocompletePrefix {
|
|
|
|
|
RoomMention = '#',
|
|
|
|
|
UserMention = '@',
|
|
|
|
|
Emoticon = ':',
|
2023-10-18 13:15:30 +11:00
|
|
|
Command = '/',
|
2023-06-12 21:15:23 +10:00
|
|
|
}
|
|
|
|
|
export const AUTOCOMPLETE_PREFIXES: readonly AutocompletePrefix[] = [
|
|
|
|
|
AutocompletePrefix.RoomMention,
|
|
|
|
|
AutocompletePrefix.UserMention,
|
|
|
|
|
AutocompletePrefix.Emoticon,
|
2023-10-18 13:15:30 +11:00
|
|
|
AutocompletePrefix.Command,
|
2023-06-12 21:15:23 +10:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
export type AutocompleteQuery<TPrefix extends string> = {
|
|
|
|
|
range: BaseRange;
|
|
|
|
|
prefix: TPrefix;
|
|
|
|
|
text: string;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getAutocompletePrefix = <TPrefix extends string>(
|
|
|
|
|
editor: Editor,
|
|
|
|
|
queryRange: BaseRange,
|
|
|
|
|
validPrefixes: readonly TPrefix[]
|
|
|
|
|
): TPrefix | undefined => {
|
|
|
|
|
const world = Editor.string(editor, queryRange);
|
2023-06-14 03:47:18 +10:00
|
|
|
return validPrefixes.find((p) => world.startsWith(p));
|
2023-06-12 21:15:23 +10:00
|
|
|
};
|
|
|
|
|
|
2023-06-14 03:47:18 +10:00
|
|
|
export const getAutocompleteQueryText = (
|
|
|
|
|
editor: Editor,
|
|
|
|
|
queryRange: BaseRange,
|
|
|
|
|
prefix: string
|
|
|
|
|
): string => Editor.string(editor, queryRange).slice(prefix.length);
|
2023-06-12 21:15:23 +10:00
|
|
|
|
|
|
|
|
export const getAutocompleteQuery = <TPrefix extends string>(
|
|
|
|
|
editor: Editor,
|
|
|
|
|
queryRange: BaseRange,
|
|
|
|
|
validPrefixes: readonly TPrefix[]
|
|
|
|
|
): AutocompleteQuery<TPrefix> | undefined => {
|
|
|
|
|
const prefix = getAutocompletePrefix(editor, queryRange, validPrefixes);
|
|
|
|
|
if (!prefix) return undefined;
|
|
|
|
|
return {
|
|
|
|
|
range: queryRange,
|
|
|
|
|
prefix,
|
2023-06-14 03:47:18 +10:00
|
|
|
text: getAutocompleteQueryText(editor, queryRange, prefix),
|
2023-06-12 21:15:23 +10:00
|
|
|
};
|
|
|
|
|
};
|