From 3ea3c092b565b2f55193b82f296114fa4d1d04f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=91=D0=B0=D0=B1?= =?UTF-8?q?=D1=83=D1=88=D0=BA=D0=B8=D0=BD?= Date: Mon, 24 Feb 2025 13:46:28 +0100 Subject: [PATCH] implementing conference call --- .../Assist/ChatWindow/ChatWindow.tsx | 6 +- .../AssistActions/AssistActions.tsx | 18 +-- .../VideoContainer/VideoContainer.tsx | 23 +++- .../app/player/web/assist/AssistManager.ts | 13 ++- frontend/app/player/web/assist/Call.ts | 105 +++++++++++++++--- tracker/tracker-assist/.yarn/install-state.gz | Bin 549988 -> 515844 bytes tracker/tracker-assist/src/Assist.ts | 61 ++++++---- 7 files changed, 171 insertions(+), 55 deletions(-) diff --git a/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx b/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx index 70272c9f1..e9e5b8ea2 100644 --- a/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx +++ b/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx @@ -9,7 +9,7 @@ import type { LocalStream } from 'Player'; import { PlayerContext } from 'App/components/Session/playerContext'; export interface Props { - incomeStream: MediaStream[] | null; + incomeStream: { stream: MediaStream, isAgent: boolean }[] | null; localStream: LocalStream | null; userId: string; isPrestart?: boolean; @@ -50,8 +50,8 @@ function ChatWindow({ userId, incomeStream, localStream, endCall, isPrestart }: > {incomeStream ? ( incomeStream.map((stream) => ( - - + + )) ) : ( diff --git a/frontend/app/components/Assist/components/AssistActions/AssistActions.tsx b/frontend/app/components/Assist/components/AssistActions/AssistActions.tsx index 99b976556..6c4c23ed9 100644 --- a/frontend/app/components/Assist/components/AssistActions/AssistActions.tsx +++ b/frontend/app/components/Assist/components/AssistActions/AssistActions.tsx @@ -80,7 +80,7 @@ function AssistActions({ } = store.get(); const [isPrestart, setPrestart] = useState(false); - const [incomeStream, setIncomeStream] = useState([]); + const [incomeStream, setIncomeStream] = useState<{ stream: MediaStream; isAgent: boolean }[] | null>([]); const [localStream, setLocalStream] = useState(null); const [callObject, setCallObject] = useState<{ end: () => void } | null>(null); @@ -131,12 +131,12 @@ function AssistActions({ } }, [peerConnectionStatus]); - const addIncomeStream = (stream: MediaStream) => { + const addIncomeStream = (stream: MediaStream, isAgent: boolean) => { setIncomeStream((oldState) => { - if (oldState === null) return [stream]; - if (!oldState.find((existingStream) => existingStream.id === stream.id)) { + if (oldState === null) return [{ stream, isAgent }]; + if (!oldState.find((existingStream) => existingStream.stream.id === stream.id)) { audioContextManager.mergeAudioStreams(stream); - return [...oldState, stream]; + return [...oldState, { stream, isAgent }]; } return oldState; }); @@ -156,16 +156,16 @@ function AssistActions({ addIncomeStream, () => { player.assistManager.ping(AssistActionsPing.call.end, agentId) - lStream.stop.bind(lStream); + lStream.stop.apply(lStream); removeIncomeStream(lStream.stream); }, onReject, onError ); setCallObject(callPeer()); - if (additionalAgentIds) { - callPeer(additionalAgentIds); - } + // if (additionalAgentIds) { + // callPeer(additionalAgentIds); + // } }) .catch(onError); } diff --git a/frontend/app/components/Assist/components/VideoContainer/VideoContainer.tsx b/frontend/app/components/Assist/components/VideoContainer/VideoContainer.tsx index 303d98eae..4d8b9ece4 100644 --- a/frontend/app/components/Assist/components/VideoContainer/VideoContainer.tsx +++ b/frontend/app/components/Assist/components/VideoContainer/VideoContainer.tsx @@ -6,9 +6,17 @@ interface Props { height?: number | string; setRemoteEnabled?: (isEnabled: boolean) => void; local?: boolean; + isAgent?: boolean; } -function VideoContainer({ stream, muted = false, height = 280, setRemoteEnabled, local }: Props) { +function VideoContainer({ + stream, + muted = false, + height = 280, + setRemoteEnabled, + local, + isAgent, +}: Props) { const ref = useRef(null); const [isEnabled, setEnabled] = React.useState(false); @@ -16,14 +24,14 @@ function VideoContainer({ stream, muted = false, height = 280, setRemoteEnabled, if (ref.current) { ref.current.srcObject = stream; } - }, [ref.current, stream, stream.getVideoTracks()[0]?.getSettings().width]); + }, [ref.current, stream, stream?.getVideoTracks()[0]?.getSettings().width]); useEffect(() => { if (!stream) { return; } const iid = setInterval(() => { - const track = stream.getVideoTracks()[0] + const track = stream.getVideoTracks()[0]; const settings = track?.getSettings(); const isDummyVideoTrack = settings ? settings.width === 2 || @@ -52,6 +60,15 @@ function VideoContainer({ stream, muted = false, height = 280, setRemoteEnabled, }} >