import React, { Component } from 'react'; import { connect } from 'react-redux'; import Tinycon from 'tinycon'; import { notify, beep } from '@/utils/notifications'; import { toggleNotificationAllowed, toggleNotificationEnabled } from '@/actions'; const mapStateToProps = state => { return { activities: state.activities.items, unreadMessageCount: state.app.unreadMessageCount, windowIsFocused: state.app.windowIsFocused, soundIsEnabled: state.app.soundIsEnabled, notificationIsEnabled: state.app.notificationIsEnabled, notificationIsAllowed: state.app.notificationIsAllowed, room: state.room, }; }; const mapDispatchToProps = { toggleNotificationAllowed, toggleNotificationEnabled, }; const WithNewMessageNotification = WrappedComponent => { return connect( mapStateToProps, mapDispatchToProps, )( class WithNotificationHOC extends Component { state = { lastMessage: null, unreadMessageCount: 0 }; static getDerivedStateFromProps(nextProps, prevState) { const { room: { id: roomId }, activities, notificationIsEnabled, notificationIsAllowed, soundIsEnabled, unreadMessageCount, windowIsFocused, } = nextProps; if (activities.length === 0) { return null; } const lastMessage = activities[activities.length - 1]; const { username, type, text, fileName, locked, newUsername, currentUsername, action } = lastMessage; if (lastMessage !== prevState.lastMessage && !windowIsFocused) { if (notificationIsAllowed && notificationIsEnabled) { // Generate the proper notification according to the message type switch (type) { case 'USER_ENTER': notify(`User ${username} joined`); break; case 'USER_EXIT': notify(`User ${username} left`); break; case 'RECEIVE_FILE': notify(`${username} sent file <${fileName}>`); break; case 'TEXT_MESSAGE': notify(`${username} said:`, text); break; case 'USER_ACTION': notify(`${username} ${action}`); break; case 'CHANGE_USERNAME': notify(`${currentUsername} changed their name to ${newUsername}`); break; case 'TOGGLE_LOCK_ROOM': if (locked) { notify(`Room ${roomId} is now locked`); } else { notify(`Room ${roomId} is now unlocked`); } break; default: break; } } if (soundIsEnabled) beep.play(); } if (unreadMessageCount !== prevState.unreadMessageCount) { Tinycon.setBubble(unreadMessageCount); } return { lastMessage, unreadMessageCount }; } componentDidMount() { switch (Notification.permission) { case 'granted': this.props.toggleNotificationAllowed(true); this.props.toggleNotificationEnabled(true); break; case 'denied': this.props.toggleNotificationAllowed(false); break; default: this.props.toggleNotificationAllowed(null); } } render() { // Filter props const { room, activities, notificationIsEnabled, motificationIsAllowed, soundIsEnabled, unreadMessageCount, windowIsFocused, toggleNotificationAllowed, toggleNotificationnEnabled, ...rest } = this.props; return ; } }, ); }; export default WithNewMessageNotification;