index.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
  2. import { CUSTOM_BASIC_EMOJI_URL, CUSTOM_BIG_EMOJI_URL, CUSTOM_BASIC_EMOJI_URL_MAPPING, CUSTOM_BIG_EMOJI_GROUP_LIST } from './custom-emoji';
  3. import { DEFAULT_BASIC_EMOJI_URL, BIG_EMOJI_GROUP_LIST, DEFAULT_BASIC_EMOJI_URL_MAPPING, BASIC_EMOJI_NAME_TO_KEY_MAPPING, DEFAULT_BIG_EMOJI_URL } from './default-emoji';
  4. import { default as emojiCNLocales } from './locales/zh_cn';
  5. import { IEmojiGroupList } from '../../../interface';
  6. import { EMOJI_TYPE } from '../../../constant';
  7. import { isWeChat } from '../../../utils/env';
  8. const hasCustomBasicEmoji = CUSTOM_BASIC_EMOJI_URL && Object.keys(CUSTOM_BASIC_EMOJI_URL_MAPPING).length;
  9. const BASIC_EMOJI_URL = hasCustomBasicEmoji ? CUSTOM_BASIC_EMOJI_URL : DEFAULT_BASIC_EMOJI_URL;
  10. const BASIC_EMOJI_URL_MAPPING = hasCustomBasicEmoji ? CUSTOM_BASIC_EMOJI_URL_MAPPING : DEFAULT_BASIC_EMOJI_URL_MAPPING;
  11. const EMOJI_GROUP_LIST: IEmojiGroupList = [
  12. {
  13. emojiGroupID: 0,
  14. type: EMOJI_TYPE.BASIC,
  15. url: BASIC_EMOJI_URL,
  16. list: Object.keys(BASIC_EMOJI_URL_MAPPING),
  17. },
  18. ...BIG_EMOJI_GROUP_LIST,
  19. ...CUSTOM_BIG_EMOJI_GROUP_LIST,
  20. ];
  21. /**
  22. * Converts a basic emoji key into its corresponding name.
  23. * Example:
  24. * '[Smile]' => '[TUIEmoji_Smile]'
  25. * @param {string} key - The emoji key.
  26. * @return {string} The corresponding emoji name.
  27. */
  28. const convertKeyToEmojiName = (key: string): string => {
  29. // WeChat does not support emoji translation
  30. return isWeChat ? emojiCNLocales[key] : TUITranslateService.t(`Emoji.${key}`);
  31. };
  32. /**
  33. * Transforms a text containing emoji keys into a text with Chinese or English basic emoji names
  34. * Example:
  35. * 'hello[TUIEmoji_Smile]!' => 'hello[Smile]!''
  36. * @param {string} text - The text containing emoji keys.
  37. * @return {string} The transformed text with emoji keys replaced by emoji names.
  38. */
  39. const transformTextWithKeysToEmojiNames = (text: string): string => {
  40. if (!text) {
  41. return '';
  42. }
  43. const reg = /(\[.+?\])/g;
  44. let txt: string = text;
  45. if (reg.test(text)) {
  46. txt = text.replace(reg, match => BASIC_EMOJI_URL_MAPPING[match] ? convertKeyToEmojiName(match) : match);
  47. }
  48. return txt;
  49. };
  50. /**
  51. * Transforms a text containing Chinese or English basic emoji names into a text with emoji keys.
  52. * Example:
  53. * 'hello[Smile]!' => 'hello[TUIEmoji_Smile]!'
  54. * @param {string} text - The text containing emoji names.
  55. * @return {string} The transformed text with emoji names replaced by emoji keys.
  56. */
  57. const transformTextWithEmojiNamesToKeys = (text: string) => {
  58. if (!text) {
  59. return '';
  60. }
  61. const reg = /(\[.+?\])/g;
  62. let txt: string = text;
  63. if (reg.test(text)) {
  64. txt = text.replace(reg, match => BASIC_EMOJI_NAME_TO_KEY_MAPPING[match] || match);
  65. }
  66. return txt;
  67. };
  68. /**
  69. * The configuration aims to provide compatibility with versions prior to 2.2.0
  70. */
  71. const emojiConfig = {
  72. emojiBaseUrl: BASIC_EMOJI_URL,
  73. emojiUrlMapping: BASIC_EMOJI_URL_MAPPING,
  74. emojiNameMapping: {
  75. ...emojiCNLocales,
  76. },
  77. };
  78. /**
  79. * Transform text message to renderable array contains image and text.
  80. * Example: hello[TUIEmoji_Smile], I am happy.
  81. * -> [{type: 'text', content: 'hello'}, {type: 'image', content: 'https://.../smile.png'}, {type: 'text', content: ', I am happy.'}]
  82. * @param text
  83. * @returns Array<{ type: 'text' | 'image'; content: string; emojiKey?: string; }>
  84. */
  85. const parseTextToRenderArray = (text: string): Array<{ type: 'text' | 'image'; content: string; emojiKey?: string }> => {
  86. const emojiRegex = /\[([^\]]+)\]/g;
  87. const result: any[] = [];
  88. let match: RegExpExecArray | null;
  89. let lastIndex = 0;
  90. while ((match = emojiRegex.exec(text)) !== null) {
  91. const startIndex = match.index;
  92. const endIndex = emojiRegex.lastIndex;
  93. const emojiKey = match[0];
  94. if (startIndex > lastIndex) {
  95. result.push({ type: 'text', content: text.substring(lastIndex, startIndex) });
  96. }
  97. const emojiUrl = BASIC_EMOJI_URL + BASIC_EMOJI_URL_MAPPING[emojiKey];
  98. if (emojiUrl) {
  99. result.push({ type: 'image', content: emojiUrl, emojiKey });
  100. } else {
  101. result.push({ type: 'text', content: emojiKey });
  102. }
  103. lastIndex = endIndex;
  104. emojiRegex.lastIndex = lastIndex;
  105. }
  106. if (lastIndex < text.length) {
  107. result.push({ type: 'text', content: text.substring(lastIndex) });
  108. }
  109. return result;
  110. };
  111. export {
  112. EMOJI_GROUP_LIST,
  113. CUSTOM_BIG_EMOJI_URL,
  114. DEFAULT_BIG_EMOJI_URL,
  115. CUSTOM_BASIC_EMOJI_URL,
  116. BASIC_EMOJI_URL_MAPPING,
  117. CUSTOM_BASIC_EMOJI_URL_MAPPING,
  118. convertKeyToEmojiName,
  119. parseTextToRenderArray,
  120. transformTextWithKeysToEmojiNames,
  121. transformTextWithEmojiNamesToKeys,
  122. emojiConfig,
  123. };