PLT-5035 Added loading of missing profiles when hovering over reactions (#5887)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
c06a23ea0b
Коммит
ee3b983a63
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -196,10 +196,7 @@ export default class PostBody extends React.Component {
|
|||||||
<div className={'post__body ' + mentionHighlightClass}>
|
<div className={'post__body ' + mentionHighlightClass}>
|
||||||
{messageWithAdditionalContent}
|
{messageWithAdditionalContent}
|
||||||
{fileAttachmentHolder}
|
{fileAttachmentHolder}
|
||||||
<ReactionListContainer
|
<ReactionListContainer post={post}/>
|
||||||
post={post}
|
|
||||||
currentUserId={this.props.currentUser.id}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
// See License.txt for license information.
|
// See License.txt for license information.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {OverlayTrigger, Tooltip} from 'react-bootstrap';
|
||||||
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
import EmojiStore from 'stores/emoji_store.jsx';
|
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 * as Utils from 'utils/utils.jsx';
|
||||||
import {OverlayTrigger, Tooltip} from 'react-bootstrap';
|
|
||||||
|
|
||||||
export default class Reaction extends React.Component {
|
export default class Reaction extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -16,7 +15,14 @@ export default class Reaction extends React.Component {
|
|||||||
currentUserId: React.PropTypes.string.isRequired,
|
currentUserId: React.PropTypes.string.isRequired,
|
||||||
emojiName: React.PropTypes.string.isRequired,
|
emojiName: React.PropTypes.string.isRequired,
|
||||||
reactions: React.PropTypes.arrayOf(React.PropTypes.object),
|
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) {
|
constructor(props) {
|
||||||
@@ -28,12 +34,12 @@ export default class Reaction extends React.Component {
|
|||||||
|
|
||||||
addReaction(e) {
|
addReaction(e) {
|
||||||
e.preventDefault();
|
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) {
|
removeReaction(e) {
|
||||||
e.preventDefault();
|
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() {
|
render() {
|
||||||
@@ -43,23 +49,16 @@ export default class Reaction extends React.Component {
|
|||||||
|
|
||||||
let currentUserReacted = false;
|
let currentUserReacted = false;
|
||||||
const users = [];
|
const users = [];
|
||||||
let otherUsers = 0;
|
const otherUsers = this.props.otherUsers;
|
||||||
for (const reaction of this.props.reactions) {
|
for (const user of this.props.profiles) {
|
||||||
if (reaction.user_id === this.props.currentUserId) {
|
if (user.id === this.props.currentUserId) {
|
||||||
currentUserReacted = true;
|
currentUserReacted = true;
|
||||||
} else {
|
} else {
|
||||||
const displayName = Utils.displayUsername(reaction.user_id);
|
users.push(Utils.displayUsernameForUser(user));
|
||||||
|
|
||||||
if (displayName) {
|
|
||||||
users.push(displayName);
|
|
||||||
} else {
|
|
||||||
// Just count users that we don't have loaded
|
|
||||||
otherUsers += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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();
|
users.sort();
|
||||||
if (currentUserReacted) {
|
if (currentUserReacted) {
|
||||||
users.unshift(Utils.localizeMessage('reaction.you', 'You'));
|
users.unshift(Utils.localizeMessage('reaction.you', 'You'));
|
||||||
@@ -184,6 +183,7 @@ export default class Reaction extends React.Component {
|
|||||||
{clickTooltip}
|
{clickTooltip}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
|
onEnter={this.props.actions.getMissingProfiles}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={className}
|
className={className}
|
||||||
|
|||||||
88
webapp/components/post_view/components/reaction_container.jsx
Обычный файл
88
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
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,8 +11,7 @@ import ReactionListView from './reaction_list_view.jsx';
|
|||||||
|
|
||||||
export default class ReactionListContainer extends React.Component {
|
export default class ReactionListContainer extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
post: React.PropTypes.object.isRequired,
|
post: React.PropTypes.object.isRequired
|
||||||
currentUserId: React.PropTypes.string.isRequired
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -86,7 +85,6 @@ export default class ReactionListContainer extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<ReactionListView
|
<ReactionListView
|
||||||
post={this.props.post}
|
post={this.props.post}
|
||||||
currentUserId={this.props.currentUserId}
|
|
||||||
reactions={this.state.reactions}
|
reactions={this.state.reactions}
|
||||||
emojis={this.state.emojis}
|
emojis={this.state.emojis}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -3,12 +3,11 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Reaction from './reaction.jsx';
|
import Reaction from './reaction_container.jsx';
|
||||||
|
|
||||||
export default class ReactionListView extends React.Component {
|
export default class ReactionListView extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
post: React.PropTypes.object.isRequired,
|
post: React.PropTypes.object.isRequired,
|
||||||
currentUserId: React.PropTypes.string.isRequired,
|
|
||||||
reactions: React.PropTypes.arrayOf(React.PropTypes.object),
|
reactions: React.PropTypes.arrayOf(React.PropTypes.object),
|
||||||
emojis: React.PropTypes.object.isRequired
|
emojis: React.PropTypes.object.isRequired
|
||||||
}
|
}
|
||||||
@@ -33,7 +32,6 @@ export default class ReactionListView extends React.Component {
|
|||||||
<Reaction
|
<Reaction
|
||||||
key={emojiName}
|
key={emojiName}
|
||||||
post={this.props.post}
|
post={this.props.post}
|
||||||
currentUserId={this.props.currentUserId}
|
|
||||||
emojiName={emojiName}
|
emojiName={emojiName}
|
||||||
reactions={reactionsByName.get(emojiName)}
|
reactions={reactionsByName.get(emojiName)}
|
||||||
emojis={this.props.emojis}
|
emojis={this.props.emojis}
|
||||||
|
|||||||
@@ -592,10 +592,7 @@ export default class RhsComment extends React.Component {
|
|||||||
<PostMessageContainer post={post}/>
|
<PostMessageContainer post={post}/>
|
||||||
</div>
|
</div>
|
||||||
{fileAttachment}
|
{fileAttachment}
|
||||||
<ReactionListContainer
|
<ReactionListContainer post={post}/>
|
||||||
post={post}
|
|
||||||
currentUserId={this.props.currentUser.id}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -559,10 +559,7 @@ export default class RhsRootPost extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{fileAttachment}
|
{fileAttachment}
|
||||||
<ReactionListContainer
|
<ReactionListContainer post={post}/>
|
||||||
post={post}
|
|
||||||
currentUserId={this.props.currentUser.id}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user