diff --git a/web/settings/relationship/user-list.css b/web/settings/relationship/user-list.css index 27646f197..3ebd61e82 100644 --- a/web/settings/relationship/user-list.css +++ b/web/settings/relationship/user-list.css @@ -1,31 +1,37 @@ .panelContainer { flex: 1; } .container { display: flex; flex-direction: column; height: 100%; padding: 8px; } .searchContainer { padding: 8px; } .userListContainer { overflow: auto; flex-grow: 1; flex-basis: 120px; } .noScroll { overflow: hidden; } .searchModalContent { display: flex; flex-direction: column; row-gap: 8px; height: 625px; } + +.emptyList { + text-align: center; + margin-top: 8px; + color: var(--text-background-tertiary-default); +} diff --git a/web/settings/relationship/user-list.react.js b/web/settings/relationship/user-list.react.js index 130a3377b..6362ac617 100644 --- a/web/settings/relationship/user-list.react.js +++ b/web/settings/relationship/user-list.react.js @@ -1,80 +1,93 @@ // @flow import classNames from 'classnames'; import * as React from 'react'; import { useENSNames } from 'lib/hooks/ens-cache.js'; import { useUserSearchIndex } from 'lib/selectors/nav-selectors.js'; import type { AccountUserInfo, UserInfo } from 'lib/types/user-types.js'; import { values } from 'lib/utils/objects.js'; import css from './user-list.css'; import { useSelector } from '../../redux/redux-utils.js'; export type UserRowProps = { +userInfo: AccountUserInfo, +onMenuVisibilityChange?: (visible: boolean) => void, }; type UserListProps = { +userRowComponent: React.ComponentType, +filterUser: (userInfo: UserInfo) => boolean, +usersComparator: (user1: AccountUserInfo, user2: AccountUserInfo) => number, +searchText: string, }; export function UserList(props: UserListProps): React.Node { const { userRowComponent, filterUser, usersComparator, searchText } = props; const userInfos = useSelector(state => state.userStore.userInfos); const userInfosArray = React.useMemo( () => values(userInfos).filter(filterUser), [userInfos, filterUser], ); const userStoreSearchIndex = useUserSearchIndex(userInfosArray); const [isMenuVisible, setIsMenuVisible] = React.useState(false); const onMenuVisibilityChange = React.useCallback( (visible: boolean) => setIsMenuVisible(visible), [], ); const searchResult = React.useMemo( () => userStoreSearchIndex.getSearchResults(searchText), [searchText, userStoreSearchIndex], ); const users = React.useMemo(() => { const userIDs = searchText ? searchResult : userInfosArray.map(u => u.id); const matchedUserInfos = []; for (const id of userIDs) { const { username, relationshipStatus } = userInfos[id]; if (!username) { continue; } matchedUserInfos.push({ id, username, relationshipStatus, }); } return matchedUserInfos.sort(usersComparator); }, [userInfosArray, searchResult, searchText, userInfos, usersComparator]); const usersWithENSNames = useENSNames(users); const userRows = React.useMemo(() => { const UserRow = userRowComponent; return usersWithENSNames.map(user => ( )); - }, [userRowComponent, usersWithENSNames, onMenuVisibilityChange]); + }, [usersWithENSNames, userRowComponent, onMenuVisibilityChange]); + + const noResultsMessage = React.useMemo(() => { + if (searchText.length === 0 || usersWithENSNames.length > 0) { + return null; + } + + return
No results
; + }, [searchText.length, usersWithENSNames.length]); const containerClasses = classNames(css.userListContainer, { [css.noScroll]: isMenuVisible, }); - return
{userRows}
; + return ( +
+ {userRows} + {noResultsMessage} +
+ ); }