// Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; import type { LocalizerType, ThemeType } from '../../../types/Util'; import { getOwn } from '../../../util/getOwn'; import type { BadgeType } from '../../../badges/types'; import { Avatar } from '../../Avatar'; import { Emojify } from '../Emojify'; import { ConversationDetailsIcon, IconType } from './ConversationDetailsIcon'; import type { ConversationType } from '../../../state/ducks/conversations'; import { PanelRow } from './PanelRow'; import { PanelSection } from './PanelSection'; export type GroupV2Membership = { isAdmin: boolean; member: ConversationType; }; export type Props = { canAddNewMembers: boolean; conversationId: string; i18n: LocalizerType; maxShownMemberCount?: number; memberships: Array; preferredBadgeByConversation: Record; showContactModal: (contactId: string, conversationId: string) => void; startAddingNewMembers?: () => void; theme: ThemeType; }; const collator = new Intl.Collator(undefined, { sensitivity: 'base' }); function sortConversationTitles( left: GroupV2Membership, right: GroupV2Membership ) { const leftTitle = left.member.title; const rightTitle = right.member.title; return collator.compare(leftTitle, rightTitle); } function sortMemberships( memberships: ReadonlyArray ): Array { let you: undefined | GroupV2Membership; const admins: Array = []; const nonAdmins: Array = []; memberships.forEach(membershipInfo => { const { isAdmin, member } = membershipInfo; if (member.isMe) { you = membershipInfo; } else if (isAdmin) { admins.push(membershipInfo); } else { nonAdmins.push(membershipInfo); } }); admins.sort(sortConversationTitles); nonAdmins.sort(sortConversationTitles); const sortedMemberships = []; if (you) { sortedMemberships.push(you); } sortedMemberships.push(...admins); sortedMemberships.push(...nonAdmins); return sortedMemberships; } export const ConversationDetailsMembershipList: React.ComponentType = ({ canAddNewMembers, conversationId, i18n, maxShownMemberCount = 5, memberships, preferredBadgeByConversation, showContactModal, startAddingNewMembers, theme, }) => { const [showAllMembers, setShowAllMembers] = React.useState(false); const sortedMemberships = sortMemberships(memberships); const shouldHideRestMembers = sortedMemberships.length - maxShownMemberCount > 1; const membersToShow = shouldHideRestMembers && !showAllMembers ? maxShownMemberCount : sortedMemberships.length; return ( {canAddNewMembers && ( } label={i18n('ConversationDetailsMembershipList--add-members')} onClick={() => startAddingNewMembers?.()} /> )} {sortedMemberships.slice(0, membersToShow).map(({ isAdmin, member }) => ( showContactModal(member.id, conversationId)} icon={ } label={} right={isAdmin ? i18n('GroupV2--admin') : ''} /> ))} {showAllMembers === false && shouldHideRestMembers && ( } onClick={() => setShowAllMembers(true)} label={i18n('ConversationDetailsMembershipList--show-all')} /> )} ); };