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.any.ts 4.3KB

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