diff --git a/web/modals/threads/members/members-modal.css b/web/modals/threads/members/members-modal.css --- a/web/modals/threads/members/members-modal.css +++ b/web/modals/threads/members/members-modal.css @@ -1,3 +1,11 @@ +div.membersContainer { + overflow: inherit; + display: flex; + flex-direction: column; + overflow: hidden; + margin: 16px; +} + div.membersList { overflow: scroll; padding: 8px 0; diff --git a/web/modals/threads/members/members-modal.react.js b/web/modals/threads/members/members-modal.react.js new file mode 100644 --- /dev/null +++ b/web/modals/threads/members/members-modal.react.js @@ -0,0 +1,90 @@ +// @flow + +import * as React from 'react'; + +import { threadInfoSelector } from 'lib/selectors/thread-selectors'; +import { userStoreSearchIndex } from 'lib/selectors/user-selectors'; +import { memberHasAdminPowers, memberIsAdmin } from 'lib/shared/thread-utils'; +import { type RelativeMemberInfo } from 'lib/types/thread-types'; + +import Search from '../../../components/search.react'; +import Tabs from '../../../components/tabs.react'; +import { useSelector } from '../../../redux/redux-utils'; +import Modal from '../../modal.react'; +import ThreadMembersList from './members-list.react'; +import css from './members-modal.css'; + +type Props = { + +threadID: string, + +onClose: () => void, +}; +function ThreadMembersModal(props: Props): React.Node { + const { threadID, onClose } = props; + + const [tab, setTab] = React.useState<'All Members' | 'Admins'>('All Members'); + const [searchText, setSearchText] = React.useState(''); + + const threadInfo = useSelector(state => threadInfoSelector(state)[threadID]); + const { members: threadMembersNotFiltered } = threadInfo; + + const userSearchIndex = useSelector(userStoreSearchIndex); + const userIDs = React.useMemo( + () => userSearchIndex.getSearchResults(searchText), + [searchText, userSearchIndex], + ); + + const allMembers = React.useMemo( + () => + threadMembersNotFiltered.filter((member: RelativeMemberInfo) => + searchText.length > 0 ? userIDs.includes(member.id) : true, + ), + [searchText.length, threadMembersNotFiltered, userIDs], + ); + const adminMembers = React.useMemo( + () => + allMembers.filter( + (member: RelativeMemberInfo) => + memberIsAdmin(member, threadInfo) || memberHasAdminPowers(member), + ), + [allMembers, threadInfo], + ); + + const allUsersTab = React.useMemo( + () => ( + + + + ), + [allMembers, threadInfo], + ); + + const allAdminsTab = React.useMemo( + () => ( + + + + ), + [adminMembers, threadInfo], + ); + + return ( + + + + + {allUsersTab} + {allAdminsTab} + + + + ); +} + +export default ThreadMembersModal;