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.

NotificationsContainer.tsx 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import React, { useCallback } from 'react';
  2. import { connect } from 'react-redux';
  3. import { makeStyles } from 'tss-react/mui';
  4. import { IReduxState, IStore } from '../../../app/types';
  5. import { hideNotification } from '../../actions';
  6. import { areThereNotifications } from '../../functions';
  7. import { INotificationProps } from '../../types';
  8. import NotificationsTransition from '../NotificationsTransition';
  9. import Notification from './Notification';
  10. interface IProps {
  11. /**
  12. * Whether we are a SIP gateway or not.
  13. */
  14. _iAmSipGateway: boolean;
  15. /**
  16. * Whether or not the chat is open.
  17. */
  18. _isChatOpen: boolean;
  19. /**
  20. * The notifications to be displayed, with the first index being the
  21. * notification at the top and the rest shown below it in order.
  22. */
  23. _notifications: Array<{
  24. props: INotificationProps;
  25. uid: string;
  26. }>;
  27. /**
  28. * Invoked to update the redux store in order to remove notifications.
  29. */
  30. dispatch: IStore['dispatch'];
  31. /**
  32. * Whether or not the notifications are displayed in a portal.
  33. */
  34. portal?: boolean;
  35. }
  36. const useStyles = makeStyles()(() => {
  37. return {
  38. container: {
  39. position: 'absolute',
  40. left: '16px',
  41. bottom: '84px',
  42. width: '320px',
  43. maxWidth: '100%',
  44. zIndex: 600
  45. },
  46. containerPortal: {
  47. width: '100%',
  48. maxWidth: 'calc(100% - 32px)'
  49. }
  50. };
  51. });
  52. const NotificationsContainer = ({
  53. _iAmSipGateway,
  54. _notifications,
  55. dispatch,
  56. portal
  57. }: IProps) => {
  58. const { classes, cx } = useStyles();
  59. const _onDismissed = useCallback((uid: string) => {
  60. dispatch(hideNotification(uid));
  61. }, []);
  62. if (_iAmSipGateway) {
  63. return null;
  64. }
  65. return (
  66. <div
  67. className = { cx(classes.container, {
  68. [classes.containerPortal]: portal
  69. }) }
  70. id = 'notifications-container'>
  71. <NotificationsTransition>
  72. {_notifications.map(({ props, uid }) => (
  73. <Notification
  74. { ...props }
  75. key = { uid }
  76. onDismissed = { _onDismissed }
  77. uid = { uid } />
  78. )) || null}
  79. </NotificationsTransition>
  80. </div>
  81. );
  82. };
  83. /**
  84. * Maps (parts of) the Redux state to the associated props for this component.
  85. *
  86. * @param {Object} state - The Redux state.
  87. * @private
  88. * @returns {IProps}
  89. */
  90. function _mapStateToProps(state: IReduxState) {
  91. const { notifications } = state['features/notifications'];
  92. const { iAmSipGateway } = state['features/base/config'];
  93. const { isOpen: isChatOpen } = state['features/chat'];
  94. const _visible = areThereNotifications(state);
  95. return {
  96. _iAmSipGateway: Boolean(iAmSipGateway),
  97. _isChatOpen: isChatOpen,
  98. _notifications: _visible ? notifications : []
  99. };
  100. }
  101. export default connect(_mapStateToProps)(NotificationsContainer);