MM-19308 Fixed date wrapping (#3445)

* MM-19308 Fixed date wrapping

Updated the displayName to check for the reply button and bot tag. If seen the displayName container is set from 60% to 55% to allow for the extra space.

* MM-19308 Updated logic and added tests

Updated logic based on feedback.
Added Jest/Snapshots

* MM-19308 Apply change to other sections

Applied the change to autoresponder/webhook section.
This commit is contained in:
CJ 2019-10-28 12:22:50 -04:00 committed by Elias Nahum
parent 6b7d043c05
commit 558f6ad280
3 changed files with 617 additions and 2 deletions

View file

@ -0,0 +1,507 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PostHeader should match snapshot when just a base post 1`] = `
<React.Fragment>
<View
style={
Array [
Object {
"flex": 1,
"marginTop": 10,
},
false,
]
}
>
<View
style={
Object {
"flex": 1,
"flexDirection": "row",
}
}
>
<TouchableWithFeedbackIOS
onPress={[Function]}
style={
Array [
Object {
"marginBottom": 3,
"marginRight": 5,
"maxWidth": "60%",
},
null,
]
}
type="opacity"
>
<Text
ellipsizeMode="tail"
numberOfLines={1}
style={
Object {
"color": "#3d3c40",
"flexGrow": 1,
"fontSize": 15,
"fontWeight": "600",
"paddingVertical": 2,
}
}
>
John Smith
</Text>
</TouchableWithFeedbackIOS>
<FormattedTime
hour12={true}
style={
Object {
"color": "#3d3c40",
"flex": 1,
"fontSize": 12,
"marginTop": 5,
"opacity": 0.5,
}
}
timeZone=""
value={0}
/>
</View>
</View>
</React.Fragment>
`;
exports[`PostHeader should match snapshot when post is autoresponder 1`] = `
<React.Fragment>
<View
style={
Array [
Object {
"flex": 1,
"marginTop": 10,
},
false,
]
}
>
<View
style={
Object {
"flex": 1,
"flexDirection": "row",
}
}
>
<View
style={
Array [
Object {
"marginBottom": 3,
"marginRight": 5,
"maxWidth": "60%",
},
null,
]
}
>
<Text
ellipsizeMode="tail"
numberOfLines={1}
style={
Object {
"color": "#3d3c40",
"flexGrow": 1,
"fontSize": 15,
"fontWeight": "600",
"paddingVertical": 2,
}
}
>
John Smith
</Text>
</View>
<Tag
defaultMessage="AUTOMATIC REPLY"
id="post_info.auto_responder"
show={true}
style={
Object {
"marginBottom": 5,
"marginLeft": 0,
"marginRight": 5,
}
}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
/>
<FormattedTime
hour12={true}
style={
Object {
"color": "#3d3c40",
"flex": 1,
"fontSize": 12,
"marginTop": 5,
"opacity": 0.5,
}
}
timeZone=""
value={0}
/>
</View>
</View>
</React.Fragment>
`;
exports[`PostHeader should match snapshot when post is from system message 1`] = `
<React.Fragment>
<View
style={
Array [
Object {
"flex": 1,
"marginTop": 10,
},
false,
]
}
>
<View
style={
Object {
"flex": 1,
"flexDirection": "row",
}
}
>
<View
style={
Object {
"marginBottom": 3,
"marginRight": 5,
"maxWidth": "60%",
}
}
>
<FormattedText
defaultMessage="System"
id="post_info.system"
style={
Array [
Object {
"color": "#3d3c40",
"flexGrow": 1,
"fontSize": 15,
"fontWeight": "600",
"paddingVertical": 2,
},
]
}
/>
</View>
<FormattedTime
hour12={true}
style={
Object {
"color": "#3d3c40",
"flex": 1,
"fontSize": 12,
"marginTop": 5,
"opacity": 0.5,
}
}
timeZone=""
value={0}
/>
</View>
</View>
</React.Fragment>
`;
exports[`PostHeader should match snapshot when post isBot and shouldRenderReplyButton 1`] = `
<React.Fragment>
<View
style={
Array [
Object {
"flex": 1,
"marginTop": 10,
},
false,
]
}
>
<View
style={
Object {
"flex": 1,
"flexDirection": "row",
}
}
>
<TouchableWithFeedbackIOS
onPress={[Function]}
style={
Array [
Object {
"marginBottom": 3,
"marginRight": 5,
"maxWidth": "60%",
},
Object {
"maxWidth": "50%",
},
]
}
type="opacity"
>
<Text
ellipsizeMode="tail"
numberOfLines={1}
style={
Object {
"color": "#3d3c40",
"flexGrow": 1,
"fontSize": 15,
"fontWeight": "600",
"paddingVertical": 2,
}
}
>
John Smith
</Text>
</TouchableWithFeedbackIOS>
<BotTag
style={
Object {
"marginBottom": 5,
"marginLeft": 0,
"marginRight": 5,
}
}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
/>
<FormattedTime
hour12={true}
style={
Object {
"color": "#3d3c40",
"flex": 1,
"fontSize": 12,
"marginTop": 5,
"opacity": 0.5,
}
}
timeZone=""
value={0}
/>
<View
style={
Object {
"flex": 1,
"justifyContent": "flex-end",
}
}
>
<TouchableWithFeedbackIOS
onPress={[MockFunction]}
style={
Object {
"alignItems": "flex-start",
"flex": 1,
"flexDirection": "row",
"justifyContent": "flex-end",
"minWidth": 40,
"paddingBottom": 10,
"paddingTop": 2,
}
}
type="opacity"
>
<ReplyIcon
color="#2389d7"
height={16}
width={16}
/>
<Text
style={
Object {
"color": "#2389d7",
"fontSize": 12,
"marginLeft": 2,
"marginTop": 2,
}
}
>
0
</Text>
</TouchableWithFeedbackIOS>
</View>
</View>
</View>
</React.Fragment>
`;
exports[`PostHeader should match snapshot when post should display reply button 1`] = `
<React.Fragment>
<View
style={
Array [
Object {
"flex": 1,
"marginTop": 10,
},
false,
]
}
>
<View
style={
Object {
"flex": 1,
"flexDirection": "row",
}
}
>
<TouchableWithFeedbackIOS
onPress={[Function]}
style={
Array [
Object {
"marginBottom": 3,
"marginRight": 5,
"maxWidth": "60%",
},
null,
]
}
type="opacity"
>
<Text
ellipsizeMode="tail"
numberOfLines={1}
style={
Object {
"color": "#3d3c40",
"flexGrow": 1,
"fontSize": 15,
"fontWeight": "600",
"paddingVertical": 2,
}
}
>
John Smith
</Text>
</TouchableWithFeedbackIOS>
<FormattedTime
hour12={true}
style={
Object {
"color": "#3d3c40",
"flex": 1,
"fontSize": 12,
"marginTop": 5,
"opacity": 0.5,
}
}
timeZone=""
value={0}
/>
<View
style={
Object {
"flex": 1,
"justifyContent": "flex-end",
}
}
>
<TouchableWithFeedbackIOS
onPress={[MockFunction]}
style={
Object {
"alignItems": "flex-start",
"flex": 1,
"flexDirection": "row",
"justifyContent": "flex-end",
"minWidth": 40,
"paddingBottom": 10,
"paddingTop": 2,
}
}
type="opacity"
>
<ReplyIcon
color="#2389d7"
height={16}
width={16}
/>
<Text
style={
Object {
"color": "#2389d7",
"fontSize": 12,
"marginLeft": 2,
"marginTop": 2,
}
}
>
0
</Text>
</TouchableWithFeedbackIOS>
</View>
</View>
</View>
</React.Fragment>
`;

View file

@ -117,9 +117,16 @@ export default class PostHeader extends PureComponent {
fromAutoResponder,
overrideUsername,
theme,
renderReplies,
shouldRenderReplyButton,
commentedOnDisplayName,
commentCount,
isBot,
} = this.props;
const style = getStyleSheet(theme);
const showReply = shouldRenderReplyButton || (!commentedOnDisplayName && commentCount > 0 && renderReplies);
const displayNameStyle = [style.displayNameContainer, showReply && (isBot || fromAutoResponder || fromWebHook) ? style.displayNameContainerBotReplyWidth : null];
if (fromAutoResponder || fromWebHook) {
let name = displayName;
@ -128,7 +135,7 @@ export default class PostHeader extends PureComponent {
}
return (
<View style={[style.displayNameContainer, {maxWidth: fromAutoResponder ? '30%' : '60%'}]}>
<View style={displayNameStyle}>
<Text
style={style.displayName}
ellipsizeMode={'tail'}
@ -152,7 +159,7 @@ export default class PostHeader extends PureComponent {
return (
<TouchableWithFeedback
onPress={this.handleUsernamePress}
style={style.displayNameContainer}
style={displayNameStyle}
type={'opacity'}
>
<Text
@ -357,5 +364,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
marginBottom: 3,
lineHeight: 21,
},
displayNameContainerBotReplyWidth: {
maxWidth: '50%',
},
};
});

View file

@ -0,0 +1,98 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import Preferences from 'mattermost-redux/constants/preferences';
import PostHeader from './post_header';
describe('PostHeader', () => {
const baseProps = {
commentCount: 0,
commentedOnDisplayName: '',
createAt: 0,
displayName: 'John Smith',
enablePostUsernameOverride: false,
fromWebHook: false,
isPendingOrFailedPost: false,
isSearchResult: false,
isSystemMessage: false,
fromAutoResponder: false,
militaryTime: false,
overrideUsername: '',
renderReplies: false,
shouldRenderReplyButton: false,
showFullDate: false,
theme: Preferences.THEMES.default,
username: 'JohnSmith',
isBot: false,
isGuest: false,
userTimezone: '',
enableTimezone: false,
previousPostExists: false,
post: {id: 'post'},
beforePrevPostUserId: '0',
onPress: jest.fn(),
};
test('should match snapshot when just a base post', () => {
const wrapper = shallow(
<PostHeader {...baseProps}/>
);
expect(wrapper.getElement()).toMatchSnapshot();
expect(wrapper.find('#ReplyIcon').exists()).toEqual(false);
});
test('should match snapshot when post isBot and shouldRenderReplyButton', () => {
const props = {
...baseProps,
shouldRenderReplyButton: true,
isBot: true,
};
const wrapper = shallow(
<PostHeader {...props}/>
);
expect(wrapper.getElement()).toMatchSnapshot();
});
test('should match snapshot when post should display reply button', () => {
const props = {
...baseProps,
shouldRenderReplyButton: true,
};
const wrapper = shallow(
<PostHeader {...props}/>
);
expect(wrapper.getElement()).toMatchSnapshot();
});
test('should match snapshot when post is autoresponder', () => {
const props = {
...baseProps,
fromAutoResponder: true,
};
const wrapper = shallow(
<PostHeader {...props}/>
);
expect(wrapper.getElement()).toMatchSnapshot();
expect(wrapper.find('#ReplyIcon').exists()).toEqual(false);
});
test('should match snapshot when post is from system message', () => {
const props = {
...baseProps,
isSystemMessage: true,
};
const wrapper = shallow(
<PostHeader {...props}/>
);
expect(wrapper.getElement()).toMatchSnapshot();
expect(wrapper.find('#ReplyIcon').exists()).toEqual(false);
});
});