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.js 4.2KB

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