diff --git a/ts/components/leftpane/LeftPaneMessageSection.tsx b/ts/components/leftpane/LeftPaneMessageSection.tsx index b87d5d022..71cd42f97 100644 --- a/ts/components/leftpane/LeftPaneMessageSection.tsx +++ b/ts/components/leftpane/LeftPaneMessageSection.tsx @@ -64,8 +64,8 @@ const ClosableOverlay = () => { }; const ConversationRow = ( - conversationIds: Array, - { index, key, style }: ListRowProps + { index, key, style }: ListRowProps, + conversationIds: Array ): JSX.Element | null => { // assume conversations that have been marked unapproved should be filtered out by selector. if (!conversationIds) { @@ -105,7 +105,7 @@ const ConversationList = () => { height={height} rowCount={conversationIds.length} rowHeight={64} - rowRenderer={props => ConversationRow(conversationIds, props)} + rowRenderer={props => ConversationRow(props, conversationIds)} width={width} autoHeight={false} conversationIds={conversationIds} diff --git a/ts/components/leftpane/overlay/OverlayClosedGroup.tsx b/ts/components/leftpane/overlay/OverlayClosedGroup.tsx index 1e16ce353..782dcf4d6 100644 --- a/ts/components/leftpane/overlay/OverlayClosedGroup.tsx +++ b/ts/components/leftpane/overlay/OverlayClosedGroup.tsx @@ -5,7 +5,7 @@ import useKey from 'react-use/lib/useKey'; import styled from 'styled-components'; import { isEmpty } from 'lodash'; -import { MemberListItem } from '../../MemberListItem'; +import { AutoSizer, List, ListRowProps } from 'react-virtualized'; import { SessionButton } from '../../basic/SessionButton'; import { SessionSpinner } from '../../loading'; @@ -20,6 +20,7 @@ import { getSearchTerm, isSearching, } from '../../../state/selectors/search'; +import { MemberListItem } from '../../MemberListItem'; import { SessionSearchInput } from '../../SessionSearchInput'; import { Flex } from '../../basic/Flex'; import { SpacerLG, SpacerMD } from '../../basic/Text'; @@ -40,6 +41,8 @@ const StyledNoResults = styled.div` const StyledGroupMemberListContainer = styled.div` padding: 0; width: 100%; + height: 100%; + overflow-x: hidden; overflow-y: auto; border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); @@ -55,21 +58,49 @@ const NoContacts = () => { ); }; +const MemberRow = ( + { index, key }: ListRowProps, + contactsToRender: Array, + selectedMemberIds: Array, + addToSelected: (memberId: string) => void, + removeFromSelected: (memberId: string) => void +): JSX.Element | null => { + // assume conversations that have been marked unapproved should be filtered out by selector. + if (!contactsToRender) { + throw new Error('MemberRow: Tried to render without contacts'); + } + + const memberPubkey = contactsToRender[index]; + if (!memberPubkey) { + throw new Error('MemberRow: contact selector returned element containing falsy value.'); + } + + return ( + m === memberPubkey)} + onSelect={addToSelected} + onUnselect={removeFromSelected} + /> + ); +}; + /** * Makes some validity check and return true if the group was indead created */ async function createClosedGroupWithErrorHandling( groupName: string, groupMemberIds: Array, - errorHandler: (error: string) => void + onError: (error: string) => void ): Promise { // Validate groupName and groupMembers length if (groupName.length === 0) { - errorHandler(window.i18n('invalidGroupNameTooShort')); + onError(window.i18n('invalidGroupNameTooShort')); return false; } if (groupName.length > VALIDATION.MAX_GROUP_NAME_LENGTH) { - errorHandler(window.i18n('invalidGroupNameTooLong')); + onError(window.i18n('invalidGroupNameTooLong')); return false; } @@ -77,11 +108,11 @@ async function createClosedGroupWithErrorHandling( // the same is valid with groups count < 1 if (groupMemberIds.length < 1) { - errorHandler(window.i18n('pickClosedGroupMember')); + onError(window.i18n('pickClosedGroupMember')); return false; } if (groupMemberIds.length >= VALIDATION.CLOSED_GROUP_SIZE_LIMIT) { - errorHandler(window.i18n('closedGroupMaxSize')); + onError(window.i18n('closedGroupMaxSize')); return false; } @@ -173,23 +204,32 @@ export const OverlayClosedGroup = () => { - + {noContactsForClosedGroup ? ( - ) : !isEmpty(searchTerm) && contactsToRender.length === 0 ? ( + ) : searchTerm && !contactsToRender.length ? ( {window.i18n('noSearchResults', [searchTerm])} ) : ( -
- {contactsToRender.map((memberPubkey: string) => ( - m === memberPubkey)} - key={memberPubkey} - onSelect={addToSelected} - onUnselect={removeFromSelected} + + {({ height, width }) => ( + + MemberRow( + props, + contactsToRender, + selectedMemberIds, + addToSelected, + removeFromSelected + ) + } /> - ))} -
+ )} + )}