diff --git a/app/components/ReadyBox.js b/app/components/ReadyBox.js index c2e9f5d..00f18c5 100644 --- a/app/components/ReadyBox.js +++ b/app/components/ReadyBox.js @@ -1,599 +1,599 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import autoBind from 'auto-bind'; import { FlatList, View, Platform} from 'react-native'; import { IconButton, Title, Button } from 'react-native-paper'; import ConferenceModal from './ConferenceModal'; import ContactsListBox from './ContactsListBox'; import FooterBox from './FooterBox'; import URIInput from './URIInput'; import config from '../config'; import utils from '../utils'; import styles from '../assets/styles/blink/_ReadyBox.scss'; class ReadyBox extends Component { constructor(props) { super(props); autoBind(this); this.state = { targetUri: '', contacts: this.props.contacts, selectedContact: this.props.selectedContact, showConferenceModal: false, sticky: false, favoriteUris: this.props.favoriteUris, blockedUris: this.props.blockedUris, historyFilter: null, missedCalls: this.props.missedCalls, isLandscape: this.props.isLandscape, participants: null, myInvitedParties: this.props.myInvitedParties, messages: this.props.messages, myDisplayName: this.props.myDisplayName, chat: (this.props.selectedContact !== null) && (this.props.call !== null), call: this.props.call, inviteContacts: this.props.inviteContacts, selectedContacts: this.props.selectedContacts, pinned: this.props.pinned }; this.ended = false; } UNSAFE_componentWillReceiveProps(nextProps) { if (this.ended) { return; } if (this.state.selectedContact && nextProps.selectedContact === null) { this.setState({targetUri: '', chat: false}); } if (this.state.selectedContact !== nextProps.selectedContact && nextProps.selectedContact) { this.setState({chat: !this.chatDisabledForUri(nextProps.selectedContact.uri)}); } if (nextProps.missedCalls.length === 0 && this.state.historyFilter === 'missed') { this.setState({'historyFilter': null}); } if (nextProps.blockedUris.length === 0 && this.state.historyFilter === 'blocked') { this.setState({'historyFilter': null}); } if (nextProps.favoriteUris.length === 0 && this.state.historyFilter === 'favorite') { this.setState({'historyFilter': null}); } this.setState({myInvitedParties: nextProps.myInvitedParties, messages: nextProps.messages, myDisplayName: nextProps.myDisplayName, call: nextProps.call, contacts: nextProps.contacts, inviteContacts: nextProps.inviteContacts, selectedContacts: nextProps.selectedContacts, selectedContact: nextProps.selectedContact, pinned: nextProps.pinned, favoriteUris: nextProps.favoriteUris, blockedUris: nextProps.blockedUris, missedCalls: nextProps.missedCalls, isLandscape: nextProps.isLandscape}); } getTargetUri(uri) { return utils.normalizeUri(uri, this.props.defaultDomain); } async componentDidMount() { this.ended = false; } componentWillUnmount() { this.ended = true; } filterHistory(filter) { if (this.ended) { return; } this.setState({'historyFilter': filter}); this.handleTargetChange(''); } chatDisabledForUri(uri) { if (uri.indexOf('@videoconference') > -1) { return true; } if (uri.indexOf('@guest') > -1) { return true; } if (uri.indexOf('3333@') > -1) { return true; } return false; } get showSearchBar() { if (this.props.isTablet || this.props.isLandscape) { return true; } if (this.state.call) { return false; } return (this.state.selectedContact === null); } get showButtonsBar() { if (this.props.isTablet) { return true; } if (this.state.call) { return true; } if (this.state.chat && this.state.selectedContact) { return false; } return true; } handleTargetChange(value, contact) { //console.log('handleTargetChange', value, contact); if (this.state.inviteContacts && contact) { const uri = contact.uri; this.props.updateSelection(uri); return; } if (this.state.selectedContact === contact) { if (this.state.chat) { this.setState({chat: false}); } return; } else { this.setState({chat: false}); } let new_value = value; if (contact) { if (this.state.targetUri === contact.uri) { new_value = ''; } } else { contact = null; } if (this.state.targetUri === value) { new_value = ''; } if (new_value === '') { contact = null; } //new_value = new_value.replace(' ',''); this.props.selectContact(contact); this.setState({targetUri: new_value}); } handleTargetSelect() { if (this.props.connection === null) { this.props._notificationCenter.postSystemNotification("Server unreachable"); return; } let uri = this.state.targetUri.toLowerCase(); if (uri.endsWith(`@${config.defaultConferenceDomain}`)) { let participants; if (this.state.myInvitedParties && this.state.myInvitedParties.hasOwnProperty(uri)) { participants = this.state.myInvitedParties[uri]; } this.props.startConference(uri, {audio: true, video: true, participants: this.state.participants}); } else { this.props.startCall(this.getTargetUri(uri), {audio: true, video: true}); } } showConferenceModal(event) { event.preventDefault(); this.setState({showConferenceModal: true}); return; } handleChat(event) { event.preventDefault(); let targetUri; if (!this.state.chat && !this.state.selectedContact && this.state.targetUri.toLowerCase().indexOf('@') === -1) { targetUri = this.getTargetUri(this.state.targetUri); this.setState({targetUri: targetUri}); } let chat = !this.state.chat; let uri = this.state.targetUri.toLowerCase(); if (chat && !this.selectedContact && targetUri) { let contact = this.props.newContactFunc(targetUri, null, {src: 'new chat'}); this.handleTargetChange(targetUri, contact); } this.setState({chat: !this.state.chat}); } handleAudioCall(event) { event.preventDefault(); let uri = this.state.targetUri.toLowerCase(); var uri_parts = uri.split("/"); if (uri_parts.length === 5 && uri_parts[0] === 'https:') { // https://webrtc.sipthor.net/conference/DaffodilFlyChill0 from external web link // https://webrtc.sipthor.net/call/alice@example.com from external web link let event = uri_parts[3]; uri = uri_parts[4]; if (event === 'conference') { uri = uri.split("@")[0] + '@' + config.defaultConferenceDomain; } } if (uri.endsWith(`@${config.defaultConferenceDomain}`)) { this.props.startConference(uri, {audio: true, video: false}); } else { this.props.startCall(this.getTargetUri(uri), {audio: true, video: false}); } } handleVideoCall(event) { event.preventDefault(); let uri = this.state.targetUri.toLowerCase(); var uri_parts = uri.split("/"); if (uri_parts.length === 5 && uri_parts[0] === 'https:') { // https://webrtc.sipthor.net/conference/DaffodilFlyChill0 from external web link // https://webrtc.sipthor.net/call/alice@example.com from external web link let event = uri_parts[3]; uri = uri_parts[4]; if (event === 'conference') { uri = uri.split("@")[0] + '@' + config.defaultConferenceDomain; } } if (uri.endsWith(`@${config.defaultConferenceDomain}`)) { this.props.startConference(uri, {audio: true, video: true}); } else { this.props.startCall(this.getTargetUri(uri), {audio: true, video: true}); } } handleConferenceCall(targetUri, options={audio: true, video: true, participants: []}) { this.props.startConference(targetUri, {audio: options.audio, video: options.video, participants: options.participants}); this.setState({showConferenceModal: false}); } conferenceButtonActive() { if (this.state.targetUri.indexOf('@guest.') > -1) { return false; } if (this.state.targetUri.indexOf('@') > -1 && this.state.targetUri.indexOf(config.defaultConferenceDomain) === -1) { return false; } let uri = this.state.targetUri.toLowerCase(); var uri_parts = uri.split("/"); if (uri_parts.length === 5 && uri_parts[0] === 'https:') { // https://webrtc.sipthor.net/conference/DaffodilFlyChill0 from external web link // https://webrtc.sipthor.net/call/alice@example.com from external web link let event = uri_parts[3]; if (event === 'call') { return false; } } if (this.state.targetUri.match(/^(\+)(\d+)$/)) { return false; } return true; } get chatButtonDisabled() { let uri = this.state.targetUri.trim(); if (this.chatDisabledForUri(uri)) { return true; } return this.callButtonDisabled; } get callButtonDisabled() { let uri = this.state.targetUri.trim(); if (uri.indexOf(' ') > -1) { return true; } if (uri.length === 0 || uri.indexOf('@videoconference') > -1 || uri.indexOf('@guest') > -1 ) { return true; } return false; } renderNavigationItem(object) { if (!object.item.enabled) { return (null); } let title = object.item.title; let key = object.item.key; let buttonStyle = object.item.selected ? styles.navigationButtonSelected : styles.navigationButton; return (); } render() { let uriClass = styles.portraitUriInputBox; let uriGroupClass = styles.portraitUriButtonGroup; let titleClass = styles.portraitTitle; let uri = this.state.targetUri.toLowerCase(); var uri_parts = uri.split("/"); if (uri_parts.length === 5 && uri_parts[0] === 'https:') { // https://webrtc.sipthor.net/conference/DaffodilFlyChill0 from external web link // https://webrtc.sipthor.net/call/alice@example.com from external web link let event = uri_parts[3]; uri = uri_parts[4]; if (event === 'conference') { uri = uri.split("@")[0] + '@' + config.defaultConferenceDomain; } } //console.log('Render missed calls', this.state.missedCalls); const buttonClass = (Platform.OS === 'ios') ? styles.iosButton : styles.androidButton; if (this.props.isTablet) { titleClass = this.props.orientation === 'landscape' ? styles.landscapeTabletTitle : styles.portraitTabletTitle; } else { titleClass = this.props.orientation === 'landscape' ? styles.landscapeTitle : styles.portraitTitle; } if (this.props.isTablet) { uriGroupClass = this.props.orientation === 'landscape' ? styles.landscapeTabletUriButtonGroup : styles.portraitTabletUriButtonGroup; } else { uriGroupClass = this.props.orientation === 'landscape' ? styles.landscapeUriButtonGroup : styles.portraitUriButtonGroup; } if (this.props.isTablet) { uriClass = this.props.orientation === 'landscape' ? styles.landscapeTabletUriInputBox : styles.portraitTabletUriInputBox; } else { uriClass = this.props.orientation === 'landscape' ? styles.landscapeUriInputBox : styles.portraitUriInputBox; } const historyContainer = this.props.orientation === 'landscape' ? styles.historyLandscapeContainer : styles.historyPortraitContainer; const buttonGroupClass = this.props.orientation === 'landscape' ? styles.landscapeButtonGroup : styles.buttonGroup; const borderClass = this.state.chat ? null : styles.historyBorder; let callType = 'Back to call'; if (this.state.call && this.state.call.hasOwnProperty('_participants')) { callType = this.state.selectedContacts.length > 0 ? 'Invite people' : 'Back to conference'; } let navigationMenuData = [ {key: null, title: 'All', enabled: true, selected: false}, {key: 'history', title: 'Calls', enabled: true, selected: this.state.historyFilter === 'history'}, {key: 'chat', title: 'Chat', enabled: true, selected: this.state.historyFilter === 'chat'}, {key: 'missed', title: 'Missed', enabled: this.state.missedCalls.length > 0, selected: this.state.historyFilter === 'missed'}, {key: 'favorite', title: 'Favorites', enabled: this.state.favoriteUris.length > 0, selected: this.state.historyFilter === 'favorite'}, {key: 'blocked', title: 'Blocked', enabled: this.state.blockedUris.length > 0, selected: this.state.historyFilter === 'blocked'}, - {key: 'conference', title: 'Conference', enabled: true, selected: this.state.historyFilter === 'conference'}, + {key: 'conference', title: 'Conference', enabled: Object.keys(this.state.myInvitedParties).length >0 , selected: this.state.historyFilter === 'conference'}, {key: 'test', title: 'Test', enabled: true, selected: this.state.historyFilter === 'test'}, ]; return ( {this.showButtonsBar ? {this.showSearchBar ? : null} {( this.state.call && this.state.call.state == 'established') ? : } : null} { !this.state.selectedContact ? item.key} renderItem={this.renderNavigationItem} /> : null} {this.props.isTablet && 0? : null} ); } } ReadyBox.propTypes = { account : PropTypes.object, password : PropTypes.string.isRequired, config : PropTypes.object.isRequired, startCall : PropTypes.func.isRequired, startConference : PropTypes.func.isRequired, contacts : PropTypes.array, orientation : PropTypes.string, isTablet : PropTypes.bool, isLandscape : PropTypes.bool, refreshHistory : PropTypes.bool, refreshFavorites: PropTypes.bool, saveHistory : PropTypes.func, localHistory : PropTypes.array, myDisplayName : PropTypes.string, myPhoneNumber : PropTypes.string, toggleFavorite : PropTypes.func, myInvitedParties: PropTypes.object, toggleBlocked : PropTypes.func, favoriteUris : PropTypes.array, blockedUris : PropTypes.array, defaultDomain : PropTypes.string, saveContact : PropTypes.func, selectContact : PropTypes.func, lookupContacts : PropTypes.func, call : PropTypes.object, goBackFunc : PropTypes.func, messages : PropTypes.object, sendMessage : PropTypes.func, reSendMessage : PropTypes.func, confirmRead : PropTypes.func, deleteMessage : PropTypes.func, expireMessage : PropTypes.func, getMessages : PropTypes.func, deleteMessages : PropTypes.func, pinMessage : PropTypes.func, unpinMessage : PropTypes.func, sendPublicKey : PropTypes.func, inviteContacts : PropTypes.bool, selectedContacts: PropTypes.array, updateSelection : PropTypes.func, loadEarlierMessages: PropTypes.func, newContactFunc : PropTypes.func, missedCalls : PropTypes.array }; export default ReadyBox;