[MM-22948] - Improve unread badge UI on the hamburger menu and team icons (#4635)

* updates to bage UI

* fixed spacing

* updated tests with npm test command

* fixed badge theme colors

* updated badge width to deal with larger mention counts

* updated tests

* fixed sizing issue

* fixed sizing issue & moved maxWidth to Badge layout

* added constants for badge maxWidth & adjusted badge position

* adjusted top position for badge on burger menu

* fixed last issue for max mentions positioning on burger menu badge
This commit is contained in:
Adrian Brown 2020-08-17 12:46:49 -04:00 committed by GitHub
parent 40a264a4de
commit 169ed80243
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 99 additions and 21 deletions

View file

@ -11,6 +11,7 @@ import {
View,
ViewPropTypes,
} from 'react-native';
import {CHANNEL_ITEM_LARGE_BADGE_MAX_WIDTH, CHANNEL_ITEM_SMALL_BADGE_MAX_WIDTH, LARGE_BADGE_MAX_WIDTH, SMALL_BADGE_MAX_WIDTH} from '@constants/view';
export default class Badge extends PureComponent {
static defaultProps = {
@ -27,6 +28,7 @@ export default class Badge extends PureComponent {
countStyle: Text.propTypes.style,
minHeight: PropTypes.number,
minWidth: PropTypes.number,
isChannelItem: PropTypes.bool,
onPress: PropTypes.func,
};
@ -78,6 +80,12 @@ export default class Badge extends PureComponent {
onLayout = (e) => {
if (!this.layoutReady) {
let width;
let maxWidth;
if (this.props.isChannelItem) {
maxWidth = this.props.count > 99 ? CHANNEL_ITEM_LARGE_BADGE_MAX_WIDTH : CHANNEL_ITEM_SMALL_BADGE_MAX_WIDTH;
} else {
maxWidth = this.props.count > 99 ? LARGE_BADGE_MAX_WIDTH : SMALL_BADGE_MAX_WIDTH;
}
if (e.nativeEvent.layout.width <= e.nativeEvent.layout.height) {
width = e.nativeEvent.layout.height;
@ -86,11 +94,13 @@ export default class Badge extends PureComponent {
}
width = Math.max(this.props.count < 10 ? width : width + 10, this.props.minWidth);
const borderRadius = width / 2;
this.setNativeProps({
style: {
width,
borderRadius,
opacity: 1,
maxWidth,
},
});
this.layoutReady = true;
@ -106,11 +116,7 @@ export default class Badge extends PureComponent {
<View
style={[styles.text, this.props.countStyle]}
onLayout={this.onLayout}
>
<View style={styles.verticalAlign}>
<View style={[styles.unreadIndicator, {backgroundColor: this.props.countStyle.color}]}/>
</View>
</View>
/>
);
} else {
let mentionCount = count;

View file

@ -965,9 +965,11 @@ exports[`ChannelItem should match snapshot with mentions and muted 1`] = `
Object {
"color": "#145dbf",
"fontSize": 12,
"fontWeight": "bold",
}
}
extraPaddingHorizontal={10}
isChannelItem={true}
minHeight={20}
minWidth={21}
onPress={[Function]}

View file

@ -143,6 +143,7 @@ export default class ChannelItem extends PureComponent {
count={mentions}
onPress={this.onPress}
minWidth={21}
isChannelItem={true}
/>
);
}
@ -246,6 +247,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
mention: {
color: theme.mentionColor,
fontSize: 12,
fontWeight: 'bold',
},
muted: {
opacity: 0.5,

View file

@ -46,12 +46,17 @@ export default class SwitchTeamsButton extends React.PureComponent {
const styles = getStyleSheet(theme);
const lowMentionCount = mentionCount <= 0;
const minWidth = lowMentionCount ? 8 : 20;
const badgeStyle = lowMentionCount ? styles.smallBadge : styles.badge;
const containerStyle = lowMentionCount ? styles.smallBadgeContainer : styles.badgeContainer;
const badge = (
<Badge
containerStyle={styles.badgeContainer}
style={styles.badge}
containerStyle={containerStyle}
style={badgeStyle}
countStyle={styles.mention}
minWidth={20}
minWidth={minWidth}
count={mentionCount}
/>
);
@ -89,6 +94,11 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
height: 20,
padding: 3,
},
smallBadge: {
backgroundColor: theme.mentionBg,
height: 8,
padding: 3,
},
badgeContainer: {
borderColor: theme.sidebarBg,
borderRadius: 14,
@ -97,9 +107,18 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
right: 0,
top: -9,
},
smallBadgeContainer: {
borderColor: theme.sidebarBg,
borderRadius: 14,
borderWidth: 2,
position: 'absolute',
right: 6,
top: -5,
},
mention: {
color: theme.mentionColor,
fontSize: 10,
fontWeight: 'bold',
},
switcherArrow: {
color: theme.sidebarHeaderBg,

View file

@ -46,13 +46,18 @@ export default class TeamsListItem extends React.PureComponent {
} = this.props;
const styles = getStyleSheet(theme);
const lowMentionCount = mentionCount <= 0;
const minWidth = lowMentionCount ? 8 : 20;
const badgeStyle = lowMentionCount ? styles.smallBadge : styles.badge;
const containerStyle = lowMentionCount ? styles.smallBadgeContainer : styles.badgeContainer;
const badge = (
<Badge
containerStyle={styles.badgeContainer}
containerStyle={containerStyle}
countStyle={styles.mention}
count={mentionCount}
minWidth={20}
style={styles.badge}
minWidth={minWidth}
style={badgeStyle}
/>
);
@ -152,6 +157,11 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
height: 20,
padding: 3,
},
smallBadge: {
backgroundColor: theme.mentionBg,
height: 8,
padding: 3,
},
badgeContainer: {
borderColor: theme.sidebarBg,
borderRadius: 14,
@ -160,9 +170,18 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
right: -12,
top: -10,
},
smallBadgeContainer: {
borderColor: theme.sidebarBg,
borderRadius: 14,
borderWidth: 2,
position: 'absolute',
right: -7,
top: -6,
},
mention: {
color: theme.mentionColor,
fontSize: 10,
fontWeight: 'bold',
},
};
});

View file

@ -36,6 +36,14 @@ export const NotificationLevels = {
export const NOTIFY_ALL_MEMBERS = 5;
export const INDICATOR_BAR_HEIGHT = 38;
export const CHANNEL_ITEM_LARGE_BADGE_MAX_WIDTH = 38;
export const CHANNEL_ITEM_SMALL_BADGE_MAX_WIDTH = 32;
export const LARGE_BADGE_MAX_WIDTH = 30;
export const SMALL_BADGE_MAX_WIDTH = 26;
export const MAX_BADGE_RIGHT_POSITION = -17;
export const LARGE_BADGE_RIGHT_POSITION = -16;
export const SMALL_BADGE_RIGHT_POSITION = -13;
const ViewTypes = keyMirror({
DATA_CLEANUP: null,
SERVER_URL_CHANGED: null,

View file

@ -79,8 +79,8 @@ exports[`ChannelDrawerButton should match, full snapshot 2`] = `
"borderRadius": 14,
"borderWidth": 2,
"position": "absolute",
"right": -14,
"top": -7,
"right": -13,
"top": -6,
}
}
count={1}
@ -88,16 +88,17 @@ exports[`ChannelDrawerButton should match, full snapshot 2`] = `
Object {
"color": "#145dbf",
"fontSize": 10,
"fontWeight": "bold",
}
}
extraPaddingHorizontal={10}
minHeight={20}
minWidth={19}
minWidth={18}
onPress={[Function]}
style={
Object {
"backgroundColor": "#ffffff",
"height": 19,
"height": 18,
"padding": 3,
}
}

View file

@ -18,6 +18,7 @@ import {t} from 'app/utils/i18n';
import {intlShape} from 'react-intl';
import telemetry from 'app/telemetry';
import {LARGE_BADGE_RIGHT_POSITION, SMALL_BADGE_RIGHT_POSITION, MAX_BADGE_RIGHT_POSITION} from '@constants/view';
export default class ChannelDrawerButton extends PureComponent {
static propTypes = {
@ -87,14 +88,21 @@ export default class ChannelDrawerButton extends PureComponent {
let badge;
if (badgeCount && visible) {
const badgeCountLow = badgeCount <= 0;
const minWidth = badgeCountLow ? 8 : 18;
const badgeStyle = badgeCountLow ? style.smallBadge : style.badge;
const smallBadgeRightPosition = badgeCount > 9 ? LARGE_BADGE_RIGHT_POSITION : SMALL_BADGE_RIGHT_POSITION;
const rightStylePosition = badgeCount > 99 ? MAX_BADGE_RIGHT_POSITION : smallBadgeRightPosition;
const containerStyle = badgeCountLow ? style.smallBadgeContainer : {...style.badgeContainer, right: rightStylePosition};
badge = (
<Badge
containerStyle={style.badgeContainer}
style={style.badge}
containerStyle={containerStyle}
style={badgeStyle}
countStyle={style.mention}
count={badgeCount}
onPress={this.handlePress}
minWidth={19}
minWidth={minWidth}
/>
);
}
@ -155,7 +163,12 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
},
badge: {
backgroundColor: theme.mentionBg,
height: 19,
height: 18,
padding: 3,
},
smallBadge: {
backgroundColor: theme.mentionBg,
height: 8,
padding: 3,
},
badgeContainer: {
@ -163,12 +176,20 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
borderRadius: 14,
borderWidth: 2,
position: 'absolute',
right: -14,
top: -7,
top: -6,
},
smallBadgeContainer: {
borderColor: theme.sidebarHeaderBg,
borderRadius: 14,
borderWidth: 2,
position: 'absolute',
right: -7,
top: 0,
},
mention: {
color: theme.mentionColor,
fontSize: 10,
fontWeight: 'bold',
},
};
});