Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

functions.any.ts 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import { v4 as uuidv4 } from 'uuid';
  2. import { IReduxState } from '../app/types';
  3. import { REACTIONS_ENABLED } from '../base/flags/constants';
  4. import { getFeatureFlag } from '../base/flags/functions';
  5. import { getLocalParticipant } from '../base/participants/functions';
  6. import { extractFqnFromPath } from '../dynamic-branding/functions.any';
  7. import { IReactionEmojiProps, REACTIONS, ReactionThreshold, SOUNDS_THRESHOLDS } from './constants';
  8. import logger from './logger';
  9. /**
  10. * Returns the queue of reactions.
  11. *
  12. * @param {Object} state - The state of the application.
  13. * @returns {Array}
  14. */
  15. export function getReactionsQueue(state: IReduxState): Array<IReactionEmojiProps> {
  16. return state['features/reactions'].queue;
  17. }
  18. /**
  19. * Returns chat message from reactions buffer.
  20. *
  21. * @param {Array} buffer - The reactions buffer.
  22. * @returns {string}
  23. */
  24. export function getReactionMessageFromBuffer(buffer: Array<string>): string {
  25. return buffer.map<string>(reaction => REACTIONS[reaction].message).reduce((acc, val) => `${acc}${val}`);
  26. }
  27. /**
  28. * Returns reactions array with uid.
  29. *
  30. * @param {Array} buffer - The reactions buffer.
  31. * @returns {Array}
  32. */
  33. export function getReactionsWithId(buffer: Array<string>): Array<IReactionEmojiProps> {
  34. return buffer.map<IReactionEmojiProps>(reaction => {
  35. return {
  36. reaction,
  37. uid: uuidv4()
  38. };
  39. });
  40. }
  41. /**
  42. * Sends reactions to the backend.
  43. *
  44. * @param {Object} state - The redux state object.
  45. * @param {Array} reactions - Reactions array to be sent.
  46. * @returns {void}
  47. */
  48. export async function sendReactionsWebhook(state: IReduxState, reactions: Array<string>) {
  49. const { webhookProxyUrl: url } = state['features/base/config'];
  50. const { conference } = state['features/base/conference'];
  51. const { jwt } = state['features/base/jwt'];
  52. const { connection } = state['features/base/connection'];
  53. const jid = connection?.getJid();
  54. const localParticipant = getLocalParticipant(state);
  55. const headers = {
  56. ...jwt ? { 'Authorization': `Bearer ${jwt}` } : {},
  57. 'Content-Type': 'application/json'
  58. };
  59. const reqBody = {
  60. meetingFqn: extractFqnFromPath(),
  61. sessionId: conference?.sessionId,
  62. submitted: Date.now(),
  63. reactions,
  64. participantId: localParticipant?.jwtId,
  65. participantName: localParticipant?.name,
  66. participantJid: jid
  67. };
  68. if (url) {
  69. try {
  70. const res = await fetch(`${url}/reactions`, {
  71. method: 'POST',
  72. headers,
  73. body: JSON.stringify(reqBody)
  74. });
  75. if (!res.ok) {
  76. logger.error('Status error:', res.status);
  77. }
  78. } catch (err) {
  79. logger.error('Could not send request', err);
  80. }
  81. }
  82. }
  83. /**
  84. * Returns unique reactions from the reactions buffer.
  85. *
  86. * @param {Array} reactions - The reactions buffer.
  87. * @returns {Array}
  88. */
  89. function getUniqueReactions(reactions: Array<string>): Array<string> {
  90. return [ ...new Set(reactions) ];
  91. }
  92. /**
  93. * Returns frequency of given reaction in array.
  94. *
  95. * @param {Array} reactions - Array of reactions.
  96. * @param {string} reaction - Reaction to get frequency for.
  97. * @returns {number}
  98. */
  99. function getReactionFrequency(reactions: Array<string>, reaction: string): number {
  100. return reactions.filter(r => r === reaction).length;
  101. }
  102. /**
  103. * Returns the threshold number for a given frequency.
  104. *
  105. * @param {number} frequency - Frequency of reaction.
  106. * @returns {number}
  107. */
  108. function getSoundThresholdByFrequency(frequency: number): number {
  109. for (const i of SOUNDS_THRESHOLDS) {
  110. if (frequency <= i) {
  111. return i;
  112. }
  113. }
  114. return SOUNDS_THRESHOLDS[SOUNDS_THRESHOLDS.length - 1];
  115. }
  116. /**
  117. * Returns unique reactions with threshold.
  118. *
  119. * @param {Array} reactions - The reactions buffer.
  120. * @returns {Array}
  121. */
  122. export function getReactionsSoundsThresholds(reactions: Array<string>): Array<ReactionThreshold> {
  123. const unique = getUniqueReactions(reactions);
  124. return unique.map<ReactionThreshold>(reaction => {
  125. return {
  126. reaction,
  127. threshold: getSoundThresholdByFrequency(getReactionFrequency(reactions, reaction))
  128. };
  129. });
  130. }
  131. /**
  132. * Whether or not the reactions are enabled.
  133. *
  134. * @param {Object} state - The Redux state object.
  135. * @returns {boolean}
  136. */
  137. export function isReactionsEnabled(state: IReduxState): boolean {
  138. const { disableReactions } = state['features/base/config'];
  139. if (navigator.product === 'ReactNative') {
  140. return !disableReactions && getFeatureFlag(state, REACTIONS_ENABLED, true);
  141. }
  142. return !disableReactions;
  143. }