This repository has been archived by the owner on Jun 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 230
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NEW] Audio and Video calling in Livechat using WebRTC #646
* add callnotification,msg,iframe code * fix eslint issues * fix eslint file path issues * fix stylelint issues * done ui changes * add icons and improve ui * fix error * remove-icons * add icons * add i18n.t, change classname, improve ui * remove font-family * change iframe link * add check for jitsi * add jitsi link * add time message in system message and add catch * display alert, change function name * Improve overall codebase * Convert tabs to spaces for translation file * Accept jitsi url info from the message and remove dependency from Livechat.videoCall endpoint * Update index.js * add message in i18n file Co-authored-by: Murtaza Patrawala <34130764+murtaza98@users.noreply.github.com> add joinCallBtn, endCall message, callRing functionalities. (#618) * add callnotification,msg,iframe code * fix eslint issues * fix eslint file path issues * fix stylelint issues * done ui changes * add join call button * add icons and improve ui * fix error * remove-icons * add icons * ui changes * add icon and timeout functionality * add I18n.t * add i18n.t, change classname, improve ui * remove font-family * change iframe link * add check for jitsi * add jitsi link * add time message in system message and add catch * display alert, change function name * Improve overall codebase * Convert tabs to spaces for translation file * Accept jitsi url info from the message and remove dependency from Livechat.videoCall endpoint * Update index.js * add message in i18n file * add joincall btn, call time, timeout * fix lint error * Update ShowJoinCallButton.js * fix conflicts * improve codebase * fix bugs * update some files * improve css, codebase and change condition * add correct link for iframe and joinCallBtn, show correct time * update call status at rc-core * update api file * rebase file * change link, use store class * update callIframe file * handle corner cases * remove file * Update room.js file Co-authored-by: Murtaza Patrawala <34130764+murtaza98@users.noreply.github.com> * update one file * revert roomjs file * add common condition in room.js file Co-authored-by: Murtaza Patrawala <34130764+murtaza98@users.noreply.github.com> [NEW] Handle endCall and expandView control buttons (#633) * [NEW] Handle endCall and expandView control buttons * [FIX] Lint errors * [FIX] Join Call Button giving call ended even when call inProgress * [FIX] slash omitted in the url * [REF] Remove redundant async keyword * [REF] Use spread operator, set ongoingCall status when expanding * [FIX] String enclosed within double quotes Co-authored-by: Murtaza Patrawala <34130764+murtaza98@users.noreply.github.com> * [FIX] ongoingCall variable not destructured but used Co-authored-by: Murtaza Patrawala <34130764+murtaza98@users.noreply.github.com> [FIX] Notify agent on call decline (#634) [NEW] WebRTC-call in new tab for mobile devices (#629) * open webrtc call in new tab for mobile devices * improve codebase * add helper function * update one file * checking call status from room object * update one file * handle refresh case * change message filter condition Co-authored-by: Murtaza Patrawala <34130764+murtaza98@users.noreply.github.com> [NEW] add-jitsi-call-support Co-Authored-By: Deepak Agarwal <56799414+Deepak-learner@users.noreply.github.com> Improve overall codebase - Define an enum like structure for call statuses - Fix formatting and spelling issues - General refactoring update Rocket.Chat.js.SDK version to 1.0.0-alpha.42 Fix Join call button layout Fix typo Apply review suggestions - Use date-fns library to calculate call duration Refactor Call Statuses to remove redundancy Rename endTs property on Message to webRtcCallEndTs
- Loading branch information
1 parent
cb24408
commit f65ac0a
Showing
26 changed files
with
519 additions
and
17 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { h } from 'preact'; | ||
|
||
import { Livechat } from '../../api'; | ||
import store from '../../store'; | ||
import { createClassName } from '../helpers'; | ||
import { CallStatus } from './CallStatus'; | ||
import styles from './styles.scss'; | ||
|
||
|
||
export const CallIframe = () => { | ||
const { token, room, incomingCallAlert, ongoingCall } = store.state; | ||
const url = `${ Livechat.client.host }/meet/${ room._id }?token=${ token }&layout=embedded`; | ||
window.handleIframeClose = () => store.setState({ incomingCallAlert: { ...incomingCallAlert, show: false } }); | ||
window.expandCall = () => { | ||
window.open( | ||
`${ Livechat.client.host }/meet/${ room._id }?token=${ token }`, | ||
room._id, | ||
); | ||
return store.setState({ | ||
incomingCallAlert: { ...incomingCallAlert, show: false }, | ||
ongoingCall: { | ||
...ongoingCall, | ||
callStatus: CallStatus.IN_PROGRESS_DIFFERENT_TAB, | ||
}, | ||
}); | ||
}; | ||
return ( | ||
<div className={createClassName(styles, 'call-iframe')}> | ||
<iframe className={createClassName(styles, 'call-iframe__content')} allow='camera;microphone' src={url} /> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { h } from 'preact'; | ||
import { useState } from 'preact/compat'; | ||
|
||
import { Livechat } from '../../api'; | ||
import I18n from '../../i18n'; | ||
import PhoneAccept from '../../icons/phone.svg'; | ||
import PhoneDecline from '../../icons/phoneOff.svg'; | ||
import constants from '../../lib/constants'; | ||
import store from '../../store'; | ||
import { Avatar } from '../Avatar'; | ||
import { Button } from '../Button'; | ||
import { createClassName, getAvatarUrl, isMobileDevice } from '../helpers'; | ||
import { CallStatus } from './CallStatus'; | ||
import styles from './styles.scss'; | ||
|
||
|
||
export const CallNotification = ({ | ||
callProvider, | ||
callerUsername, | ||
url, | ||
dispatch, | ||
time, | ||
rid, | ||
callId, | ||
}) => { | ||
const [show, setShow] = useState(true); | ||
|
||
const callInNewTab = async () => { | ||
const { token } = store.state; | ||
const url = `${ Livechat.client.host }/meet/${ rid }?token=${ token }`; | ||
await dispatch({ | ||
ongoingCall: { | ||
callStatus: CallStatus.IN_PROGRESS_DIFFERENT_TAB, | ||
time: { time }, | ||
}, | ||
incomingCallAlert: { | ||
show: false, | ||
callProvider, | ||
}, | ||
}); | ||
window.open(url, rid); | ||
}; | ||
|
||
const acceptClick = async () => { | ||
setShow(!{ show }); | ||
switch (callProvider) { | ||
case constants.jitsiCallStartedMessageType: { | ||
window.open(url, rid); | ||
await dispatch({ | ||
incomingCallAlert: { show: false, url, callProvider }, | ||
ongoingCall: { | ||
callStatus: CallStatus.IN_PROGRESS_DIFFERENT_TAB, | ||
time: { time }, | ||
}, | ||
}); | ||
break; | ||
} | ||
case constants.webRTCCallStartedMessageType: { | ||
await Livechat.updateCallStatus(CallStatus.IN_PROGRESS, rid, callId); | ||
if (isMobileDevice()) { | ||
callInNewTab(); | ||
break; | ||
} | ||
await dispatch({ ongoingCall: { callStatus: CallStatus.IN_PROGRESS_SAME_TAB, time: { time } } }); | ||
break; | ||
} | ||
} | ||
}; | ||
|
||
const declineClick = async () => { | ||
await Livechat.updateCallStatus(CallStatus.DECLINED, rid, callId); | ||
await Livechat.notifyCallDeclined(rid); | ||
await dispatch({ | ||
incomingCallAlert: null, | ||
ongoingCall: { | ||
callStatus: CallStatus.DECLINED, | ||
time: { time }, | ||
}, | ||
}); | ||
}; | ||
|
||
return ( | ||
<div className={createClassName(styles, 'call-notification')}> | ||
{ | ||
show && ( | ||
<div className = { createClassName(styles, 'call-notification__content') }> | ||
<div className = { createClassName(styles, 'call-notification__content-avatar') }> | ||
<Avatar src = { getAvatarUrl(callerUsername) } large /> | ||
</div> | ||
<div className = { createClassName(styles, 'call-notification__content-message') }> | ||
{ I18n.t('Incoming video Call') } | ||
</div> | ||
<div className = { createClassName(styles, 'call-notification__content-actions') }> | ||
<Button | ||
onClick = { declineClick } | ||
className = { createClassName(styles, 'call-notification__content-actions-decline') }> | ||
<PhoneDecline width = { 20 } height = { 20 } /> | ||
<span style='margin-left:5px'> {I18n.t('Decline')} </span > | ||
</Button> | ||
<Button onClick = { acceptClick } | ||
className = {createClassName(styles, 'call-notification__content-actions-accept') }> | ||
<PhoneAccept width = { 20 } height = { 20} /> | ||
<span style='margin-left:5px'> {I18n.t('Accept')} </span > | ||
</Button> | ||
</div> | ||
</div> | ||
) | ||
} | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
export const CallStatus = { | ||
RINGING: 'ringing', | ||
DECLINED: 'declined', | ||
IN_PROGRESS: 'inProgress', // although on Livechat we only use "IN_PROGRESS_SAME_TAB" and "IN_PROGRESS_DIFFERENT_TAB", we still need this status since on Rocket.Chat core, this is the status of ongoing calls | ||
IN_PROGRESS_SAME_TAB: 'inProgressSameTab', | ||
IN_PROGRESS_DIFFERENT_TAB: 'inProgressDifferentTab', | ||
ENDED: 'ended', | ||
}; | ||
|
||
export const isCallOngoing = (callStatus) => callStatus === CallStatus.IN_PROGRESS | ||
|| callStatus === CallStatus.IN_PROGRESS_DIFFERENT_TAB | ||
|| callStatus === CallStatus.IN_PROGRESS_SAME_TAB; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { h } from 'preact'; | ||
|
||
import { Livechat } from '../../api'; | ||
import I18n from '../../i18n'; | ||
import VideoIcon from '../../icons/video.svg'; | ||
import constants from '../../lib/constants'; | ||
import store from '../../store'; | ||
import { Button } from '../Button'; | ||
import { createClassName } from '../helpers'; | ||
import { isCallOngoing } from './CallStatus'; | ||
import styles from './styles.scss'; | ||
|
||
|
||
export const JoinCallButton = (props) => { | ||
const { token, room } = store.state; | ||
|
||
const clickJoinCall = () => { | ||
switch (props.callProvider) { | ||
case constants.jitsiCallStartedMessageType: { | ||
window.open(props.url, room._id); | ||
break; | ||
} | ||
case constants.webRTCCallStartedMessageType: { | ||
window.open(`${ Livechat.client.host }/meet/${ room._id }?token=${ token }`, room._id); | ||
break; | ||
} | ||
} | ||
}; | ||
return ( | ||
<div className={createClassName(styles, 'joinCall')}> | ||
{ | ||
isCallOngoing(props.callStatus) | ||
&& ( | ||
<div> | ||
<div className={createClassName(styles, 'joinCall__content')} > | ||
<div className={createClassName(styles, 'joinCall__content-videoIcon')} > | ||
<VideoIcon width={20} height={20} /> | ||
</div> | ||
{ I18n.t('Join my room to start the video call') } | ||
</div> | ||
<Button onClick={clickJoinCall} className={createClassName(styles, 'joinCall__content-action')}> | ||
<VideoIcon width={20} height={20} /> | ||
{I18n.t('Join Call')} | ||
</Button> | ||
</div> | ||
) | ||
} | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
@import '../../styles/colors'; | ||
@import '../../styles/variables'; | ||
|
||
.call-notification { | ||
position: relative; | ||
|
||
display: flex; | ||
|
||
width: 100%; | ||
height: 50%; | ||
|
||
&__content { | ||
display: flex; | ||
flex-direction: column; | ||
|
||
width: 100%; | ||
height: 100%; | ||
|
||
background: #1f2329; | ||
|
||
font-weight: 600; | ||
justify-content: space-evenly; | ||
|
||
&-avatar { | ||
display: flex; | ||
|
||
margin: 0 auto; | ||
align-self: flex-end; | ||
} | ||
|
||
&-message { | ||
margin: 0 auto; | ||
|
||
color: #ffffff; | ||
} | ||
|
||
&-actions { | ||
display: flex; | ||
flex-direction: row; | ||
|
||
margin: 0 auto; | ||
margin-bottom: 15px; | ||
|
||
color: white; | ||
|
||
align-items: flex-end; | ||
|
||
> button { | ||
margin-bottom: 0; | ||
margin-left: 10px; | ||
} | ||
|
||
&-accept { | ||
border-color: green; | ||
background-color: #2de0a5; | ||
} | ||
|
||
&-decline { | ||
border-color: red; | ||
background-color: #f5455c; | ||
} | ||
} | ||
} | ||
} | ||
|
||
.call-iframe { | ||
position: absolute; | ||
top: 0; | ||
|
||
width: 100%; | ||
height: 41%; | ||
|
||
&__content { | ||
width: 100%; | ||
height: 100%; | ||
} | ||
} | ||
|
||
.joinCall { | ||
width: 300px; | ||
margin: 15px; | ||
|
||
padding: 5px; | ||
|
||
border: 1px solid #e4e7ea; | ||
|
||
&__content { | ||
display: flex; | ||
flex-direction: row; | ||
|
||
padding: 15px; | ||
|
||
line-height: 16px; | ||
justify-content: space-around; | ||
|
||
&-videoIcon { | ||
display: flex; | ||
|
||
height: 7%; | ||
margin-right: 10px; | ||
|
||
padding: 5px; | ||
|
||
border: 1px solid white; | ||
background-color: #d1ebfe; | ||
} | ||
|
||
&-action { | ||
display: block; | ||
|
||
width: 120px; | ||
margin-top: 0; | ||
margin-bottom: 3%; | ||
margin-left: 20%; | ||
padding: 5px; | ||
|
||
color: white; | ||
border: 1px solid blue; | ||
background-color: #1d74f5; | ||
} | ||
} | ||
} | ||
|
||
@media screen and (min-width: 410px) { | ||
.joinCall { | ||
margin-left: 3%; | ||
} | ||
} |
Oops, something went wrong.