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.

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