您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

functions.any.ts 4.6KB

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