diff --git a/app/components/ConferenceModal.js b/app/components/ConferenceModal.js
index 5ef1c25..7cc400d 100644
--- a/app/components/ConferenceModal.js
+++ b/app/components/ConferenceModal.js
@@ -1,186 +1,186 @@
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
});
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].toLowerCase();
- if (this.props.myInvitedParties && this.props.myInvitedParties.hasOwnProperty(uri)) {
+ uri = uri.split('@')[0];
+ if (this.state.myInvitedParties && this.state.myInvitedParties.hasOwnProperty(uri)) {
participants = this.props.myInvitedParties[uri].toString();
} else if (this.state.selectedContact && this.state.selectedContact.participants) {
participants = this.state.selectedContact.participants.toString();
}
participants.split(',').forEach((item) => {
item = item.trim().toLowerCase();
if (item.indexOf('@') === -1) {
item = `${item}@${this.props.defaultDomain}`;
}
username = item.split('@')[0];
domain = item.split('@')[1];
if (username && username !== ',') {
if (domain === this.props.defaultDomain) {
sanitizedParticipants.push(username);
} else {
sanitizedParticipants.push(item);
}
}
});
}
this.setState({targetUri: targetUri, participants: sanitizedParticipants.toString()});
}
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();
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();
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.setState({participants: value});}}
value={this.state.participants}
placeholder="bob,carol,alice@sip2sip.info"
/>
);
}
}
ConferenceModal.propTypes = {
show: PropTypes.bool.isRequired,
handleConferenceCall: PropTypes.func.isRequired,
myInvitedParties: PropTypes.object,
selectedContact: PropTypes.object,
targetUri: PropTypes.string.isRequired,
defaultDomain: PropTypes.string
};
export default ConferenceModal;
diff --git a/app/components/EditConferenceModal.js b/app/components/EditConferenceModal.js
index f1a70ce..4c4aa93 100644
--- a/app/components/EditConferenceModal.js
+++ b/app/components/EditConferenceModal.js
@@ -1,120 +1,120 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import autoBind from 'auto-bind';
import { View } from 'react-native';
import { Chip, Dialog, Portal, Text, Button, Surface, TextInput, Paragraph } 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/_InviteParticipantsModal.scss';
class EditConferenceModal extends Component {
constructor(props) {
super(props);
autoBind(this);
let users = '';
if (this.props.invitedParties && this.props.invitedParties.length > 0) {
users = this.props.invitedParties;
} else if (this.props.selectedContact && this.props.selectedContact.participants) {
users = this.props.selectedContact.participants;
}
this.state = {
users: users.toString(),
selectedContact: this.props.selectedContact,
invitedParties: this.props.invitedParties
}
}
UNSAFE_componentWillReceiveProps(nextProps) {
let users = '';
if (nextProps.invitedParties && nextProps.invitedParties.length > 0) {
users = nextProps.invitedParties;
} else if (nextProps.selectedContact && nextProps.selectedContact.participants) {
users = nextProps.selectedContact.participants;
}
- this.state = {
+ this.setState({
users: users.toString(),
selectedContact: nextProps.selectedContact,
invitedParties: nextProps.invitedParties
- }
+ });
}
saveParticipants(event) {
event.preventDefault();
const uris = [];
if (this.state.users) {
this.state.users.split(',').forEach((item) => {
item = item.trim();
if (item.indexOf('@') === -1) {
item = `${item}@${this.props.defaultDomain}`;
}
let username = item.split('@')[0];
if (username && username !== ',') {
uris.push(item);
}
});
}
if (uris) {
this.props.saveInvitedParties(uris);
this.setState({users: null});
}
this.props.close();
}
onInputChange(value) {
this.setState({users: value});
}
render() {
return (
{this.props.room}
People you wish to invite automatically to the conference when you join the room:
);
}
}
EditConferenceModal.propTypes = {
show: PropTypes.bool.isRequired,
close: PropTypes.func.isRequired,
saveInvitedParties: PropTypes.func,
invitedParties: PropTypes.array,
room: PropTypes.string,
selectedContact: PropTypes.object,
defaultDomain: PropTypes.string
};
export default EditConferenceModal;
diff --git a/app/components/HistoryCard.js b/app/components/HistoryCard.js
index 00ba0a5..a0f8193 100644
--- a/app/components/HistoryCard.js
+++ b/app/components/HistoryCard.js
@@ -1,406 +1,405 @@
import React, { Component, Fragment} from 'react';
import { View, SafeAreaView, FlatList } from 'react-native';
import autoBind from 'auto-bind';
import PropTypes from 'prop-types';
import moment from 'moment';
import momentFormat from 'moment-duration-format';
import { Card, IconButton, Button, Caption, Title, Subheading, List, Text} from 'react-native-paper';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import uuid from 'react-native-uuid';
import EditConferenceModal from './EditConferenceModal';
import styles from '../assets/styles/blink/_HistoryCard.scss';
import UserIcon from './UserIcon';
function toTitleCase(str) {
return str.replace(
/\w\S*/g,
function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
}
);
}
const Item = ({ nr, uri, displayName }) => (
{displayName !== uri?
{displayName} ({uri})
:
{uri}
}
);
const renderItem = ({ item }) => (
-
);
class HistoryCard extends Component {
constructor(props) {
super(props);
autoBind(this);
this.state = {
id: this.props.contact.id,
contact: this.props.contact,
displayName: this.props.contact.displayName,
uri: this.props.contact.remoteParty,
invitedParties: this.props.invitedParties,
participants: this.props.contact.participants,
conference: this.props.contact.conference,
type: this.props.contact.type,
photo: this.props.contact.photo,
label: this.props.contact.label,
orientation: this.props.orientation,
isTablet: this.props.isTablet,
favorite: (this.props.contact.tags.indexOf('favorite') > -1)? true : false,
blocked: (this.props.contact.tags.indexOf('blocked') > -1)? true : false,
confirmed: false,
showEditConferenceModal: false
}
}
UNSAFE_componentWillReceiveProps(nextProps) {
this.setState({
id: nextProps.contact.id,
contact: nextProps.contact,
displayName: nextProps.contact.displayName,
uri: nextProps.contact.remoteParty,
invitedParties: nextProps.invitedParties,
participants: nextProps.contact.participants,
conference: nextProps.contact.conference,
type: nextProps.contact.type,
photo: nextProps.contact.photo,
label: nextProps.contact.label,
orientation: nextProps.orientation,
favorite: (nextProps.contact.tags.indexOf('favorite') > -1)? true : false,
blocked: (nextProps.contact.tags.indexOf('blocked') > -1)? true : false,
});
}
shouldComponentUpdate(nextProps) {
//https://medium.com/sanjagh/how-to-optimize-your-react-native-flatlist-946490c8c49b
return true;
}
toggleEditConferenceModal() {
this.setState({showEditConferenceModal: !this.state.showEditConferenceModal});
}
saveInvitedParties(uris) {
this.setState({invitedParties: uris});
this.props.saveInvitedParties(this.state.uri.split('@')[0], uris);
}
handleParticipant() {
}
findObjectByKey(array, key, value) {
for (var i = 0; i < array.length; i++) {
if (array[i][key] === value) {
return array[i];
}
}
return null;
}
setBlockedUri() {
let newBlockedState = this.props.setBlockedUri(this.state.uri);
this.setState({blocked: newBlockedState});
}
editConference() {
this.toggleEditConferenceModal();
}
deleteHistoryEntry() {
this.props.deleteHistoryEntry(this.state.uri);
}
undo() {
this.setState({confirmed: false, action: null});
}
setFavoriteUri() {
if (this.state.favorite) {
if (this.state.confirmed) {
let newFavoriteState = this.props.setFavoriteUri(this.state.uri);
this.setState({favorite: newFavoriteState, action: null, confirmed: false});
this.props.setTargetUri(this.state.uri);
} else {
this.setState({confirmed: true});
}
} else {
let newFavoriteState = this.props.setFavoriteUri(this.state.uri);
this.setState({favorite: newFavoriteState});
}
}
setTargetUri(uri, contact) {
if (this.isAnonymous(this.state.uri)) {
return;
}
this.props.setTargetUri(uri, this.state.contact);
}
isAnonymous(uri) {
if (uri.indexOf('@guest.') > -1 || uri.indexOf('@anonymous.') > -1) {
return true
}
return false;
}
render () {
let containerClass = styles.portraitContainer;
let cardClass = styles.card;
let showActions = this.props.contact.showActions && this.props.contact.tags.indexOf('test') === -1;
let uri = this.state.uri;
let username = uri.split('@')[0];
let displayName = this.state.displayName;
let buttonMode = 'text';
let showBlockButton = uri.indexOf('@videoconference.') === -1 ? true : false;
let showFavoriteButton = true;
let showUndoButton = this.state.confirmed ? true : false;
let showDeleteButton = (this.props.contact.tags.indexOf('local') > -1 && !this.state.favorite ) ? true: false;
let showEditButton = (uri.indexOf('@videoconference.') > -1 && this.state.favorite && !this.state.confirmed ) ? true: false;
let blockTextbutton = 'Block';
let editTextbutton = 'Edit';
let favoriteTextbutton = 'Favorite';
let undoTextbutton = 'Abort';
let deleteTextbutton = 'Delete';
let participantsData = [];
if (this.isAnonymous(uri)) {
uri = 'anonymous@anonymous.invalid';
displayName = displayName + ' - from the Web';
let showFavoriteButton = false;
}
if (this.state.favorite) {
favoriteTextbutton = this.state.confirmed ? 'Confirm' : 'Remove favorite';
if (!this.state.blocked) {
showBlockButton = false;
}
}
if (uri.indexOf('3333@') > -1) {
showBlockButton = false;
}
if (uri.indexOf('4444@') > -1) {
showBlockButton = false;
}
if (displayName === 'Myself') {
showBlockButton = false;
}
if (this.state.blocked) {
blockTextbutton = 'Unblock';
showFavoriteButton = false;
}
if (this.state.isTablet) {
containerClass = (this.state.orientation === 'landscape') ? styles.landscapeTabletContainer : styles.portraitTabletContainer;
} else {
containerClass = (this.state.orientation === 'landscape') ? styles.landscapeContainer : styles.portraitContainer;
}
if (showActions) {
cardClass = styles.expandedCard;
}
let color = {};
let title = displayName || username;
let subtitle = uri;
let description = this.props.contact.startTime;
if (displayName === uri) {
title = toTitleCase(username);
}
if (this.props.contact.tags.indexOf('history') > -1) {
let duration = moment.duration(this.props.contact.duration, 'seconds').format('HH:mm:ss', {trim: false});
if (this.props.contact.direction === 'received' && this.props.contact.duration === 0) {
color.color = '#a94442';
duration = 'missed';
} else if (this.props.contact.direction === 'placed' && this.props.contact.duration === 0) {
duration = 'cancelled';
}
if (this.state.conference) {
let participants = (this.state.invitedParties && this.state.invitedParties.length > 0) ? this.state.invitedParties: this.state.participants;
if (participants && participants.length > 0) {
- console.log('participants.length', participants.length);
const p_text = participants.length > 1 ? 'participants' : 'participant';
subtitle = 'With ' + participants.length + ' ' + p_text;
let i = 1;
let contact_obj;
let dn;
let _item;
participants.forEach((participant) => {
contact_obj = this.findObjectByKey(this.props.contacts, 'remoteParty', participant);
dn = contact_obj ? contact_obj.displayName : participant;
_item = {nr: i, id: uuid.v4(), uri: participant, displayName: dn};
participantsData.push(_item);
i = i + 1;
});
} else {
subtitle = 'With no participants';
}
let dn;
if (participantsData.length > 4 || participantsData.length === 0) {
title = username.length > 10 ? 'Conference' : 'Conference ' + toTitleCase(username);
} else if (participantsData.length > 0 || participantsData.length <= 4 ) {
let j = 0;
title = '';
participantsData.forEach((participant) => {
if (participant.displayName === participant.uri) {
dn = toTitleCase(participant.uri.split('@')[0]);
} else {
dn = participant.displayName.split(' ')[0];
}
title = title + dn;
if (j < participantsData.length - 1) {
title = title + ' & ';
}
j = j + 1;
});
}
}
if (!displayName) {
title = uri;
if (duration === 'missed') {
subtitle = 'Last call missed';
} else if (duration === 'cancelled') {
subtitle = 'Last call cancelled';
} else {
subtitle = 'Last call duration ' + duration ;
}
}
description = description + ' (' + duration + ')';
return (
{this.setTargetUri(uri, this.props.contact)}}
style={[containerClass, cardClass]}
>
{title}
{subtitle}
{description}
{participantsData && participantsData.length && showActions ?
item.id}
key={item => item.id}
/>
: null}
{showActions ?
{showEditButton? : null}
{showDeleteButton? : null}
{showBlockButton? : null}
{showFavoriteButton?: null}
{showUndoButton?: null}
: null}
);
} else {
return (
{this.props.setTargetUri(uri, this.props.contact)}}
style={[containerClass, cardClass]}
>
{title}
{uri}
{this.state.label}
{showActions ?
{showBlockButton? : null}
{showFavoriteButton?: null}
{showUndoButton?: null}
: null}
);
}
}
}
HistoryCard.propTypes = {
id : PropTypes.string,
contact : PropTypes.object,
setTargetUri : PropTypes.func,
setBlockedUri : PropTypes.func,
setFavoriteUri : PropTypes.func,
saveInvitedParties : PropTypes.func,
deleteHistoryEntry : PropTypes.func,
orientation : PropTypes.string,
isTablet : PropTypes.bool,
contacts : PropTypes.array,
defaultDomain : PropTypes.string
};
export default HistoryCard;
diff --git a/app/components/HistoryTileBox.js b/app/components/HistoryTileBox.js
index 9ec4a71..9ad36d9 100644
--- a/app/components/HistoryTileBox.js
+++ b/app/components/HistoryTileBox.js
@@ -1,542 +1,550 @@
import React, { Component} from 'react';
import autoBind from 'auto-bind';
import PropTypes from 'prop-types';
import { SafeAreaView, ScrollView, View, FlatList, Text } from 'react-native';
import HistoryCard from './HistoryCard';
import utils from '../utils';
import DigestAuthRequest from 'digest-auth-request';
import uuid from 'react-native-uuid';
import moment from 'moment';
import momenttz from 'moment-timezone';
import styles from '../assets/styles/blink/_HistoryTileBox.scss';
class HistoryTileBox extends Component {
constructor(props) {
super(props);
autoBind(this);
this.state = {
serverHistory: this.props.serverHistory,
localHistory: this.props.localHistory,
accountId: this.props.account ? this.props.account.id : '',
password: this.props.password,
targetUri: this.props.targetUri,
favoriteUris: this.props.favoriteUris,
blockedUris: this.props.blockedUris,
isRefreshing: false,
myInvitedParties: this.props.myInvitedParties
}
const echoTest = {
remoteParty: '4444@sylk.link',
displayName: 'Echo test',
type: 'contact',
label: 'Call to test microphone',
id: uuid.v4(),
tags: ['test']
};
this.echoTest = Object.assign({}, echoTest);
const videoTest = {
remoteParty: '3333@sylk.link',
displayName: 'Video test',
type: 'contact',
label: 'Call to test video',
id: uuid.v4(),
tags: ['test']
};
this.videoTest = Object.assign({}, videoTest);
this.ended = false;
}
componentDidMount() {
this.getServerHistory();
}
componentWillUnmount() {
this.ended = true;
}
setTargetUri(uri, contact) {
//console.log('Set target uri uri in history list', uri);
this.props.setTargetUri(uri, contact);
}
deleteHistoryEntry(uri) {
this.props.deleteHistoryEntry(uri);
this.props.setTargetUri(uri);
}
setFavoriteUri(uri) {
return this.props.setFavoriteUri(uri);
}
saveInvitedParties(room, uris) {
this.props.saveInvitedParties(room, uris);
let myInvitedParties = this.state.myInvitedParties;
if (myInvitedParties && myInvitedParties.hasOwnProperty(room)) {
myInvitedParties[room] = uris;
this.setState({myInvitedParties: myInvitedParties});
}
}
setBlockedUri(uri) {
return this.props.setBlockedUri(uri);
}
renderItem(item) {
let invitedParties = [];
let uri = item.item.remoteParty;
let username = uri.split('@')[0];
if (this.state.myInvitedParties && this.state.myInvitedParties.hasOwnProperty(username)) {
invitedParties = this.state.myInvitedParties[username];
}
return(
);
}
findObjectByKey(array, key, value) {
for (var i = 0; i < array.length; i++) {
if (array[i][key] === value) {
return array[i];
}
}
return null;
}
//getDerivedStateFromProps(nextProps, state) {
UNSAFE_componentWillReceiveProps(nextProps) {
if (this.ended) {
return;
}
if (nextProps.myInvitedParties !== this.state.myInvitedParties) {
this.setState({myInvitedParties: nextProps.myInvitedParties});
}
const { refreshHistory } = this.props;
if (nextProps.refreshHistory !== refreshHistory) {
this.getServerHistory();
}
}
getLocalHistory() {
let history = this.state.localHistory;
history.sort((a, b) => (a.startTime < b.startTime) ? 1 : -1)
let known = [];
+ let uri;
+
history = history.filter((elem) => {
- if (known.indexOf(elem.remoteParty) <= -1) {
+ uri = elem.remoteParty.toLowerCase();
+
+ if (known.indexOf(uri) <= -1) {
elem.type = 'history';
if (!elem.tags) {
elem.tags = [];
}
if (elem.tags.indexOf('history') === -1) {
elem.tags.push('history');
}
if (elem.tags.indexOf('local') === -1) {
elem.tags.push('local');
}
- known.push(elem.remoteParty);
+
+ known.push(uri);
return elem;
}
});
return history;
}
getFavoriteContacts() {
let favoriteContacts = [];
let displayName;
let label;
let conference;
let contacts= this.props.contacts
contacts = contacts.concat(this.videoTest);
contacts = contacts.concat(this.echoTest);
this.state.favoriteUris.forEach((uri) => {
+ uri = uri.toLowerCase();
const contact_obj = this.findObjectByKey(contacts, 'remoteParty', uri);
displayName = contact_obj ? contact_obj.displayName : uri;
label = contact_obj ? contact_obj.label: null;
conference = false;
let tags = ['favorite'];
const history_obj = this.findObjectByKey(this.state.serverHistory, 'remoteParty', uri);
const startTime = history_obj? history_obj.startTime : null;
const stopTime = history_obj? history_obj.stopTime : null;
const duration = history_obj? history_obj.duration : 0;
let media = history_obj? history_obj.media : ['audio'];
tags.push('history');
if (uri.indexOf('@videoconference.') > -1) {
displayName = uri.split('@')[0];
uri = uri.split('@')[0] + '@' + this.props.config.defaultConferenceDomain;
conference = true;
media = ['audio', 'video', 'chat'];
}
const item = {
remoteParty: uri,
displayName: displayName,
conference: conference,
media: media,
type: 'contact',
startTime: startTime,
startTime: startTime,
duration: duration,
label: label,
id: uuid.v4(),
tags: tags
};
favoriteContacts.push(item);
});
return favoriteContacts;
}
getBlockedContacts() {
let blockedContacts = [];
let contact_obj;
let displayName;
let label;
let contacts= this.props.contacts
contacts = contacts.concat(this.videoTest);
contacts = contacts.concat(this.echoTest);
this.state.blockedUris.forEach((uri) => {
contact_obj = this.findObjectByKey(contacts, 'remoteParty', uri);
displayName = contact_obj ? contact_obj.displayName : uri;
label = contact_obj ? contact_obj.label: null;
const item = {
- remoteParty: uri,
+ remoteParty: uri.toLowerCase(),
displayName: displayName,
conference: false,
type: 'contact',
label: label,
id: uuid.v4(),
tags: ['blocked']
};
blockedContacts.push(item);
});
return blockedContacts;
}
getServerHistory() {
utils.timestampedLog('Requesting call history from server');
let history = [];
let localTime;
let hasMissedCalls = false;
this.setState({isRefreshing: true});
let getServerCallHistory = new DigestAuthRequest(
'GET',
`${this.props.config.serverCallHistoryUrl}?action=get_history&realm=${this.state.accountId.split('@')[1]}`,
this.state.accountId.split('@')[0],
this.state.password
);
// Disable logging
getServerCallHistory.loggingOn = false;
getServerCallHistory.request((data) => {
if (data.success !== undefined && data.success === false) {
console.log('Error getting call history from server', data.error_message);
return;
}
if (data.received) {
data.received.map(elem => {elem.direction = 'received'; return elem});
history = history.concat(data.received);
}
if (data.placed) {
data.placed.map(elem => {elem.direction = 'placed'; return elem});
history = history.concat(data.placed);
}
history.sort((a, b) => (a.startTime < b.startTime) ? 1 : -1)
if (history) {
const known = [];
history = history.filter((elem) => {
elem.conference = false;
if (!elem.tags) {
elem.tags = [];
}
if (elem.remoteParty.indexOf('@conference.') > -1) {
return null;
}
+ elem.remoteParty = elem.remoteParty.toLowerCase();
+
let username = elem.remoteParty.split('@')[0];
let isPhoneNumber = username.match(/^(\+|0)(\d+)$/);
let contact_obj;
if (this.props.contacts) {
if (isPhoneNumber) {
contact_obj = this.findObjectByKey(this.props.contacts, 'remoteParty', username);
} else {
contact_obj = this.findObjectByKey(this.props.contacts, 'remoteParty', elem.remoteParty);
}
}
if (contact_obj) {
elem.displayName = contact_obj.displayName;
elem.photo = contact_obj.photo;
if (isPhoneNumber) {
elem.remoteParty = username;
}
// TODO update icon here
} else {
elem.photo = null;
}
if (elem.remoteParty.indexOf('@videoconference.') > -1) {
elem.displayName = elem.remoteParty.split('@')[0];
elem.remoteParty = elem.remoteParty.split('@')[0] + '@' + this.props.config.defaultConferenceDomain;
elem.conference = true;
elem.media = ['audio', 'video', 'chat'];
}
if (elem.remoteParty === this.state.accountId) {
elem.displayName = this.props.myDisplayName || 'Myself';
}
elem.type = 'history';
elem.id = uuid.v4();
if (elem.tags.indexOf('history') === -1) {
elem.tags.push('history');
}
elem.label = elem.direction;
if (!elem.displayName) {
elem.displayName = elem.remoteParty;
}
if (!elem.media || !Array.isArray(elem.media)) {
elem.media = ['audio'];
}
if (elem.remoteParty.indexOf('3333@') > -1) {
// see Call.js as well if we change this
elem.displayName = 'Video Test';
}
if (elem.remoteParty.indexOf('4444@') > -1) {
// see Call.js as well if we change this
elem.displayName = 'Echo Test';
}
if (elem.timezone !== undefined) {
localTime = momenttz.tz(elem.startTime, elem.timezone).toDate();
elem.startTime = moment(localTime).format('YYYY-MM-DD HH:mm:ss');
localTime = momenttz.tz(elem.stopTime, elem.timezone).toDate();
elem.stopTime = moment(localTime).format('YYYY-MM-DD HH:mm:ss');
}
if (known.indexOf(elem.remoteParty) <= -1) {
known.push(elem.remoteParty);
if (elem.direction === 'received' && elem.duration === 0) {
elem.tags.push('missed');
hasMissedCalls = true;
}
return elem;
}
});
this.props.cacheHistory(history);
this.setState({serverHistory: history, isRefreshing: false});
this.props.setMissedCalls(hasMissedCalls);
}
}, (errorCode) => {
console.log('Error getting call history from server', errorCode);
});
}
render() {
if (!this.state.accountId) {
return null;
}
let history = [];
let searchExtraItems = [];
let items = [];
if (this.props.filter === 'favorite') {
let favoriteContacts = this.getFavoriteContacts();
items = favoriteContacts.filter(historyItem => historyItem.remoteParty.startsWith(this.props.targetUri));
} else if (this.props.filter === 'blocked') {
let blockedContacts = this.getBlockedContacts();
items = blockedContacts.filter(historyItem => historyItem.remoteParty.startsWith(this.props.targetUri));
} else if (this.props.filter === 'missed') {
history = this.state.serverHistory;
items = history.filter(historyItem => historyItem.remoteParty.startsWith(this.props.targetUri) && historyItem.tags.indexOf('missed') > -1);
} else {
history = this.getLocalHistory();
history = history.concat(this.state.serverHistory);
searchExtraItems = this.props.contacts;
searchExtraItems.concat(this.videoTest);
searchExtraItems.concat(this.echoTest);
items = history.filter(historyItem => historyItem.remoteParty.startsWith(this.props.targetUri));
let matchedContacts = [];
if (this.props.targetUri && this.props.targetUri.length > 2 && !this.props.selectedContact) {
matchedContacts = searchExtraItems.filter(contact => (contact.remoteParty.toLowerCase().indexOf(this.props.targetUri) > -1 || contact.displayName.toLowerCase().indexOf(this.props.targetUri) > -1));
} else if (this.props.selectedContact && this.props.selectedContact.type === 'contact') {
matchedContacts.push(this.props.selectedContact);
}
items = items.concat(matchedContacts);
}
const known = [];
items = items.filter((elem) => {
if (known.indexOf(elem.remoteParty) <= -1) {
known.push(elem.remoteParty);
return elem;
}
});
items.sort((a, b) => (a.startTime < b.startTime) ? 1 : -1)
if (!this.props.targetUri && !this.props.filter) {
if (!this.findObjectByKey(items, 'remoteParty', this.echoTest.remoteParty)) {
items.push(this.echoTest);
}
if (!this.findObjectByKey(items, 'remoteParty', this.videoTest.remoteParty)) {
items.push(this.videoTest);
}
}
items.forEach((item) => {
item.showActions = false;
if (!item.tags) {
item.tags = [];
}
if (this.state.favoriteUris.indexOf(item.remoteParty) > -1 && item.tags.indexOf('favorite') === -1) {
item.tags.push('favorite');
}
if (this.state.blockedUris.indexOf(item.remoteParty) > -1 && item.tags.indexOf('blocked') === -1) {
item.tags.push('blocked');
}
let idx = item.tags.indexOf('blocked');
if (this.state.blockedUris.indexOf(item.remoteParty) === -1 && idx > -1) {
item.tags.splice(idx, 1);
}
idx = item.tags.indexOf('favorite');
if (this.state.favoriteUris.indexOf(item.remoteParty) === -1 && idx > -1) {
item.tags.splice(idx, 1);
}
});
let filteredItems = [];
items.forEach((item) => {
if (this.props.filter && item.tags.indexOf(this.props.filter) > -1) {
filteredItems.push(item);
} else if (this.state.blockedUris.indexOf(item.remoteParty) === -1) {
filteredItems.push(item);
}
});
items = filteredItems;
if (items.length === 1) {
items[0].showActions = true;
}
let columns = 1;
if (this.props.isTablet) {
columns = this.props.orientation === 'landscape' ? 3 : 2;
} else {
columns = this.props.orientation === 'landscape' ? 2 : 1;
}
return (
item.id}
key={this.props.orientation}
/>
);
}
}
HistoryTileBox.propTypes = {
account : PropTypes.object,
password : PropTypes.string.isRequired,
config : PropTypes.object.isRequired,
targetUri : PropTypes.string,
selectedContact : PropTypes.object,
contacts : PropTypes.array,
orientation : PropTypes.string,
setTargetUri : PropTypes.func,
isTablet : PropTypes.bool,
refreshHistory : PropTypes.bool,
cacheHistory : PropTypes.func,
serverHistory : PropTypes.array,
localHistory : PropTypes.array,
myDisplayName : PropTypes.string,
myPhoneNumber : PropTypes.string,
setFavoriteUri : PropTypes.func,
saveInvitedParties: PropTypes.func,
myInvitedParties: PropTypes.object,
setBlockedUri : PropTypes.func,
deleteHistoryEntry : PropTypes.func,
favoriteUris : PropTypes.array,
blockedUris : PropTypes.array,
setMissedCalls : PropTypes.func,
filter : PropTypes.string,
defaultDomain : PropTypes.string
};
export default HistoryTileBox;