Merge pull request #9 from torjusti/feat/new-messages-counter

Add a counter for unread messages
master
Stefan Otto 2018-07-13 10:12:14 +02:00 committed by GitHub
commit 57ce39852b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 30 deletions

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import * as stateActions from '../../redux/stateActions'; import * as toolTabActions from '../../redux/stateActions';
import ParticipantList from '../ParticipantList/ParticipantList'; import ParticipantList from '../ParticipantList/ParticipantList';
import Chat from '../Chat/Chat'; import Chat from '../Chat/Chat';
import Settings from '../Settings'; import Settings from '../Settings';
@ -16,7 +16,8 @@ class ToolArea extends React.Component
render() render()
{ {
const { const {
toolarea, currentToolTab,
unread,
setToolTab setToolTab
} = this.props; } = this.props;
@ -31,9 +32,15 @@ class ToolArea extends React.Component
{ {
setToolTab('chat'); setToolTab('chat');
}} }}
checked={toolarea.currentToolTab === 'chat'} checked={currentToolTab === 'chat'}
/> />
<label htmlFor='tab-chat'>Chat</label> <label htmlFor='tab-chat'>
Chat
{unread > 0 && (
<span className='badge'>{unread}</span>
)}
</label>
<div className='tab'> <div className='tab'>
<Chat /> <Chat />
@ -47,7 +54,7 @@ class ToolArea extends React.Component
{ {
setToolTab('users'); setToolTab('users');
}} }}
checked={toolarea.currentToolTab === 'users'} checked={currentToolTab === 'users'}
/> />
<label htmlFor='tab-users'>Users</label> <label htmlFor='tab-users'>Users</label>
@ -63,7 +70,7 @@ class ToolArea extends React.Component
{ {
setToolTab('settings'); setToolTab('settings');
}} }}
checked={toolarea.currentToolTab === 'settings'} checked={currentToolTab === 'settings'}
/> />
<label htmlFor='tab-settings'>Settings</label> <label htmlFor='tab-settings'>Settings</label>
@ -79,25 +86,18 @@ class ToolArea extends React.Component
ToolArea.propTypes = ToolArea.propTypes =
{ {
advancedMode : PropTypes.bool, advancedMode : PropTypes.bool,
toolarea : PropTypes.object.isRequired, currentToolTab : PropTypes.string.isRequired,
setToolTab : PropTypes.func.isRequired setToolTab : PropTypes.func.isRequired,
unread : PropTypes.number.isRequired
}; };
const mapStateToProps = (state) => const mapStateToProps = (state) => ({
{ currentToolTab : state.toolarea.currentToolTab,
return { unread : state.toolarea.unread
toolarea : state.toolarea });
};
};
const mapDispatchToProps = (dispatch) => const mapDispatchToProps = {
{ setToolTab : toolTabActions.setToolTab
return {
setToolTab : (toolTab) =>
{
dispatch(stateActions.setToolTab(toolTab));
}
};
}; };
const ToolAreaContainer = connect( const ToolAreaContainer = connect(

View File

@ -10,7 +10,8 @@ class ToolAreaButton extends React.Component
{ {
const { const {
toolAreaOpen, toolAreaOpen,
toggleToolArea toggleToolArea,
unread
} = this.props; } = this.props;
return ( return (
@ -24,6 +25,12 @@ class ToolAreaButton extends React.Component
data-for='globaltip' data-for='globaltip'
onClick={() => toggleToolArea()} onClick={() => toggleToolArea()}
/> />
{unread > 0 && (
<span className={classnames('badge', { long: unread >= 10 })}>
{unread}
</span>
)}
</div> </div>
); );
} }
@ -32,13 +39,15 @@ class ToolAreaButton extends React.Component
ToolAreaButton.propTypes = ToolAreaButton.propTypes =
{ {
toolAreaOpen : PropTypes.bool.isRequired, toolAreaOpen : PropTypes.bool.isRequired,
toggleToolArea : PropTypes.func.isRequired toggleToolArea : PropTypes.func.isRequired,
unread : PropTypes.bool.isRequired
}; };
const mapStateToProps = (state) => const mapStateToProps = (state) =>
{ {
return { return {
toolAreaOpen : state.toolarea.toolAreaOpen toolAreaOpen : state.toolarea.toolAreaOpen,
unread : state.toolarea.unread
}; };
}; };

View File

@ -1,7 +1,8 @@
const initialState = const initialState =
{ {
toolAreaOpen : false, toolAreaOpen : false,
currentToolTab : 'chat' // chat, settings, users currentToolTab : 'chat', // chat, settings, users
unread : 0
}; };
const toolarea = (state = initialState, action) => const toolarea = (state = initialState, action) =>
@ -11,15 +12,27 @@ const toolarea = (state = initialState, action) =>
case 'TOGGLE_TOOL_AREA': case 'TOGGLE_TOOL_AREA':
{ {
const toolAreaOpen = !state.toolAreaOpen; const toolAreaOpen = !state.toolAreaOpen;
const unread = toolAreaOpen && state.currentToolTab === 'chat' ? 0 : state.unread;
return { ...state, toolAreaOpen }; return { ...state, toolAreaOpen, unread };
} }
case 'SET_TOOL_TAB': case 'SET_TOOL_TAB':
{ {
const { toolTab } = action.payload; const { toolTab } = action.payload;
const unread = toolTab === 'chat' ? 0 : state.unread;
return { ...state, currentToolTab: toolTab }; return { ...state, currentToolTab: toolTab, unread };
}
case 'ADD_NEW_RESPONSE_MESSAGE':
{
if (state.toolAreaOpen && state.currentToolTab === 'chat')
{
return state;
}
return { ...state, unread: state.unread + 1 };
} }
default: default:

View File

@ -49,6 +49,25 @@
} }
} }
} }
> .badge {
border-radius: 50%;
font-size: 1rem;
background: #b12525;
color: #fff;
text-align: center;
margin-top: -8px;
line-height: 1rem;
margin-right: -8px;
position: absolute;
padding: 0.2rem 0.4rem;
top: 0;
right: 0;
&.long {
border-radius: 25% / 50%;
}
}
} }
[data-component='ToolArea'] { [data-component='ToolArea'] {
@ -63,7 +82,7 @@
> label { > label {
order: 1; order: 1;
display: block; display: block;
padding: 1vmin 0 1vmin 0; padding: 1vmin 0 0.8vmin 0;
cursor: pointer; cursor: pointer;
background: rgba(#000, 0.3); background: rgba(#000, 0.3);
font-weight: bold; font-weight: bold;
@ -72,6 +91,17 @@
width: 33.33%; width: 33.33%;
font-size: 1.3vmin; font-size: 1.3vmin;
height: 3vmin; height: 3vmin;
> .badge {
padding: 0.1vmin 1vmin;
text-align: center;
font-weight: 300;
font-size: 1.2vmin;
color: #fff;
background-color: #b12525;
border-radius: 2px;
margin-left: 1vmin;
}
} }
> .tab { > .tab {