PLT-7567: Integration of Team Icons (#1470)

* PLT-7567: Integration of team icons in
channel drawer teams, switch team button, team selection, os share extenions

* PLT-7567: adopt updated eslint changes

* PLT-7567: Component for team icon display, refactoring

* PLT-7567: removed redundant styles

* PLT-7567: redux connected component for team icon, error handling
This commit is contained in:
Christian Hoff 2018-03-06 21:39:24 +01:00 committed by Harrison Healey
parent 31d48fa49c
commit 98fee5e473
8 changed files with 178 additions and 101 deletions

View file

@ -13,7 +13,6 @@ function mapStateToProps(state) {
return {
currentTeamId: team.id,
displayName: team.display_name,
mentionCount: getChannelDrawerBadgeCount(state),
teamsCount: getMyTeamsCount(state),
theme: getTheme(state),

View file

@ -4,7 +4,6 @@
import PropTypes from 'prop-types';
import React from 'react';
import {
Text,
TouchableHighlight,
View,
} from 'react-native';
@ -14,10 +13,11 @@ import Badge from 'app/components/badge';
import {preventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import TeamIcon from 'app/components/team_icon';
export default class SwitchTeamsButton extends React.PureComponent {
static propTypes = {
currentTeamId: PropTypes.string,
displayName: PropTypes.string,
searching: PropTypes.bool.isRequired,
onShowTeams: PropTypes.func.isRequired,
mentionCount: PropTypes.number.isRequired,
@ -32,7 +32,6 @@ export default class SwitchTeamsButton extends React.PureComponent {
render() {
const {
currentTeamId,
displayName,
mentionCount,
searching,
teamsCount,
@ -69,12 +68,13 @@ export default class SwitchTeamsButton extends React.PureComponent {
<AwesomeIcon
name='chevron-left'
size={12}
color={theme.sidebarHeaderBg}
style={styles.switcherArrow}
/>
<TeamIcon
teamId={currentTeamId}
styleContainer={styles.teamIconContainer}
styleText={styles.teamIconText}
/>
<View style={styles.switcherDivider}/>
<Text style={styles.switcherTeam}>
{displayName.substr(0, 2).toUpperCase()}
</Text>
</View>
</TouchableHighlight>
{badge}
@ -86,25 +86,26 @@ export default class SwitchTeamsButton extends React.PureComponent {
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
switcherContainer: {
alignItems: 'center',
backgroundColor: theme.sidebarHeaderTextColor,
borderRadius: 2,
flexDirection: 'row',
height: 32,
alignItems: 'center',
justifyContent: 'center',
height: 32,
borderRadius: 2,
marginLeft: 6,
marginRight: 5,
paddingHorizontal: 6,
marginRight: 6,
paddingHorizontal: 3,
},
switcherDivider: {
backgroundColor: theme.sidebarHeaderBg,
height: 15,
marginHorizontal: 6,
width: 1,
},
switcherTeam: {
switcherArrow: {
color: theme.sidebarHeaderBg,
fontFamily: 'OpenSans',
marginRight: 3,
},
teamIconContainer: {
width: 26,
height: 26,
marginLeft: 3,
},
teamIconText: {
fontSize: 14,
},
badge: {

View file

@ -11,6 +11,8 @@ import {
import IonIcon from 'react-native-vector-icons/Ionicons';
import Badge from 'app/components/badge';
import TeamIcon from 'app/components/team_icon';
import {preventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
@ -71,11 +73,11 @@ export default class TeamsListItem extends React.PureComponent {
onPress={this.selectTeam}
>
<View style={styles.teamContainer}>
<View style={styles.teamIconContainer}>
<Text style={styles.teamIcon}>
{displayName.substr(0, 2).toUpperCase()}
</Text>
</View>
<TeamIcon
teamId={teamId}
styleContainer={styles.teamIconContainer}
styleText={styles.teamIconText}
/>
<View style={styles.teamNameContainer}>
<Text
numberOfLines={1}
@ -112,20 +114,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
flexDirection: 'row',
marginHorizontal: 16,
},
teamIconContainer: {
alignItems: 'center',
backgroundColor: theme.sidebarText,
borderRadius: 2,
height: 40,
justifyContent: 'center',
width: 40,
},
teamIcon: {
color: theme.sidebarBg,
fontFamily: 'OpenSans',
fontSize: 18,
fontWeight: '600',
},
teamNameContainer: {
flex: 1,
flexDirection: 'column',
@ -135,6 +123,13 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
color: theme.sidebarText,
fontSize: 18,
},
teamIconContainer: {
width: 40,
height: 40,
},
teamIconText: {
fontSize: 18,
},
teamUrl: {
color: changeOpacity(theme.sidebarText, 0.5),
fontSize: 12,

View file

@ -0,0 +1,18 @@
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import {connect} from 'react-redux';
import {getTeam} from 'mattermost-redux/selectors/entities/teams';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
import TeamIcon from './team_icon';
function mapStateToProps(state, ownProps) {
return {
team: getTeam(state, ownProps.teamId),
theme: getTheme(state),
};
}
export default connect(mapStateToProps)(TeamIcon);

View file

@ -0,0 +1,97 @@
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import PropTypes from 'prop-types';
import {
Text,
Image,
View,
} from 'react-native';
import {makeStyleSheetFromTheme} from 'app/utils/theme';
import {Client4} from 'mattermost-redux/client';
export default class TeamIcon extends React.PureComponent {
static propTypes = {
teamId: PropTypes.string.isRequired, // eslint-disable-line react/no-unused-prop-types
styleContainer: PropTypes.any,
styleText: PropTypes.any,
styleImage: PropTypes.any,
team: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
};
state = {
imageError: false,
};
componentWillReceiveProps() {
this.setState({imageError: false});
}
render() {
const {
team,
theme,
styleContainer,
styleText,
styleImage,
} = this.props;
const styles = getStyleSheet(theme);
let teamIconContent;
if (team.last_team_icon_update && !this.state.imageError) {
const teamIconUrl = Client4.getTeamIconUrl(team.id, team.last_team_icon_update);
teamIconContent = (
<Image
style={[styles.image, styleImage]}
source={{uri: teamIconUrl}}
onError={() => this.setState({imageError: true})}
/>
);
} else {
teamIconContent = (
<Text style={[styles.text, styleText]}>
{team.display_name.substr(0, 2).toUpperCase()}
</Text>
);
}
return (
<View style={[styles.container, styleContainer]}>
{teamIconContent}
</View>
);
}
}
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
container: {
width: 30,
height: 30,
borderRadius: 2,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: theme.sidebarText,
},
text: {
color: theme.sidebarBg,
fontFamily: 'OpenSans',
fontWeight: '600',
fontSize: 15,
},
image: {
borderRadius: 2,
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
},
};
});

View file

@ -23,6 +23,8 @@ import {ListTypes} from 'app/constants';
import {preventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme, setNavigatorStyles} from 'app/utils/theme';
import TeamIcon from 'app/components/team_icon';
const VIEWABILITY_CONFIG = ListTypes.VISIBILITY_CONFIG_DEFAULTS;
export default class SelectTeam extends PureComponent {
@ -177,11 +179,11 @@ export default class SelectTeam extends PureComponent {
onPress={preventDoubleTap(() => this.onSelectTeam(item))}
>
<View style={styles.teamContainer}>
<View style={styles.teamIconContainer}>
<Text style={styles.teamIcon}>
{item.display_name.substr(0, 2).toUpperCase()}
</Text>
</View>
<TeamIcon
teamId={item.id}
styleContainer={styles.teamIconContainer}
styleText={styles.teamIconText}
/>
<View style={styles.teamNameContainer}>
<Text
numberOfLines={1}
@ -271,23 +273,16 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
marginHorizontal: 16,
},
teamIconContainer: {
alignItems: 'center',
backgroundColor: theme.buttonBg,
borderRadius: 2,
height: 40,
justifyContent: 'center',
width: 40,
height: 40,
},
teamIconText: {
fontSize: 18,
},
noTeam: {
color: theme.centerChannelColor,
fontSize: 14,
},
teamIcon: {
color: theme.buttonColor,
fontFamily: 'OpenSans',
fontSize: 18,
fontWeight: '600',
},
teamNameContainer: {
flex: 1,
flexDirection: 'column',

View file

@ -13,6 +13,8 @@ import IonIcon from 'react-native-vector-icons/Ionicons';
import {wrapWithPreventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import TeamIcon from 'app/components/team_icon';
export default class TeamItem extends PureComponent {
static propTypes = {
currentTeamId: PropTypes.string.isRequired,
@ -46,14 +48,6 @@ export default class TeamItem extends PureComponent {
);
}
const icon = (
<View style={styles.iconContainer}>
<Text style={styles.icon}>
{team.display_name.substr(0, 2).toUpperCase()}
</Text>
</View>
);
return (
<TouchableHighlight
underlayColor={changeOpacity(theme.sidebarTextHoverBg, 0.5)}
@ -61,7 +55,11 @@ export default class TeamItem extends PureComponent {
>
<View style={styles.container}>
<View style={styles.item}>
{icon}
<TeamIcon
teamId={team.id}
styleContainer={styles.teamIconContainer}
styleText={styles.teamIconText}
/>
<Text
style={[styles.text]}
ellipsizeMode='tail'
@ -97,21 +95,9 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
fontSize: 16,
paddingRight: 5,
},
iconContainer: {
alignItems: 'center',
backgroundColor: theme.linkColor,
borderRadius: 2,
height: 30,
justifyContent: 'center',
width: 30,
teamIconContainer: {
marginRight: 10,
},
icon: {
color: theme.sidebarText,
fontFamily: 'OpenSans',
fontSize: 15,
fontWeight: '600',
},
checkmarkContainer: {
alignItems: 'flex-end',
},

View file

@ -12,6 +12,8 @@ import {
import {wrapWithPreventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import TeamIcon from 'app/components/team_icon';
export default class TeamsListItem extends React.PureComponent {
static propTypes = {
currentTeamId: PropTypes.string.isRequired,
@ -33,14 +35,6 @@ export default class TeamsListItem extends React.PureComponent {
} = this.props;
const styles = getStyleSheet(theme);
const icon = (
<View style={styles.iconContainer}>
<Text style={styles.icon}>
{team.display_name.substr(0, 2).toUpperCase()}
</Text>
</View>
);
const wrapperStyle = [styles.wrapper];
if (team.id === currentTeamId) {
wrapperStyle.push({
@ -56,7 +50,11 @@ export default class TeamsListItem extends React.PureComponent {
>
<View style={styles.container}>
<View style={styles.item}>
{icon}
<TeamIcon
teamId={team.id}
styleContainer={styles.teamIconContainer}
styleText={styles.teamIconText}
/>
<Text
style={[styles.text]}
ellipsizeMode='tail'
@ -97,21 +95,9 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
lineHeight: 16,
paddingRight: 5,
},
iconContainer: {
alignItems: 'center',
backgroundColor: theme.linkColor,
borderRadius: 2,
height: 30,
justifyContent: 'center',
width: 30,
teamIconContainer: {
marginRight: 10,
},
icon: {
color: theme.sidebarText,
fontFamily: 'OpenSans',
fontSize: 15,
fontWeight: '600',
},
checkmarkContainer: {
alignItems: 'flex-end',
},