Skip to content

Commit 2457fb4

Browse files
committed
fix: added search logic to manage/group members
1 parent ba3914e commit 2457fb4

File tree

3 files changed

+57
-26
lines changed

3 files changed

+57
-26
lines changed

ts/components/dialog/UpdateGroupMembersDialog.tsx

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ import { useSelectedIsGroupV2 } from '../../state/selectors/selectedConversation
3232
import { SessionSpinner } from '../loading';
3333
import { SessionToggle } from '../basic/SessionToggle';
3434
import { localize } from '../../localization/localeTools';
35+
import { SessionSearchInput } from '../SessionSearchInput';
36+
import { NoGroupMembers } from '../search/NoResults';
37+
import { useContactsToInviteTo } from '../../hooks/useContactsToInviteToGroup';
38+
import { searchActions } from '../../state/ducks/search';
3539

3640
type Props = {
3741
conversationId: string;
@@ -41,10 +45,35 @@ const StyledMemberList = styled.div`
4145
max-height: 240px;
4246
`;
4347

44-
/**
45-
* Admins are always put first in the list of group members.
46-
* Also, admins have a little crown on their avatar.
47-
*/
48+
function useSortedListOfMembers(convoId: string) {
49+
const groupMembersLegacy = useSortedGroupMembers(convoId);
50+
const groupMembers03Group = useStateOf03GroupMembers(convoId);
51+
const isV2Group = useSelectedIsGroupV2();
52+
const groupAdmins = useGroupAdmins(convoId);
53+
54+
const sortedMembersNon03 = useMemo(
55+
() => [...groupMembersLegacy].sort(m => (groupAdmins?.includes(m) ? -1 : 0)),
56+
[groupMembersLegacy, groupAdmins]
57+
);
58+
const sortedMembers = isV2Group ? groupMembers03Group.map(m => m.pubkeyHex) : sortedMembersNon03;
59+
60+
return sortedMembers;
61+
}
62+
63+
const useFilteredSortedListOfMembers = (convoId: string) => {
64+
const sortedMembers = useSortedListOfMembers(convoId);
65+
const { contactsToInvite: globalSearchResults, searchTerm } =
66+
useContactsToInviteTo('manage-group-members');
67+
68+
return useMemo(
69+
() =>
70+
!searchTerm || globalSearchResults === undefined
71+
? sortedMembers
72+
: sortedMembers.filter(m => globalSearchResults.includes(m)),
73+
[sortedMembers, globalSearchResults, searchTerm]
74+
);
75+
};
76+
4877
const MemberList = (props: {
4978
convoId: string;
5079
selectedMembers: Array<string>;
@@ -54,17 +83,8 @@ const MemberList = (props: {
5483
const { onSelect, convoId, onUnselect, selectedMembers } = props;
5584
const weAreAdmin = useWeAreAdmin(convoId);
5685
const isV2Group = useSelectedIsGroupV2();
57-
5886
const groupAdmins = useGroupAdmins(convoId);
59-
const groupMembersLegacy = useSortedGroupMembers(convoId);
60-
const groupMembers03Group = useStateOf03GroupMembers(convoId);
61-
62-
const sortedMembersNon03 = useMemo(
63-
() => [...groupMembersLegacy].sort(m => (groupAdmins?.includes(m) ? -1 : 0)),
64-
[groupMembersLegacy, groupAdmins]
65-
);
66-
67-
const sortedMembers = isV2Group ? groupMembers03Group.map(m => m.pubkeyHex) : sortedMembersNon03;
87+
const sortedMembers = useFilteredSortedListOfMembers(convoId);
6888

6989
return (
7090
<>
@@ -114,6 +134,7 @@ export const UpdateGroupMembersDialog = (props: Props) => {
114134

115135
const closeDialog = () => {
116136
dispatch(updateGroupMembersModal(null));
137+
dispatch(searchActions.clearSearch());
117138
};
118139

119140
const onClickOK = async () => {
@@ -165,8 +186,6 @@ export const UpdateGroupMembersDialog = (props: Props) => {
165186
removeFrom(member);
166187
};
167188

168-
const showNoMembersMessage = existingMembers.length === 0;
169-
170189
return (
171190
<SessionWrapperModal
172191
title={
@@ -194,15 +213,19 @@ export const UpdateGroupMembersDialog = (props: Props) => {
194213
</span>
195214
</>
196215
) : null}
216+
<SessionSearchInput searchType="manage-group-members" />
197217
<StyledMemberList className="contact-selection-list">
198-
<MemberList
199-
convoId={conversationId}
200-
onSelect={onSelect}
201-
onUnselect={onUnselect}
202-
selectedMembers={membersToRemove}
203-
/>
218+
{!existingMembers.length ? (
219+
<NoGroupMembers />
220+
) : (
221+
<MemberList
222+
convoId={conversationId}
223+
onSelect={onSelect}
224+
onUnselect={onUnselect}
225+
selectedMembers={membersToRemove}
226+
/>
227+
)}
204228
</StyledMemberList>
205-
{showNoMembersMessage && <p>{window.i18n('groupMembersNone')}</p>}
206229

207230
<SpacerLG />
208231
<SessionSpinner loading={isProcessingUIChange} />

ts/components/search/NoResults.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,18 @@ const StyledMemberListNoContacts = styled.div`
2323
padding: 20px;
2424
`;
2525

26-
export function NoContacts() {
26+
function NoneAtStart({ token }: { token: 'contactNone' | 'groupMembersNone' }) {
2727
return (
2828
<StyledMemberListNoContacts>
29-
<Localizer token="contactNone" />
29+
<Localizer token={token} />
3030
</StyledMemberListNoContacts>
3131
);
3232
}
33+
34+
export function NoContacts() {
35+
return <NoneAtStart token="contactNone" />;
36+
}
37+
38+
export function NoGroupMembers() {
39+
return <NoneAtStart token="groupMembersNone" />;
40+
}

ts/state/ducks/search.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ReduxConversationType } from './conversations';
1010
import { localize } from '../../localization/localeTools';
1111
import { BlockedNumberController } from '../../util';
1212

13-
export type SearchType = 'global' | 'create-group' | 'invite-contact-to';
13+
export type SearchType = 'global' | 'create-group' | 'invite-contact-to' | 'manage-group-members';
1414

1515
export type SearchStateType = {
1616
/**

0 commit comments

Comments
 (0)