From 85750d305f9ec78f9a895b4caf9e7dc302d9fde5 Mon Sep 17 00:00:00 2001 From: Stefan Otto Date: Tue, 19 Jun 2018 16:25:27 +0200 Subject: [PATCH] Added chat badge displaying unread messages --- app/lib/components/ChatWidget.jsx | 23 ++++++++++++++++++----- app/lib/redux/reducers/chatbehavior.js | 7 ++++++- app/lib/redux/stateActions.js | 7 +++++++ app/stylus/components/Chat.styl | 19 +++++++++++++++---- 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/app/lib/components/ChatWidget.jsx b/app/lib/components/ChatWidget.jsx index b7329a5..654b7ec 100644 --- a/app/lib/components/ChatWidget.jsx +++ b/app/lib/components/ChatWidget.jsx @@ -7,6 +7,13 @@ import MessageList from './Chat/MessageList'; class ChatWidget extends Component { + componentWillReceiveProps(nextProps) + { + if (nextProps.chatmessages.length !== this.props.chatmessages.length) + if (!this.props.showChat) + this.props.increaseBadge(); + } + render() { const { @@ -68,15 +75,15 @@ ChatWidget.propTypes = disabledInput : PropTypes.bool, badge : PropTypes.number, autofocus : PropTypes.bool, - displayName : PropTypes.string + displayName : PropTypes.string, + chatmessages : PropTypes.arrayOf(PropTypes.object), + increaseBadge : PropTypes.func }; ChatWidget.defaultProps = { senderPlaceHolder : 'Type a message...', - badge : 0, - autofocus : true, - displayName : null + autofocus : true }; const mapStateToProps = (state) => @@ -84,7 +91,9 @@ const mapStateToProps = (state) => return { showChat : state.chatbehavior.showChat, disabledInput : state.chatbehavior.disabledInput, - displayName : state.me.displayName + displayName : state.me.displayName, + badge : state.chatbehavior.badge, + chatmessages : state.chatmessages }; }; @@ -106,6 +115,10 @@ const mapDispatchToProps = (dispatch) => dispatch(requestActions.sendChatMessage(userInput, displayName)); } event.target.message.value = ''; + }, + increaseBadge : () => + { + dispatch(stateActions.increaseBadge()); } }; }; diff --git a/app/lib/redux/reducers/chatbehavior.js b/app/lib/redux/reducers/chatbehavior.js index bee0d85..12e3e51 100644 --- a/app/lib/redux/reducers/chatbehavior.js +++ b/app/lib/redux/reducers/chatbehavior.js @@ -12,8 +12,9 @@ const chatbehavior = (state = initialState, action) => case 'TOGGLE_CHAT': { const showChat = !state.showChat; + const badge = 0; - return { ...state, showChat }; + return { ...state, showChat, badge }; } case 'TOGGLE_INPUT_DISABLED': @@ -23,6 +24,10 @@ const chatbehavior = (state = initialState, action) => return { ...state, disabledInput }; } + case 'INCREASE_BADGE': + { + return { ...state, badge: state.badge + (state.showChat ? 0 : 1) }; + } default: return state; } diff --git a/app/lib/redux/stateActions.js b/app/lib/redux/stateActions.js index 4fb47fe..dfc3e28 100644 --- a/app/lib/redux/stateActions.js +++ b/app/lib/redux/stateActions.js @@ -338,6 +338,13 @@ export const toggleChat = () => }; }; +export const increaseBadge = () => +{ + return { + type : 'INCREASE_BADGE' + }; +}; + export const toggleInputDisabled = () => { return { diff --git a/app/stylus/components/Chat.styl b/app/stylus/components/Chat.styl index 45f5b63..4ae0c0b 100644 --- a/app/stylus/components/Chat.styl +++ b/app/stylus/components/Chat.styl @@ -8,7 +8,7 @@ right: 0; width: 90vw; z-index: 9999; - + > .launcher { align-self: flex-end; margin-top: 10px; @@ -23,11 +23,12 @@ border-radius: 100%; height: 45px; width: 45px; + position: relative; &.focus { outline: none; } - + &.on { background-color: rgba(#fff, 0.7); } @@ -36,6 +37,17 @@ pointer-events: none; opacity: 0.5; } + > .badge{ + border-radius: 50%; + padding: 0.7vmin; + top: -1vmin; + font-size: 1.5vmin; + left: -1vmin; + background: rgba(255,0,0,0.9); + color: #fff; + font-weight: bold; + position: absolute; + } } } @@ -105,7 +117,7 @@ height: 35px; padding: 5px; border-radius: 0 0 5px 5px; - + > .new-message { width: 100%; border: 0; @@ -121,4 +133,3 @@ } } } -