-
Notifications
You must be signed in to change notification settings - Fork 298
Expand file tree
/
Copy pathuseMessageDeliveryStatus.ts
More file actions
105 lines (89 loc) · 3.17 KB
/
useMessageDeliveryStatus.ts
File metadata and controls
105 lines (89 loc) · 3.17 KB
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
import { useCallback, useEffect, useState } from 'react';
import type { Channel, Event, LocalMessage, UserResponse } from 'stream-chat';
import { useChatContext } from '../../../context';
export enum MessageDeliveryStatus {
SENT = 'sent',
DELIVERED = 'delivered',
READ = 'read',
}
type UseMessageStatusParamsChannelPreviewProps = {
channel: Channel;
/** The last message received in a channel */
lastMessage?: LocalMessage;
};
export const useMessageDeliveryStatus = ({
channel,
lastMessage,
}: UseMessageStatusParamsChannelPreviewProps) => {
const { client } = useChatContext();
const [messageDeliveryStatus, setMessageDeliveryStatus] = useState<
MessageDeliveryStatus | undefined
>();
const isOwnMessage = useCallback(
(message?: { user?: UserResponse | null }) =>
client.user && message && message.user?.id === client.user.id,
[client],
);
useEffect(() => {
// empty channel
if (!lastMessage) {
setMessageDeliveryStatus(undefined);
}
const lastMessageIsOwn = isOwnMessage(lastMessage);
if (!lastMessage?.created_at || !lastMessageIsOwn) return;
const msgRef = {
msgId: lastMessage.id,
timestampMs: lastMessage.created_at.getTime(),
};
const readersForMessage = channel.messageReceiptsTracker.readersForMessage(msgRef);
const deliveredForMessage =
channel.messageReceiptsTracker.deliveredForMessage(msgRef);
setMessageDeliveryStatus(
readersForMessage.length > 1 ||
(readersForMessage.length === 1 && readersForMessage[0].id !== client.user?.id)
? MessageDeliveryStatus.READ
: deliveredForMessage.length > 1 ||
(deliveredForMessage.length === 1 &&
deliveredForMessage[0].id !== client.user?.id)
? MessageDeliveryStatus.DELIVERED
: MessageDeliveryStatus.SENT,
);
}, [channel, client, isOwnMessage, lastMessage]);
useEffect(() => {
const handleMessageNew = (event: Event) => {
// the last message is not mine, so do not show the delivery status
if (!isOwnMessage(event.message)) {
return setMessageDeliveryStatus(undefined);
}
return setMessageDeliveryStatus(MessageDeliveryStatus.SENT);
};
channel.on('message.new', handleMessageNew);
return () => {
channel.off('message.new', handleMessageNew);
};
}, [channel, isOwnMessage]);
useEffect(() => {
if (!isOwnMessage(lastMessage)) return;
const handleMessageDelivered = (event: Event) => {
if (
event.user?.id !== client.user?.id &&
lastMessage &&
lastMessage.id === event.last_delivered_message_id
)
setMessageDeliveryStatus(MessageDeliveryStatus.DELIVERED);
};
const handleMarkRead = (event: Event) => {
if (event.user?.id !== client.user?.id)
setMessageDeliveryStatus(MessageDeliveryStatus.READ);
};
channel.on('message.delivered', handleMessageDelivered);
channel.on('message.read', handleMarkRead);
return () => {
channel.off('message.delivered', handleMessageDelivered);
channel.off('message.read', handleMarkRead);
};
}, [channel, client, isOwnMessage, lastMessage]);
return {
messageDeliveryStatus,
};
};