forked from twilio/twilio-video-app-react
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.tsx
96 lines (84 loc) · 3.16 KB
/
index.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
import React, { createContext, useCallback, useEffect, useRef, useState } from 'react';
import { Client } from '@twilio/conversations';
import { Conversation } from '@twilio/conversations/';
import { Message } from '@twilio/conversations/';
import useVideoContext from '../../hooks/useVideoContext/useVideoContext';
type ChatContextType = {
isChatWindowOpen: boolean;
setIsChatWindowOpen: (isChatWindowOpen: boolean) => void;
connect: (token: string) => void;
hasUnreadMessages: boolean;
messages: Message[];
conversation: Conversation | null;
};
export const ChatContext = createContext<ChatContextType>(null!);
export const ChatProvider: React.FC = ({ children }) => {
const { room, onError } = useVideoContext();
const isChatWindowOpenRef = useRef(false);
const [isChatWindowOpen, setIsChatWindowOpen] = useState(false);
const [conversation, setConversation] = useState<Conversation | null>(null);
const [messages, setMessages] = useState<Message[]>([]);
const [hasUnreadMessages, setHasUnreadMessages] = useState(false);
const [chatClient, setChatClient] = useState<Client>();
const connect = useCallback(
(token: string) => {
const client = new Client(token);
const handleClientInitialized = (state: string) => {
if (state === 'initialized') {
// @ts-ignore
window.chatClient = client;
setChatClient(client);
} else if (state === 'failed') {
onError(new Error("There was a problem connecting to Twilio's conversation service."));
}
};
client.on('stateChanged', handleClientInitialized);
return () => {
client.off('stateChanged', handleClientInitialized);
};
},
[onError]
);
useEffect(() => {
if (conversation) {
const handleMessageAdded = (message: Message) => setMessages(oldMessages => [...oldMessages, message]);
conversation.getMessages().then(newMessages => setMessages(newMessages.items));
conversation.on('messageAdded', handleMessageAdded);
return () => {
conversation.off('messageAdded', handleMessageAdded);
};
}
}, [conversation]);
useEffect(() => {
// If the chat window is closed and there are new messages, set hasUnreadMessages to true
if (!isChatWindowOpenRef.current && messages.length) {
setHasUnreadMessages(true);
}
}, [messages]);
useEffect(() => {
isChatWindowOpenRef.current = isChatWindowOpen;
if (isChatWindowOpen) setHasUnreadMessages(false);
}, [isChatWindowOpen]);
useEffect(() => {
if (room && chatClient) {
chatClient
.getConversationByUniqueName(room.sid)
.then(newConversation => {
//@ts-ignore
window.chatConversation = newConversation;
setConversation(newConversation);
})
.catch(e => {
console.error(e);
onError(new Error('There was a problem getting the Conversation associated with this room.'));
});
}
}, [room, chatClient, onError]);
return (
<ChatContext.Provider
value={{ isChatWindowOpen, setIsChatWindowOpen, connect, hasUnreadMessages, messages, conversation }}
>
{children}
</ChatContext.Provider>
);
};