diff --git a/frontend/app/components/Assist/ChatControls/ChatControls.tsx b/frontend/app/components/Assist/ChatControls/ChatControls.tsx
index 42866ed4b..0b85dab09 100644
--- a/frontend/app/components/Assist/ChatControls/ChatControls.tsx
+++ b/frontend/app/components/Assist/ChatControls/ChatControls.tsx
@@ -9,9 +9,10 @@ interface Props {
stream: LocalStream | null,
endCall: () => void,
videoEnabled: boolean,
- setVideoEnabled: (boolean) => void
+ isPrestart?: boolean,
+ setVideoEnabled: (isEnabled: boolean) => void
}
-function ChatControls({ stream, endCall, videoEnabled, setVideoEnabled } : Props) {
+function ChatControls({ stream, endCall, videoEnabled, setVideoEnabled, isPrestart } : Props) {
const [audioEnabled, setAudioEnabled] = useState(true)
const toggleAudio = () => {
@@ -25,6 +26,13 @@ function ChatControls({ stream, endCall, videoEnabled, setVideoEnabled } : Props
.then(setVideoEnabled)
}
+ /** muting user if he is auto connected to the call */
+ React.useEffect(() => {
+ if (isPrestart) {
+ audioEnabled && toggleAudio();
+ }
+ }, [])
+
return (
diff --git a/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx b/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx
index 8eb2a3620..5a6608fcf 100644
--- a/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx
+++ b/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx
@@ -1,5 +1,4 @@
-//@ts-nocheck
-import React, { useState, FC, useEffect } from 'react'
+import React, { useState, useEffect } from 'react'
import VideoContainer from '../components/VideoContainer'
import cn from 'classnames'
import Counter from 'App/components/shared/SessionItem/Counter'
@@ -8,23 +7,23 @@ import ChatControls from '../ChatControls/ChatControls'
import Draggable from 'react-draggable';
import type { LocalStream } from 'Player/MessageDistributor/managers/LocalStream';
-
export interface Props {
- incomeStream: MediaStream | null,
+ incomeStream: MediaStream[] | null,
localStream: LocalStream | null,
- userId: String,
+ userId: string,
+ isPrestart?: boolean;
endCall: () => void
}
-const ChatWindow: FC
= function ChatWindow({ userId, incomeStream, localStream, endCall }) {
+function ChatWindow({ userId, incomeStream, localStream, endCall, isPrestart }: Props) {
const [localVideoEnabled, setLocalVideoEnabled] = useState(false)
const [remoteVideoEnabled, setRemoteVideoEnabled] = useState(false)
useEffect(() => {
- if (!incomeStream) { return }
+ if (!incomeStream || incomeStream.length === 0) { return }
const iid = setInterval(() => {
- const settings = incomeStream.getVideoTracks()[0]?.getSettings()
- const isDummyVideoTrack = !!settings ? (settings.width === 2 || settings.frameRate === 0) : true
+ const settings = incomeStream.map(stream => stream.getVideoTracks()[0]?.getSettings()).filter(Boolean)
+ const isDummyVideoTrack = settings.length > 0 ? (settings.every(s => s.width === 2 || s.frameRate === 0 || s.frameRate === undefined)) : true
const shouldBeEnabled = !isDummyVideoTrack
if (shouldBeEnabled !== localVideoEnabled) {
setRemoteVideoEnabled(shouldBeEnabled)
@@ -42,16 +41,20 @@ const ChatWindow: FC = function ChatWindow({ userId, incomeStream, localS
style={{ width: '280px' }}
>
-
Talking to {userId ? userId : 'Anonymous User'}
+
+ Talking to {userId ? userId : 'Anonymous User'}
+ {incomeStream && incomeStream.length > 2 ? ' (+ other agents in the call)' : ''}
+
-
+ {!incomeStream &&
Error obtaining incoming streams
}
+ {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 ba1a7cf0b..757beca54 100644
--- a/frontend/app/components/Assist/components/AssistActions/AssistActions.tsx
+++ b/frontend/app/components/Assist/components/AssistActions/AssistActions.tsx
@@ -1,11 +1,12 @@
import React, { useState, useEffect } from 'react';
import { Popup, Icon, Button, IconButton } from 'UI';
+import logger from 'App/logger';
import { connect } from 'react-redux';
import cn from 'classnames';
import { toggleChatWindow } from 'Duck/sessions';
import { connectPlayer } from 'Player/store';
import ChatWindow from '../../ChatWindow';
-import { callPeer, requestReleaseRemoteControl, toggleAnnotation } from 'Player';
+import { callPeer, setCallArgs, requestReleaseRemoteControl, toggleAnnotation } from 'Player';
import { CallingState, ConnectionStatus, RemoteControlStatus } from 'Player/MessageDistributor/managers/AssistManager';
import RequestLocalStream from 'Player/MessageDistributor/managers/LocalStream';
import type { LocalStream } from 'Player/MessageDistributor/managers/LocalStream';
@@ -14,15 +15,12 @@ import { toast } from 'react-toastify';
import { confirm } from 'UI';
import stl from './AassistActions.module.css';
-function onClose(stream) {
- stream.getTracks().forEach((t) => t.stop());
-}
-
function onReject() {
toast.info(`Call was rejected.`);
}
function onError(e) {
+ console.log(e)
toast.error(typeof e === 'string' ? e : e.message);
}
@@ -35,6 +33,8 @@ interface Props {
remoteControlStatus: RemoteControlStatus;
hasPermission: boolean;
isEnterprise: boolean;
+ isCallActive: boolean;
+ agentIds: string[];
}
function AssistActions({
@@ -46,14 +46,21 @@ function AssistActions({
remoteControlStatus,
hasPermission,
isEnterprise,
+ isCallActive,
+ agentIds
}: Props) {
- const [incomeStream, setIncomeStream] = useState
(null);
+ const [isPrestart, setPrestart] = useState(false);
+ const [incomeStream, setIncomeStream] = useState([]);
const [localStream, setLocalStream] = useState(null);
const [callObject, setCallObject] = useState<{ end: () => void } | null>(null);
+ const onCall = calling === CallingState.OnCall || calling === CallingState.Reconnecting;
+ const cannotCall = peerConnectionStatus !== ConnectionStatus.Connected || (isEnterprise && !hasPermission);
+ const remoteActive = remoteControlStatus === RemoteControlStatus.Enabled;
+
useEffect(() => {
- return callObject?.end();
- }, []);
+ return callObject?.end()
+ }, [])
useEffect(() => {
if (peerConnectionStatus == ConnectionStatus.Disconnected) {
@@ -61,15 +68,36 @@ function AssistActions({
}
}, [peerConnectionStatus]);
- function call() {
- RequestLocalStream()
- .then((lStream) => {
- setLocalStream(lStream);
- setCallObject(callPeer(lStream, setIncomeStream, lStream.stop.bind(lStream), onReject, onError));
- })
- .catch(onError);
+ const addIncomeStream = (stream: MediaStream) => {
+ console.log('new stream in component')
+ setIncomeStream(oldState => [...oldState, stream]);
}
+ function call(agentIds?: string[]) {
+ RequestLocalStream().then(lStream => {
+ setLocalStream(lStream);
+ setCallArgs(
+ lStream,
+ addIncomeStream,
+ lStream.stop.bind(lStream),
+ onReject,
+ onError
+ )
+ setCallObject(callPeer());
+ if (agentIds) {
+ callPeer(agentIds)
+ }
+ }).catch(onError)
+ }
+
+ React.useEffect(() => {
+ if (!onCall && isCallActive && agentIds) {
+ logger.log('joinig the party', agentIds)
+ setPrestart(true);
+ call(agentIds)
+ }
+ }, [agentIds, isCallActive])
+
const confirmCall = async () => {
if (
await confirm({
@@ -82,10 +110,6 @@ function AssistActions({
}
};
- const onCall = calling === CallingState.OnCall || calling === CallingState.Reconnecting;
- const cannotCall = peerConnectionStatus !== ConnectionStatus.Connected || (isEnterprise && !hasPermission);
- const remoteActive = remoteControlStatus === RemoteControlStatus.Enabled;
-
return (
{(onCall || remoteActive) && (
@@ -123,7 +147,7 @@ function AssistActions({
-
+
{onCall && callObject && (
-
+
)}
diff --git a/frontend/app/components/Session_/PlayerBlockHeader.js b/frontend/app/components/Session_/PlayerBlockHeader.js
index f0576e419..f7afb2bdb 100644
--- a/frontend/app/components/Session_/PlayerBlockHeader.js
+++ b/frontend/app/components/Session_/PlayerBlockHeader.js
@@ -105,7 +105,7 @@ export default class PlayerBlockHeader extends React.PureComponent {
const { hideBack } = this.state;
- const { sessionId, userId, userNumericHash, live, metadata } = session;
+ const { sessionId, userId, userNumericHash, live, metadata, isCallActive, agentIds } = session;
let _metaList = Object.keys(metadata)
.filter((i) => metaList.includes(i))
.map((key) => {
@@ -142,7 +142,7 @@ export default class PlayerBlockHeader extends React.PureComponent {
)}
- {isAssist && }
+ {isAssist && }
{!isAssist && (
diff --git a/frontend/app/components/shared/SessionItem/SessionItem.tsx b/frontend/app/components/shared/SessionItem/SessionItem.tsx
index fa886ab8b..83d2e6bb3 100644
--- a/frontend/app/components/shared/SessionItem/SessionItem.tsx
+++ b/frontend/app/components/shared/SessionItem/SessionItem.tsx
@@ -41,6 +41,8 @@ interface Props {
userSessionsCount: number;
issueTypes: [];
active: boolean;
+ isCallActive?: boolean;
+ agentIds?: string[];
};
onUserClick?: (userId: string, userAnonymousId: string) => void;
hasUserFilter?: boolean;
@@ -168,6 +170,15 @@ function SessionItem(props: RouteComponentProps & Props) {