// IncomingCall: displays Accept & Reject buttons for incoming calls. import React from 'react'; import BadgeList from './badge-list.jsx'; import LetterTile from './letter-tile.jsx'; import { MAX_TITLE_LENGTH, MAX_PEER_TITLE_LENGTH } from '../config.js'; import { CALL_STATE_INCOMING_RECEIVED } from '../constants.js'; import { makeImageUrl } from '../lib/blob-helpers.js'; import { clipStr } from '../lib/utils.js' const RING_SOUND = new Audio('audio/call-in.m4a'); export default class CallIncoming extends React.Component { constructor(props) { super(props); this.state = { topic: null, fullName: undefined, avatar: null, trustedBadges: [], previousMetaDesc: undefined, }; this.resetDesc = this.resetDesc.bind(this); this.onMetaDesc = this.onMetaDesc.bind(this); this.handleRejectCall = this.handleRejectCall.bind(this); this.handleAcceptCall = this.handleAcceptCall.bind(this); this.ringTimer = null; } componentDidMount() { const topic = this.props.tinode.getTopic(this.props.topic); if (!topic) { return; } this.resetDesc(topic, this.props); if (this.props.callState == CALL_STATE_INCOMING_RECEIVED) { RING_SOUND.play(); this.ringTimer = setInterval(() => RING_SOUND.play(), 2000); this.props.onRinging(this.props.topic, this.props.seq); } } // No need to separately handle component mount. componentDidUpdate(props) { const topic = this.props.tinode.getTopic(props.topic); if (!topic) { return; } if (this.onMetaDesc != topic.onMetaDesc) { this.previousMetaDesc = topic.onMetaDesc; topic.onMetaDesc = this.onMetaDesc; } if (this.state.topic != props.topic) { this.setState({topic: props.topic}); this.resetDesc(topic, props); } } componentWillUnmount() { if (this.ringTimer != null) { clearInterval(this.ringTimer); RING_SOUND.pause(); } const topic = this.props.tinode.getTopic(this.props.topic); if (!topic) { return; } this.setState({topic: null}); topic.onMetaDesc = this.previousMetaDesc; } resetDesc(topic, props) { const defacs = topic.getDefaultAccess() || {}; const acs = topic.getAccessMode(); const badges = []; if (topic.trusted) { for (const [key, val] of Object.entries(topic.trusted)) { if (val) { badges.push(key); } } } this.setState({ fullName: clipStr(topic.public ? topic.public.fn : undefined, MAX_TITLE_LENGTH), avatar: makeImageUrl(topic.public ? topic.public.photo : null), trustedBadges: badges, }); } onMetaDesc(desc) { const topic = this.props.tinode.getTopic(this.props.topic); if (!topic) { return; } this.resetDesc(topic, this.props); if (this.previousMetaDesc && this.previousMetaDesc != this.onMetaDesc) { this.previousMetaDesc(desc); } } handleAcceptCall() { this.props.onAcceptCall(this.props.topic); } handleRejectCall() { this.props.onReject(this.props.topic, this.props.seq); this.props.onClose(); } render() { return (