PLT-5488 Add an Unread indicator on the button to open the channel drawer (#277)

* Unread indicator in burger button

* Set badge to always be red
This commit is contained in:
enahum 2017-02-20 17:11:19 -03:00 committed by GitHub
parent 3eb7e377cf
commit d0209aa8c3
3 changed files with 92 additions and 16 deletions

View file

@ -1,8 +1,8 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import {View, Text, StyleSheet} from 'react-native';
import React, {PropTypes, PureComponent} from 'react';
import {View, Text, TouchableWithoutFeedback, StyleSheet} from 'react-native';
const styles = StyleSheet.create({
container: {
@ -20,20 +20,22 @@ const styles = StyleSheet.create({
}
});
export default class Badge extends React.Component {
export default class Badge extends PureComponent {
static defaultProps = {
extraPaddingHorizontal: 10,
minHeight: 0,
minWidth: 0
minWidth: 0,
onPress: () => true
};
static propTypes = {
count: React.PropTypes.number.isRequired,
extraPaddingHorizontal: React.PropTypes.number,
count: PropTypes.number.isRequired,
extraPaddingHorizontal: PropTypes.number,
style: View.propTypes.style,
countStyle: Text.propTypes.style,
minHeight: React.PropTypes.number,
minWidth: React.PropTypes.number
minHeight: PropTypes.number,
minWidth: PropTypes.number,
onPress: PropTypes.func
};
constructor(props) {
@ -42,16 +44,25 @@ export default class Badge extends React.Component {
}
renderText = () => {
const {count} = this.props;
let text = count.toString();
if (count < 0) {
text = '•';
}
return (
<Text
onLayout={this.onLayout}
style={[styles.text, this.props.countStyle]}
>
{this.props.count}
{text}
</Text>
);
};
badgeRef = (ref) => {
this.container = ref;
};
onLayout = (e) => {
let width;
@ -81,12 +92,14 @@ export default class Badge extends React.Component {
render() {
return (
<View
ref={(component) => {
this.container = component;
}}
ref={this.badgeRef}
style={[styles.container, this.props.style]}
>
{this.renderText()}
<TouchableWithoutFeedback onPress={this.props.onPress}>
<View>
{this.renderText()}
</View>
</TouchableWithoutFeedback>
</View>
);
}

View file

@ -8,10 +8,44 @@ import {
View
} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import Badge from 'app/components/badge';
import {getUnreads} from 'service/selectors/entities/channels';
import {getTheme} from 'service/selectors/entities/preferences';
function ChannelDrawerButton(props) {
let badge;
let badgeCount = props.mentionCount;
if (!badgeCount && props.messageCount) {
badgeCount = -1;
}
if (badgeCount !== 0) {
const badgeStyle = {
position: 'absolute',
top: 5,
left: 5,
flexDirection: 'row',
backgroundColor: 'rgb(214, 73, 70)'
};
const mentionStyle = {
color: '#fff',
fontSize: 12
};
badge = (
<Badge
style={badgeStyle}
countStyle={mentionStyle}
count={badgeCount}
minHeight={5}
minWidth={5}
onPress={() => props.emitter('open_channel_drawer')}
/>
);
}
return (
<View style={{flexDirection: 'column', justifyContent: 'center', alignItems: 'center', flex: 1}}>
<TouchableOpacity
@ -24,23 +58,29 @@ function ChannelDrawerButton(props) {
color={props.theme.sidebarHeaderTextColor}
/>
</TouchableOpacity>
{badge}
</View>
);
}
ChannelDrawerButton.propTypes = {
emitter: PropTypes.func.isRequired,
theme: PropTypes.object
theme: PropTypes.object,
messageCount: PropTypes.number,
mentionCount: PropTypes.number
};
ChannelDrawerButton.defaultProps = {
currentChannel: {},
theme: {}
theme: {},
messageCount: 0,
mentionCount: 0
};
function mapStateToProps(state) {
return {
theme: getTheme(state)
theme: getTheme(state),
...getUnreads(state)
};
}

View file

@ -101,3 +101,26 @@ export const getMoreChannels = createSelector(
return getNotMemberChannels(Object.values(allChannels), myMembers);
}
);
export const getUnreads = createSelector(
getAllChannels,
getChannelMemberships,
(channels, myMembers) => {
let messageCount = 0;
let mentionCount = 0;
Object.keys(myMembers).forEach((id) => {
const m = myMembers[id];
const channel = channels[id];
if (channel.type === 'D') {
mentionCount += channel.total_msg_count - m.msg_count;
} else if (m.mention_count > 0) {
mentionCount += m.mention_count;
}
if (m.notify_props.mark_unread !== 'mention' && channel.total_msg_count - m.msg_count > 0) {
messageCount += 1;
}
});
return {messageCount, mentionCount};
}
);