diff --git a/app/components/message_attachments/action_button/action_button.js b/app/components/message_attachments/action_button/action_button.js
index 760a101d8..54c9c2ec7 100644
--- a/app/components/message_attachments/action_button/action_button.js
+++ b/app/components/message_attachments/action_button/action_button.js
@@ -7,6 +7,7 @@ import Button from 'react-native-button';
import {preventDoubleTap} from 'app/utils/tap';
import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme';
+import {STATUS_COLORS} from 'app/constants/colors';
import ActionButtonText from './action_button_text';
export default class ActionButton extends PureComponent {
@@ -20,6 +21,7 @@ export default class ActionButton extends PureComponent {
theme: PropTypes.object.isRequired,
cookie: PropTypes.string.isRequired,
disabled: PropTypes.bool,
+ buttonColor: PropTypes.string,
};
handleActionPress = preventDoubleTap(() => {
@@ -28,19 +30,27 @@ export default class ActionButton extends PureComponent {
}, 4000);
render() {
- const {name, theme, disabled} = this.props;
+ const {name, theme, disabled, buttonColor} = this.props;
const style = getStyleSheet(theme);
+ let customButtonStyle;
+ let customButtonTextStyle;
+
+ if (buttonColor) {
+ const hexColor = STATUS_COLORS[buttonColor] || theme[buttonColor] || buttonColor;
+ customButtonStyle = {borderColor: changeOpacity(hexColor, 0.25), backgroundColor: '#ffffff'};
+ customButtonTextStyle = {color: hexColor};
+ }
return (
);
@@ -50,24 +60,23 @@ export default class ActionButton extends PureComponent {
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
button: {
- borderRadius: 2,
- backgroundColor: theme.buttonBg,
+ borderRadius: 4,
+ borderColor: changeOpacity(STATUS_COLORS.default, 0.25),
+ borderWidth: 2,
opacity: 1,
alignItems: 'center',
- marginBottom: 2,
- marginRight: 5,
- marginTop: 10,
- paddingHorizontal: 10,
- paddingVertical: 7,
+ marginTop: 12,
+ justifyContent: 'center',
+ height: 36,
},
buttonDisabled: {
backgroundColor: changeOpacity(theme.buttonBg, 0.3),
},
text: {
- color: theme.buttonColor,
- fontSize: 12,
+ color: STATUS_COLORS.default,
+ fontSize: 15,
fontWeight: '600',
- lineHeight: 13,
+ lineHeight: 17,
},
};
});
diff --git a/app/components/message_attachments/action_button/action_button.test.js b/app/components/message_attachments/action_button/action_button.test.js
new file mode 100644
index 000000000..dd797bbf3
--- /dev/null
+++ b/app/components/message_attachments/action_button/action_button.test.js
@@ -0,0 +1,127 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React from 'react';
+import {shallow} from 'enzyme';
+import ActionButton from './action_button';
+import {changeOpacity} from 'app/utils/theme';
+import {STATUS_COLORS} from 'app/constants/colors';
+
+import Preferences from 'mattermost-redux/constants/preferences';
+
+describe('ActionButton', () => {
+ test('correct styles when from global theme', () => {
+ const buttonConfig = {
+ id: 'gpc1tihowfabfmmcizddo',
+ name: 'Option 1',
+ style: 'onlineIndicator',
+ };
+
+ const baseProps = {
+ id: buttonConfig.id,
+ cookie: '',
+ name: buttonConfig.name,
+ postId: buttonConfig.id,
+ buttonColor: buttonConfig.style,
+ theme: Preferences.THEMES.default,
+ actions: {
+ doPostActionWithCookie: jest.fn(),
+ },
+ };
+
+ const wrapper = shallow();
+
+ const buttonTextChild = wrapper.getElement().props.children;
+ const dynamicButtonStyles = wrapper.getElement().props.containerStyle[1];
+
+ expect(dynamicButtonStyles.borderColor).toBe(changeOpacity(Preferences.THEMES.default[buttonConfig.style], 0.25));
+ expect(buttonTextChild.props.style.color).toBe(Preferences.THEMES.default[buttonConfig.style]);
+ });
+
+ test('correct styles when a status color', () => {
+ const buttonConfig = {
+ id: 'gpc1tihowbfmmcizofm7zhr1to',
+ name: 'Option 2',
+ style: 'danger',
+ };
+
+ const baseProps = {
+ id: buttonConfig.id,
+ cookie: '',
+ name: buttonConfig.name,
+ postId: buttonConfig.id,
+ buttonColor: buttonConfig.style,
+ theme: Preferences.THEMES.default,
+ actions: {
+ doPostActionWithCookie: jest.fn(),
+ },
+ };
+
+ const wrapper = shallow();
+
+ const buttonTextChild = wrapper.getElement().props.children;
+ const dynamicButtonStyles = wrapper.getElement().props.containerStyle[1];
+
+ expect(dynamicButtonStyles.borderColor).toBe(changeOpacity(STATUS_COLORS[buttonConfig.style], 0.25));
+ expect(buttonTextChild.props.style.color).toBe(STATUS_COLORS[buttonConfig.style]);
+ });
+
+ test('correct styles when a hex style', () => {
+ const buttonConfig = {
+ id: 'gpc1tihowbfawemmcizddo',
+ name: 'Option 3',
+ style: '#166de0',
+ };
+
+ const baseProps = {
+ id: buttonConfig.id,
+ cookie: '',
+ name: buttonConfig.name,
+ postId: buttonConfig.id,
+ buttonColor: buttonConfig.style,
+ theme: Preferences.THEMES.default,
+ actions: {
+ doPostActionWithCookie: jest.fn(),
+ },
+ };
+
+ const wrapper = shallow();
+
+ const buttonTextChild = wrapper.getElement().props.children;
+ const dynamicButtonStyles = wrapper.getElement().props.containerStyle[1];
+
+ expect(dynamicButtonStyles.borderColor).toBe(changeOpacity(buttonConfig.style, 0.25));
+ expect(buttonTextChild.props.style.color).toBe(buttonConfig.style);
+ });
+
+ test('correct default styles', () => {
+ const buttonConfig = {
+ id: 'gpc1tihowbfawemmcizddo',
+ name: 'Option 4',
+ };
+
+ const baseProps = {
+ id: buttonConfig.id,
+ cookie: '',
+ name: buttonConfig.name,
+ postId: buttonConfig.id,
+ buttonColor: buttonConfig.style,
+ theme: Preferences.THEMES.default,
+ actions: {
+ doPostActionWithCookie: jest.fn(),
+ },
+ };
+
+ const wrapper = shallow();
+
+ const buttonTextChild = wrapper.getElement().props.children;
+ const baseButtonStyles = wrapper.getElement().props.containerStyle[0];
+ const dynamicButtonStyles = wrapper.getElement().props.containerStyle[1];
+
+ expect(baseButtonStyles.borderColor).toBe(changeOpacity(Preferences.THEMES.default.centerChannelColor, 0.25));
+ expect(baseButtonStyles.borderWidth).toBe(2);
+ expect(baseButtonStyles.borderRadius).toBe(4);
+ expect(dynamicButtonStyles).toBe(undefined);
+ expect(buttonTextChild.props.style.color).toBe(Preferences.THEMES.default.centerChannelColor);
+ });
+});
\ No newline at end of file
diff --git a/app/components/message_attachments/attachment_actions.js b/app/components/message_attachments/attachment_actions.js
index 361e1c30e..e80f84618 100644
--- a/app/components/message_attachments/attachment_actions.js
+++ b/app/components/message_attachments/attachment_actions.js
@@ -55,6 +55,7 @@ export default class AttachmentActions extends PureComponent {
name={action.name}
postId={postId}
disabled={action.disabled}
+ buttonColor={action.style}
/>,
);
break;
diff --git a/app/components/message_attachments/message_attachment.js b/app/components/message_attachments/message_attachment.js
index 1c750b9b0..e29bf1cae 100644
--- a/app/components/message_attachments/message_attachment.js
+++ b/app/components/message_attachments/message_attachment.js
@@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
import {View} from 'react-native';
import CustomPropTypes from 'app/constants/custom_prop_types';
+import {STATUS_COLORS} from 'app/constants/colors';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import AttachmentActions from './attachment_actions';
@@ -18,12 +19,6 @@ import AttachmentThumbnail from './attachment_thumbnail';
import AttachmentTitle from './attachment_title';
import AttachmentFooter from './attachment_footer';
-const STATUS_COLORS = {
- good: '#00c100',
- warning: '#dede01',
- danger: '#e40303',
-};
-
export default class MessageAttachment extends PureComponent {
static propTypes = {
attachment: PropTypes.object.isRequired,
@@ -138,7 +133,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
borderRightWidth: 1,
borderTopWidth: 1,
marginTop: 5,
- padding: 10,
+ padding: 12,
},
border: {
borderLeftColor: changeOpacity(theme.linkColor, 0.6),
diff --git a/app/constants/colors.js b/app/constants/colors.js
new file mode 100644
index 000000000..795bb23e4
--- /dev/null
+++ b/app/constants/colors.js
@@ -0,0 +1,13 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import Preferences from 'mattermost-redux/constants/preferences';
+
+export const STATUS_COLORS = {
+ good: '#00c100',
+ warning: '#dede01',
+ danger: Preferences.THEMES.default.errorTextColor,
+ default: Preferences.THEMES.default.centerChannelColor,
+ primary: Preferences.THEMES.default.buttonBg,
+ success: Preferences.THEMES.default.onlineIndicator,
+};