From 643925469b8a04511fdceb58d2c5debcfab5f016 Mon Sep 17 00:00:00 2001 From: Stan Chan Date: Mon, 10 Jul 2017 15:09:15 -0700 Subject: [PATCH] RN-38 Clicking on an at mention should open user profile (#728) --- app/components/at_mention/at_mention.js | 57 +++++++++++++++++++++---- app/components/at_mention/index.js | 3 ++ app/components/markdown/index.js | 12 +++--- app/components/post/post.js | 3 +- 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/app/components/at_mention/at_mention.js b/app/components/at_mention/at_mention.js index ae2a87e5b..f0d7ec094 100644 --- a/app/components/at_mention/at_mention.js +++ b/app/components/at_mention/at_mention.js @@ -4,39 +4,70 @@ import React from 'react'; import PropTypes from 'prop-types'; import {Text} from 'react-native'; +import {injectIntl, intlShape} from 'react-intl'; import CustomPropTypes from 'app/constants/custom_prop_types'; -export default class AtMention extends React.PureComponent { +class AtMention extends React.PureComponent { static propTypes = { + intl: intlShape, mentionName: PropTypes.string.isRequired, mentionStyle: CustomPropTypes.Style, + navigator: PropTypes.object.isRequired, textStyle: CustomPropTypes.Style, + theme: PropTypes.object.isRequired, usersByUsername: PropTypes.object.isRequired }; constructor(props) { super(props); + const userDetails = this.getUserDetailsFromMentionName(props); this.state = { - username: this.getUsernameFromMentionName(props) + username: userDetails.username, + id: userDetails.id }; } componentWillReceiveProps(nextProps) { if (nextProps.mentionName !== this.props.mentionName || nextProps.usersByUsername !== this.props.usersByUsername) { + const userDetails = this.getUserDetailsFromMentionName(nextProps); this.setState({ - username: this.getUsernameFromMentionName(nextProps) + username: userDetails.username, + id: userDetails.id }); } } - getUsernameFromMentionName(props) { + goToUserProfile = () => { + const {intl, navigator, theme} = this.props; + navigator.push({ + screen: 'UserProfile', + title: intl.formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'}), + animated: true, + backButtonTitle: '', + passProps: { + userId: this.state.id + }, + navigatorStyle: { + navBarTextColor: theme.sidebarHeaderTextColor, + navBarBackgroundColor: theme.sidebarHeaderBg, + navBarButtonColor: theme.sidebarHeaderTextColor, + screenBackgroundColor: theme.centerChannelBg + } + }); + }; + + getUserDetailsFromMentionName(props) { let mentionName = props.mentionName; while (mentionName.length > 0) { if (props.usersByUsername[mentionName]) { - return props.usersByUsername[mentionName].username; + const user = props.usersByUsername[mentionName]; + return { + username: user.username, + id: user.id + }; } // Repeatedly trim off trailing punctuation in case this is at the end of a sentence @@ -47,21 +78,27 @@ export default class AtMention extends React.PureComponent { } } - return ''; + return { + username: '' + }; } render() { + const {mentionName, mentionStyle, textStyle} = this.props; const username = this.state.username; if (!username) { - return {'@' + this.props.mentionName}; + return {'@' + mentionName}; } const suffix = this.props.mentionName.substring(username.length); return ( - - + + {'@' + username} {suffix} @@ -69,3 +106,5 @@ export default class AtMention extends React.PureComponent { ); } } + +export default injectIntl(AtMention); diff --git a/app/components/at_mention/index.js b/app/components/at_mention/index.js index d89a4847d..09f22aea7 100644 --- a/app/components/at_mention/index.js +++ b/app/components/at_mention/index.js @@ -5,10 +5,13 @@ import {connect} from 'react-redux'; import {getUsersByUsername} from 'mattermost-redux/selectors/entities/users'; +import {getTheme} from 'app/selectors/preferences'; + import AtMention from './at_mention'; function mapStateToProps(state, ownProps) { return { + theme: getTheme(state), usersByUsername: getUsersByUsername(state), ...ownProps }; diff --git a/app/components/markdown/index.js b/app/components/markdown/index.js index 9890a413d..bbfc0e7ba 100644 --- a/app/components/markdown/index.js +++ b/app/components/markdown/index.js @@ -3,7 +3,7 @@ import {Parser} from 'commonmark'; import Renderer from 'commonmark-react-renderer'; -import React from 'react'; +import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import { Platform, @@ -24,14 +24,15 @@ import MarkdownLink from './markdown_link'; import MarkdownList from './markdown_list'; import MarkdownListItem from './markdown_list_item'; -export default class Markdown extends React.PureComponent { +export default class Markdown extends PureComponent { static propTypes = { baseTextStyle: CustomPropTypes.Style, - textStyles: PropTypes.object, blockStyles: PropTypes.object, emojiSizes: PropTypes.object, - value: PropTypes.string.isRequired, - onLongPress: PropTypes.func + navigator: PropTypes.object.isRequired, + onLongPress: PropTypes.func, + textStyles: PropTypes.object, + value: PropTypes.string.isRequired }; static defaultProps = { @@ -134,6 +135,7 @@ export default class Markdown extends React.PureComponent { mentionStyle={this.props.textStyles.mention} textStyle={this.computeTextStyle(this.props.baseTextStyle, context)} mentionName={mentionName} + navigator={this.props.navigator} /> ); } diff --git a/app/components/post/post.js b/app/components/post/post.js index ed238ce9b..aa4f9ca8b 100644 --- a/app/components/post/post.js +++ b/app/components/post/post.js @@ -344,7 +344,7 @@ class Post extends PureComponent { renderMessage = (style, messageStyle, blockStyles, textStyles, replyBar = false) => { const {formatMessage} = this.props.intl; - const {isFlagged, post, theme} = this.props; + const {isFlagged, post, theme, navigator} = this.props; const {flagPost, unflagPost} = this.props.actions; const actions = []; @@ -391,6 +391,7 @@ class Post extends PureComponent { blockStyles={blockStyles} value={post.message} onLongPress={this.showOptionsContext} + navigator={navigator} />