2020-10-30 20:34:04 +00:00
|
|
|
// Copyright 2020 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2020-05-27 21:37:06 +00:00
|
|
|
import * as React from 'react';
|
|
|
|
import { take } from 'lodash';
|
|
|
|
import { Avatar, Props as AvatarProps } from '../Avatar';
|
|
|
|
import { ContactName } from './ContactName';
|
2021-01-26 01:01:19 +00:00
|
|
|
import { About } from './About';
|
2020-05-27 21:37:06 +00:00
|
|
|
import { Emojify } from './Emojify';
|
|
|
|
import { Intl } from '../Intl';
|
|
|
|
import { LocalizerType } from '../../types/Util';
|
|
|
|
|
|
|
|
export type Props = {
|
2021-01-26 01:01:19 +00:00
|
|
|
about?: string;
|
2020-05-27 21:37:06 +00:00
|
|
|
i18n: LocalizerType;
|
|
|
|
isMe?: boolean;
|
2020-08-05 01:13:19 +00:00
|
|
|
sharedGroupNames?: Array<string>;
|
2020-05-27 21:37:06 +00:00
|
|
|
membersCount?: number;
|
2020-07-24 01:35:32 +00:00
|
|
|
phoneNumber?: string;
|
2020-05-27 21:37:06 +00:00
|
|
|
onHeightChange?: () => unknown;
|
2020-08-07 00:50:54 +00:00
|
|
|
updateSharedGroups?: () => unknown;
|
2020-05-27 21:37:06 +00:00
|
|
|
} & Omit<AvatarProps, 'onClick' | 'size' | 'noteToSelf'>;
|
|
|
|
|
|
|
|
const renderMembershipRow = ({
|
|
|
|
i18n,
|
2021-04-01 16:27:17 +00:00
|
|
|
phoneNumber,
|
|
|
|
sharedGroupNames = [],
|
2020-05-27 21:37:06 +00:00
|
|
|
conversationType,
|
|
|
|
isMe,
|
2021-04-01 16:27:17 +00:00
|
|
|
}: Pick<
|
|
|
|
Props,
|
|
|
|
'i18n' | 'phoneNumber' | 'sharedGroupNames' | 'conversationType' | 'isMe'
|
|
|
|
>) => {
|
2020-05-27 21:37:06 +00:00
|
|
|
const className = 'module-conversation-hero__membership';
|
|
|
|
const nameClassName = `${className}__name`;
|
|
|
|
|
2021-04-01 16:27:17 +00:00
|
|
|
if (conversationType !== 'direct') {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-05-27 21:37:06 +00:00
|
|
|
if (isMe) {
|
|
|
|
return <div className={className}>{i18n('noteToSelfHero')}</div>;
|
|
|
|
}
|
|
|
|
|
2021-04-01 16:27:17 +00:00
|
|
|
if (sharedGroupNames.length > 0) {
|
2020-08-05 01:13:19 +00:00
|
|
|
const firstThreeGroups = take(sharedGroupNames, 3).map((group, i) => (
|
2020-09-14 19:51:27 +00:00
|
|
|
// We cannot guarantee uniqueness of group names
|
|
|
|
// eslint-disable-next-line react/no-array-index-key
|
2020-05-27 21:37:06 +00:00
|
|
|
<strong key={i} className={nameClassName}>
|
|
|
|
<Emojify text={group} />
|
|
|
|
</strong>
|
|
|
|
));
|
|
|
|
|
2020-08-05 01:13:19 +00:00
|
|
|
if (sharedGroupNames.length > 3) {
|
|
|
|
const remainingCount = sharedGroupNames.length - 3;
|
|
|
|
return (
|
|
|
|
<div className={className}>
|
|
|
|
<Intl
|
|
|
|
i18n={i18n}
|
|
|
|
id="ConversationHero--membership-extra"
|
|
|
|
components={{
|
|
|
|
group1: firstThreeGroups[0],
|
|
|
|
group2: firstThreeGroups[1],
|
|
|
|
group3: firstThreeGroups[2],
|
|
|
|
remainingCount: remainingCount.toString(),
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
);
|
2020-09-14 19:51:27 +00:00
|
|
|
}
|
|
|
|
if (firstThreeGroups.length === 3) {
|
2020-07-29 23:20:05 +00:00
|
|
|
return (
|
|
|
|
<div className={className}>
|
|
|
|
<Intl
|
|
|
|
i18n={i18n}
|
|
|
|
id="ConversationHero--membership-3"
|
|
|
|
components={{
|
|
|
|
group1: firstThreeGroups[0],
|
|
|
|
group2: firstThreeGroups[1],
|
|
|
|
group3: firstThreeGroups[2],
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
);
|
2020-09-14 19:51:27 +00:00
|
|
|
}
|
|
|
|
if (firstThreeGroups.length >= 2) {
|
2020-07-29 23:20:05 +00:00
|
|
|
return (
|
|
|
|
<div className={className}>
|
|
|
|
<Intl
|
|
|
|
i18n={i18n}
|
|
|
|
id="ConversationHero--membership-2"
|
|
|
|
components={{
|
|
|
|
group1: firstThreeGroups[0],
|
|
|
|
group2: firstThreeGroups[1],
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
);
|
2020-09-14 19:51:27 +00:00
|
|
|
}
|
|
|
|
if (firstThreeGroups.length >= 1) {
|
2020-07-29 23:20:05 +00:00
|
|
|
return (
|
|
|
|
<div className={className}>
|
|
|
|
<Intl
|
|
|
|
i18n={i18n}
|
|
|
|
id="ConversationHero--membership-1"
|
|
|
|
components={{
|
|
|
|
group: firstThreeGroups[0],
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2020-05-27 21:37:06 +00:00
|
|
|
}
|
|
|
|
|
2021-04-01 16:27:17 +00:00
|
|
|
if (!phoneNumber) {
|
|
|
|
return <div className={className}>{i18n('no-groups-in-common')}</div>;
|
|
|
|
}
|
|
|
|
|
2020-05-27 21:37:06 +00:00
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const ConversationHero = ({
|
|
|
|
i18n,
|
2021-01-26 01:01:19 +00:00
|
|
|
about,
|
2020-05-27 21:37:06 +00:00
|
|
|
avatarPath,
|
|
|
|
color,
|
|
|
|
conversationType,
|
|
|
|
isMe,
|
|
|
|
membersCount,
|
2020-08-05 01:13:19 +00:00
|
|
|
sharedGroupNames = [],
|
2020-05-27 21:37:06 +00:00
|
|
|
name,
|
|
|
|
phoneNumber,
|
|
|
|
profileName,
|
2020-07-24 01:35:32 +00:00
|
|
|
title,
|
2020-05-27 21:37:06 +00:00
|
|
|
onHeightChange,
|
2020-08-07 00:50:54 +00:00
|
|
|
updateSharedGroups,
|
2020-09-14 19:51:27 +00:00
|
|
|
}: Props): JSX.Element => {
|
2020-05-27 21:37:06 +00:00
|
|
|
const firstRenderRef = React.useRef(true);
|
|
|
|
|
2020-09-14 19:51:27 +00:00
|
|
|
// TODO: DESKTOP-686
|
|
|
|
/* eslint-disable react-hooks/exhaustive-deps */
|
2020-05-27 21:37:06 +00:00
|
|
|
React.useEffect(() => {
|
|
|
|
// If any of the depenencies for this hook change then the height of this
|
|
|
|
// component may have changed. The cleanup function notifies listeners of
|
|
|
|
// any potential height changes.
|
|
|
|
return () => {
|
2020-08-07 00:50:54 +00:00
|
|
|
// Kick off the expensive hydration of the current sharedGroupNames
|
|
|
|
if (updateSharedGroups) {
|
|
|
|
updateSharedGroups();
|
|
|
|
}
|
|
|
|
|
2020-05-27 21:37:06 +00:00
|
|
|
if (onHeightChange && !firstRenderRef.current) {
|
|
|
|
onHeightChange();
|
|
|
|
} else {
|
|
|
|
firstRenderRef.current = false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}, [
|
|
|
|
firstRenderRef,
|
|
|
|
onHeightChange,
|
|
|
|
// Avoid collisions in these dependencies by prefixing them
|
|
|
|
// These dependencies may be dynamic, and therefore may cause height changes
|
|
|
|
`mc-${membersCount}`,
|
|
|
|
`n-${name}`,
|
|
|
|
`pn-${profileName}`,
|
2020-08-07 00:50:54 +00:00
|
|
|
sharedGroupNames.map(g => `g-${g}`).join(' '),
|
2020-05-27 21:37:06 +00:00
|
|
|
]);
|
2020-09-14 19:51:27 +00:00
|
|
|
/* eslint-enable react-hooks/exhaustive-deps */
|
2020-05-27 21:37:06 +00:00
|
|
|
|
2020-07-24 01:35:32 +00:00
|
|
|
const phoneNumberOnly = Boolean(
|
|
|
|
!name && !profileName && conversationType === 'direct'
|
|
|
|
);
|
|
|
|
|
2020-09-14 19:51:27 +00:00
|
|
|
/* eslint-disable no-nested-ternary */
|
2020-05-27 21:37:06 +00:00
|
|
|
return (
|
|
|
|
<div className="module-conversation-hero">
|
|
|
|
<Avatar
|
|
|
|
i18n={i18n}
|
|
|
|
color={color}
|
|
|
|
noteToSelf={isMe}
|
|
|
|
avatarPath={avatarPath}
|
|
|
|
conversationType={conversationType}
|
|
|
|
name={name}
|
|
|
|
profileName={profileName}
|
2020-07-24 01:35:32 +00:00
|
|
|
title={title}
|
2020-05-27 21:37:06 +00:00
|
|
|
size={112}
|
|
|
|
className="module-conversation-hero__avatar"
|
|
|
|
/>
|
|
|
|
<h1 className="module-conversation-hero__profile-name">
|
|
|
|
{isMe ? (
|
|
|
|
i18n('noteToSelf')
|
|
|
|
) : (
|
|
|
|
<ContactName
|
2020-07-24 01:35:32 +00:00
|
|
|
title={title}
|
2020-07-29 23:20:05 +00:00
|
|
|
name={name}
|
2020-05-27 21:37:06 +00:00
|
|
|
profileName={profileName}
|
|
|
|
phoneNumber={phoneNumber}
|
2020-07-24 01:35:32 +00:00
|
|
|
i18n={i18n}
|
2020-05-27 21:37:06 +00:00
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</h1>
|
2021-01-28 00:18:50 +00:00
|
|
|
{about && !isMe && (
|
2021-01-26 01:01:19 +00:00
|
|
|
<div className="module-about__container">
|
|
|
|
<About text={about} />
|
|
|
|
</div>
|
|
|
|
)}
|
2020-05-27 21:37:06 +00:00
|
|
|
{!isMe ? (
|
|
|
|
<div className="module-conversation-hero__with">
|
|
|
|
{membersCount === 1
|
|
|
|
? i18n('ConversationHero--members-1')
|
|
|
|
: membersCount !== undefined
|
|
|
|
? i18n('ConversationHero--members', [`${membersCount}`])
|
2020-07-24 01:35:32 +00:00
|
|
|
: phoneNumberOnly
|
|
|
|
? null
|
2020-05-27 21:37:06 +00:00
|
|
|
: phoneNumber}
|
|
|
|
</div>
|
|
|
|
) : null}
|
2021-04-01 16:27:17 +00:00
|
|
|
{renderMembershipRow({
|
|
|
|
conversationType,
|
|
|
|
i18n,
|
|
|
|
isMe,
|
|
|
|
phoneNumber,
|
|
|
|
sharedGroupNames,
|
|
|
|
})}
|
2020-05-27 21:37:06 +00:00
|
|
|
</div>
|
|
|
|
);
|
2020-09-14 19:51:27 +00:00
|
|
|
/* eslint-enable no-nested-ternary */
|
2020-05-27 21:37:06 +00:00
|
|
|
};
|