All files / src/components Notifier.js

14.71% Statements 5/34
0% Branches 0/15
23.08% Functions 3/13
12.9% Lines 4/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102                                                                                                                                                                1x       1x 1x           1x                    
/* eslint-disable react/prop-types */
import React, { Component } from "react";
import { connect } from "react-redux";
import { withSnackbar } from "notistack";
import { IconButton, withStyles } from "@material-ui/core";
import { Close as CloseIcon } from "@material-ui/icons";
import { customVariant } from "./MuiTheme";
import {
  removeSnackbar as removeSnackbarAction,
  closeSnackbar as closeSnackbarAction
} from "../redux/actions/notifierActions";
 
export class Notifier extends Component {
  displayed = [];
 
  shouldComponentUpdate({ notifications: newSnacks = [] }) {
    if (!newSnacks.length) {
      this.displayed = [];
      return false;
    }
 
    const {
      notifications: currentSnacks,
      closeSnackbar,
      removeSnackbar
    } = this.props;
    let notExists = false;
    for (let i = 0; i < newSnacks.length; i += 1) {
      const newSnack = newSnacks[i];
      if (newSnack.dismissed) {
        closeSnackbar(newSnack.key);
        removeSnackbar(newSnack.key);
      }
 
      if (!notExists) {
        notExists =
          notExists ||
          !currentSnacks.filter(({ key }) => newSnack.key === key).length;
      }
    }
    return notExists;
  }
 
  componentDidUpdate() {
    const {
      notifications = [],
      classes,
      enqueueSnackbar,
      closeSnackbarFunc,
      removeSnackbar
    } = this.props;
 
    notifications.forEach(({ key, message, options = {} }) => {
      if (this.displayed.includes(key)) return;
      enqueueSnackbar(message, {
        ...options,
        action: () => (
          <IconButton
            className="close-snackbar-icon"
            onClick={() => closeSnackbarFunc(key)}
          >
            <CloseIcon className={classes.whiteIcon} />
          </IconButton>
        ),
        onClose: (event, reason) => {
          if (options.onClose) {
            options.onClose(event, reason, key);
          }
          removeSnackbar(key);
        }
      });
      this.storeDisplayed(key);
    });
  }
 
  storeDisplayed = id => {
    this.displayed = [...this.displayed, id];
  };
 
  render() {
    return <div />;
  }
}
 
const mapDispatchToProps = dispatch => {
  return {
    removeSnackbar: key => dispatch(removeSnackbarAction(key)),
    closeSnackbarFunc: key => dispatch(closeSnackbarAction(key))
  };
};
 
const mapStateToProps = state => ({
  notifications: state.notifierReducer.notifications
});
 
export default withSnackbar(
  connect(
    mapStateToProps,
    mapDispatchToProps
  )(withStyles(customVariant)(Notifier))
);