summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--webapp/actions/user_actions.jsx10
-rw-r--r--webapp/components/post_view/components/post_body.jsx5
-rw-r--r--webapp/components/post_view/components/reaction.jsx38
-rw-r--r--webapp/components/post_view/components/reaction_container.jsx88
-rw-r--r--webapp/components/post_view/components/reaction_list_container.jsx4
-rw-r--r--webapp/components/post_view/components/reaction_list_view.jsx4
-rw-r--r--webapp/components/rhs_comment.jsx5
-rw-r--r--webapp/components/rhs_root_post.jsx5
8 files changed, 122 insertions, 37 deletions
diff --git a/webapp/actions/user_actions.jsx b/webapp/actions/user_actions.jsx
index 231b09f11..3b1fa96a8 100644
--- a/webapp/actions/user_actions.jsx
+++ b/webapp/actions/user_actions.jsx
@@ -882,3 +882,13 @@ export function loadProfiles(offset = UserStore.getPagingOffset(), limit = Const
}
);
}
+
+export function getMissingProfiles(ids, success, error) {
+ const missingIds = ids.filter((id) => !UserStore.hasProfile(id));
+
+ if (missingIds.length === 0) {
+ return;
+ }
+
+ AsyncClient.getProfilesByIds(missingIds, success, error);
+}
diff --git a/webapp/components/post_view/components/post_body.jsx b/webapp/components/post_view/components/post_body.jsx
index eb1159987..741722ceb 100644
--- a/webapp/components/post_view/components/post_body.jsx
+++ b/webapp/components/post_view/components/post_body.jsx
@@ -196,10 +196,7 @@ export default class PostBody extends React.Component {
<div className={'post__body ' + mentionHighlightClass}>
{messageWithAdditionalContent}
{fileAttachmentHolder}
- <ReactionListContainer
- post={post}
- currentUserId={this.props.currentUser.id}
- />
+ <ReactionListContainer post={post}/>
</div>
</div>
);
diff --git a/webapp/components/post_view/components/reaction.jsx b/webapp/components/post_view/components/reaction.jsx
index 92ec675b6..ae658da1f 100644
--- a/webapp/components/post_view/components/reaction.jsx
+++ b/webapp/components/post_view/components/reaction.jsx
@@ -2,13 +2,12 @@
// See License.txt for license information.
import React from 'react';
+import {OverlayTrigger, Tooltip} from 'react-bootstrap';
+import {FormattedMessage} from 'react-intl';
import EmojiStore from 'stores/emoji_store.jsx';
-import * as PostActions from 'actions/post_actions.jsx';
-import * as Utils from 'utils/utils.jsx';
-import {FormattedMessage} from 'react-intl';
-import {OverlayTrigger, Tooltip} from 'react-bootstrap';
+import * as Utils from 'utils/utils.jsx';
export default class Reaction extends React.Component {
static propTypes = {
@@ -16,7 +15,14 @@ export default class Reaction extends React.Component {
currentUserId: React.PropTypes.string.isRequired,
emojiName: React.PropTypes.string.isRequired,
reactions: React.PropTypes.arrayOf(React.PropTypes.object),
- emojis: React.PropTypes.object.isRequired
+ emojis: React.PropTypes.object.isRequired,
+ profiles: React.PropTypes.array.isRequired,
+ otherUsers: React.PropTypes.number.isRequired,
+ actions: React.PropTypes.shape({
+ addReaction: React.PropTypes.func.isRequired,
+ getMissingProfiles: React.PropTypes.func.isRequired,
+ removeReaction: React.PropTypes.func.isRequired
+ })
}
constructor(props) {
@@ -28,12 +34,12 @@ export default class Reaction extends React.Component {
addReaction(e) {
e.preventDefault();
- PostActions.addReaction(this.props.post.channel_id, this.props.post.id, this.props.emojiName);
+ this.props.actions.addReaction(this.props.post.channel_id, this.props.post.id, this.props.emojiName);
}
removeReaction(e) {
e.preventDefault();
- PostActions.removeReaction(this.props.post.channel_id, this.props.post.id, this.props.emojiName);
+ this.props.actions.removeReaction(this.props.post.channel_id, this.props.post.id, this.props.emojiName);
}
render() {
@@ -43,23 +49,16 @@ export default class Reaction extends React.Component {
let currentUserReacted = false;
const users = [];
- let otherUsers = 0;
- for (const reaction of this.props.reactions) {
- if (reaction.user_id === this.props.currentUserId) {
+ const otherUsers = this.props.otherUsers;
+ for (const user of this.props.profiles) {
+ if (user.id === this.props.currentUserId) {
currentUserReacted = true;
} else {
- const displayName = Utils.displayUsername(reaction.user_id);
-
- if (displayName) {
- users.push(displayName);
- } else {
- // Just count users that we don't have loaded
- otherUsers += 1;
- }
+ users.push(Utils.displayUsernameForUser(user));
}
}
- // sort users in alphabetical order with "you" being first if the current user reacted
+ // Sort users in alphabetical order with "you" being first if the current user reacted
users.sort();
if (currentUserReacted) {
users.unshift(Utils.localizeMessage('reaction.you', 'You'));
@@ -184,6 +183,7 @@ export default class Reaction extends React.Component {
{clickTooltip}
</Tooltip>
}
+ onEnter={this.props.actions.getMissingProfiles}
>
<div
className={className}
diff --git a/webapp/components/post_view/components/reaction_container.jsx b/webapp/components/post_view/components/reaction_container.jsx
new file mode 100644
index 000000000..09e6ce5ea
--- /dev/null
+++ b/webapp/components/post_view/components/reaction_container.jsx
@@ -0,0 +1,88 @@
+// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import React from 'react';
+
+import {addReaction, removeReaction} from 'actions/post_actions.jsx';
+import * as UserActions from 'actions/user_actions.jsx';
+
+import UserStore from 'stores/user_store.jsx';
+
+import Reaction from './reaction.jsx';
+
+export default class ReactionContainer extends React.Component {
+ static propTypes = {
+ post: React.PropTypes.object.isRequired,
+ emojiName: React.PropTypes.string.isRequired,
+ reactions: React.PropTypes.arrayOf(React.PropTypes.object),
+ emojis: React.PropTypes.object.isRequired
+ }
+
+ constructor(props) {
+ super(props);
+
+ this.handleUsersChanged = this.handleUsersChanged.bind(this);
+
+ this.getStateFromStore = this.getStateFromStore.bind(this);
+
+ this.getProfilesForReactions = this.getProfilesForReactions.bind(this);
+ this.getMissingProfiles = this.getMissingProfiles.bind(this);
+
+ this.state = this.getStateFromStore(props);
+ }
+
+ componentDidMount() {
+ UserStore.addChangeListener(this.handleUsersChanged);
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.reactions !== this.props.reactions) {
+ this.setState(this.getStateFromStore(nextProps));
+ }
+ }
+
+ componentWillUnmount() {
+ UserStore.removeChangeListener(this.handleUsersChanged);
+ }
+
+ handleUsersChanged() {
+ this.setState(this.getStateFromStore());
+ }
+
+ getStateFromStore(props = this.props) {
+ const profiles = this.getProfilesForReactions(props.reactions);
+ const otherUsers = props.reactions.length - profiles.length;
+
+ return {
+ profiles,
+ otherUsers,
+ currentUserId: UserStore.getCurrentId()
+ };
+ }
+
+ getProfilesForReactions(reactions) {
+ return reactions.map((reaction) => {
+ return UserStore.getProfile(reaction.user_id);
+ }).filter((profile) => Boolean(profile));
+ }
+
+ getMissingProfiles() {
+ const ids = this.props.reactions.map((reaction) => reaction.user_id);
+
+ UserActions.getMissingProfiles(ids);
+ }
+
+ render() {
+ return (
+ <Reaction
+ {...this.props}
+ {...this.state}
+ actions={{
+ addReaction,
+ getMissingProfiles: this.getMissingProfiles,
+ removeReaction
+ }}
+ />
+ );
+ }
+}
diff --git a/webapp/components/post_view/components/reaction_list_container.jsx b/webapp/components/post_view/components/reaction_list_container.jsx
index 3ee8f73a3..906145eed 100644
--- a/webapp/components/post_view/components/reaction_list_container.jsx
+++ b/webapp/components/post_view/components/reaction_list_container.jsx
@@ -11,8 +11,7 @@ import ReactionListView from './reaction_list_view.jsx';
export default class ReactionListContainer extends React.Component {
static propTypes = {
- post: React.PropTypes.object.isRequired,
- currentUserId: React.PropTypes.string.isRequired
+ post: React.PropTypes.object.isRequired
}
constructor(props) {
@@ -86,7 +85,6 @@ export default class ReactionListContainer extends React.Component {
return (
<ReactionListView
post={this.props.post}
- currentUserId={this.props.currentUserId}
reactions={this.state.reactions}
emojis={this.state.emojis}
/>
diff --git a/webapp/components/post_view/components/reaction_list_view.jsx b/webapp/components/post_view/components/reaction_list_view.jsx
index aaa896c9a..c322ce727 100644
--- a/webapp/components/post_view/components/reaction_list_view.jsx
+++ b/webapp/components/post_view/components/reaction_list_view.jsx
@@ -3,12 +3,11 @@
import React from 'react';
-import Reaction from './reaction.jsx';
+import Reaction from './reaction_container.jsx';
export default class ReactionListView extends React.Component {
static propTypes = {
post: React.PropTypes.object.isRequired,
- currentUserId: React.PropTypes.string.isRequired,
reactions: React.PropTypes.arrayOf(React.PropTypes.object),
emojis: React.PropTypes.object.isRequired
}
@@ -33,7 +32,6 @@ export default class ReactionListView extends React.Component {
<Reaction
key={emojiName}
post={this.props.post}
- currentUserId={this.props.currentUserId}
emojiName={emojiName}
reactions={reactionsByName.get(emojiName)}
emojis={this.props.emojis}
diff --git a/webapp/components/rhs_comment.jsx b/webapp/components/rhs_comment.jsx
index 52e4d9851..278163bf7 100644
--- a/webapp/components/rhs_comment.jsx
+++ b/webapp/components/rhs_comment.jsx
@@ -592,10 +592,7 @@ export default class RhsComment extends React.Component {
<PostMessageContainer post={post}/>
</div>
{fileAttachment}
- <ReactionListContainer
- post={post}
- currentUserId={this.props.currentUser.id}
- />
+ <ReactionListContainer post={post}/>
</div>
</div>
</div>
diff --git a/webapp/components/rhs_root_post.jsx b/webapp/components/rhs_root_post.jsx
index 231033fb1..f07826d63 100644
--- a/webapp/components/rhs_root_post.jsx
+++ b/webapp/components/rhs_root_post.jsx
@@ -559,10 +559,7 @@ export default class RhsRootPost extends React.Component {
/>
</div>
{fileAttachment}
- <ReactionListContainer
- post={post}
- currentUserId={this.props.currentUser.id}
- />
+ <ReactionListContainer post={post}/>
</div>
</div>
</div>