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:
Harrison Healey 2017-12-22 11:29:09 -05:00 committed by Jarred Witt
parent 593dd9f033
commit db3556325e
3 changed files with 76 additions and 17 deletions

View file

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

View file

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