diff --git a/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js b/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js index f195d4bc624d..b49896ac3fed 100755 --- a/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js +++ b/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js @@ -49,6 +49,7 @@ const customHTMLElementModels = { tagName: 'strong', mixedUAStyles: {whiteSpace: 'pre'}, }), + 'mention-user': defaultHTMLElementModels.span.extend({tagName: 'mention-user'}), }; // We are using the explicit composite architecture for performance gains. diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js new file mode 100644 index 000000000000..91ac89fdc33c --- /dev/null +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js @@ -0,0 +1,59 @@ +import React from 'react'; +import _ from 'underscore'; +import { + TNodeChildrenRenderer, +} from 'react-native-render-html'; +import Navigation from '../../../libs/Navigation/Navigation'; +import ROUTES from '../../../ROUTES'; +import Text from '../../Text'; +import Tooltip from '../../Tooltip'; +import htmlRendererPropTypes from './htmlRendererPropTypes'; +import withCurrentUserPersonalDetails from '../../withCurrentUserPersonalDetails'; +import personalDetailsPropType from '../../../pages/personalDetailsPropType'; +import * as StyleUtils from '../../../styles/StyleUtils'; + +const propTypes = { + ...htmlRendererPropTypes, + + /** + * Current user personal details + */ + currentUserPersonalDetails: personalDetailsPropType.isRequired, +}; + +/** + * Navigates to user details screen based on email + * @param {String} email + * @returns {void} + * */ +const showUserDetails = email => Navigation.navigate(ROUTES.getDetailsRoute(email)); + +const MentionUserRenderer = (props) => { + const defaultRendererProps = _.omit(props, ['TDefaultRenderer', 'style']); + + // We need to remove the leading @ from data as it is not part of the login + const loginWhithoutLeadingAt = props.tnode.data.slice(1); + + const isOurMention = loginWhithoutLeadingAt === props.currentUserPersonalDetails.login; + + return ( + + + showUserDetails(loginWhithoutLeadingAt)} + > + + + + + ); +}; + +MentionUserRenderer.propTypes = propTypes; +MentionUserRenderer.displayName = 'MentionUserRenderer'; + +export default withCurrentUserPersonalDetails(MentionUserRenderer); diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/index.js index 4b9d0fc85962..01a0721cd5c4 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/index.js @@ -2,6 +2,7 @@ import AnchorRenderer from './AnchorRenderer'; import CodeRenderer from './CodeRenderer'; import EditedRenderer from './EditedRenderer'; import ImageRenderer from './ImageRenderer'; +import MentionUserRenderer from './MentionUserRenderer'; import PreRenderer from './PreRenderer'; /** @@ -16,4 +17,5 @@ export default { // Custom tag renderers edited: EditedRenderer, pre: PreRenderer, + 'mention-user': MentionUserRenderer, }; diff --git a/src/styles/StyleUtils.js b/src/styles/StyleUtils.js index 5b1be7cc1a63..cc0fe59696dc 100644 --- a/src/styles/StyleUtils.js +++ b/src/styles/StyleUtils.js @@ -1109,6 +1109,29 @@ function getGoogleListViewStyle(shouldDisplayBorder) { }; } +/** + * Returns style object for the user mention component based on whether the mention is ours or not. + * @param {Boolean} isOurMention + * @returns {Object} + */ +function getUserMentionStyle(isOurMention) { + const backgroundColor = isOurMention ? themeColors.ourMentionBG : themeColors.mentionBG; + return { + backgroundColor, + borderRadius: variables.componentBorderRadiusSmall, + paddingHorizontal: 2, + }; +} + +/** + * Returns text color for the user mention text based on whether the mention is ours or not. + * @param {Boolean} isOurMention + * @returns {Object} + */ +function getUserMentionTextColor(isOurMention) { + return isOurMention ? themeColors.ourMentionText : themeColors.mentionText; +} + export { getAvatarSize, getAvatarStyle, @@ -1169,4 +1192,6 @@ export { getFontSizeStyle, getSignInWordmarkWidthStyle, getGoogleListViewStyle, + getUserMentionStyle, + getUserMentionTextColor, }; diff --git a/src/styles/colors.js b/src/styles/colors.js index 592715e66ab1..0fc14575ca84 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -37,13 +37,17 @@ export default { midnight: '#002140', // Brand Colors from Figma + blue100: '#B0D9FF', blue200: '#8DC8FF', blue400: '#0185FF', + blue600: '#0164BF', blue700: '#003C73', blue800: '#002140', + green100: '#B1F2D6', green200: '#8EECC4', green400: '#03D47C', + green600: '#008C59', green700: '#085239', green800: '#002E22', diff --git a/src/styles/themes/default.js b/src/styles/themes/default.js index c35b0d53eb26..0917d1d5b794 100644 --- a/src/styles/themes/default.js +++ b/src/styles/themes/default.js @@ -69,6 +69,10 @@ const darkTheme = { reactionActive: '#003C73', badgeAdHoc: colors.pink600, badgeAdHocHover: colors.pink700, + mentionText: colors.blue100, + mentionBG: colors.blue600, + ourMentionText: colors.green100, + ourMentionBG: colors.green600, }; const oldTheme = {