CommentMentionHelper.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import i18n from 'i18next';
  2. import { debounce } from 'throttle-debounce';
  3. import { apiv3Get } from '~/client/util/apiv3-client';
  4. export default class CommentMentionHelper {
  5. editor;
  6. pattern: RegExp;
  7. constructor(editor) {
  8. this.editor = editor;
  9. }
  10. getUsernamHint = () => {
  11. // Get word that contains `@` character at the begining
  12. const currentPos = this.editor.getCursor();
  13. const wordStart = this.editor.findWordAt(currentPos).anchor.ch - 1;
  14. const wordEnd = this.editor.findWordAt(currentPos).head.ch;
  15. const searchFrom = { line: currentPos.line, ch: wordStart };
  16. const searchTo = { line: currentPos.line, ch: wordEnd };
  17. const searchMention = this.editor.getRange(searchFrom, searchTo);
  18. const isMentioning = searchMention.charAt(0) === '@';
  19. // Return nothing if not mentioning
  20. if (!isMentioning) {
  21. return;
  22. }
  23. // Get username after `@` character and search username
  24. const mention = searchMention.substr(1);
  25. this.editor.showHint({
  26. completeSingle: false,
  27. hint: async() => {
  28. if (mention.length > 0) {
  29. const users = await this.getUsersList(mention);
  30. return {
  31. list: users.length > 0 ? users : [{ text: '', displayText: i18n.t('page_comment.no_user_found') }],
  32. from: searchFrom,
  33. to: searchTo,
  34. };
  35. }
  36. },
  37. });
  38. }
  39. getUsersList = async(q: string) => {
  40. const limit = 20;
  41. const { data } = await apiv3Get('/users/usernames', { q, limit });
  42. return data.activeUser.usernames.map(username => ({
  43. text: `@${username} `,
  44. displayText: username,
  45. }));
  46. }
  47. showUsernameHint= debounce(800, () => this.getUsernamHint());
  48. }