Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

NotificationsContainer.tsx 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import { withStyles } from '@mui/styles';
  2. import clsx from 'clsx';
  3. import React, { Component } from 'react';
  4. import { WithTranslation } from 'react-i18next';
  5. import { connect } from 'react-redux';
  6. import { IReduxState } from '../../../app/types';
  7. import { hideNotification } from '../../actions';
  8. import { areThereNotifications } from '../../functions';
  9. import { INotificationProps } from '../../types';
  10. import NotificationsTransition from '../NotificationsTransition';
  11. import Notification from './Notification';
  12. interface IProps extends WithTranslation {
  13. /**
  14. * Whether we are a SIP gateway or not.
  15. */
  16. _iAmSipGateway: boolean;
  17. /**
  18. * Whether or not the chat is open.
  19. */
  20. _isChatOpen: boolean;
  21. /**
  22. * The notifications to be displayed, with the first index being the
  23. * notification at the top and the rest shown below it in order.
  24. */
  25. _notifications: Array<{
  26. props: INotificationProps;
  27. uid: string;
  28. }>;
  29. /**
  30. * JSS classes object.
  31. */
  32. classes: any;
  33. /**
  34. * Invoked to update the redux store in order to remove notifications.
  35. */
  36. dispatch: Function;
  37. /**
  38. * Whether or not the notifications are displayed in a portal.
  39. */
  40. portal?: boolean;
  41. }
  42. const useStyles = () => {
  43. return {
  44. container: {
  45. position: 'absolute' as const,
  46. left: '16px',
  47. bottom: '84px',
  48. width: '320px',
  49. maxWidth: '100%',
  50. zIndex: 600
  51. },
  52. containerPortal: {
  53. width: '100%',
  54. maxWidth: 'calc(100% - 32px)'
  55. }
  56. };
  57. };
  58. /**
  59. * Implements a React {@link Component} which displays notifications and handles
  60. * automatic dismissal after a notification is shown for a defined timeout
  61. * period.
  62. *
  63. * @augments {Component}
  64. */
  65. class NotificationsContainer extends Component<IProps> {
  66. /**
  67. * Initializes a new {@code NotificationsContainer} instance.
  68. *
  69. * @inheritdoc
  70. */
  71. constructor(props: IProps) {
  72. super(props);
  73. // Bind event handlers so they are only bound once for every instance.
  74. this._onDismissed = this._onDismissed.bind(this);
  75. }
  76. /**
  77. * Implements React's {@link Component#render()}.
  78. *
  79. * @inheritdoc
  80. * @returns {ReactElement}
  81. */
  82. render() {
  83. const { _notifications } = this.props;
  84. if (this.props._iAmSipGateway) {
  85. return null;
  86. }
  87. return (
  88. <div
  89. className = { clsx(this.props.classes.container, {
  90. [this.props.classes.containerPortal]: this.props.portal
  91. }) }
  92. id = 'notifications-container'>
  93. <NotificationsTransition>
  94. {_notifications.map(({ props, uid }) => (
  95. <Notification
  96. { ...props }
  97. key = { uid }
  98. onDismissed = { this._onDismissed }
  99. uid = { uid } />
  100. )) || null }
  101. </NotificationsTransition>
  102. </div>
  103. );
  104. }
  105. /**
  106. * Emits an action to remove the notification from the redux store so it
  107. * stops displaying.
  108. *
  109. * @param {string} uid - The id of the notification to be removed.
  110. * @private
  111. * @returns {void}
  112. */
  113. _onDismissed(uid: string) {
  114. this.props.dispatch(hideNotification(uid));
  115. }
  116. }
  117. /**
  118. * Maps (parts of) the Redux state to the associated props for this component.
  119. *
  120. * @param {Object} state - The Redux state.
  121. * @private
  122. * @returns {IProps}
  123. */
  124. function _mapStateToProps(state: IReduxState) {
  125. const { notifications } = state['features/notifications'];
  126. const { iAmSipGateway } = state['features/base/config'];
  127. const { isOpen: isChatOpen } = state['features/chat'];
  128. const _visible = areThereNotifications(state);
  129. return {
  130. _iAmSipGateway: Boolean(iAmSipGateway),
  131. _isChatOpen: isChatOpen,
  132. _notifications: _visible ? notifications : []
  133. };
  134. }
  135. export default connect(_mapStateToProps)(withStyles(useStyles)(NotificationsContainer));