diff --git a/packages/call/src/store.tsx b/packages/call/src/store.tsx index e2595b6..6f3955c 100644 --- a/packages/call/src/store.tsx +++ b/packages/call/src/store.tsx @@ -6,6 +6,7 @@ import { log, toast } from "@tensamin/shared/log"; import { ttp } from "@tensamin/shared/data"; import { useCrypto } from "@tensamin/crypto/context"; import { useStorage } from "@tensamin/storage/context"; +import { useSession } from "@tensamin/storage/session"; import { useUser } from "@tensamin/user/context"; import { DeepFilterNoiseFilterProcessor } from "deepfilternet3-noise-filter"; import { @@ -890,7 +891,7 @@ export async function joinCall( log(2, "call", "purple", "Call creation initialised"); useCall.setState({ state: "encrypting", - invitedUserId: sendInvite ? userId : null, + invitedUserId: sendInvite && !existingCallId ? userId : null, }); if (callSecret) { @@ -1089,6 +1090,7 @@ export function useInitializeCall() { const { send, subscribePush } = useTTP(); const { getSharedSecret, decryptText, encryptText } = useCrypto(); const { load } = useStorage(); + const { insertCall } = useSession(); const { get } = useUser(); const callId = useCall((state) => state.callId); @@ -1137,29 +1139,41 @@ export function useInitializeCall() { } }, []); - const respondToInvite = useCallback((accepted: boolean) => { - const invite = useCall.getState().incomingCallInvite; + const respondToInvite = useCallback( + (accepted: boolean) => { + const invite = useCall.getState().incomingCallInvite; - useCall.setState({ incomingCallInvite: null }); + useCall.setState({ incomingCallInvite: null }); - if (!invite) { - return; - } + if (!invite) { + return; + } - if (accepted) { - joinCall(invite.senderId, invite.callSecret, invite.callId, false).catch( - (err) => { + insertCall({ + call_id: invite.callId, + call_secret: invite.callSecret, + call_members: [invite.senderId], + }); + + if (accepted) { + joinCall( + invite.senderId, + invite.callSecret, + invite.callId, + false, + ).catch((err) => { log(1, "call", "red", "Failed to join call", err); - }, - ); - return; - } + }); + return; + } - log(2, "call", "purple", "Declined call invite", { - callId: invite.callId, - senderId: invite.senderId, - }); - }, []); + log(2, "call", "purple", "Declined call invite", { + callId: invite.callId, + senderId: invite.senderId, + }); + }, + [insertCall], + ); // listen to call invites useEffect(() => { diff --git a/packages/storage/src/session.tsx b/packages/storage/src/session.tsx index d992a03..892f3e6 100644 --- a/packages/storage/src/session.tsx +++ b/packages/storage/src/session.tsx @@ -15,6 +15,7 @@ interface SessionContextType { calls: Calls; moveUserIdToTop: (userId: number) => void; insertContact: (userId: number) => void; + insertCall: (call: Calls[number]) => void; } const SessionContext = createContext(undefined); @@ -24,6 +25,7 @@ export default function SessionProvider({ children }: { children: ReactNode }) { const { load, save } = useStorage(); const [contacts, setContacts] = useState([]); const [communities, setCommunities] = useState([]); + const [calls, setCalls] = useState([]); // Get cached data and merge fresh data useEffect(() => { @@ -51,6 +53,15 @@ export default function SessionProvider({ children }: { children: ReactNode }) { }); }, [load, freshContacts, freshCommunities]); + useEffect(() => { + setCalls((prevCalls) => [ + ...freshCalls, + ...prevCalls.filter( + (call) => !freshCalls.some((fresh) => fresh.call_id === call.call_id), + ), + ]); + }, [freshCalls]); + // Save data useEffect(() => { save("cached_contacts", contacts); @@ -86,14 +97,25 @@ export default function SessionProvider({ children }: { children: ReactNode }) { }); }; + const insertCall = (call: Calls[number]) => { + setCalls((prevCalls) => { + if (prevCalls.some((prevCall) => prevCall.call_id === call.call_id)) { + return prevCalls; + } + + return [call, ...prevCalls]; + }); + }; + return ( {children}