blob: 8a405bb34f79528a2898023d4536c514152f5eed [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 */
idillon07d31cc2022-12-06 22:40:14 -050018import { ConversationMessage, IConversationSummary, LookupResult, WebSocketMessageType } from 'jami-web-common';
simon5c677962022-12-02 16:51:54 -050019import { createContext, ReactNode, useContext, useEffect, useMemo, useState } from 'react';
simon21f7d9f2022-11-28 14:21:54 -050020
Misha Krieger-Raynauldcfa44302022-11-30 18:36:36 -050021import { Contact } from '../models/contact';
idillon07d31cc2022-12-06 22:40:14 -050022import { useConversationsSummariesQuery, useRefreshConversationsSummaries } from '../services/conversationQueries';
simon21f7d9f2022-11-28 14:21:54 -050023import { SetState } from '../utils/utils';
24import { useAuthContext } from './AuthProvider';
25import { WebSocketContext } from './WebSocketProvider';
26
27export interface IMessengerContext {
idillon07d31cc2022-12-06 22:40:14 -050028 conversationsSummaries: IConversationSummary[] | undefined;
simon21f7d9f2022-11-28 14:21:54 -050029
30 setSearchQuery: SetState<string | undefined>;
31
idillon07d31cc2022-12-06 22:40:14 -050032 searchResult: Contact[] | undefined;
simon21f7d9f2022-11-28 14:21:54 -050033}
34
35const defaultMessengerContext: IMessengerContext = {
idillon07d31cc2022-12-06 22:40:14 -050036 conversationsSummaries: undefined,
simon21f7d9f2022-11-28 14:21:54 -050037 setSearchQuery: () => {},
38 searchResult: undefined,
39};
40
41export const MessengerContext = createContext<IMessengerContext>(defaultMessengerContext);
42
43export default ({ children }: { children: ReactNode }) => {
simon21f7d9f2022-11-28 14:21:54 -050044 const { accountId, axiosInstance } = useAuthContext();
45 const webSocket = useContext(WebSocketContext);
46
simon21f7d9f2022-11-28 14:21:54 -050047 const [searchQuery, setSearchQuery] = useState<string>();
idillon07d31cc2022-12-06 22:40:14 -050048 const [searchResult, setSearchResults] = useState<Contact[] | undefined>(undefined);
simon21f7d9f2022-11-28 14:21:54 -050049
idillon07d31cc2022-12-06 22:40:14 -050050 const conversationsSummariesQuery = useConversationsSummariesQuery();
51 const conversationsSummaries = conversationsSummariesQuery.data;
52 const refreshConversationsSummaries = useRefreshConversationsSummaries();
simon21f7d9f2022-11-28 14:21:54 -050053
54 useEffect(() => {
55 if (!webSocket) {
56 return;
57 }
58
59 const conversationMessageListener = (_data: ConversationMessage) => {
idillon07d31cc2022-12-06 22:40:14 -050060 refreshConversationsSummaries();
simon21f7d9f2022-11-28 14:21:54 -050061 };
62
63 webSocket.bind(WebSocketMessageType.ConversationMessage, conversationMessageListener);
64
65 return () => {
66 webSocket.unbind(WebSocketMessageType.ConversationMessage, conversationMessageListener);
67 };
idillon07d31cc2022-12-06 22:40:14 -050068 }, [refreshConversationsSummaries, webSocket]);
simon21f7d9f2022-11-28 14:21:54 -050069
70 useEffect(() => {
71 if (!searchQuery) return;
72 const controller = new AbortController();
simon21f7d9f2022-11-28 14:21:54 -050073 axiosInstance
Misha Krieger-Raynauldcfa44302022-11-30 18:36:36 -050074 .get<LookupResult>(`/ns/username/${searchQuery}`, {
simon21f7d9f2022-11-28 14:21:54 -050075 signal: controller.signal,
76 })
77 .then(({ data }) => {
Misha Krieger-Raynauldcfa44302022-11-30 18:36:36 -050078 const contact = new Contact(data.address, data.username);
idillon07d31cc2022-12-06 22:40:14 -050079 setSearchResults([contact]);
simon21f7d9f2022-11-28 14:21:54 -050080 })
81 .catch(() => {
82 setSearchResults(undefined);
83 });
84 // return () => controller.abort() // crash on React18
85 }, [accountId, searchQuery, axiosInstance]);
86
idillon07d31cc2022-12-06 22:40:14 -050087 const value = useMemo<IMessengerContext>(
simon5c677962022-12-02 16:51:54 -050088 () => ({
idillon07d31cc2022-12-06 22:40:14 -050089 conversationsSummaries,
simon5c677962022-12-02 16:51:54 -050090 setSearchQuery,
91 searchResult,
simon5c677962022-12-02 16:51:54 -050092 }),
idillon07d31cc2022-12-06 22:40:14 -050093 [conversationsSummaries, setSearchQuery, searchResult]
simon21f7d9f2022-11-28 14:21:54 -050094 );
simon5c677962022-12-02 16:51:54 -050095
96 return <MessengerContext.Provider value={value}>{children}</MessengerContext.Provider>;
simon21f7d9f2022-11-28 14:21:54 -050097};