blob: f92a6d754c5a242ad87db8bf6a240c4550fdedc2 [file] [log] [blame]
simon21f7d9f2022-11-28 14:21:54 -05001/*
2 * Copyright (C) 2022 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public
15 * License along with this program. If not, see
16 * <https://www.gnu.org/licenses/>.
17 */
18import { Contact, Conversation, ConversationMessage, WebSocketMessageType } from 'jami-web-common';
19import React, { createContext, ReactNode, useContext, useEffect, useState } from 'react';
20
21import { setRefreshFromSlice } from '../redux/appSlice';
22import { useAppDispatch, useAppSelector } from '../redux/hooks';
23import { SetState } from '../utils/utils';
24import { useAuthContext } from './AuthProvider';
25import { WebSocketContext } from './WebSocketProvider';
26
27export interface IMessengerContext {
28 conversations: Conversation[] | undefined;
29
30 setSearchQuery: SetState<string | undefined>;
31
32 searchResult: Conversation | undefined;
33
34 newContactId: string | undefined;
35 setNewContactId: SetState<string | undefined>;
36}
37
38const defaultMessengerContext: IMessengerContext = {
39 conversations: undefined,
40 newContactId: undefined,
41 setNewContactId: () => {},
42 setSearchQuery: () => {},
43 searchResult: undefined,
44};
45
46export const MessengerContext = createContext<IMessengerContext>(defaultMessengerContext);
47
48export default ({ children }: { children: ReactNode }) => {
49 const { refresh } = useAppSelector((state) => state.userInfo);
50 const dispatch = useAppDispatch();
51 const { accountId, axiosInstance } = useAuthContext();
52 const webSocket = useContext(WebSocketContext);
53
54 const [conversations, setConversations] = useState<Conversation[] | undefined>(undefined);
55 const [searchQuery, setSearchQuery] = useState<string>();
56 const [searchResult, setSearchResults] = useState<Conversation | undefined>(undefined);
57 const [newContactId, setNewContactId] = useState<string>();
58
59 useEffect(() => {
60 const controller = new AbortController();
61 axiosInstance
62 .get<Conversation[]>('/conversations', {
63 signal: controller.signal,
64 })
65 .then(({ data }) => {
66 setConversations(Object.values(data).map((c) => Conversation.from(accountId, c)));
67 });
68 // return () => controller.abort()
69 }, [axiosInstance, accountId, refresh]);
70
71 useEffect(() => {
72 if (!webSocket) {
73 return;
74 }
75
76 const conversationMessageListener = (_data: ConversationMessage) => {
77 dispatch(setRefreshFromSlice());
78 };
79
80 webSocket.bind(WebSocketMessageType.ConversationMessage, conversationMessageListener);
81
82 return () => {
83 webSocket.unbind(WebSocketMessageType.ConversationMessage, conversationMessageListener);
84 };
85 }, [webSocket, dispatch]);
86
87 useEffect(() => {
88 if (!searchQuery) return;
89 const controller = new AbortController();
90 // TODO: Type properly https://git.jami.net/savoirfairelinux/jami-web/-/issues/92
91 axiosInstance
92 .get<{ state: number; address: string; username: string }>(`/ns/username/${searchQuery}`, {
93 signal: controller.signal,
94 })
95 .then(({ data }) => {
96 const contact = new Contact(data.address);
97 contact.setRegisteredName(data.username);
98 setSearchResults(contact ? Conversation.fromSingleContact(accountId, contact) : undefined);
99 })
100 .catch(() => {
101 setSearchResults(undefined);
102 });
103 // return () => controller.abort() // crash on React18
104 }, [accountId, searchQuery, axiosInstance]);
105
106 return (
107 <MessengerContext.Provider
108 value={{
109 conversations,
110 setSearchQuery,
111 searchResult,
112 newContactId,
113 setNewContactId,
114 }}
115 >
116 {children}
117 </MessengerContext.Provider>
118 );
119};