You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

functions.ts 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // @ts-ignore
  2. import aliases from 'react-emoji-render/data/aliases';
  3. // eslint-disable-next-line lines-around-comment
  4. // @ts-ignore
  5. import emojiAsciiAliases from 'react-emoji-render/data/asciiAliases';
  6. import { IState } from '../app/types';
  7. import { escapeRegexp } from '../base/util/helpers';
  8. /**
  9. * An ASCII emoticon regexp array to find and replace old-style ASCII
  10. * emoticons (such as :O) with the new Unicode representation, so that
  11. * devices and browsers that support them can render these natively
  12. * without a 3rd party component.
  13. *
  14. * NOTE: this is currently only used on mobile, but it can be used
  15. * on web too once we drop support for browsers that don't support
  16. * unicode emoji rendering.
  17. */
  18. const ASCII_EMOTICON_REGEXP_ARRAY: Array<[RegExp, string]> = [];
  19. /**
  20. * An emoji regexp array to find and replace alias emoticons
  21. * (such as :smiley:) with the new Unicode representation, so that
  22. * devices and browsers that support them can render these natively
  23. * without a 3rd party component.
  24. *
  25. * NOTE: this is currently only used on mobile, but it can be used
  26. * on web too once we drop support for browsers that don't support
  27. * unicode emoji rendering.
  28. */
  29. const SLACK_EMOJI_REGEXP_ARRAY: Array<[RegExp, string]> = [];
  30. (function() {
  31. for (const [ key, value ] of Object.entries(aliases)) {
  32. // Add ASCII emoticons
  33. const asciiEmoticons = emojiAsciiAliases[key];
  34. if (asciiEmoticons) {
  35. const asciiEscapedValues = asciiEmoticons.map((v: string) => escapeRegexp(v));
  36. const asciiRegexp = `(${asciiEscapedValues.join('|')})`;
  37. // Escape urls
  38. const formattedAsciiRegexp = key === 'confused'
  39. ? `(?=(${asciiRegexp}))(:(?!//).)`
  40. : asciiRegexp;
  41. ASCII_EMOTICON_REGEXP_ARRAY.push([ new RegExp(formattedAsciiRegexp, 'g'), value as string ]);
  42. }
  43. // Add slack-type emojis
  44. const emojiRegexp = `\\B(${escapeRegexp(`:${key}:`)})\\B`;
  45. SLACK_EMOJI_REGEXP_ARRAY.push([ new RegExp(emojiRegexp, 'g'), value as string ]);
  46. }
  47. })();
  48. /**
  49. * Replaces ASCII and other non-unicode emoticons with unicode emojis to let the emojis be rendered
  50. * by the platform native renderer.
  51. *
  52. * @param {string} message - The message to parse and replace.
  53. * @returns {string}
  54. */
  55. export function replaceNonUnicodeEmojis(message: string) {
  56. let replacedMessage = message;
  57. for (const [ regexp, replaceValue ] of SLACK_EMOJI_REGEXP_ARRAY) {
  58. replacedMessage = replacedMessage.replace(regexp, replaceValue);
  59. }
  60. for (const [ regexp, replaceValue ] of ASCII_EMOTICON_REGEXP_ARRAY) {
  61. replacedMessage = replacedMessage.replace(regexp, replaceValue);
  62. }
  63. return replacedMessage;
  64. }
  65. /**
  66. * Selector for calculating the number of unread chat messages.
  67. *
  68. * @param {IState} state - The redux state.
  69. * @returns {number} The number of unread messages.
  70. */
  71. export function getUnreadCount(state: IState) {
  72. const { lastReadMessage, messages } = state['features/chat'];
  73. const messagesCount = messages.length;
  74. if (!messagesCount) {
  75. return 0;
  76. }
  77. let reactionMessages = 0;
  78. if (!lastReadMessage) {
  79. return 0;
  80. }
  81. if (navigator.product === 'ReactNative') {
  82. // React native stores the messages in a reversed order.
  83. const lastReadIndex = messages.indexOf(lastReadMessage);
  84. for (let i = 0; i < lastReadIndex; i++) {
  85. if (messages[i].isReaction) {
  86. reactionMessages++;
  87. }
  88. }
  89. return lastReadIndex - reactionMessages;
  90. }
  91. const lastReadIndex = messages.lastIndexOf(lastReadMessage);
  92. for (let i = lastReadIndex + 1; i < messagesCount; i++) {
  93. if (messages[i].isReaction) {
  94. reactionMessages++;
  95. }
  96. }
  97. return messagesCount - (lastReadIndex + 1) - reactionMessages;
  98. }
  99. /**
  100. * Selector for calculating the number of unread chat messages.
  101. *
  102. * @param {IState} state - The redux state.
  103. * @returns {number} The number of unread messages.
  104. */
  105. export function getUnreadMessagesCount(state: IState) {
  106. const { nbUnreadMessages } = state['features/chat'];
  107. return nbUnreadMessages;
  108. }
  109. /**
  110. * Get whether the chat smileys are disabled or not.
  111. *
  112. * @param {IState} state - The redux state.
  113. * @returns {boolean} The disabled flag.
  114. */
  115. export function areSmileysDisabled(state: IState) {
  116. const disableChatSmileys = state['features/base/config']?.disableChatSmileys === true;
  117. return disableChatSmileys;
  118. }