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.

actions.js 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // @flow
  2. import throttle from 'lodash/throttle';
  3. import type { Dispatch } from 'redux';
  4. import { NOTIFICATIONS_ENABLED, getFeatureFlag } from '../base/flags';
  5. import { getParticipantCount } from '../base/participants/functions';
  6. import {
  7. CLEAR_NOTIFICATIONS,
  8. HIDE_NOTIFICATION,
  9. HIDE_RAISE_HAND_NOTIFICATIONS,
  10. SET_NOTIFICATIONS_ENABLED,
  11. SHOW_NOTIFICATION
  12. } from './actionTypes';
  13. import {
  14. NOTIFICATION_TIMEOUT,
  15. NOTIFICATION_TYPE,
  16. SILENT_JOIN_THRESHOLD
  17. } from './constants';
  18. /**
  19. * Clears (removes) all the notifications.
  20. *
  21. * @returns {{
  22. * type: CLEAR_NOTIFICATIONS
  23. * }}
  24. */
  25. export function clearNotifications() {
  26. return {
  27. type: CLEAR_NOTIFICATIONS
  28. };
  29. }
  30. /**
  31. * Removes the notification with the passed in id.
  32. *
  33. * @param {string} uid - The unique identifier for the notification to be
  34. * removed.
  35. * @returns {{
  36. * type: HIDE_NOTIFICATION,
  37. * uid: string
  38. * }}
  39. */
  40. export function hideNotification(uid: string) {
  41. return {
  42. type: HIDE_NOTIFICATION,
  43. uid
  44. };
  45. }
  46. /**
  47. * Removes the raise hand notifications.
  48. *
  49. * @returns {{
  50. * type: HIDE_RAISE_HAND_NOTIFICATIONS
  51. * }}
  52. */
  53. export function hideRaiseHandNotifications() {
  54. return {
  55. type: HIDE_RAISE_HAND_NOTIFICATIONS
  56. };
  57. }
  58. /**
  59. * Stops notifications from being displayed.
  60. *
  61. * @param {boolean} enabled - Whether or not notifications should display.
  62. * @returns {{
  63. * type: SET_NOTIFICATIONS_ENABLED,
  64. * enabled: boolean
  65. * }}
  66. */
  67. export function setNotificationsEnabled(enabled: boolean) {
  68. return {
  69. type: SET_NOTIFICATIONS_ENABLED,
  70. enabled
  71. };
  72. }
  73. /**
  74. * Queues an error notification for display.
  75. *
  76. * @param {Object} props - The props needed to show the notification component.
  77. * @returns {Object}
  78. */
  79. export function showErrorNotification(props: Object) {
  80. return showNotification({
  81. ...props,
  82. appearance: NOTIFICATION_TYPE.ERROR
  83. });
  84. }
  85. /**
  86. * Queues a notification for display.
  87. *
  88. * @param {Object} props - The props needed to show the notification component.
  89. * @param {number} timeout - How long the notification should display before
  90. * automatically being hidden.
  91. * @returns {Function}
  92. */
  93. export function showNotification(props: Object = {}, timeout: ?number) {
  94. return function(dispatch: Function, getState: Function) {
  95. const { notifications } = getState()['features/base/config'];
  96. const enabledFlag = getFeatureFlag(getState(), NOTIFICATIONS_ENABLED, true);
  97. const shouldDisplay = enabledFlag
  98. && (!notifications
  99. || notifications.includes(props.descriptionKey)
  100. || notifications.includes(props.titleKey));
  101. if (shouldDisplay) {
  102. return dispatch({
  103. type: SHOW_NOTIFICATION,
  104. props,
  105. timeout,
  106. uid: props.uid || window.Date.now().toString()
  107. });
  108. }
  109. };
  110. }
  111. /**
  112. * Queues a warning notification for display.
  113. *
  114. * @param {Object} props - The props needed to show the notification component.
  115. * @param {number} timeout - How long the notification should display before
  116. * automatically being hidden.
  117. * @returns {Object}
  118. */
  119. export function showWarningNotification(props: Object, timeout: ?number) {
  120. return showNotification({
  121. ...props,
  122. appearance: NOTIFICATION_TYPE.WARNING
  123. }, timeout);
  124. }
  125. /**
  126. * An array of names of participants that have joined the conference. The array
  127. * is replaced with an empty array as notifications are displayed.
  128. *
  129. * @private
  130. * @type {string[]}
  131. */
  132. let joinedParticipantsNames = [];
  133. /**
  134. * A throttled internal function that takes the internal list of participant
  135. * names, {@code joinedParticipantsNames}, and triggers the display of a
  136. * notification informing of their joining.
  137. *
  138. * @private
  139. * @type {Function}
  140. */
  141. const _throttledNotifyParticipantConnected = throttle((dispatch: Dispatch<any>, getState: Function) => {
  142. const participantCount = getParticipantCount(getState());
  143. // Skip join notifications altogether for large meetings.
  144. if (participantCount > SILENT_JOIN_THRESHOLD) {
  145. joinedParticipantsNames = [];
  146. return;
  147. }
  148. const joinedParticipantsCount = joinedParticipantsNames.length;
  149. let notificationProps;
  150. if (joinedParticipantsCount >= 3) {
  151. notificationProps = {
  152. titleArguments: {
  153. name: joinedParticipantsNames[0]
  154. },
  155. titleKey: 'notify.connectedThreePlusMembers'
  156. };
  157. } else if (joinedParticipantsCount === 2) {
  158. notificationProps = {
  159. titleArguments: {
  160. first: joinedParticipantsNames[0],
  161. second: joinedParticipantsNames[1]
  162. },
  163. titleKey: 'notify.connectedTwoMembers'
  164. };
  165. } else if (joinedParticipantsCount) {
  166. notificationProps = {
  167. titleArguments: {
  168. name: joinedParticipantsNames[0]
  169. },
  170. titleKey: 'notify.connectedOneMember'
  171. };
  172. }
  173. if (notificationProps) {
  174. dispatch(
  175. showNotification(notificationProps, NOTIFICATION_TIMEOUT));
  176. }
  177. joinedParticipantsNames = [];
  178. }, 2000, { leading: false });
  179. /**
  180. * Queues the display of a notification of a participant having connected to
  181. * the meeting. The notifications are batched so that quick consecutive
  182. * connection events are shown in one notification.
  183. *
  184. * @param {string} displayName - The name of the participant that connected.
  185. * @returns {Function}
  186. */
  187. export function showParticipantJoinedNotification(displayName: string) {
  188. joinedParticipantsNames.push(displayName);
  189. return (dispatch: Dispatch<any>, getState: Function) => _throttledNotifyParticipantConnected(dispatch, getState);
  190. }