| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- import { Editor } from 'codemirror';
- import { i18n } from 'next-i18next';
- import { debounce } from 'throttle-debounce';
- import { apiv3Get } from '~/client/util/apiv3-client';
- type UsersListForHints = {
- text: string
- displayText: string
- }
- export default class CommentMentionHelper {
- editor: Editor;
- constructor(editor: Editor) {
- this.editor = editor;
- }
- getUsenameHint = (): void => {
- // Get word that contains `@` character at the begining
- const currentPos = this.editor.getCursor();
- const wordStart = this.editor.findWordAt(currentPos).anchor.ch - 1;
- const wordEnd = this.editor.findWordAt(currentPos).head.ch;
- const searchFrom = { line: currentPos.line, ch: wordStart };
- const searchTo = { line: currentPos.line, ch: wordEnd };
- const searchMention = this.editor.getRange(searchFrom, searchTo);
- const isMentioning = searchMention.charAt(0) === '@';
- // Return nothing if not mentioning
- if (!isMentioning) {
- return;
- }
- // Get username after `@` character and search username
- const mention = searchMention.slice(1);
- this.editor.showHint({
- completeSingle: false,
- hint: async() => {
- if (mention.length > 0) {
- const users = await this.getUsersList(mention);
- return {
- // Returns default value if i18n is null because it cannot do early return.
- list: users.length > 0 ? users : [{ text: '', displayText: i18n != null ? i18n.t('page_comment.no_user_found') : 'No user found' }],
- from: searchFrom,
- to: searchTo,
- };
- }
- },
- });
- };
- getUsersList = async(q: string): Promise<UsersListForHints[]> => {
- const limit = 20;
- const { data } = await apiv3Get('/users/usernames', { q, limit });
- return data.activeUser.usernames.map((username: string) => ({
- text: `@${username} `,
- displayText: username,
- }));
- };
- showUsernameHint = debounce(800, () => this.getUsenameHint());
- }
|