EmojiPickerHelper.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import { CSSProperties } from 'react';
  2. import i18n from 'i18next';
  3. // https://regex101.com/r/Gqhor8/1
  4. const EMOJI_PATTERN = new RegExp(/\B:[^:\s]+/);
  5. export default class EmojiPickerHelper {
  6. editor;
  7. pattern: RegExp;
  8. constructor(editor) {
  9. this.editor = editor;
  10. this.pattern = EMOJI_PATTERN;
  11. }
  12. setStyle = ():CSSProperties => {
  13. const offset = 20;
  14. const emojiPickerHeight = 420;
  15. const cursorPos = this.editor.cursorCoords(true);
  16. const editorPos = this.editor.getWrapperElement().getBoundingClientRect();
  17. // Emoji Picker bottom position exceed editor's bottom position
  18. if (cursorPos.bottom + emojiPickerHeight > editorPos.bottom) {
  19. return {
  20. top: editorPos.bottom - emojiPickerHeight,
  21. left: cursorPos.left + offset,
  22. position: 'fixed',
  23. };
  24. }
  25. return {
  26. top: cursorPos.top + offset,
  27. left: cursorPos.left + offset,
  28. position: 'fixed',
  29. };
  30. }
  31. getSearchCursor =() => {
  32. const currentPos = this.editor.getCursor();
  33. const sc = this.editor.getSearchCursor(this.pattern, currentPos, { multiline: false });
  34. return sc;
  35. }
  36. // Add emoji when triggered by search
  37. addEmojiOnSearch = (emoji) => {
  38. const currentPos = this.editor.getCursor();
  39. const sc = this.getSearchCursor();
  40. if (sc.findPrevious()) {
  41. sc.replace(`${emoji.colons} `, this.editor.getTokenAt(currentPos).string);
  42. this.editor.focus();
  43. this.editor.refresh();
  44. }
  45. }
  46. // Add emoji when triggered by click emoji icon on top of editor
  47. addEmoji = (emoji) => {
  48. const currentPos = this.editor.getCursor();
  49. const doc = this.editor.getDoc();
  50. doc.replaceRange(`${emoji.colons} `, currentPos);
  51. this.editor.focus();
  52. this.editor.refresh();
  53. }
  54. getEmoji = () => {
  55. const sc = this.getSearchCursor();
  56. const currentPos = this.editor.getCursor();
  57. if (sc.findPrevious()) {
  58. const isInputtingEmoji = (currentPos.line === sc.to().line && currentPos.ch === sc.to().ch);
  59. // current search cursor position
  60. if (!isInputtingEmoji) {
  61. return;
  62. }
  63. const pos = {
  64. line: sc.to().line,
  65. ch: sc.to().ch,
  66. };
  67. const currentSearchText = sc.matches(true, pos).match[0];
  68. const searchWord = currentSearchText.replace(':', '');
  69. return searchWord;
  70. }
  71. return;
  72. }
  73. }
  74. export const getEmojiTranslation = () => {
  75. const categories = {};
  76. [
  77. 'search',
  78. 'recent',
  79. 'smileys',
  80. 'people',
  81. 'nature',
  82. 'foods',
  83. 'activity',
  84. 'places',
  85. 'objects',
  86. 'symbols',
  87. 'flags',
  88. 'custom',
  89. ].forEach((category) => {
  90. categories[category] = i18n.t(`emoji.categories.${category}`);
  91. });
  92. const skintones = {};
  93. (Array.from(Array(6).keys())).forEach((tone) => {
  94. skintones[tone + 1] = i18n.t(`emoji.skintones.${tone + 1}`);
  95. });
  96. const translation = {
  97. search: i18n.t('emoji.search'),
  98. clear: i18n.t('emoji.clear'),
  99. notfound: i18n.t('emoji.notfound'),
  100. skintext: i18n.t('emoji.skintext'),
  101. categories,
  102. categorieslabel: i18n.t('emoji.categorieslabel'),
  103. skintones,
  104. title: i18n.t('emoji.title'),
  105. };
  106. return translation;
  107. };