From 6743aa376db086e23affc910b7c84658f86c886c Mon Sep 17 00:00:00 2001
From: Dhruv Jain
Date: Thu, 12 Aug 2021 08:47:23 +0530
Subject: [PATCH 01/14] [NEW] Control Buttons - mic, cam, expand and end call
---
app/webrtc/client/WebRTCClass.js | 64 +++++++++-----------
client/views/meet/CallPage.css | 11 ++++
client/views/meet/CallPage.js | 70 ++++++++++++++++++++--
client/views/meet/MeetPage.js | 2 +
packages/rocketchat-i18n/i18n/en.i18n.json | 9 ++-
5 files changed, 113 insertions(+), 43 deletions(-)
create mode 100644 client/views/meet/CallPage.css
diff --git a/app/webrtc/client/WebRTCClass.js b/app/webrtc/client/WebRTCClass.js
index def834495a262..96e0012abd1d5 100644
--- a/app/webrtc/client/WebRTCClass.js
+++ b/app/webrtc/client/WebRTCClass.js
@@ -145,8 +145,8 @@ class WebRTCClass {
this.remoteItems = new ReactiveVar([]);
this.remoteItemsById = new ReactiveVar({});
this.callInProgress = new ReactiveVar(false);
- this.audioEnabled = new ReactiveVar(true);
- this.videoEnabled = new ReactiveVar(true);
+ this.audioEnabled = new ReactiveVar(false);
+ this.videoEnabled = new ReactiveVar(false);
this.overlayEnabled = new ReactiveVar(false);
this.screenShareEnabled = new ReactiveVar(false);
this.localUrl = new ReactiveVar();
@@ -169,7 +169,7 @@ class WebRTCClass {
this.screenShareAvailable = ['chrome', 'firefox', 'electron'].includes(this.navigator);
this.media = {
- video: false,
+ video: true,
audio: true,
};
this.transport = new this.TransportClass(this);
@@ -498,9 +498,9 @@ class WebRTCClass {
}
const onSuccess = (stream) => {
this.localStream = stream;
+ !this.audioEnabled.get() && this.disableAudio();
+ !this.videoEnabled.get() && this.disableVideo();
this.localUrl.set(stream);
- this.videoEnabled.set(this.media.video === true);
- this.audioEnabled.set(this.media.audio === true);
const { peerConnections } = this;
Object.entries(peerConnections).forEach(([, peerConnection]) => peerConnection.addStream(stream));
document.querySelector('video#localVideo').srcObject = stream;
@@ -538,19 +538,10 @@ class WebRTCClass {
setAudioEnabled(enabled = true) {
if (this.localStream != null) {
- if (enabled === true && this.media.audio !== true) {
- delete this.localStream;
- this.media.audio = true;
- this.getLocalUserMedia(() => {
- this.stopAllPeerConnections();
- this.joinCall();
- });
- } else {
- this.localStream.getAudioTracks().forEach(function(audio) {
- audio.enabled = enabled;
- });
- this.audioEnabled.set(enabled);
- }
+ this.localStream.getAudioTracks().forEach(function(audio) {
+ audio.enabled = enabled;
+ });
+ this.audioEnabled.set(enabled);
}
}
@@ -562,21 +553,19 @@ class WebRTCClass {
this.setAudioEnabled(true);
}
+ toggleAudio() {
+ if (this.audioEnabled.get()) {
+ return this.disableAudio();
+ }
+ return this.enableAudio();
+ }
+
setVideoEnabled(enabled = true) {
if (this.localStream != null) {
- if (enabled === true && this.media.video !== true) {
- delete this.localStream;
- this.media.video = true;
- this.getLocalUserMedia(() => {
- this.stopAllPeerConnections();
- this.joinCall();
- });
- } else {
- this.localStream.getVideoTracks().forEach(function(video) {
- video.enabled = enabled;
- });
- this.videoEnabled.set(enabled);
- }
+ this.localStream.getVideoTracks().forEach(function(video) {
+ video.enabled = enabled;
+ });
+ this.videoEnabled.set(enabled);
}
}
@@ -611,6 +600,13 @@ class WebRTCClass {
this.setVideoEnabled(true);
}
+ toggleVideo() {
+ if (this.videoEnabled.get()) {
+ return this.disableVideo();
+ }
+ return this.enableVideo();
+ }
+
stop() {
this.active = false;
this.monitor = false;
@@ -735,12 +731,6 @@ class WebRTCClass {
*/
joinCall(data = {}, ...args) {
- if (data.media && data.media.audio) {
- this.media.audio = data.media.audio;
- }
- if (data.media && data.media.video) {
- this.media.video = data.media.video;
- }
data.media = this.media;
this.log('joinCall', [data, ...args]);
this.getLocalUserMedia(() => {
diff --git a/client/views/meet/CallPage.css b/client/views/meet/CallPage.css
new file mode 100644
index 0000000000000..a19cb17d28b6d
--- /dev/null
+++ b/client/views/meet/CallPage.css
@@ -0,0 +1,11 @@
+.Off {
+ color: #ffffff !important;
+ border-color: #2f343d !important;
+ background-color: #2f343d !important;
+}
+
+.On {
+ color: #000000 !important;
+ border-color: #ffffff !important;
+ background-color: #ffffff !important;
+}
diff --git a/client/views/meet/CallPage.js b/client/views/meet/CallPage.js
index 00d2eab6bef3c..39094629e461f 100644
--- a/client/views/meet/CallPage.js
+++ b/client/views/meet/CallPage.js
@@ -1,13 +1,16 @@
-import { Box, Flex } from '@rocket.chat/fuselage';
+import { Box, Flex, ButtonGroup, Button, Icon } from '@rocket.chat/fuselage';
import React, { useEffect, useState } from 'react';
import { Notifications } from '../../../app/notifications/client';
import { WebRTC } from '../../../app/webrtc/client';
import { WEB_RTC_EVENTS } from '../../../app/webrtc/index';
import { useTranslation } from '../../contexts/TranslationContext';
+import './CallPage.css';
-function CallPage({ roomId, visitorToken, visitorId, status, setStatus }) {
+function CallPage({ roomId, visitorToken, visitorId, status, setStatus, layout }) {
const [isAgentActive, setIsAgentActive] = useState(false);
+ const [isMicOn, setIsMicOn] = useState(false);
+ const [isCameraOn, setIsCameraOn] = useState(false);
const t = useTranslation();
useEffect(() => {
if (visitorToken) {
@@ -62,6 +65,22 @@ function CallPage({ roomId, visitorToken, visitorId, status, setStatus }) {
}
}, [isAgentActive, status, setStatus, visitorId, roomId, visitorToken]);
+ const toggleButton = (control) => {
+ if (control === 'mic') {
+ WebRTC.getInstanceByRoomId(roomId, visitorToken).toggleAudio();
+ return setIsMicOn(!isMicOn);
+ }
+ WebRTC.getInstanceByRoomId(roomId, visitorToken).toggleVideo();
+ setIsCameraOn(!isCameraOn);
+ };
+
+ const closeWindow = () => {
+ if (layout === 'embedded') {
+ return parent.handleIframeClose();
+ }
+ return window.close();
+ };
+
switch (status) {
case 'ringing':
// Todo Deepak
@@ -89,7 +108,7 @@ function CallPage({ roomId, visitorToken, visitorId, status, setStatus }) {
+
+
+
+ {layout === 'embedded' && (
+
+ )}
+
+
+
@@ -337,15 +343,17 @@ function CallPage({
className='rcx-message__avatar'
size='x124'
/>
- {'Calling...'}
-
+ {'Calling...'}
+
+
{visitorName}
-
+
@@ -367,7 +375,9 @@ function CallPage({
case 'inProgress':
return (
- {visitorToken ? showAvatar(visitorName, agentName) : showAvatar(agentName, visitorName)}
+ {visitorToken
+ ? showCallPage(visitorName, agentName)
+ : showCallPage(agentName, visitorName)}
);
}
diff --git a/client/views/meet/MeetPage.js b/client/views/meet/MeetPage.js
index 2624c5ed8de4d..fb7ff04c9102b 100644
--- a/client/views/meet/MeetPage.js
+++ b/client/views/meet/MeetPage.js
@@ -19,13 +19,9 @@ function MeetPage() {
const layout = useQueryStringParameter('layout');
const [visitorName, setVisitorName] = useState('');
const [agentName, setAgentName] = useState('');
+ const [callStartTime, setCallStartTime] = useState(undefined);
- const ismobiledevice = () => {
- if (window.innerWidth <= 450 && window.innerHeight >= 620) {
- return true;
- }
- return false;
- };
+ const isMobileDevice = () => window.innerWidth <= 450;
const setupCallForVisitor = useCallback(async () => {
const room = await APIClient.v1.get(`/livechat/room?token=${visitorToken}&rid=${roomId}`);
@@ -36,6 +32,7 @@ function MeetPage() {
? setAgentName(room.room.responseBy.username)
: setAgentName(room.room.servedBy.username);
setStatus(room?.room?.callStatus || 'ended');
+ setCallStartTime(room.room.webRtcCallStartTime);
return setIsRoomMember(true);
}
}, [visitorToken, roomId]);
@@ -48,6 +45,7 @@ function MeetPage() {
? setAgentName(room.room.responseBy.username)
: setAgentName(room.room.servedBy.username);
setStatus(room?.room?.callStatus || 'ended');
+ setCallStartTime(room.room.webRtcCallStartTime);
return setIsRoomMember(true);
}
}, [roomId]);
@@ -70,149 +68,76 @@ function MeetPage() {
if (status === 'ended') {
return (
- {visitorToken ? (
+
-
-
-
-
-
- {'Call Ended!'}
-
- {agentName}
-
-
-
-
-
+ username={visitorToken ? visitorName : agentName}
+ className='rcx-message__avatar'
+ size={isMobileDevice() ? 'x32' : 'x48'}
+ />
- ) : (
-
-
-
-
+ {'Call Ended!'}
+
-
-
{'Call Ended!'}
-
- {visitorName}
-
-
-
-
-
+ {visitorToken ? agentName : visitorName}
+
+
+
+
- )}
+
);
}
@@ -227,7 +152,8 @@ function MeetPage() {
visitorName={visitorName}
agentName={agentName}
layout={layout}
- >
+ callStartTime={callStartTime}
+ />
);
}
diff --git a/client/views/meet/OngoingCallDuration.tsx b/client/views/meet/OngoingCallDuration.tsx
new file mode 100644
index 0000000000000..e3a60a123a46c
--- /dev/null
+++ b/client/views/meet/OngoingCallDuration.tsx
@@ -0,0 +1,22 @@
+import { Box } from '@rocket.chat/fuselage';
+import React, { FC, useEffect, useState } from 'react';
+
+type OngoingCallDurationProps = {
+ counter: number;
+ fontSize: number;
+};
+
+const OngoingCallDuration: FC = ({ counter: defaultCounter = 0 }) => {
+ const [counter, setCounter] = useState(defaultCounter);
+ useEffect(() => {
+ setTimeout(() => setCounter(counter + 1), 1000);
+ }, [counter]);
+
+ return (
+
+ {new Date(counter * 1000).toISOString().substr(11, 8)}
+
+ );
+};
+
+export default OngoingCallDuration;
diff --git a/definition/IRoom.ts b/definition/IRoom.ts
index 6cccc2223e8bd..74110e2e43eb6 100644
--- a/definition/IRoom.ts
+++ b/definition/IRoom.ts
@@ -34,6 +34,7 @@ export interface IRoom extends IRocketChatRecord {
usersCount: number;
jitsiTimeout: Date;
callStatus?: CallStatus;
+ webRtcCallStartTime?: Date;
streamingOptions?: {
id?: string;
diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json
index 774c3945f14ed..4a0f2e01f4403 100644
--- a/packages/rocketchat-i18n/i18n/en.i18n.json
+++ b/packages/rocketchat-i18n/i18n/en.i18n.json
@@ -4579,4 +4579,4 @@
"Your_temporary_password_is_password": "Your temporary password is [password].",
"Your_TOTP_has_been_reset": "Your Two Factor TOTP has been reset.",
"Your_workspace_is_ready": "Your workspace is ready to use ๐"
-}
\ No newline at end of file
+}
From 4463dce0614fc05c3e3f75b3b6de328cc9c42227 Mon Sep 17 00:00:00 2001
From: Deepak Agarwal
Date: Wed, 25 Aug 2021 13:34:24 +0530
Subject: [PATCH 14/14] some css changes
---
client/views/meet/CallPage.css | 4 ++--
client/views/meet/CallPage.js | 2 +-
client/views/meet/MeetPage.js | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/client/views/meet/CallPage.css b/client/views/meet/CallPage.css
index b23a8b6b8203d..799fd59faec80 100644
--- a/client/views/meet/CallPage.css
+++ b/client/views/meet/CallPage.css
@@ -14,7 +14,7 @@
display: flex;
width: 15%;
- height: 15%;
+ height: 17.5%;
justify-content: center;
}
@@ -29,7 +29,7 @@
@media (max-width: 900px) and (max-height: 500px) {
.Self_Video {
width: 30%;
- height: 30%;
+ height: 35%;
}
}
diff --git a/client/views/meet/CallPage.js b/client/views/meet/CallPage.js
index 16fd8bf3348a4..ecc8ea8d85cf7 100644
--- a/client/views/meet/CallPage.js
+++ b/client/views/meet/CallPage.js
@@ -349,7 +349,7 @@ function CallPage({
{visitorName}
diff --git a/client/views/meet/MeetPage.js b/client/views/meet/MeetPage.js
index fb7ff04c9102b..6985889dd6348 100644
--- a/client/views/meet/MeetPage.js
+++ b/client/views/meet/MeetPage.js
@@ -120,7 +120,7 @@ function MeetPage() {
{visitorToken ? agentName : visitorName}