diff --git a/app/assets/styles/blink/_ConferenceModal.scss b/app/assets/styles/blink/_ConferenceModal.scss index c724639..f3cff03 100644 --- a/app/assets/styles/blink/_ConferenceModal.scss +++ b/app/assets/styles/blink/_ConferenceModal.scss @@ -1,30 +1,37 @@ .container { padding: 5px; - margin: 10px; + margin: 0px; flex-direction: column; justify-content: center; align-items: center; } .title { - padding: 5px; + padding: 3px; font-size: 24px; text-align: center; } -.body { - padding: 10px; +.room { + padding: 5px; font-size: 18px; width: 100%; } -.button { - margin: 10px; - width: 130; +.participants { + padding: 5px; + font-size: 14px; + text-align: center; + width: 100%; } .buttonRow { flex-direction: row; - justify-content: center; } +.button { + margin: 10px; + width: 130; +} + + diff --git a/app/assets/styles/blink/_InviteParticipantsModal.scss b/app/assets/styles/blink/_InviteParticipantsModal.scss index 748305f..e2473fd 100644 --- a/app/assets/styles/blink/_InviteParticipantsModal.scss +++ b/app/assets/styles/blink/_InviteParticipantsModal.scss @@ -1,37 +1,41 @@ .container { padding: 15px; margin: 00px; } .title { - padding: 5px; + padding: 3px; font-size: 24px; text-align: center; } -.body { - padding: 10px; - font-size: 18px; +.shareText { + padding: 3px; + font-size: 16px; text-align: center; } -.button { - margin: 10px; - width: 120; +.participants { + padding: 0px; + font-size: 14px; + text-align: center; + width: 100%; } -.participantButton { +.button { margin: 10px; - width: 190; + width: 120; } .buttonRow { flex-direction: row; justify-content: center; + padding-bottom: 10px; } .iconContainer { + padding-top: 5px; flex-direction: row; justify-content: center; } diff --git a/app/components/ConferenceModal.js b/app/components/ConferenceModal.js index fa1fc7f..f1349ed 100644 --- a/app/components/ConferenceModal.js +++ b/app/components/ConferenceModal.js @@ -1,195 +1,197 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { View } from 'react-native'; import { Portal, Dialog, Button, Text, TextInput, Surface, Chip } from 'react-native-paper'; import KeyboardAwareDialog from './KeyBoardAwareDialog'; const DialogType = Platform.OS === 'ios' ? KeyboardAwareDialog : Dialog; import config from '../config'; import styles from '../assets/styles/blink/_ConferenceModal.scss'; class ConferenceModal extends Component { constructor(props) { super(props); this.state = { targetUri: props.targetUri ? props.targetUri.split('@')[0] : '', myInvitedParties: props.myInvitedParties, selectedContact: props.selectedContact, participants: null }; this.handleConferenceTargetChange = this.handleConferenceTargetChange.bind(this); this.onHide = this.onHide.bind(this); this.joinAudio = this.joinAudio.bind(this); this.joinVideo = this.joinVideo.bind(this); } componentDidMount() { this.handleConferenceTargetChange(this.state.targetUri); } //getDerivedStateFromProps(nextProps, state) { UNSAFE_componentWillReceiveProps(nextProps) { let uri = ''; if (nextProps.targetUri) { uri = nextProps.targetUri.split('@')[0]; } this.setState({targetUri: uri, myInvitedParties: nextProps.myInvitedParties, selectedContact: nextProps.selectedContact, participants: nextProps.participants }); this.handleConferenceTargetChange(uri); } handleConferenceTargetChange(value) { let targetUri = value; let participants = []; let sanitizedParticipants = []; let username; let domain; if (targetUri) { let uri = `${targetUri.replace(/[\s()-]/g, '')}@${config.defaultConferenceDomain}`; uri = uri.split('@')[0]; if (this.state.myInvitedParties && this.state.myInvitedParties.hasOwnProperty(uri)) { participants = this.state.myInvitedParties[uri]; } else if (this.state.selectedContact && this.state.selectedContact.participants) { participants = this.state.selectedContact.participants; } participants.forEach((item) => { item = item.trim().toLowerCase(); if (item === this.props.accountId) { return; } if (item.indexOf('@') === -1) { sanitizedParticipants.push(item); } else { const domain = item.split('@')[1]; if (domain === this.props.defaultDomain) { sanitizedParticipants.push(item.split('@')[0]); } else { sanitizedParticipants.push(item); } } }); } if (targetUri) { this.setState({targetUri: targetUri}); } this.setState({participants: sanitizedParticipants.toString().replace(/,/g, ", ")}); } joinAudio(event) { event.preventDefault(); const uri = `${this.state.targetUri.replace(/[\s()-]/g, '')}@${config.defaultConferenceDomain}`; const participants = []; if (this.state.participants) { this.state.participants.split(',').forEach((item) => { item = item.trim().toLowerCase().replace(' ', ''); if (item.indexOf('@') === -1) { item = `${item}@${this.props.defaultDomain}`; } participants.push(item); }); } this.props.handleConferenceCall(uri.toLowerCase(), {audio: true, video: false, participants: participants}); } joinVideo(event) { event.preventDefault(); const uri = `${this.state.targetUri.replace(/[\s()-]/g, '')}@${config.defaultConferenceDomain}`; const participants = []; if (this.state.participants) { this.state.participants.split(',').forEach((item) => { item = item.trim().toLowerCase().replace(' ', ''); if (item.indexOf('@') === -1) { item = `${item}@${this.props.defaultDomain}`; } participants.push(item); }); } this.props.handleConferenceCall(uri.toLowerCase(), {audio: true, video: true, participants: participants}); } onHide() { this.props.handleConferenceCall(null); } render() { const validUri = this.state.targetUri.length > 0 && this.state.targetUri.indexOf('@') === -1; return ( Join Conference {this.handleConferenceTargetChange(text);}} name="uri" required defaultValue={this.state.targetUri} /> {this.setState({participants: value});}} value={this.state.participants} placeholder="Enter accounts separated by ," + clearButtonMode="always" /> ); } } ConferenceModal.propTypes = { show: PropTypes.bool.isRequired, handleConferenceCall: PropTypes.func.isRequired, myInvitedParties: PropTypes.object, accountId: PropTypes.string, selectedContact: PropTypes.object, targetUri: PropTypes.string.isRequired, defaultDomain: PropTypes.string }; export default ConferenceModal; diff --git a/app/components/InviteParticipantsModal.js b/app/components/InviteParticipantsModal.js index 9ca93f4..95200e6 100644 --- a/app/components/InviteParticipantsModal.js +++ b/app/components/InviteParticipantsModal.js @@ -1,197 +1,198 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import autoBind from 'auto-bind'; import { View } from 'react-native'; import { Dialog, Portal, Text, Button, Surface, TextInput, IconButton} from 'react-native-paper'; import KeyboardAwareDialog from './KeyBoardAwareDialog'; import { openComposer } from 'react-native-email-link'; import Share from 'react-native-share'; const DialogType = Platform.OS === 'ios' ? KeyboardAwareDialog : Dialog; import config from '../config'; import styles from '../assets/styles/blink/_InviteParticipantsModal.scss'; import utils from '../utils'; class InviteParticipantsModal extends Component { constructor(props) { super(props); autoBind(this); const sanitizedParticipants = []; let participants = []; if (this.props.previousParticipants && this.props.currentParticipants && this.props.alreadyInvitedParticipants) { participants = this.props.previousParticipants.filter(x => !this.props.currentParticipants.includes(x)); participants = participants.filter(x => !this.props.alreadyInvitedParticipants.includes(x) && x !== this.props.accountId); } participants.forEach((item) => { item = item.trim().toLowerCase(); if (item.indexOf('@') === -1) { sanitizedParticipants.push(item); } else { const domain = item.split('@')[1]; if (domain === this.props.defaultDomain) { sanitizedParticipants.push(item.split('@')[0]); } else { sanitizedParticipants.push(item); } } }); this.state = { participants: sanitizedParticipants.toString().replace(/,/g, ", "), previousParticipants: this.props.previousParticipants, currentParticipants: this.props.currentParticipants, roomUrl: config.publicUrl + '/conference/' + this.props.room } } UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.hasOwnProperty('muted')) { this.setState({audioMuted: nextProps.muted}); } let difference = nextProps.previousParticipants.filter(x => !nextProps.currentParticipants.includes(x)); difference = difference.filter(x => !nextProps.alreadyInvitedParticipants.includes(x) && x !== this.props.accountId); this.setState({ participants: difference.toString(), alreadyInvitedParticipants: nextProps.alreadyInvitedParticipants, previousParticipants: nextProps.previousParticipants, currentParticipants: nextProps.currentParticipants }); } handleClipboardButton(event) { utils.copyToClipboard(this.state.roomUrl); this.props.notificationCenter().postSystemNotification('Join conference', {body: 'Conference address copied to clipboard'}); this.props.close(); } handleEmailButton(event) { const emailMessage = 'You can join the conference using a Web browser at ' + this.state.roomUrl + ' or by using Sylk client app from https://sylkserver.com'; const subject = 'Join conference, maybe?'; openComposer({ subject, body: emailMessage }) this.props.close(); } handleShareButton(event) { const subject = 'Join conference, maybe?'; const message = 'You can join the conference using a Web browser at ' + this.state.roomUrl + ' or by using Sylk client app from https://sylkserver.com'; let options= { subject: subject, message: message } Share.open(options) .then((res) => { this.props.close(); }) .catch((err) => { this.props.close(); }); } invite(event) { event.preventDefault(); const uris = []; if (this.state.participants) { this.state.participants.split(',').forEach((item) => { item = item.trim(); if (item.indexOf('@') === -1) { item = `${item}@${this.props.defaultDomain}`; } uris.push(item); }); } if (uris) { this.props.inviteParticipants(uris); this.setState({participants: null}); } this.props.close(); } onInputChange(value) { this.setState({participants: value}); } render() { return ( Invite to conference - - + Or share the conference link: ); } } InviteParticipantsModal.propTypes = { notificationCenter : PropTypes.func.isRequired, show: PropTypes.bool.isRequired, close: PropTypes.func.isRequired, inviteParticipants: PropTypes.func, currentParticipants: PropTypes.array, previousParticipants: PropTypes.array, alreadyInvitedParticipants: PropTypes.array, room: PropTypes.string, defaultDomain: PropTypes.string, accountId: PropTypes.string }; export default InviteParticipantsModal;