diff --git a/app/components/at_mention/at_mention.js b/app/components/at_mention/at_mention.js
new file mode 100644
index 000000000..7fe1b0c72
--- /dev/null
+++ b/app/components/at_mention/at_mention.js
@@ -0,0 +1,50 @@
+// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import React, {PropTypes, PureComponent} from 'react';
+import {Text} from 'react-native';
+
+import CustomPropTypes from 'app/constants/custom_prop_types';
+
+export default class AtMention extends PureComponent {
+ static propTypes = {
+ mentionName: PropTypes.string.isRequired,
+ mentionStyle: CustomPropTypes.Style,
+ textStyle: CustomPropTypes.Style,
+ usersByUsername: PropTypes.object.isRequired
+ };
+
+ getUsernameFromMentionName = () => {
+ let mentionName = this.props.mentionName;
+
+ while (mentionName.length > 0) {
+ if (this.props.usersByUsername[mentionName]) {
+ return this.props.usersByUsername[mentionName].username;
+ }
+
+ // Repeatedly trim off trailing punctuation in case this is at the end of a sentence
+ if ((/[._-]$/).test(mentionName)) {
+ mentionName = mentionName.substring(0, mentionName.length - 1);
+ } else {
+ break;
+ }
+ }
+
+ // Just assume this is a mention for a user that we don't have
+ return mentionName;
+ }
+
+ render() {
+ const username = this.getUsernameFromMentionName();
+ const suffix = this.props.mentionName.substring(username.length);
+
+ return (
+
+
+ {'@' + username}
+
+ {suffix}
+
+ );
+ }
+}
diff --git a/app/components/at_mention/at_mention_container.js b/app/components/at_mention/at_mention_container.js
new file mode 100644
index 000000000..fe5ffee2b
--- /dev/null
+++ b/app/components/at_mention/at_mention_container.js
@@ -0,0 +1,17 @@
+// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import {connect} from 'react-redux';
+
+import {getUsersByUsername} from 'mattermost-redux/selectors/entities/users';
+
+import AtMention from './at_mention';
+
+function mapStateToProps(state, ownProps) {
+ return {
+ usersByUsername: getUsersByUsername(state),
+ ...ownProps
+ };
+}
+
+export default connect(mapStateToProps)(AtMention);
diff --git a/app/components/at_mention/index.js b/app/components/at_mention/index.js
new file mode 100644
index 000000000..6ff7e5ece
--- /dev/null
+++ b/app/components/at_mention/index.js
@@ -0,0 +1,5 @@
+// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import AtMention from './at_mention_container';
+export default AtMention;
diff --git a/app/components/markdown/markdown.js b/app/components/markdown/markdown.js
index 34994e390..c7af96f31 100644
--- a/app/components/markdown/markdown.js
+++ b/app/components/markdown/markdown.js
@@ -10,6 +10,7 @@ import {
View
} from 'react-native';
+import AtMention from 'app/components/at_mention';
import CustomPropTypes from 'app/constants/custom_prop_types';
import {concatStyles} from 'app/utils/theme';
@@ -49,6 +50,7 @@ export default class Markdown extends PureComponent {
code: this.renderCodeSpan,
link: MarkdownLink,
image: this.renderImage,
+ atMention: this.renderAtMention,
paragraph: this.renderParagraph,
heading: this.renderHeading,
@@ -95,6 +97,16 @@ export default class Markdown extends PureComponent {
);
}
+ renderAtMention = ({context, mentionName}) => {
+ return (
+
+ );
+ }
+
renderParagraph = ({children}) => {
return (
diff --git a/app/components/post/post.js b/app/components/post/post.js
index 6bfe885d2..3e8f331de 100644
--- a/app/components/post/post.js
+++ b/app/components/post/post.js
@@ -564,6 +564,9 @@ const getMarkdownTextStyles = makeStyleSheetFromTheme((theme) => {
height: StyleSheet.hairlineWidth,
flex: 1,
marginVertical: 10
+ },
+ mention: {
+ color: theme.linkColor
}
});
});
diff --git a/package.json b/package.json
index ee279b6a7..1c8143665 100644
--- a/package.json
+++ b/package.json
@@ -3,8 +3,8 @@
"version": "0.0.1",
"private": true,
"dependencies": {
- "commonmark": "hmhealey/commonmark.js#00189db64c261926de98db16ca14d5b1bcba4d8e",
- "commonmark-react-renderer": "hmhealey/commonmark-react-renderer#2e8ea6ac67b683b44782f403b69a06bb0e5c63e6",
+ "commonmark": "hmhealey/commonmark.js#46784f1461fa34e148940534c1763af6d344ab0f",
+ "commonmark-react-renderer": "hmhealey/commonmark-react-renderer#7479202c42ab1b722359adadaa13f738edf5f88a",
"deep-equal": "1.0.1",
"harmony-reflect": "1.5.1",
"intl": "1.2.5",