RN-38 Clicking on an at mention should open user profile (#728)

This commit is contained in:
Stan Chan 2017-07-10 15:09:15 -07:00 committed by enahum
parent b65c7ce3be
commit 643925469b
4 changed files with 60 additions and 15 deletions

View file

@ -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 <Text style={this.props.textStyle}>{'@' + this.props.mentionName}</Text>;
return <Text style={textStyle}>{'@' + mentionName}</Text>;
}
const suffix = this.props.mentionName.substring(username.length);
return (
<Text style={this.props.textStyle}>
<Text style={this.props.mentionStyle}>
<Text
style={textStyle}
onPress={this.goToUserProfile}
>
<Text style={mentionStyle}>
{'@' + username}
</Text>
{suffix}
@ -69,3 +106,5 @@ export default class AtMention extends React.PureComponent {
);
}
}
export default injectIntl(AtMention);

View file

@ -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
};

View file

@ -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}
/>
);
}

View file

@ -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}
/>
</View>
</View>