// Copyright 2018-2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; import { compact, flatten } from 'lodash'; import { ContactName } from './ContactName'; import { Intl } from '../Intl'; import { LocalizerType } from '../../types/Util'; import { missingCaseError } from '../../util/missingCaseError'; type Contact = { phoneNumber?: string; profileName?: string; name?: string; title: string; isMe?: boolean; }; export type ChangeType = 'add' | 'remove' | 'name' | 'avatar' | 'general'; type Change = { type: ChangeType; newName?: string; contacts?: Array; }; export type PropsData = { from: Contact; changes: Array; }; type PropsHousekeeping = { i18n: LocalizerType; }; export type Props = PropsData & PropsHousekeeping; export class GroupNotification extends React.Component { public renderChange( change: Change, from: Contact ): JSX.Element | string | null | undefined { const { contacts, type, newName } = change; const { i18n } = this.props; const otherPeople: Array = compact( (contacts || []).map(contact => { if (contact.isMe) { return null; } return ( ); }) ); const otherPeopleWithCommas: Array = compact( flatten( otherPeople.map((person, index) => [index > 0 ? ', ' : null, person]) ) ); const contactsIncludesMe = (contacts || []).length !== otherPeople.length; switch (type) { case 'name': return ( ); case 'avatar': return ; case 'add': if (!contacts || !contacts.length) { throw new Error('Group update is missing contacts'); } // eslint-disable-next-line no-case-declarations const otherPeopleNotifMsg = otherPeople.length === 1 ? 'joinedTheGroup' : 'multipleJoinedTheGroup'; return ( <> {otherPeople.length > 0 && ( )} {contactsIncludesMe && (
)} ); case 'remove': if (from && from.isMe) { return i18n('youLeftTheGroup'); } if (!contacts || !contacts.length) { throw new Error('Group update is missing contacts'); } // eslint-disable-next-line no-case-declarations const leftKey = contacts.length > 1 ? 'multipleLeftTheGroup' : 'leftTheGroup'; return ( ); case 'general': // eslint-disable-next-line consistent-return return; default: throw missingCaseError(type); } } public render(): JSX.Element { const { changes, i18n, from } = this.props; // Leave messages are always from the person leaving, so we omit the fromLabel if // the change is a 'leave.' const isLeftOnly = changes && changes.length === 1 && changes[0].type === 'remove'; const fromContact = ( ); const fromLabel = from.isMe ? ( ) : ( ); return (
{isLeftOnly ? null : ( <> {fromLabel}
)} {(changes || []).map((change, i) => ( // eslint-disable-next-line react/no-array-index-key
{this.renderChange(change, from)}
))}
); } }