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 = {