GH-11994: Add support for footer and footer_icon in attachments (#3228)

This commit adds support for the footer and footer_icon fields that are
rendered at the bottom of message attachments.
This commit is contained in:
Nathan Friend
2019-09-11 21:58:55 -03:00
committed by Ben Schumacher
parent 7b6033ba5d
commit 9ccde970fa
5 changed files with 260 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AttachmentFooter it matches snapshot when both footer and footer_icon are provided 1`] = `
<View
style={
Object {
"flex": 1,
"flexDirection": "row",
"marginTop": 5,
}
}
>
<Image
key="footer_icon"
source={
Object {
"uri": "https://images.com/image.png",
}
}
style={
Object {
"height": 12,
"marginRight": 5,
"marginTop": 1,
"width": 12,
}
}
/>
<Text
key="footer_text"
style={
Object {
"color": "rgba(61,60,64,0.5)",
"fontSize": 11,
}
}
>
This is the footer!
</Text>
</View>
`;
exports[`AttachmentFooter it matches snapshot when footer text is provided 1`] = `
<View
style={
Object {
"flex": 1,
"flexDirection": "row",
"marginTop": 5,
}
}
>
<Text
key="footer_text"
style={
Object {
"color": "rgba(61,60,64,0.5)",
"fontSize": 11,
}
}
>
This is the footer!
</Text>
</View>
`;
exports[`AttachmentFooter it matches snapshot when no footer is provided 1`] = `""`;
exports[`AttachmentFooter it matches snapshot when only the footer icon is provided 1`] = `""`;
exports[`AttachmentFooter it matches snapshot when the footer is longer than the maximum length 1`] = `
<View
style={
Object {
"flex": 1,
"flexDirection": "row",
"marginTop": 5,
}
}
>
<Image
key="footer_icon"
source={
Object {
"uri": "https://images.com/image.png",
}
}
style={
Object {
"height": 12,
"marginRight": 5,
"marginTop": 1,
"width": 12,
}
}
/>
<Text
key="footer_text"
style={
Object {
"color": "rgba(61,60,64,0.5)",
"fontSize": 11,
}
}
>
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…
</Text>
</View>
`;

View File

@@ -0,0 +1,77 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {PureComponent} from 'react';
import {Image, Text, View, Platform} from 'react-native';
import PropTypes from 'prop-types';
import truncate from 'lodash/truncate';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import {MAX_ATTACHMENT_FOOTER_LENGTH} from 'app/constants/attachment';
export default class AttachmentFooter extends PureComponent {
static propTypes = {
text: PropTypes.string,
icon: PropTypes.string,
theme: PropTypes.object.isRequired,
};
render() {
const {
text,
icon,
theme,
} = this.props;
if (!text) {
return null;
}
const style = getStyleSheet(theme);
return (
<View style={style.container}>
{Boolean(icon) &&
<Image
source={{uri: icon}}
key='footer_icon'
style={style.icon}
/>
}
<Text
key='footer_text'
style={style.text}
>
{truncate(text, {length: MAX_ATTACHMENT_FOOTER_LENGTH, omission: '…'})}
</Text>
</View>
);
}
}
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
container: {
flex: 1,
flexDirection: 'row',
marginTop: 5,
},
icon: {
height: 12,
width: 12,
marginRight: 5,
...Platform.select({
ios: {
marginTop: 1,
},
android: {
marginTop: 2,
},
}),
},
text: {
color: changeOpacity(theme.centerChannelColor, 0.5),
fontSize: 11,
},
};
});

View File

@@ -0,0 +1,64 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import {MAX_ATTACHMENT_FOOTER_LENGTH} from 'app/constants/attachment';
import AttachmentFooter from './attachment_footer';
import Preferences from 'mattermost-redux/constants/preferences';
describe('AttachmentFooter', () => {
const baseProps = {
text: 'This is the footer!',
icon: 'https://images.com/image.png',
theme: Preferences.THEMES.default,
};
test('it matches snapshot when no footer is provided', () => {
const props = {
...baseProps,
text: undefined,
icon: undefined,
};
const wrapper = shallow(<AttachmentFooter {...props}/>);
expect(wrapper).toMatchSnapshot();
});
test('it matches snapshot when footer text is provided', () => {
const props = {
...baseProps,
icon: undefined,
};
const wrapper = shallow(<AttachmentFooter {...props}/>);
expect(wrapper).toMatchSnapshot();
});
test('it matches snapshot when only the footer icon is provided', () => {
const props = {
...baseProps,
text: undefined,
};
const wrapper = shallow(<AttachmentFooter {...props}/>);
expect(wrapper).toMatchSnapshot();
});
test('it matches snapshot when both footer and footer_icon are provided', () => {
const wrapper = shallow(<AttachmentFooter {...baseProps}/>);
expect(wrapper).toMatchSnapshot();
});
test('it matches snapshot when the footer is longer than the maximum length', () => {
const props = {
...baseProps,
text: 'a'.repeat(MAX_ATTACHMENT_FOOTER_LENGTH + 1),
};
const wrapper = shallow(<AttachmentFooter {...props}/>);
expect(wrapper).toMatchSnapshot();
});
});

View File

@@ -16,6 +16,7 @@ import AttachmentPreText from './attachment_pretext';
import AttachmentText from './attachment_text';
import AttachmentThumbnail from './attachment_thumbnail';
import AttachmentTitle from './attachment_title';
import AttachmentFooter from './attachment_footer';
const STATUS_COLORS = {
good: '#00c100',
@@ -104,6 +105,11 @@ export default class MessageAttachment extends PureComponent {
textStyles={textStyles}
theme={theme}
/>
<AttachmentFooter
icon={attachment.footer_icon}
text={attachment.footer}
theme={theme}
/>
<AttachmentActions
actions={attachment.actions}
postId={postId}

View File

@@ -0,0 +1,4 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
export const MAX_ATTACHMENT_FOOTER_LENGTH = 300;