-
Notifications
You must be signed in to change notification settings - Fork 281
/
Copy pathMessageStatus.tsx
107 lines (91 loc) · 3.17 KB
/
MessageStatus.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import React from 'react';
import { DeliveredCheckIcon } from './icons';
import { getReadByTooltipText, mapToUserNameOrId, TooltipUsernameMapper } from './utils';
import { AvatarProps, Avatar as DefaultAvatar } from '../Avatar';
import { LoadingIndicator } from '../Loading';
import { Tooltip } from '../Tooltip';
import { useChatContext } from '../../context/ChatContext';
import { useComponentContext } from '../../context/ComponentContext';
import { useMessageContext } from '../../context/MessageContext';
import { useTranslationContext } from '../../context/TranslationContext';
import type { DefaultStreamChatGenerics } from '../../types/types';
export type MessageStatusProps = {
Avatar?: React.ComponentType<AvatarProps>;
messageType?: string;
tooltipUserNameMapper?: TooltipUsernameMapper;
};
const UnMemoizedMessageStatus = <
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics
>(
props: MessageStatusProps,
) => {
const {
Avatar: propAvatar,
messageType = 'simple',
tooltipUserNameMapper = mapToUserNameOrId,
} = props;
const { client } = useChatContext<StreamChatGenerics>('MessageStatus');
const { Avatar: contextAvatar } = useComponentContext<StreamChatGenerics>('MessageStatus');
const {
isMyMessage,
lastReceivedId,
message,
readBy,
threadList,
} = useMessageContext<StreamChatGenerics>('MessageStatus');
const { t } = useTranslationContext('MessageStatus');
const Avatar = propAvatar || contextAvatar || DefaultAvatar;
if (!isMyMessage() || message.type === 'error') {
return null;
}
const justReadByMe = readBy?.length === 1 && readBy[0].id === client.user?.id;
if (message.status === 'sending') {
return (
<span
className={`str-chat__message-${messageType}-status`}
data-testid='message-status-sending'
>
<Tooltip>{t<string>('Sending...')}</Tooltip>
<LoadingIndicator />
</span>
);
}
if (readBy?.length && !threadList && !justReadByMe) {
const lastReadUser = readBy.filter((item) => item.id !== client.user?.id)[0];
return (
<span
className={`str-chat__message-${messageType}-status`}
data-testid='message-status-read-by'
>
<Tooltip>{getReadByTooltipText(readBy, t, client, tooltipUserNameMapper)}</Tooltip>
<Avatar
image={lastReadUser.image}
name={lastReadUser.name || lastReadUser.id}
size={15}
user={lastReadUser}
/>
{readBy.length > 2 && (
<span
className={`str-chat__message-${messageType}-status-number`}
data-testid='message-status-read-by-many'
>
{readBy.length - 1}
</span>
)}
</span>
);
}
if (message.status === 'received' && message.id === lastReceivedId && !threadList) {
return (
<span
className={`str-chat__message-${messageType}-status`}
data-testid='message-status-received'
>
<Tooltip>{t<string>('Delivered')}</Tooltip>
<DeliveredCheckIcon />
</span>
);
}
return null;
};
export const MessageStatus = React.memo(UnMemoizedMessageStatus) as typeof UnMemoizedMessageStatus;