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.4KB

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