Multiple person typing indicators in groups
This commit is contained in:
parent
17ea2b58de
commit
e4238de4db
15 changed files with 342 additions and 115 deletions
|
@ -12,39 +12,47 @@ import type { LocalizerType, ThemeType } from '../../types/Util';
|
|||
import type { ConversationType } from '../../state/ducks/conversations';
|
||||
import type { BadgeType } from '../../badges/types';
|
||||
|
||||
export type Props = Pick<
|
||||
ConversationType,
|
||||
| 'acceptedMessageRequest'
|
||||
| 'avatarPath'
|
||||
| 'color'
|
||||
| 'isMe'
|
||||
| 'phoneNumber'
|
||||
| 'profileName'
|
||||
| 'sharedGroupNames'
|
||||
| 'title'
|
||||
> & {
|
||||
badge: undefined | BadgeType;
|
||||
const MAX_AVATARS_COUNT = 3;
|
||||
|
||||
export type PropsType = {
|
||||
conversationId: string;
|
||||
conversationType: 'group' | 'direct';
|
||||
showContactModal: (contactId: string, conversationId?: string) => void;
|
||||
i18n: LocalizerType;
|
||||
theme: ThemeType;
|
||||
typingContacts: Array<
|
||||
Pick<
|
||||
ConversationType,
|
||||
| 'acceptedMessageRequest'
|
||||
| 'avatarPath'
|
||||
| 'color'
|
||||
| 'id'
|
||||
| 'isMe'
|
||||
| 'phoneNumber'
|
||||
| 'profileName'
|
||||
| 'sharedGroupNames'
|
||||
| 'title'
|
||||
> & {
|
||||
badge: undefined | BadgeType;
|
||||
}
|
||||
>;
|
||||
};
|
||||
|
||||
export function TypingBubble({
|
||||
acceptedMessageRequest,
|
||||
avatarPath,
|
||||
badge,
|
||||
color,
|
||||
conversationId,
|
||||
conversationType,
|
||||
showContactModal,
|
||||
i18n,
|
||||
isMe,
|
||||
phoneNumber,
|
||||
profileName,
|
||||
sharedGroupNames,
|
||||
theme,
|
||||
title,
|
||||
}: Props): ReactElement {
|
||||
typingContacts,
|
||||
}: PropsType): ReactElement {
|
||||
const isGroup = conversationType === 'group';
|
||||
|
||||
const typingContactsOverflowCount = Math.max(
|
||||
typingContacts.length - MAX_AVATARS_COUNT,
|
||||
0
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
|
@ -54,22 +62,50 @@ export function TypingBubble({
|
|||
)}
|
||||
>
|
||||
{isGroup && (
|
||||
<div className="module-message__author-avatar-container">
|
||||
<Avatar
|
||||
acceptedMessageRequest={acceptedMessageRequest}
|
||||
avatarPath={avatarPath}
|
||||
badge={badge}
|
||||
color={color}
|
||||
conversationType="direct"
|
||||
i18n={i18n}
|
||||
isMe={isMe}
|
||||
phoneNumber={phoneNumber}
|
||||
profileName={profileName}
|
||||
theme={theme}
|
||||
title={title}
|
||||
sharedGroupNames={sharedGroupNames}
|
||||
size={28}
|
||||
/>
|
||||
<div className="module-message__typing-avatar-container">
|
||||
{typingContactsOverflowCount > 0 && (
|
||||
<div
|
||||
className="module-message__typing-avatar module-message__typing-avatar--overflow-count
|
||||
"
|
||||
>
|
||||
<div
|
||||
aria-label={i18n('icu:TypingBubble__avatar--overflow-count', {
|
||||
count: typingContactsOverflowCount,
|
||||
})}
|
||||
className="module-Avatar"
|
||||
>
|
||||
<div className="module-Avatar__contents">
|
||||
<div aria-hidden="true" className="module-Avatar__label">
|
||||
+{typingContactsOverflowCount}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{typingContacts.slice(-1 * MAX_AVATARS_COUNT).map(contact => (
|
||||
<div key={contact.id} className="module-message__typing-avatar">
|
||||
<Avatar
|
||||
acceptedMessageRequest={contact.acceptedMessageRequest}
|
||||
avatarPath={contact.avatarPath}
|
||||
badge={contact.badge}
|
||||
color={contact.color}
|
||||
conversationType="direct"
|
||||
i18n={i18n}
|
||||
isMe={contact.isMe}
|
||||
onClick={event => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
showContactModal(contact.id, conversationId);
|
||||
}}
|
||||
phoneNumber={contact.phoneNumber}
|
||||
profileName={contact.profileName}
|
||||
theme={theme}
|
||||
title={contact.title}
|
||||
sharedGroupNames={contact.sharedGroupNames}
|
||||
size={28}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className="module-message__container-outer">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue