diff --git a/app/components/ReadyBox.js b/app/components/ReadyBox.js
index 087f77e..c2db98b 100644
--- a/app/components/ReadyBox.js
+++ b/app/components/ReadyBox.js
@@ -1,1553 +1,1553 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import autoBind from 'auto-bind';
import { FlatList, View, Platform, TouchableHighlight, TouchableOpacity} from 'react-native';
import { IconButton, Title, Button, Colors, Text, ActivityIndicator } 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';
import {Keyboard} from 'react-native';
import QRCodeScanner from 'react-native-qrcode-scanner';
import { RNCamera } from 'react-native-camera';
import AudioRecord from 'react-native-audio-record';
import uuid from 'react-native-uuid';
import RNFetchBlob from "rn-fetch-blob";
import fileType from 'react-native-file-type';
class ReadyBox extends Component {
constructor(props) {
super(props);
autoBind(this);
this.state = {
targetUri: this.props.selectedContact ? this.props.selectedContact.uri : '',
contacts: this.props.contacts,
selectedContact: this.props.selectedContact,
showConferenceModal: this.props.showConferenceModal,
sticky: false,
favoriteUris: this.props.favoriteUris,
blockedUris: this.props.blockedUris,
historyCategoryFilter: null,
messagesCategoryFilter: null,
historyPeriodFilter: 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,
shareToContacts: this.props.shareToContacts,
selectedContacts: this.props.selectedContacts,
pinned: this.props.pinned,
messageZoomFactor: this.props.messageZoomFactor,
isTyping: this.props.isTyping,
navigationItems: this.props.navigationItems,
fontScale: this.props.fontScale,
historyFilter: this.props.historyFilter,
isTablet: this.props.isTablet,
myContacts: this.props.myContacts,
showQRCodeScanner: this.props.showQRCodeScanner,
ssiCredentials: this.props.ssiCredentials,
ssiConnections: this.props.ssiConnections,
keys: this.props.keys,
isTexting: this.props.isTexting,
keyboardVisible: this.props.keyboardVisible,
contentTypes: this.props.contentTypes,
sourceContact: this.props.sourceContact
};
this.ended = false;
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (this.ended) {
return;
}
if (this.state.selectedContact) {
this.setState({targetUri: nextProps.selectedContact ? nextProps.selectedContact.uri : '', chat: false});
}
if (!this.state.inviteContacts && nextProps.inviteContacts) {
this.handleTargetChange('');
this.setState({chat: false});
}
if (this.state.selectedContact !== nextProps.selectedContact && nextProps.selectedContact) {
this.setState({chat: !this.chatDisabledForUri(nextProps.selectedContact.uri)});
}
if (nextProps.selectedContact !== this.state.selectedContact) {
this.resetContact()
this.setState({'messagesCategoryFilter': null});
if (this.navigationRef && !this.state.selectedContact) {
this.navigationRef.scrollToIndex({animated: true, index: 0});
}
if (this.state.selectedContact && this.state.pinned) {
this.props.togglePinned(this.state.selectedContact.uri);
}
}
if (!nextProps.historyFilter && this.state.historyFilter) {
this.filterHistory(null);
}
if (nextProps.historyFilter === 'ssi' && !nextProps.selectedContact) {
this.setState({'historyCategoryFilter': 'ssi'});
if (this.navigationRef && !this.state.selectedContact) {
this.navigationRef.scrollToIndex({animated: true, index: this.navigationItems.length-1});
}
}
if (nextProps.missedCalls.length === 0 && this.state.historyCategoryFilter === 'missed') {
this.setState({'historyCategoryFilter': null});
}
if (nextProps.blockedUris.length === 0 && this.state.historyCategoryFilter === 'blocked') {
this.setState({'historyCategoryFilter': null});
}
if (nextProps.favoriteUris.length === 0 && this.state.historyCategoryFilter === 'favorite') {
this.setState({'historyCategoryFilter': null});
}
if (Object.keys(this.state.myContacts).length === 0 && nextProps.myContacts && Object.keys(nextProps.myContacts).length > 0) {
this.bounceNavigation();
}
this.setState({myInvitedParties: nextProps.myInvitedParties,
myContacts: nextProps.myContacts,
messages: nextProps.messages,
historyFilter: nextProps.historyFilter,
myDisplayName: nextProps.myDisplayName,
call: nextProps.call,
showConferenceModal: nextProps.showConferenceModal,
isTyping: nextProps.isTyping,
navigationItems: nextProps.navigationItems,
messageZoomFactor: nextProps.messageZoomFactor,
contacts: nextProps.contacts,
inviteContacts: nextProps.inviteContacts,
shareToContacts: nextProps.shareToContacts,
selectedContacts: nextProps.selectedContacts,
selectedContact: nextProps.selectedContact,
pinned: nextProps.pinned,
favoriteUris: nextProps.favoriteUris,
blockedUris: nextProps.blockedUris,
missedCalls: nextProps.missedCalls,
fontScale: nextProps.fontScale,
isTablet: nextProps.isTablet,
showQRCodeScanner: nextProps.showQRCodeScanner,
isLandscape: nextProps.isLandscape,
ssiCredentials: nextProps.ssiCredentials,
ssiConnections: nextProps.ssiConnections,
keys: nextProps.keys,
isTexting: nextProps.isTexting,
keyboardVisible: nextProps.keyboardVisible,
contentTypes: nextProps.contentTypes,
sourceContact: nextProps.sourceContact
});
}
getTargetUri(uri) {
return utils.normalizeUri(uri, this.props.defaultDomain);
}
async componentDidMount() {
this.ended = false;
}
componentWillUnmount() {
this.ended = true;
}
filterHistory(filter) {
if (this.ended) {
return;
}
//console.log('filterHistory', filter);
if (this.state.selectedContact) {
if (!filter && this.state.pinned) {
this.props.togglePinned(this.state.selectedContact.uri);
}
if (filter === 'pinned') {
this.props.togglePinned(this.state.selectedContact.uri);
return;
}
if (filter === this.state.messagesCategoryFilter) {
this.setState({'messagesCategoryFilter': null});
} else {
this.setState({'messagesCategoryFilter': filter});
}
return;
}
this.props.filterHistoryFunc(filter);
if (!filter) {
this.setState({'historyPeriodFilter': null, historyCategoryFilter: null});
} else if (filter === 'today' || filter === 'yesterday') {
filter = this.state.historyPeriodFilter === filter ? null : filter;
this.setState({'historyPeriodFilter': filter});
} else {
this.setState({'historyCategoryFilter': 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;
}
if (uri.indexOf('4444@') > -1) {
return true;
}
return false;
}
get showNavigationBar() {
if (this.state.keyboardVisible) {
return;
}
if (this.state.selectedContact) {
//return false;
}
if (this.state.recording) {
return false;
}
return true;
}
get showSearchBar() {
if (this.state.selectedContact && !this.state.isTablet) {
return false;
}
if (this.state.showQRCodeScanner) {
return false;
}
if (this.state.isTablet || (!this.state.isLandscape && this.state.selectedContact)) {
return true;
}
if (this.state.call && this.state.call.state !== 'incoming' && !this.state.inviteContacts) {
return false;
}
return true;
}
get showConferenceButton() {
if (this.state.selectedContact) {
return false;
}
if (this.state.shareToContacts) {
return false;
}
return true;
}
get showAudioSendButton() {
if (!this.state.selectedContact) {
return false;
}
return true;
}
get showAudioCancelButton() {
if (!this.state.audioRecording) {
return false;
}
return true;
}
get showAudioRecordButton() {
if (!this.state.selectedContact) {
return false;
}
if (this.state.audioRecording) {
return false;
}
return true;
}
get showButtonsBar() {
if (this.state.historyCategoryFilter === 'blocked') {
return false;
}
if (this.state.historyCategoryFilter === 'ssi') {
return false;
}
if (this.state.showQRCodeScanner) {
return false;
}
if (this.state.isTablet) {
return true;
}
if (this.state.call) {
return true;
}
if (!this.state.targetUri) {
return true;
}
/*
if (this.state.selectedContact) {
if (this.state.isLandscape && !this.state.isTablet) {
return false;
}
return false;
}
*/
return true;
}
handleTargetChange(new_uri, contact) {
//console.log('---handleTargetChange new_uri =', new_uri);
//console.log('handleTargetChange contact =', contact);
if ((this.state.inviteContacts || this.state.shareToContacts) && contact) {
const uri = contact.uri;
this.props.updateSelection(uri);
return;
}
// This URLs are used to request SSI credentials
if (new_uri && new_uri.startsWith('https://didcomm.issuer.bloqzone.com?c_i=')) {
this.props.handleSSIEnrolment(new_uri);
return;
}
// This URLs are used to request SSI credentials
if (new_uri && new_uri.startsWith('https://ssimandate.vismaconnect.nl/api/acapy?c_i=')) {
this.props.handleSSIEnrolment(new_uri);
return;
}
if (contact && contact.tags.indexOf('ssi') > -1 && this.state.selectedContact !== contact) {
this.setState({'historyCategoryFilter': 'ssi'});
}
if (this.state.selectedContact === contact) {
if (this.state.chat) {
this.setState({chat: false});
}
return;
} else {
this.setState({chat: false});
}
let new_value = new_uri;
if (contact) {
if (this.state.targetUri === contact.uri) {
new_value = '';
}
} else {
contact = null;
}
if (this.state.targetUri === new_uri) {
new_value = '';
}
if (new_value === '') {
contact = null;
}
if (new_value.indexOf(' ') === -1) {
new_value = new_value.trim().toLowerCase();
}
//new_value = new_value.replace(' ','');
//console.log('--- Select new contact', contact? contact.uri : null);
//console.log('--- Select new targetUri', new_value);
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});
}
}
shareContent() {
this.props.shareContent();
}
cancelShareContent() {
this.props.cancelShareContent();
}
showConferenceModal(event) {
event.preventDefault();
this.props.showConferenceModalFunc();
}
handleChat(event) {
event.preventDefault();
let targetUri;
if (!this.state.chat && !this.state.selectedContact) {
targetUri = this.getTargetUri(this.state.targetUri);
this.setState({targetUri: targetUri});
}
let uri = this.state.targetUri.trim().toLowerCase();
if (!this.state.chat && !this.selectedContact && uri) {
if (uri.indexOf('@') === -1) {
uri = uri + '@' + this.props.defaultDomain;
}
let contact = this.props.newContactFunc(uri, null, {src: 'new chat'});
console.log('Create synthetic contact', contact);
this.props.selectContact(contact);
this.setState({targetUri: uri, chat: true});
Keyboard.dismiss();
}
this.setState({chat: !this.state.chat});
}
handleAudioCall(event) {
let uri;
if (this.state.selectedContact) {
uri = this.state.selectedContact.uri;
} else {
event.preventDefault();
Keyboard.dismiss();
uri = this.state.targetUri.trim().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) {
let uri;
if (this.state.selectedContact) {
uri = this.state.selectedContact.uri;
} else {
event.preventDefault();
Keyboard.dismiss();
uri = this.state.targetUri.trim().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: []}) {
Keyboard.dismiss();
this.props.startConference(targetUri, {audio: options.audio, video: options.video, participants: options.participants});
this.props.hideConferenceModalFunc();
}
get chatButtonDisabled() {
let uri = this.state.targetUri.trim();
if (this.state.selectedContact) {
return true;
}
if (this.state.shareToContacts) {
return true;
}
if (!uri || uri.indexOf(' ') > -1 || uri.indexOf('@guest.') > -1 || uri.indexOf('@videoconference') > -1) {
return true;
}
let username = uri.split('@')[0];
let isPhoneNumber = username.match(/^(\+|0)(\d+)$/);
if (isPhoneNumber) {
return true;
}
if (uri.indexOf('@') > -1) {
let email_reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/;
let validEmail = email_reg.test(uri);
if (!validEmail) {
return true;
}
}
if (this.chatDisabledForUri(uri)) {
return true;
}
return false;
}
get callButtonDisabled() {
let uri = this.state.targetUri.trim();
if (!uri || uri.indexOf(' ') > -1 || uri.indexOf('@guest.') > -1) {
return true;
}
if (this.state.shareToContacts) {
return true;
}
if (this.state.recording) {
return true;
}
if (this.state.audioRecording) {
return true;
}
if (uri.indexOf('@') > -1) {
let email_reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/;
let validEmail = email_reg.test(uri);
if (!validEmail) {
return true;
}
}
return false;
}
get videoButtonDisabled() {
let uri = this.state.targetUri.trim();
if (!uri || uri.indexOf(' ') > -1 || uri.indexOf('@guest.') > -1) {
return true;
}
if (uri.indexOf('4444@') > -1) {
return true;
}
if (this.state.shareToContacts) {
return true;
}
if (this.state.recording) {
return true;
}
if (this.state.audioRecording) {
return true;
}
let username = uri.split('@')[0];
let isPhoneNumber = username.match(/^(\+|0)(\d+)$/);
if (isPhoneNumber) {
return true;
}
return this.callButtonDisabled;
}
get conferenceButtonDisabled() {
if (!this.props.canSend()) {
return true;
}
let uri = this.state.targetUri.trim();
if (uri.indexOf(' ') > -1) {
return true;
}
if (this.state.shareToContacts) {
return true;
}
let username = uri.split('@')[0];
let isPhoneNumber = username.match(/^(\+|0)(\d+)$/);
if (isPhoneNumber) {
return true;
}
if (uri.indexOf('@') > -1 && uri.indexOf(config.defaultConferenceDomain) === -1) {
return true;
}
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 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;
if (key === "hideQRCodeScanner") {
return ();
}
if (key === "deleteAudio") {
return ();
}
if (key === "sendAudio") {
return ();
}
return ();
}
bounceNavigation() {
if (this.ended) {
return;
}
setTimeout(() => {
if (this.ended) {
return;
}
if (this.navigationRef && !this.state.selectedContact) {
this.navigationRef.scrollToIndex({animated: true, index: Math.floor(this.navigationItems.length / 2)});
}
}, 3000);
setTimeout(() => {
if (this.ended) {
return;
}
if (this.navigationRef && !this.state.selectedContact) {
this.navigationRef.scrollToIndex({animated: true, index: this.navigationItems.length-1});
}
}, 4500);
setTimeout(() => {
if (this.ended) {
return;
}
if (this.navigationRef && !this.state.selectedContact) {
this.navigationRef.scrollToIndex({animated: true, index: 0});
}
}, 6000);
}
get navigationItems() {
let conferenceEnabled = Object.keys(this.state.myInvitedParties).length > 0 || this.state.navigationItems['conference'];
if (this.state.inviteContacts) {
conferenceEnabled = false;
}
if (this.state.audioRecording) {
return [
{key: "deleteAudio", title: 'Delete', enabled: true, selected: false},
{key: "sendAudio", title: 'Send', enabled: true, selected: false}
];
}
if (this.state.showQRCodeScanner) {
return [
{key: "hideQRCodeScanner", title: 'Cancel', enabled: true, selected: false}
];
}
if (this.state.selectedContact) {
let content_items = [];
if ('pinned' in this.state.contentTypes) {
content_items.push({key: 'pinned', title: 'Pinned', enabled: true, selected: this.state.pinned});
}
if ('text' in this.state.contentTypes) {
content_items.push({key: 'text', title: 'Text', enabled: true, selected: this.state.messagesCategoryFilter === 'text'});
}
if ('audio' in this.state.contentTypes) {
content_items.push({key: 'audio', title: 'Audio', enabled: true, selected: this.state.messagesCategoryFilter === 'audio'});
}
if ('image' in this.state.contentTypes) {
content_items.push({key: 'image', title: 'Images', enabled: true, selected: this.state.messagesCategoryFilter === 'image'});
}
if ('movie' in this.state.contentTypes) {
content_items.push({key: 'movie', title: 'Movies', enabled: true, selected: this.state.messagesCategoryFilter === 'movie'});
}
if ('failed' in this.state.contentTypes) {
content_items.push({key: 'failed', title: 'Failed', enabled: true, selected: this.state.messagesCategoryFilter === 'failed'});
}
if ('paused' in this.state.contentTypes) {
content_items.push({key: 'paused', title: 'Paused', enabled: true, selected: this.state.messagesCategoryFilter === 'paused'});
}
if ('large' in this.state.contentTypes) {
content_items.push({key: 'large', title: 'Large', enabled: true, selected: this.state.messagesCategoryFilter === 'large'});
}
return content_items;
}
return [
{key: null, title: 'All', enabled: true, selected: false},
{key: 'favorite', title: 'Favorites', enabled: this.state.favoriteUris.length > 0, selected: this.state.historyCategoryFilter === 'favorite'},
{key: 'history', title: 'Calls', enabled: true, selected: this.state.historyCategoryFilter === 'history'},
{key: 'chat', title: 'Chat', enabled: true, selected: this.state.historyCategoryFilter === 'chat'},
{key: 'today', title: 'Today', enabled: this.state.navigationItems['today'], selected: this.state.historyPeriodFilter === 'today'},
{key: 'yesterday', title: 'Yesterday', enabled: this.state.navigationItems['yesterday'], selected: this.state.historyPeriodFilter === 'yesterday'},
{key: 'missed', title: 'Missed', enabled: this.state.missedCalls.length > 0, selected: this.state.historyCategoryFilter === 'missed'},
{key: 'blocked', title: 'Blocked', enabled: this.state.blockedUris.length > 0, selected: this.state.historyCategoryFilter === 'blocked'},
{key: 'conference', title: 'Conference', enabled: conferenceEnabled, selected: this.state.historyCategoryFilter === 'conference'},
{key: 'test', title: 'Test', enabled: !this.state.shareToContacts && !this.state.inviteContacts, selected: this.state.historyCategoryFilter === 'test'},
{key: 'ssi', title: 'SSI', enabled: (this.state.ssiConnections && this.state.ssiConnections.length > 0) || (this.state.ssiCredentials && this.state.ssiCredentials.length > 0), selected: this.state.historyCategoryFilter === 'ssi'},
];
}
toggleQRCodeScanner(event) {
if (event) {
event.preventDefault();
}
console.log('Scan QR code...');
this.props.toggleQRCodeScannerFunc();
}
QRCodeRead(e) {
//console.log('QR code object:', e);
console.log('QR code data:', e.data);
this.props.toggleQRCodeScannerFunc();
this.handleTargetChange(e.data);
}
get showContactsList() {
if (this.state.recording) {
return false;
}
if (this.state.audioRecording) {
return false;
}
return true;
}
get showQRCodeButton() {
if (!this.props.canSend()) {
return false;
}
if (this.state.shareToContacts) {
return false;
}
let uri = this.state.targetUri.toLowerCase();
return uri.length === 0 && !this.state.shareToContacts && !this.state.inviteContacts;
}
async recordAudio() {
const micAllowed = await this.props.requestMicPermission();
console.log('micAllowed', micAllowed);
if (!micAllowed) {
return;
}
if (!this.state.recording) {
if (this.state.audioRecording) {
this.deleteAudio();
} else {
this.onStartRecord();
}
} else {
this.onStopRecord();
}
}
recordAudio(event) {
event.preventDefault();
Keyboard.dismiss();
this.props.recordAudio();
}
async file2GiftedChat(fileObject) {
var id = uuid.v4();
let uri = this.state.selectedContact.uri;
let filepath = fileObject.uri ? fileObject.uri : fileObject;
let basename = fileObject.fileName || filepath.split('\\').pop().split('/').pop();
basename = basename.replace(/\s|:/g, '_');
let file_transfer = { 'path': filepath,
'filename': basename,
- 'sender': {'uri': this.state.accountId},
+ 'sender': {'uri': this.props.account.id},
'receiver': {'uri': uri},
'transfer_id': id,
'direction': 'outgoing'
};
if (filepath.startsWith('content://')) {
// on android we must copy this file early
- const localPath = RNFS.DocumentDirectoryPath + "/" + this.state.accountId + "/" + uri + "/" + id + "/" + basename;
+ const localPath = RNFS.DocumentDirectoryPath + "/" + this.props.account.id + "/" + uri + "/" + id + "/" + basename;
const dirname = path.dirname(localPath);
await RNFS.mkdir(dirname);
console.log('Copy', filepath, localPath);
await RNFS.copyFile(filepath, localPath);
filepath = localPath;
file_transfer.local_url = localPath;
}
let stats_filename = filepath.startsWith('file://') ? filepath.substr(7, filepath.length - 1) : filepath;
const { size } = await RNFetchBlob.fs.stat(stats_filename);
file_transfer.filesize = fileObject.fileSize || size;
if (fileObject.preview) {
file_transfer.preview = fileObject.preview;
}
if (fileObject.duration) {
file_transfer.duration = fileObject.duration;
}
if (fileObject.fileType) {
file_transfer.filetype = fileObject.fileType;
} else {
try {
let mime = await fileType(filepath);
if (mime.mime) {
file_transfer.filetype = mime.mime;
}
} catch (e) {
console.log('Error getting mime type', e.message);
}
}
let text = utils.beautyFileNameForBubble(file_transfer);
let msg = {
_id: id,
key: id,
text: text,
metadata: file_transfer,
createdAt: new Date(),
direction: 'outgoing',
user: {}
}
if (utils.isImage(basename, file_transfer.filetype)) {
msg.image = filepath;
} else if (utils.isAudio(basename)) {
msg.audio = filepath;
} else if (utils.isVideo(basename) || file_transfer.duration) {
msg.video = filepath;
}
return msg;
}
async sendAudioFile() {
if (this.state.audioRecording) {
this.setState({audioSendFinished: true});
setTimeout(() => {
this.setState({audioSendFinished: false});
}, 10);
let msg = await this.file2GiftedChat(this.state.audioRecording);
this.transferFile(msg);
this.setState({audioRecording: null});
}
}
async transferFile(msg) {
msg.metadata.preview = false;
this.props.sendMessage(msg.metadata.receiver.uri, msg, 'application/sylk-file-transfer');
}
deleteAudio(event) {
event.preventDefault();
Keyboard.dismiss();
this.props.deleteAudio();
}
async recordAudio() {
/*
const micAllowed = await this.props.requestMicPermission();
console.log('micAllowed', micAllowed);
if (!micAllowed) {
return;
}
*/
if (!this.state.recording) {
if (this.state.audioRecording) {
this.deleteAudio();
} else {
this.onStartRecord();
}
} else {
this.onStopRecord();
}
}
deleteAudio() {
console.log('Delete audio');
this.setState({audioRecording: null, recording: false});
if (this.recordingStopTimer !== null) {
clearTimeout(this.recordingStopTimer);
this.recordingStopTimer = null;
}
}
async onStartRecord () {
console.log('Start recording...');
this.setState({recording: true});
this.recordingStopTimer = setTimeout(() => {
this.stopRecording();
}, 20000);
if (!AudioRecord) {
AudioRecord.init(options);
}
try {
AudioRecord.start();
} catch (e) {
console.log(e.message);
}
};
stopRecording() {
console.log('Stop recording...');
this.setState({recording: false});
if (this.recordingStopTimer !== null) {
clearTimeout(this.recordingStopTimer);
this.recordingStopTimer = null;
}
this.onRecording(false);
this.onStopRecord();
}
async onStopRecord () {
console.log('Stop recording...');
const result = await AudioRecord.stop();
this.audioRecorded(result);
this.setState({audioRecording: result});
};
onRecording(state) {
this.setState({recording: state});
if (state) {
this.startRecordingTimer();
} else {
this.stopRecordingTimer()
}
}
resetContact() {
this.stopRecordingTimer()
this.setState({
recording: false,
audioRecording: null,
audioSendFinished: false
});
}
startRecordingTimer() {
let i = 0;
this.recordingTimer = setInterval(() => {
i = i + 1
this.setState({placeholder: 'Recording audio ' + i + 's'});
}, 1000);
}
stopRecordingTimer() {
if (this.recordingTimer) {
clearInterval(this.recordingTimer);
this.recordingTimer = null;
}
}
async audioRecorded(file) {
if (file) {
console.log('Audio recording ready to send', file);
} else {
console.log('Audio recording removed');
}
this.setState({recording: false, audioRecording: file});
}
render() {
let URIContainerClass = 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('RB', this.state.myContacts);
if (this.state.isTablet) {
titleClass = this.props.orientation === 'landscape' ? styles.landscapeTabletTitle : styles.portraitTabletTitle;
} else {
titleClass = this.props.orientation === 'landscape' ? styles.landscapeTitle : styles.portraitTitle;
}
if (this.state.isTablet) {
uriGroupClass = this.props.orientation === 'landscape' ? styles.landscapeTabletUriButtonGroup : styles.portraitTabletUriButtonGroup;
} else {
uriGroupClass = this.props.orientation === 'landscape' ? styles.landscapeUriButtonGroup : styles.portraitUriButtonGroup;
}
if (this.state.isTablet) {
URIContainerClass = this.props.orientation === 'landscape' ? styles.landscapeTabletUriInputBox : styles.portraitTabletUriInputBox;
} else {
URIContainerClass = 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 backButtonTitle = 'Back to call';
const showBackToCallButton = this.state.call && this.state.call.state !== 'incoming' && this.state.call.state !== 'terminated' ? true : false ;
if (showBackToCallButton) {
if (this.state.call.hasOwnProperty('_participants')) {
backButtonTitle = this.state.selectedContacts.length > 0 ? 'Invite people' : 'Back to conference';
} else {
backButtonTitle = this.state.selectedContacts.length > 0 ? 'Invite people' : 'Back to call';
}
}
let greenButtonClass = Platform.OS === 'ios' ? styles.greenButtoniOS : styles.greenButton;
let blueButtonClass = Platform.OS === 'ios' ? styles.blueButtoniOS : styles.blueButton;
let redButtonClass = Platform.OS === 'ios' ? styles.redButtoniOS : styles.redButton;
let disabledGreenButtonClass = Platform.OS === 'ios' ? styles.disabledGreenButtoniOS : styles.disabledGreenButton;
let disabledBlueButtonClass = Platform.OS === 'ios' ? styles.disabledBlueButtoniOS : styles.disabledBlueButton;
let recordIcon = this.state.recording ? 'pause' : 'microphone';
let activityTitle = this.state.recording ? "Recording audio..." : "Audio recording ready";
let fileTransfersDisabled = false;
if (this.state.selectedContact) {
fileTransfersDisabled = false;
if (this.state.selectedContact.tags.indexOf('test') > -1) {
fileTransfersDisabled = true;
}
if (this.state.selectedContact.uri.indexOf('@videoconference') > -1) {
fileTransfersDisabled = true;
}
if (this.state.selectedContact.uri.indexOf('@conference') > -1) {
fileTransfersDisabled = true;
}
}
return (
{this.showSearchBar && !this.state.isLandscape ?
: null}
{this.showButtonsBar ?
{this.showSearchBar && this.state.isLandscape ?
: null}
{showBackToCallButton ?
:
{!this.state.selectedContact ?
: null }
{this.showAudioRecordButton?
: null }
{this.showAudioCancelButton ?
: null }
{ this.state.shareToContacts ?
: null}
{this.showConferenceButton ?
: null }
{this.showAudioSendButton ?
: null }
{ this.state.shareToContacts ?
: null }
{ this.showQRCodeButton ?
: null}
}
: null}
{this.showContactsList ?
{this.state.showQRCodeScanner ?
:
}
: null
}
{ this.state.recording ?
{activityTitle}
: null
}
{ this.state.audioRecording ?
{activityTitle}
: null
}
{this.showNavigationBar ?
{ this.navigationRef = ref; }}
onScrollToIndexFailed={info => {
const wait = new Promise(resolve => setTimeout(resolve, 10));
wait.then(() => {
if (!this.state.selectedContact) {
this.navigationRef.current?.scrollToIndex({ index: info.index, animated: true/false });
}
});
}}
data={this.navigationItems}
extraData={this.state}
keyExtractor={(item, index) => item.key}
renderItem={this.renderNavigationItem}
/>
: null}
{this.state.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,
shareToContacts : PropTypes.bool,
showQRCodeScanner : PropTypes.bool,
selectedContacts: PropTypes.array,
updateSelection : PropTypes.func,
loadEarlierMessages: PropTypes.func,
newContactFunc : PropTypes.func,
missedCalls : PropTypes.array,
messageZoomFactor: PropTypes.string,
isTyping: PropTypes.bool,
navigationItems: PropTypes.object,
showConferenceModal: PropTypes.bool,
showConferenceModalFunc: PropTypes.func,
hideConferenceModalFunc: PropTypes.func,
shareContent: PropTypes.func,
cancelShareContent: PropTypes.func,
filterHistoryFunc: PropTypes.func,
historyFilter: PropTypes.string,
fontScale: PropTypes.number,
inviteToConferenceFunc: PropTypes.func,
toggleQRCodeScannerFunc: PropTypes.func,
myContacts: PropTypes.object,
handleSSIEnrolment: PropTypes.func,
ssiCredentials: PropTypes.array,
ssiConnections: PropTypes.array,
keys : PropTypes.object,
downloadFunc : PropTypes.func,
decryptFunc : PropTypes.func,
isTexting :PropTypes.bool,
keyboardVisible: PropTypes.bool,
filteredMessageIds: PropTypes.array,
contentTypes: PropTypes.object,
canSend: PropTypes.func,
forwardMessageFunc: PropTypes.func,
sourceContact: PropTypes.object,
requestCameraPermission: PropTypes.func,
requestStoragePermissions: PropTypes.func,
requestMicPermission: PropTypes.func,
postSystemNotification: PropTypes.func
};
export default ReadyBox;