RN-566 Re-rendered PostList footer when channel ID changes (#1309)
* RN-566 Re-rendered PostList footer when channel ID changes * Refactor ChannelIntro mapStateToProps into selectors
This commit is contained in:
parent
593dd9f033
commit
db3556325e
3 changed files with 76 additions and 17 deletions
|
|
@ -2,9 +2,11 @@
|
|||
// See License.txt for license information.
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
import {createSelector} from 'reselect';
|
||||
|
||||
import {General, RequestStatus} from 'mattermost-redux/constants';
|
||||
import {makeGetChannel} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getCurrentUser, makeGetProfilesInChannel} from 'mattermost-redux/selectors/entities/users';
|
||||
import {getCurrentUserId, getUser, makeGetProfilesInChannel} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
|
|
@ -14,31 +16,62 @@ function makeMapStateToProps() {
|
|||
const getChannel = makeGetChannel();
|
||||
const getProfilesInChannel = makeGetProfilesInChannel();
|
||||
|
||||
const getOtherUserIdForDm = createSelector(
|
||||
(state, channel) => channel,
|
||||
getCurrentUserId,
|
||||
(channel, currentUserId) => {
|
||||
if (!channel) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return channel.name.split('__').find((m) => m !== currentUserId);
|
||||
}
|
||||
);
|
||||
|
||||
const getChannelMembers = createSelector(
|
||||
getCurrentUserId,
|
||||
(state, channel) => getProfilesInChannel(state, channel.id),
|
||||
(currentUserId, profilesInChannel) => {
|
||||
const currentChannelMembers = profilesInChannel || [];
|
||||
return currentChannelMembers.filter((m) => m.id !== currentUserId);
|
||||
}
|
||||
);
|
||||
|
||||
const getChannelMembersForDm = createSelector(
|
||||
(state, channel) => getUser(state, getOtherUserIdForDm(state, channel)),
|
||||
(otherUser) => {
|
||||
if (!otherUser) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [otherUser];
|
||||
}
|
||||
);
|
||||
|
||||
return function mapStateToProps(state, ownProps) {
|
||||
const currentChannel = getChannel(state, {id: ownProps.channelId}) || {};
|
||||
const currentUser = getCurrentUser(state) || {};
|
||||
const {status: getPostsRequestStatus} = state.requests.posts.getPosts;
|
||||
|
||||
let currentChannelMembers = [];
|
||||
if (currentChannel.type === General.DM_CHANNEL) {
|
||||
const otherChannelMember = currentChannel.name.split('__').find((m) => m !== currentUser.id);
|
||||
const otherProfile = state.entities.users.profiles[otherChannelMember];
|
||||
if (otherProfile) {
|
||||
currentChannelMembers.push(otherProfile);
|
||||
}
|
||||
} else {
|
||||
currentChannelMembers = getProfilesInChannel(state, ownProps.channelId) || [];
|
||||
currentChannelMembers = currentChannelMembers.filter((m) => m.id !== currentUser.id);
|
||||
}
|
||||
let currentChannelMembers;
|
||||
let creator;
|
||||
let postsInChannel;
|
||||
|
||||
const creator = currentChannel.creator_id === currentUser.id ? currentUser : state.entities.users.profiles[currentChannel.creator_id];
|
||||
const postsInChannel = state.entities.posts.postsInChannel[ownProps.channelId] || [];
|
||||
if (currentChannel) {
|
||||
if (currentChannel.type === General.DM_CHANNEL) {
|
||||
currentChannelMembers = getChannelMembersForDm(state, currentChannel);
|
||||
} else {
|
||||
currentChannelMembers = getChannelMembers(state, currentChannel);
|
||||
}
|
||||
|
||||
creator = getUser(state, currentChannel.creator_id);
|
||||
postsInChannel = state.entities.posts.postsInChannel[currentChannel.Id];
|
||||
}
|
||||
|
||||
return {
|
||||
creator,
|
||||
currentChannel,
|
||||
currentChannelMembers,
|
||||
isLoadingPosts: !postsInChannel.length && getPostsRequestStatus === RequestStatus.STARTED,
|
||||
isLoadingPosts: (!postsInChannel || postsInChannel.length === 0) && getPostsRequestStatus === RequestStatus.STARTED,
|
||||
theme: getTheme(state)
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import ChannelIntro from 'app/components/channel_intro';
|
|||
import Post from 'app/components/post';
|
||||
import {DATE_LINE, START_OF_NEW_MESSAGES} from 'app/selectors/post_list';
|
||||
import mattermostManaged from 'app/mattermost_managed';
|
||||
import {makeExtraData} from 'app/utils/list_view';
|
||||
|
||||
import DateHeader from './date_header';
|
||||
import LoadMorePosts from './load_more_posts';
|
||||
|
|
@ -49,6 +50,9 @@ export default class PostList extends PureComponent {
|
|||
super(props);
|
||||
|
||||
this.newMessagesIndex = -1;
|
||||
|
||||
this.makeExtraData = makeExtraData();
|
||||
|
||||
this.state = {
|
||||
managedConfig: {}
|
||||
};
|
||||
|
|
@ -233,7 +237,7 @@ export default class PostList extends PureComponent {
|
|||
<FlatList
|
||||
ref='list'
|
||||
data={postIds}
|
||||
extraData={highlightPostId}
|
||||
extraData={this.makeExtraData(channelId, highlightPostId)}
|
||||
initialNumToRender={15}
|
||||
inverted={true}
|
||||
keyExtractor={this.keyExtractor}
|
||||
|
|
|
|||
22
app/utils/list_view.js
Normal file
22
app/utils/list_view.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import shallowEqual from 'shallow-equals';
|
||||
|
||||
// Returns a function that will construct a memoized array of its arguments for use as
|
||||
// the extraData prop for a ListView so that its rows can be re-rendered even if the items
|
||||
// themselves don't change.
|
||||
export function makeExtraData() {
|
||||
let lastArgs = [];
|
||||
|
||||
// Returns an array containing the arguments provided to this function.
|
||||
// If this function is called twice in a row with the same arguments,
|
||||
// it will return the exact same array.
|
||||
return (...args) => {
|
||||
if (!shallowEqual(lastArgs, args)) {
|
||||
lastArgs = args;
|
||||
}
|
||||
|
||||
return lastArgs;
|
||||
};
|
||||
}
|
||||
Loading…
Reference in a new issue