[FIX] Pagination when search by members and fix the duplicated members in a Room's member's list (#4446)

* [FIX] Duplicate members in a Room's member's list

* fix search and pagination

* fix the pagination for server lower than 3.16

Co-authored-by: Gleidson Daniel Silva <gleidson10daniel@hotmail.com>
This commit is contained in:
Reinaldo Neto 2022-08-19 14:27:04 -03:00 committed by GitHub
parent ded2f3792a
commit fa72d4cc76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 28 deletions

View File

@ -866,7 +866,7 @@ export const getRoomMembers = async ({
allUsers: boolean; allUsers: boolean;
type: 'all' | 'online'; type: 'all' | 'online';
roomType: SubscriptionType; roomType: SubscriptionType;
filter: boolean; filter: string;
skip: number; skip: number;
limit: number; limit: number;
}) => { }) => {
@ -888,9 +888,7 @@ export const getRoomMembers = async ({
} }
// RC 0.42.0 // RC 0.42.0
const result = await sdk.methodCallWrapper('getUsersOfRoom', rid, allUsers, { skip, limit }); const result = await sdk.methodCallWrapper('getUsersOfRoom', rid, allUsers, { skip, limit });
if (result.success) { return result?.records;
return result?.records;
}
}; };
export const e2eFetchMyKeys = async () => { export const e2eFetchMyKeys = async () => {

View File

@ -17,7 +17,6 @@ import { IApplicationState, IBaseScreen, IUser, SubscriptionType, TSubscriptionM
import I18n from '../../i18n'; import I18n from '../../i18n';
import database from '../../lib/database'; import database from '../../lib/database';
import { CustomIcon } from '../../containers/CustomIcon'; import { CustomIcon } from '../../containers/CustomIcon';
import protectedFunction from '../../lib/methods/helpers/protectedFunction';
import UserItem from '../../containers/UserItem'; import UserItem from '../../containers/UserItem';
import { getUserSelector } from '../../selectors/login'; import { getUserSelector } from '../../selectors/login';
import { ModalStackParamList } from '../../stacks/MasterDetailStack/types'; import { ModalStackParamList } from '../../stacks/MasterDetailStack/types';
@ -29,7 +28,7 @@ import log from '../../lib/methods/helpers/log';
import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps'; import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps';
import { TSupportedPermissions } from '../../reducers/permissions'; import { TSupportedPermissions } from '../../reducers/permissions';
import { RoomTypes } from '../../lib/methods'; import { RoomTypes } from '../../lib/methods';
import { getRoomTitle, hasPermission, isGroupChat } from '../../lib/methods/helpers'; import { compareServerVersion, debounce, getRoomTitle, hasPermission, isGroupChat } from '../../lib/methods/helpers';
import styles from './styles'; import styles from './styles';
import { Services } from '../../lib/services'; import { Services } from '../../lib/services';
@ -57,17 +56,19 @@ interface IRoomMembersViewProps extends IBaseScreen<ModalStackParamList, 'RoomMe
editTeamMemberPermission: string[]; editTeamMemberPermission: string[];
viewAllTeamChannelsPermission: string[]; viewAllTeamChannelsPermission: string[];
viewAllTeamsPermission: string[]; viewAllTeamsPermission: string[];
serverVersion: string;
} }
interface IRoomMembersViewState { interface IRoomMembersViewState {
isLoading: boolean; isLoading: boolean;
allUsers: boolean; allUsers: boolean;
filtering: boolean; filtering: string;
rid: string; rid: string;
members: TUserModel[]; members: TUserModel[];
membersFiltered: TUserModel[]; membersFiltered: TUserModel[];
room: TSubscriptionModel; room: TSubscriptionModel;
end: boolean; end: boolean;
page: number;
} }
class RoomMembersView extends React.Component<IRoomMembersViewProps, IRoomMembersViewState> { class RoomMembersView extends React.Component<IRoomMembersViewProps, IRoomMembersViewState> {
@ -86,12 +87,13 @@ class RoomMembersView extends React.Component<IRoomMembersViewProps, IRoomMember
this.state = { this.state = {
isLoading: false, isLoading: false,
allUsers: false, allUsers: false,
filtering: false, filtering: '',
rid, rid,
members: [], members: [],
membersFiltered: [], membersFiltered: [],
room: room || ({} as TSubscriptionModel), room: room || ({} as TSubscriptionModel),
end: false end: false,
page: 0
}; };
if (room && room.observe) { if (room && room.observe) {
this.roomObservable = room.observe(); this.roomObservable = room.observe();
@ -179,18 +181,29 @@ class RoomMembersView extends React.Component<IRoomMembersViewProps, IRoomMember
}); });
}; };
onSearchChangeText = protectedFunction((text: string) => { get isServerVersionLowerThan3_16() {
const { members } = this.state; const { serverVersion } = this.props;
let membersFiltered: TUserModel[] = []; return compareServerVersion(serverVersion, 'lowerThan', '3.16.0');
text = text.trim(); }
if (members && members.length > 0 && text) { onSearchChangeText = debounce((text: string) => {
membersFiltered = members.filter( const { members } = this.state;
m => m.username.toLowerCase().match(text.toLowerCase()) || m.name?.toLowerCase().match(text.toLowerCase()) text = text.trim();
); if (this.isServerVersionLowerThan3_16) {
let membersFiltered: TUserModel[] = [];
if (members && members.length > 0 && text) {
membersFiltered = members.filter(
m => m.username.toLowerCase().match(text.toLowerCase()) || m.name?.toLowerCase().match(text.toLowerCase())
);
}
return this.setState({ filtering: text, membersFiltered });
} }
this.setState({ filtering: !!text, membersFiltered });
}); this.setState({ filtering: text, page: 0, members: [], end: false }, () => {
this.fetchMembers();
});
}, 500);
navToDirectMessage = async (item: IUser) => { navToDirectMessage = async (item: IUser) => {
try { try {
@ -265,7 +278,9 @@ class RoomMembersView extends React.Component<IRoomMembersViewProps, IRoomMember
const message = I18n.t('User_has_been_removed_from_s', { s: getRoomTitle(room) }); const message = I18n.t('User_has_been_removed_from_s', { s: getRoomTitle(room) });
EventEmitter.emit(LISTENER, { message }); EventEmitter.emit(LISTENER, { message });
const newMembers = members.filter(member => member._id !== userId); const newMembers = members.filter(member => member._id !== userId);
const newMembersFiltered = membersFiltered.filter(member => member._id !== userId); const newMembersFiltered = this.isServerVersionLowerThan3_16
? membersFiltered.filter(member => member._id !== userId)
: [];
this.setState({ this.setState({
members: newMembers, members: newMembers,
membersFiltered: newMembersFiltered membersFiltered: newMembersFiltered
@ -423,7 +438,7 @@ class RoomMembersView extends React.Component<IRoomMembersViewProps, IRoomMember
toggleStatus = () => { toggleStatus = () => {
try { try {
const { allUsers } = this.state; const { allUsers } = this.state;
this.setState({ members: [], allUsers: !allUsers, end: false }, () => { this.setState({ members: [], allUsers: !allUsers, end: false, page: 0 }, () => {
this.fetchMembers(); this.fetchMembers();
}); });
} catch (e) { } catch (e) {
@ -445,8 +460,9 @@ class RoomMembersView extends React.Component<IRoomMembersViewProps, IRoomMember
}; };
fetchMembers = async () => { fetchMembers = async () => {
const { rid, members, isLoading, allUsers, end, room, filtering } = this.state; const { rid, members, isLoading, allUsers, end, room, filtering, page } = this.state;
const { t } = room; const { t } = room;
if (isLoading || end) { if (isLoading || end) {
return; return;
} }
@ -458,14 +474,17 @@ class RoomMembersView extends React.Component<IRoomMembersViewProps, IRoomMember
roomType: t, roomType: t,
type: allUsers ? 'all' : 'online', type: allUsers ? 'all' : 'online',
filter: filtering, filter: filtering,
skip: members.length, skip: PAGE_SIZE * page,
limit: PAGE_SIZE, limit: PAGE_SIZE,
allUsers allUsers
}); });
const end = membersResult?.length < PAGE_SIZE;
const membersResultFiltered = membersResult?.filter((member: TUserModel) => !members.some(m => m._id === member._id));
this.setState({ this.setState({
members: members.concat(membersResult || []), members: members.concat(membersResultFiltered || []),
isLoading: false, isLoading: false,
end: membersResult?.length < PAGE_SIZE end,
page: page + 1
}); });
this.setHeader(); this.setHeader();
} catch (e) { } catch (e) {
@ -599,7 +618,7 @@ class RoomMembersView extends React.Component<IRoomMembersViewProps, IRoomMember
EventEmitter.emit(LISTENER, { message }); EventEmitter.emit(LISTENER, { message });
this.setState({ this.setState({
members: members.filter(member => member._id !== userId), members: members.filter(member => member._id !== userId),
membersFiltered: membersFiltered.filter(member => member._id !== userId) membersFiltered: this.isServerVersionLowerThan3_16 ? membersFiltered.filter(member => member._id !== userId) : []
}); });
} catch (e) { } catch (e) {
log(e); log(e);
@ -629,7 +648,7 @@ class RoomMembersView extends React.Component<IRoomMembersViewProps, IRoomMember
<SafeAreaView testID='room-members-view'> <SafeAreaView testID='room-members-view'>
<StatusBar /> <StatusBar />
<FlatList <FlatList
data={filtering ? membersFiltered : members} data={!!filtering && this.isServerVersionLowerThan3_16 ? membersFiltered : members}
renderItem={this.renderItem} renderItem={this.renderItem}
style={[styles.list, { backgroundColor: themes[theme].backgroundColor }]} style={[styles.list, { backgroundColor: themes[theme].backgroundColor }]}
keyExtractor={item => item._id} keyExtractor={item => item._id}
@ -664,7 +683,8 @@ const mapStateToProps = (state: IApplicationState) => ({
removeUserPermission: state.permissions['remove-user'], removeUserPermission: state.permissions['remove-user'],
editTeamMemberPermission: state.permissions['edit-team-member'], editTeamMemberPermission: state.permissions['edit-team-member'],
viewAllTeamChannelsPermission: state.permissions['view-all-team-channels'], viewAllTeamChannelsPermission: state.permissions['view-all-team-channels'],
viewAllTeamsPermission: state.permissions['view-all-teams'] viewAllTeamsPermission: state.permissions['view-all-teams'],
serverVersion: state.server.version
}); });
export default connect(mapStateToProps)(withTheme(withActionSheet(RoomMembersView))); export default connect(mapStateToProps)(withTheme(withActionSheet(RoomMembersView)));