[MM-54021][MM-58736] Remove limit on loading channel members on initial load, reload members on reconnect, separate loading of members from channels on initial load (#28310)
* [MM-54021][MM-58736] Remove limit on loading channel members on initial load, reload members on reconnect, separate loading of members from channels on initial load * PR feedback --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
2b7b4100d2
Коммит
ed4cab7aa2
@@ -31,6 +31,7 @@ import {
|
||||
getChannelStats,
|
||||
markMultipleChannelsAsRead,
|
||||
getChannelMemberCountsByGroup,
|
||||
fetchAllMyChannelMembers,
|
||||
} from 'mattermost-redux/actions/channels';
|
||||
import {getCloudSubscription} from 'mattermost-redux/actions/cloud';
|
||||
import {clearErrors, logError} from 'mattermost-redux/actions/errors';
|
||||
@@ -235,6 +236,7 @@ export function reconnect() {
|
||||
}
|
||||
|
||||
dispatch(loadChannelsForCurrentUser());
|
||||
dispatch(fetchAllMyChannelMembers());
|
||||
|
||||
if (mostRecentPost) {
|
||||
dispatch(syncPostsInChannel(currentChannelId, mostRecentPost.create_at));
|
||||
|
||||
@@ -62,6 +62,7 @@ jest.mock('mattermost-redux/actions/users', () => ({
|
||||
|
||||
jest.mock('mattermost-redux/actions/channels', () => ({
|
||||
getChannelStats: jest.fn(() => ({type: 'GET_CHANNEL_STATS'})),
|
||||
fetchAllMyChannelMembers: jest.fn(() => ({type: 'FETCH_ALL_MY_CHANNEL_MEMBERS'})),
|
||||
}));
|
||||
|
||||
jest.mock('actions/post_actions', () => ({
|
||||
|
||||
@@ -13,7 +13,7 @@ import type {UserProfile} from '@mattermost/types/users';
|
||||
import type {RelationOneToOne} from '@mattermost/types/utilities';
|
||||
|
||||
import {UserTypes} from 'mattermost-redux/action_types';
|
||||
import {fetchAllMyTeamsChannelsAndChannelMembersREST, searchAllChannels} from 'mattermost-redux/actions/channels';
|
||||
import {fetchAllMyTeamsChannels, searchAllChannels} from 'mattermost-redux/actions/channels';
|
||||
import {logError} from 'mattermost-redux/actions/errors';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
@@ -838,12 +838,12 @@ export default class SwitchChannelProvider extends Provider {
|
||||
if (!teamId) {
|
||||
return;
|
||||
}
|
||||
const channelsAsync = this.store.dispatch(fetchAllMyTeamsChannelsAndChannelMembersREST());
|
||||
const channelsAsync = this.store.dispatch(fetchAllMyTeamsChannels());
|
||||
let channels;
|
||||
|
||||
try {
|
||||
const {data} = await channelsAsync;
|
||||
channels = data.channels as Channel[];
|
||||
channels = data as Channel[];
|
||||
} catch (err) {
|
||||
this.store.dispatch(logError(err));
|
||||
return;
|
||||
|
||||
@@ -5,7 +5,7 @@ import {connect} from 'react-redux';
|
||||
import type {ConnectedProps} from 'react-redux';
|
||||
import type {RouteComponentProps} from 'react-router-dom';
|
||||
|
||||
import {fetchAllMyTeamsChannelsAndChannelMembersREST, fetchChannelsAndMembers, unsetActiveChannelOnServer} from 'mattermost-redux/actions/channels';
|
||||
import {fetchAllMyTeamsChannels, fetchAllMyChannelMembers, fetchChannelsAndMembers, unsetActiveChannelOnServer} from 'mattermost-redux/actions/channels';
|
||||
import {getCurrentChannelId} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getLicense, getConfig} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getCurrentTeamId, getMyTeams} from 'mattermost-redux/selectors/entities/teams';
|
||||
@@ -53,7 +53,8 @@ function mapStateToProps(state: GlobalState, ownProps: OwnProps) {
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchChannelsAndMembers,
|
||||
fetchAllMyTeamsChannelsAndChannelMembersREST,
|
||||
fetchAllMyTeamsChannels,
|
||||
fetchAllMyChannelMembers,
|
||||
markAsReadOnFocus,
|
||||
initializeTeam,
|
||||
joinTeam,
|
||||
|
||||
@@ -55,13 +55,14 @@ function TeamController(props: Props) {
|
||||
|
||||
useEffect(() => {
|
||||
InitialLoadingScreen.stop();
|
||||
async function fetchInitialChannels() {
|
||||
await props.fetchAllMyTeamsChannelsAndChannelMembersREST();
|
||||
async function fetchAllChannels() {
|
||||
await props.fetchAllMyTeamsChannels();
|
||||
|
||||
setInitialChannelsLoaded(true);
|
||||
}
|
||||
|
||||
fetchInitialChannels();
|
||||
props.fetchAllMyChannelMembers();
|
||||
fetchAllChannels();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -2088,4 +2088,27 @@ describe('Actions.Channels', () => {
|
||||
expect(channelMemberCounts['group-2'].channel_member_count).toEqual(999);
|
||||
expect(channelMemberCounts['group-2'].channel_member_timezones_count).toEqual(131);
|
||||
});
|
||||
|
||||
it('fetchAllMyChannelMembers', async () => {
|
||||
const store = configureStore({
|
||||
entities: {
|
||||
users: {
|
||||
currentUserId: 'some-user-id',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
nock(Client4.getBaseRoute()).get(
|
||||
'/users/some-user-id/channel_members?page=0&per_page=200').
|
||||
reply(200, [...Array(200).keys()].map((index) => ({channel_id: `channel-${index}`, user_id: 'some-user-id'})));
|
||||
nock(Client4.getBaseRoute()).get(
|
||||
'/users/some-user-id/channel_members?page=1&per_page=200').
|
||||
reply(200, [...Array(200).keys()].map((index) => ({channel_id: `channel-${index + 200}`, user_id: 'some-user-id'})));
|
||||
nock(Client4.getBaseRoute()).get(
|
||||
'/users/some-user-id/channel_members?page=2&per_page=200').
|
||||
reply(200, [...Array(100).keys()].map((index) => ({channel_id: `channel-${index + 400}`, user_id: 'some-user-id'})));
|
||||
|
||||
await store.dispatch(Actions.fetchAllMyChannelMembers());
|
||||
expect(Object.keys(store.getState().entities.channels.myMembers).length).toBe(500);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -464,32 +464,43 @@ export function fetchChannelsAndMembers(teamId: string): ActionFuncAsync<{channe
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchAllMyTeamsChannelsAndChannelMembersREST(): ActionFuncAsync {
|
||||
export function fetchAllMyChannelMembers(): ActionFuncAsync {
|
||||
return async (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const {currentUserId} = state.entities.users;
|
||||
let channels;
|
||||
|
||||
let channelsMembers: ChannelMembership[] = [];
|
||||
let allMembers = true;
|
||||
let hasMoreMembers = true;
|
||||
let page = 0;
|
||||
do {
|
||||
try {
|
||||
try {
|
||||
while (hasMoreMembers) {
|
||||
// Expected to disable since we don't have number of pages, so we can't use Promise.all
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await Client4.getAllChannelsMembers(currentUserId, page, 200).then(
|
||||
// eslint-disable-next-line no-loop-func
|
||||
(data) => {
|
||||
channelsMembers = [...channelsMembers, ...data];
|
||||
page++;
|
||||
if (data.length < 200) {
|
||||
allMembers = false;
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
const data = await Client4.getAllChannelsMembers(currentUserId, page, 200);
|
||||
channelsMembers = [...channelsMembers, ...data];
|
||||
if (data.length < 200) {
|
||||
hasMoreMembers = false;
|
||||
}
|
||||
page++;
|
||||
}
|
||||
} while (allMembers && page <= 2);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: ChannelTypes.RECEIVED_MY_CHANNEL_MEMBERS,
|
||||
data: channelsMembers,
|
||||
currentUserId,
|
||||
});
|
||||
return {data: channelsMembers};
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchAllMyTeamsChannels(): ActionFuncAsync {
|
||||
return async (dispatch, getState) => {
|
||||
let channels;
|
||||
try {
|
||||
channels = await Client4.getAllTeamsChannels();
|
||||
} catch (error) {
|
||||
@@ -498,18 +509,11 @@ export function fetchAllMyTeamsChannelsAndChannelMembersREST(): ActionFuncAsync
|
||||
return {error};
|
||||
}
|
||||
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: ChannelTypes.RECEIVED_ALL_CHANNELS,
|
||||
data: channels,
|
||||
},
|
||||
{
|
||||
type: ChannelTypes.RECEIVED_MY_CHANNEL_MEMBERS,
|
||||
data: channelsMembers,
|
||||
currentUserId,
|
||||
},
|
||||
]));
|
||||
return {data: {channels, channelsMembers}};
|
||||
dispatch({
|
||||
type: ChannelTypes.RECEIVED_ALL_CHANNELS,
|
||||
data: channels,
|
||||
});
|
||||
return {data: channels};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user