// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import Client from 'client/web_client.jsx'; import WebSocketClient from 'client/web_websocket_client.jsx'; import UserStore from 'stores/user_store.jsx'; import WebrtcStore from 'stores/webrtc_store.jsx'; import * as GlobalActions from 'actions/global_actions.jsx'; import * as WebrtcActions from 'actions/webrtc_actions.jsx'; import * as Utils from 'utils/utils.jsx'; import {Constants, WebrtcActionTypes} from 'utils/constants.jsx'; import React from 'react'; import {FormattedMessage} from 'react-intl'; import ring from 'images/ring.mp3'; const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES; export default class WebrtcNotification extends React.Component { constructor() { super(); this.mounted = false; this.closeNotification = this.closeNotification.bind(this); this.onIncomingCall = this.onIncomingCall.bind(this); this.onCancelCall = this.onCancelCall.bind(this); this.onRhs = this.onRhs.bind(this); this.handleClose = this.handleClose.bind(this); this.handleAnswer = this.handleAnswer.bind(this); this.handleTimeout = this.handleTimeout.bind(this); this.stopRinging = this.stopRinging.bind(this); this.closeRightHandSide = this.closeRightHandSide.bind(this); this.state = { userCalling: null, rhsOpened: false }; } componentDidMount() { WebrtcStore.addNotifyListener(this.onIncomingCall); WebrtcStore.addChangedListener(this.onCancelCall); WebrtcStore.addRhsChangedListener(this.onRhs); this.mounted = true; } componentWillUnmount() { WebrtcStore.removeNotifyListener(this.onIncomingCall); WebrtcStore.removeChangedListener(this.onCancelCall); WebrtcStore.removeRhsChangedListener(this.onRhs); if (this.refs.ring) { this.refs.ring.removeListener('ended', this.handleTimeout); } this.mounted = false; } componentDidUpdate() { if (this.state.userCalling) { this.refs.ring.addEventListener('ended', this.handleTimeout); } } closeNotification() { this.setState({ userCalling: null }); } stopRinging() { if (this.refs.ring) { this.refs.ring.pause(); this.refs.ring.currentTime = 0; } this.setState({userCalling: null}); } closeRightHandSide(e) { e.preventDefault(); GlobalActions.emitCloseRightHandSide(); } onIncomingCall(incoming) { if (this.mounted) { const userId = incoming.from_user_id; const userMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; const featureEnabled = Utils.isFeatureEnabled(PreReleaseFeatures.WEBRTC_PREVIEW); if (featureEnabled) { if (WebrtcStore.isBusy()) { WebSocketClient.sendMessage('webrtc', { action: WebrtcActionTypes.BUSY, from_user_id: UserStore.getCurrentId(), to_user_id: userId }); this.stopRinging(); } else if (userMedia) { WebrtcStore.setVideoCallWith(userId); this.setState({ userCalling: UserStore.getProfile(userId) }); } else { WebSocketClient.sendMessage('webrtc', { action: WebrtcActionTypes.UNSUPPORTED, from_user_id: UserStore.getCurrentId(), to_user_id: userId }); this.stopRinging(); } } else { WebSocketClient.sendMessage('webrtc', { action: WebrtcActionTypes.DISABLED, from_user_id: UserStore.getCurrentId(), to_user_id: userId }); this.stopRinging(); } } } onCancelCall(message) { if (message && message.action !== WebrtcActionTypes.CANCEL) { return; } else if (message && message.action === WebrtcActionTypes.CANCEL && this.state.userCalling && message.from_user_id !== this.state.userCalling.id) { return; } WebrtcStore.setVideoCallWith(null); this.closeNotification(); } onRhs(rhsOpened) { this.setState({rhsOpened}); } handleTimeout() { WebSocketClient.sendMessage('webrtc', { action: WebrtcActionTypes.NO_ANSWER, from_user_id: UserStore.getCurrentId(), to_user_id: this.state.userCalling.id }); this.onCancelCall(); } handleAnswer(e) { if (e) { e.preventDefault(); } const caller = this.state.userCalling; if (caller) { const callerId = caller.id; const currentUserId = UserStore.getCurrentId(); const message = { action: WebrtcActionTypes.ANSWER, from_user_id: currentUserId, to_user_id: callerId }; GlobalActions.emitCloseRightHandSide(); WebrtcActions.initWebrtc(callerId, false); WebSocketClient.sendMessage('webrtc', message); // delay till next tick (this will give time to listen for events setTimeout(() => { //we switch from and to user to handle the event locally message.from_user_id = callerId; message.to_user_id = currentUserId; WebrtcActions.handle(message); }, 0); this.closeNotification(); } } handleClose(e) { if (e) { e.preventDefault(); } if (this.state.userCalling) { WebSocketClient.sendMessage('webrtc', { action: WebrtcActionTypes.DECLINE, from_user_id: UserStore.getCurrentId(), to_user_id: this.state.userCalling.id }); } this.onCancelCall(); } render() { const user = this.state.userCalling; if (user) { const username = Utils.displayUsername(user.id); const profileImgSrc = Client.getUsersRoute() + '/' + user.id + '/image?time=' + (user.last_picture_update || new Date().getTime()); const profileImg = ( ); const answerBtn = ( ); const rejectBtn = ( ); const msg = (
{answerBtn} {rejectBtn}
); return (
); } else if (this.state.rhsOpened && WebrtcStore.isBusy()) { return (
); } return
; } }