Page MenuHomePhabricator

D3383.id10869.diff
No OneTemporary

D3383.id10869.diff

diff --git a/web/modals/threads/members/members-list.react.js b/web/modals/threads/members/members-list.react.js
new file mode 100644
--- /dev/null
+++ b/web/modals/threads/members/members-list.react.js
@@ -0,0 +1,76 @@
+// @flow
+
+import classNames from 'classnames';
+import _groupBy from 'lodash/fp/groupBy';
+import _toPairs from 'lodash/fp/toPairs';
+import * as React from 'react';
+
+import { stringForUser } from 'lib/shared/user-utils';
+import {
+ type ThreadInfo,
+ type RelativeMemberInfo,
+} from 'lib/types/thread-types';
+
+import ThreadMember from './member.react';
+import css from './members-modal.css';
+
+type Props = {
+ +threadInfo: ThreadInfo,
+ +threadMembers: $ReadOnlyArray<RelativeMemberInfo>,
+};
+
+function ThreadMembersList(props: Props): React.Node {
+ const { threadMembers, threadInfo } = props;
+ const [openMenu, setOpenMenu] = React.useState(null);
+ const hasMembers = threadMembers.length > 0;
+
+ const groupedByFirstLetterMembers = React.useMemo(
+ () => _groupBy(member => stringForUser(member)[0])(threadMembers),
+ [threadMembers],
+ );
+
+ const groupedMembersList = React.useMemo(
+ () =>
+ _toPairs(groupedByFirstLetterMembers)
+ .sort((a, b) => a[0].localeCompare(b[0]))
+ .map(([letter, users]) => {
+ const userList = users
+ .sort((a, b) => stringForUser(a).localeCompare(stringForUser(b)))
+ .map((user: RelativeMemberInfo) => (
+ <ThreadMember
+ key={user.id}
+ memberInfo={user}
+ threadInfo={threadInfo}
+ setOpenMenu={setOpenMenu}
+ isMenuOpen={openMenu === user.id}
+ />
+ ));
+ const letterHeader = (
+ <h5 className={css.memberletterHeader} key={letter}>
+ {letter.toUpperCase()}
+ </h5>
+ );
+ return (
+ <React.Fragment key={letter}>
+ {letterHeader}
+ {userList}
+ </React.Fragment>
+ );
+ }),
+ [groupedByFirstLetterMembers, openMenu, threadInfo],
+ );
+ let content = groupedMembersList;
+ if (!hasMembers) {
+ content = (
+ <div className={css.noUsers}>
+ No matching users were found in the thread!
+ </div>
+ );
+ }
+ const membersListClasses = classNames(css.membersList, {
+ [css.noScroll]: !!openMenu,
+ });
+ return <div className={membersListClasses}>{content}</div>;
+}
+
+export default ThreadMembersList;
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,13 @@
+div.membersList {
+ overflow: scroll;
+ padding: 8px 0;
+ color: var(--members-modal-member-text);
+}
+
+div.noScroll {
+ overflow: hidden;
+}
+
div.memberContainer {
display: flex;
flex-direction: row;
@@ -23,3 +33,14 @@
div.memberAction {
position: relative;
}
+
+h5.memberletterHeader {
+ margin: 16px;
+ color: var(--members-modal-member-text);
+ font-size: var(--s-font-14);
+}
+
+div.noUsers {
+ padding-top: 16px;
+ text-align: center;
+}
diff --git a/web/theme.css b/web/theme.css
--- a/web/theme.css
+++ b/web/theme.css
@@ -132,6 +132,8 @@
--tabs-header-background-border: var(--shades-black-80);
--tabs-header-background-color-hover: var(--shades-white-80);
--tabs-header-background-border-hover: var(--shades-black-70);
+ --members-modal-member-text: var(--shades-black-60);
+ --members-modal-member-text-hover: var(--shades-white-100);
--label-default-bg: var(--violet-dark-80);
--label-default-color: var(--shades-white-80);
}

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 17, 7:36 PM (22 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2531512
Default Alt Text
D3383.id10869.diff (3 KB)

Event Timeline