Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7313466
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
29 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/app/components/NavigationBar.js b/app/components/NavigationBar.js
index d9bda81..b24770b 100644
--- a/app/components/NavigationBar.js
+++ b/app/components/NavigationBar.js
@@ -1,632 +1,633 @@
import React, { Component } from 'react';
import { Linking, Image, Platform, View } from 'react-native';
import PropTypes from 'prop-types';
import autoBind from 'auto-bind';
import { Appbar, Menu, Divider, Text } from 'react-native-paper';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import config from '../config';
import styles from '../assets/styles/blink/_NavigationBar.scss';
const blinkLogo = require('../assets/images/blink-white-big.png');
import AboutModal from './AboutModal';
import CallMeMaybeModal from './CallMeMaybeModal';
import EditConferenceModal from './EditConferenceModal';
import AddContactModal from './AddContactModal';
import EditContactModal from './EditContactModal';
import ExportPrivateKeyModal from './ExportPrivateKeyModal';
import DeleteHistoryModal from './DeleteHistoryModal';
import VersionNumber from 'react-native-version-number';
import ShareConferenceLinkModal from './ShareConferenceLinkModal';
class NavigationBar extends Component {
constructor(props) {
super(props);
autoBind(this);
let displayName = this.props.selectedContact ? this.props.selectedContact.name : this.props.displayName;
let organization = this.props.selectedContact ? this.props.selectedContact.organization : this.props.organization;
this.state = {
syncConversations: this.props.syncConversations,
inCall: this.props.inCall,
showCallMeMaybeModal: this.props.showCallMeMaybeModal,
contactsLoaded: this.props.contactsLoaded,
appStoreVersion: this.props.appStoreVersion,
showExportPrivateKeyModal: this.props.showExportPrivateKeyModal,
privateKeyPassword: null,
registrationState: this.props.registrationState,
connection: this.props.connection,
proximity: this.props.proximity,
selectedContact: this.props.selectedContact,
mute: false,
menuVisible: false,
accountId: this.props.accountId,
account: this.props.account,
displayName: displayName,
myDisplayName: this.props.myDisplayName,
email: this.props.email,
organization: organization,
publicKey: this.props.publicKey,
showPublicKey: false,
messages: this.props.messages,
userClosed: false,
blockedUris: this.props.blockedUris,
ssiRequired: this.props.ssiRequired,
filteredMessageIds: this.props.filteredMessageIds,
contentTypes: this.props.contentTypes
}
this.menuRef = React.createRef();
}
//getDerivedStateFromProps(nextProps, state) {
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.account !== null && nextProps.account.id !== this.state.accountId) {
this.setState({accountId: nextProps.accountId});
}
let displayName = nextProps.selectedContact ? nextProps.selectedContact.name : nextProps.displayName;
let organization = nextProps.selectedContact ? nextProps.selectedContact.organization : nextProps.organization;
this.setState({registrationState: nextProps.registrationState,
connection: nextProps.connection,
syncConversations: nextProps.syncConversations,
contactsLoaded: nextProps.contactsLoaded,
displayName: displayName,
myDisplayName: nextProps.myDisplayName,
appStoreVersion: nextProps.appStoreVersion,
showExportPrivateKeyModal: nextProps.showExportPrivateKeyModal,
email: nextProps.email,
organization: organization,
proximity: nextProps.proximity,
account: nextProps.account,
userClosed: true,
inCall: nextProps.inCall,
publicKey: nextProps.publicKey,
showDeleteHistoryModal: nextProps.showDeleteHistoryModal,
selectedContact: nextProps.selectedContact,
messages: nextProps.messages,
showCallMeMaybeModal: nextProps.showCallMeMaybeModal,
blockedUris: nextProps.blockedUris,
ssiRequired: nextProps.ssiRequired,
filteredMessageIds: nextProps.filteredMessageIds,
contentTypes: nextProps.contentTypes
});
if (nextProps.menuVisible) {
this.setState({menuVisible: nextProps.menuVisible});
console.log('Next menu visible', nextProps.menuVisible);
}
}
handleMenu(event) {
this.callUrl = `${config.publicUrl}/call/${this.state.accountId}`;
switch (event) {
case 'about':
this.toggleAboutModal();
break;
case 'callMeMaybe':
this.props.toggleCallMeMaybeModal();
break;
case 'shareConferenceLinkModal':
this.showConferenceLinkModal();
break;
case 'displayName':
this.toggleEditContactModal();
break;
case 'speakerphone':
this.props.toggleSpeakerPhone();
break;
case 'proximity':
this.props.toggleProximity();
break;
case 'ssi':
this.props.toggleSSIFunc();
break;
case 'logOut':
this.props.logout();
break;
case 'logs':
this.props.showLogs();
break;
case 'refetchMessages':
this.props.refetchMessages();
break;
case 'deleteSsiCredential':
this.props.deleteSsiCredential(this.state.selectedContact);
break;
case 'deleteSsiConnection':
this.props.deleteSsiConnection(this.state.selectedContact);
break;
case 'preview':
this.props.preview();
break;
case 'audio':
this.audioCall();
break;
case 'video':
this.videoCall();
break;
case 'resumeTransfers':
this.resumeTransfers();
break;
case 'conference':
this.conferenceCall();
break;
case 'addContact':
this.toggleAddContactModal();
break;
case 'editContact':
if (this.state.selectedContact && this.state.selectedContact.uri.indexOf('@videoconference') > -1) {
this.setState({showEditConferenceModal: true});
} else {
this.setState({showEditContactModal: true});
}
break;
case 'deleteMessages':
this.setState({showDeleteHistoryModal: true});
break;
case 'toggleFavorite':
this.props.toggleFavorite(this.state.selectedContact.uri);
break;
case 'toggleBlocked':
this.props.toggleBlocked(this.state.selectedContact.uri);
break;
case 'sendPublicKey':
this.props.sendPublicKey(this.state.selectedContact.uri);
break;
case 'exportPrivateKey':
if (this.state.publicKey) {
this.showExportPrivateKeyModal();
} else {
this.props.showImportModal(true);
}
break;
case 'showPublicKey':
this.setState({showEditContactModal: !this.state.showEditContactModal, showPublicKey: true});
break;
case 'checkUpdate':
if (Platform.OS === 'android') {
Linking.openURL('https://play.google.com/store/apps/details?id=com.agprojects.sylk');
} else {
Linking.openURL('https://apps.apple.com/us/app/id1489960733');
}
break;
case 'settings':
Linking.openURL(config.serverSettingsUrl);
break;
default:
break;
}
this.setState({menuVisible: false});
}
saveContact(displayName, organization='', email='') {
if (!displayName) {
return;
}
if (this.state.selectedContact && this.state.selectedContact.uri !== this.state.accountId) {
this.props.saveContact(this.state.selectedContact.uri, displayName, organization);
} else {
this.setState({displayName: displayName});
this.props.saveContact(this.state.accountId, displayName, organization, email);
}
}
toggleMute() {
this.setState(prevState => ({mute: !prevState.mute}));
this.props.toggleMute();
}
toggleAboutModal() {
this.setState({showAboutModal: !this.state.showAboutModal});
}
showConferenceLinkModal() {
this.setState({showConferenceLinkModal: true});
}
hideConferenceLinkModal() {
this.setState({showConferenceLinkModal: false});
}
audioCall() {
let uri = this.state.selectedContact.uri;
this.props.startCall(uri, {audio: true, video: false});
}
videoCall() {
let uri = this.state.selectedContact.uri;
this.props.startCall(uri, {audio: true, video: true});
}
resumeTransfers() {
this.props.resumeTransfers();
}
conferenceCall() {
this.props.showConferenceModalFunc();
}
toggleAddContactModal() {
this.setState({showAddContactModal: !this.state.showAddContactModal});
}
closeDeleteHistoryModal() {
this.setState({showDeleteHistoryModal: false});
}
showEditContactModal() {
this.setState({showEditContactModal: true,
showPublicKey: false});
}
hideEditContactModal() {
this.setState({showEditContactModal: false,
showPublicKey: false,
userClosed: true});
}
saveConference(room, participants, displayName=null) {
this.props.saveConference(room, participants, displayName);
this.setState({showEditConferenceModal: false});
}
toggleEditContactModal() {
if (this.state.showEditContactModal) {
this.hideEditContactModal();
} else {
this.showEditContactModal();
};
}
closeEditConferenceModal() {
this.setState({showEditConferenceModal: false});
}
showExportPrivateKeyModal() {
const password = Math.random().toString().substr(2, 6);
this.setState({privateKeyPassword: password});
this.props.showExportPrivateKeyModalFunc()
}
render() {
const muteIcon = this.state.mute ? 'bell-off' : 'bell';
if (this.state.menuVisible && !this.state.appStoreVersion) {
this.props.checkVersionFunc()
}
let subtitleStyle = this.props.isTablet ? styles.tabletSubtitle: styles.subtitle;
let titleStyle = this.props.isTablet ? styles.tabletTitle: styles.title;
let statusIcon = null;
let statusColor = 'green';
let tags = [];
statusIcon = 'check-circle';
if (!this.state.connection || this.state.connection.state !== 'ready') {
statusIcon = 'alert-circle';
statusColor = 'red';
} else if (this.state.registrationState !== 'registered') {
statusIcon = 'alert-circle';
statusColor = 'orange';
}
let callUrl = callUrl = config.publicUrl + "/call/" + this.state.accountId;
let subtitle = 'Signed in as ' + this.state.accountId;
let proximityTitle = this.state.proximity ? 'No proximity sensor' : 'Proximity sensor';
let proximityIcon = this.state.proximity ? 'ear-hearing-off' : 'ear-hearing';
let isConference = false;
let hasMessages = true; // allow user to select this after local messages were removed, to delete them remotely
if (this.state.selectedContact) {
if (Object.keys(this.state.messages).indexOf(this.state.selectedContact.uri) > -1 && this.state.messages[this.state.selectedContact.uri].length > 0) {
hasMessages = true;
}
tags = this.state.selectedContact.tags;
isConference = this.state.selectedContact.conference || tags.indexOf('conference') > -1;
}
let favoriteTitle = (this.state.selectedContact && tags && tags.indexOf('favorite') > -1) ? 'Unfavorite' : 'Favorite';
let favoriteIcon = (this.state.selectedContact && tags && tags.indexOf('favorite') > -1) ? 'flag-minus' : 'flag';
let extraMenu = false;
let importKeyLabel = this.state.publicKey ? "Export private key...": "Import private key...";
let showEditModal = false;
if (this.state.selectedContact) {
showEditModal = this.state.showEditContactModal && !this.state.syncConversations;
} else {
showEditModal = !this.state.syncConversations && this.state.contactsLoaded &&
(this.state.showEditContactModal || (!this.state.displayName && this.state.publicKey !== null && !this.state.userClosed))
|| false;
}
let hasUpdate = this.state.appStoreVersion && this.state.appStoreVersion.version > VersionNumber.appVersion;
let updateTitle = hasUpdate ? 'Update Sylk...' : 'Check for updates...';
let isAnonymous = this.state.selectedContact && (this.state.selectedContact.uri.indexOf('@guest.') > -1 || this.state.selectedContact.uri.indexOf('anonymous@') > -1);
let canCall = !isConference && !this.state.inCall && !isAnonymous && tags.indexOf('ssi') === -1;
let blockedTitle = (this.state.selectedContact && tags && tags.indexOf('blocked') > -1) ? 'Unblock' : isAnonymous ? 'Block anonymous callers': 'Block';
if (isAnonymous && this.state.blockedUris.indexOf('anonymous@anonymous.invalid') > -1) {
blockedTitle = 'Allow anonymous callers';
}
let ssiTitle = this.state.ssiRequired ? 'Disable SSI' : 'Enable SSI';
return (
<Appbar.Header style={{backgroundColor: 'black'}}>
{this.state.selectedContact?
<Appbar.BackAction onPress={() => {this.props.goBackFunc()}} />
: <Image source={blinkLogo} style={styles.logo}/>}
<Appbar.Content
title="Sylk"
titleStyle={titleStyle}
subtitleStyle={subtitleStyle}
subtitle={this.props.isTablet? null: ((this.state.accountId || 'Loading...') + (this.state.myDisplayName ? ' (' + this.state.myDisplayName + ')' : ''))}
/>
{this.props.isTablet?
<Text style={subtitleStyle}>{subtitle}</Text>
: null}
{statusColor == 'green' ?
<Icon name={statusIcon} size={20} color={statusColor} />
: null }
{ this.state.selectedContact ?
<Menu
visible={this.state.menuVisible}
onDismiss={() => this.setState({menuVisible: !this.state.menuVisible})}
anchor={
<Appbar.Action
ref={this.menuRef}
color="white"
icon="menu"
onPress={() => this.setState({menuVisible: !this.state.menuVisible})}
/>
}
>
+ {tags.indexOf('ssi') === -1 ? <Menu.Item onPress={() => this.handleMenu('editContact')} icon="account" title="Edit contact..."/> : null}
+
{canCall ? <Menu.Item onPress={() => this.handleMenu('audio')} icon="phone" title="Audio call"/> :null}
{canCall ? <Menu.Item onPress={() => this.handleMenu('video')} icon="video" title="Video call"/> :null}
{!this.state.inCall && isConference ? <Menu.Item onPress={() => this.handleMenu('conference')} icon="account-group" title="Join conference..."/> :null}
{!this.state.inCall && isConference ? <Menu.Item onPress={() => this.handleMenu('shareConferenceLinkModal')} icon="share-variant" title="Share web link..."/> :null}
{ hasMessages && !this.state.inCall && tags.indexOf('ssi') === -1 ?
<Menu.Item onPress={() => this.handleMenu('deleteMessages')} icon="delete" title="Delete messages..."/>
: null
}
{ hasMessages && !this.state.inCall && tags.indexOf('ssi') === -1 && 'paused' in this.state.contentTypes ?
<Menu.Item onPress={() => this.handleMenu('resumeTransfers')} icon="delete" title="Resume transfers"/>
: null
}
{ hasMessages && tags.indexOf('test') === -1 && !isConference && false?
<Menu.Item onPress={() => this.handleMenu('sendPublicKey')} icon="key-change" title="Send my public key..."/>
: null}
{this.props.publicKey && false?
<Menu.Item onPress={() => this.handleMenu('showPublicKey')} icon="key-variant" title="Show public key..."/>
: null}
{tags.indexOf('test') === -1 && !this.state.inCall && !isAnonymous && tags.indexOf('ssi') === -1 ?
<Menu.Item onPress={() => this.handleMenu('toggleFavorite')} icon={favoriteIcon} title={favoriteTitle}/>
: null}
<Divider />
{tags.indexOf('test') === -1 && tags.indexOf('favorite') === -1 && !this.state.inCall && tags.indexOf('ssi') === -1 ?
<Menu.Item onPress={() => this.handleMenu('toggleBlocked')} icon="block-helper" title={blockedTitle}/>
: null}
{!this.state.inCall && !hasMessages && tags.indexOf('test') === -1 && tags.indexOf('ssi') === -1?
<Menu.Item onPress={() => this.handleMenu('deleteMessages')} icon="delete" title="Delete contact..."/>
: null}
{tags.indexOf('ssi') === -1 ? <Menu.Item onPress={() => this.handleMenu('editContact')} icon="account" title="Edit contact..."/> : null}
{this.state.selectedContact && tags.indexOf('ssi-credential') > -1?
<Menu.Item onPress={() => this.handleMenu('deleteSsiCredential')} icon="delete" title="Delete SSI credential..."/>
: null}
{this.state.selectedContact && tags.indexOf('ssi-connection') > -1 && tags.indexOf('readonly') === -1 ?
<Menu.Item onPress={() => this.handleMenu('deleteSsiConnection')} icon="delete" title="Delete SSI connection..."/>
: null}
</Menu>
:
<Menu
visible={this.state.menuVisible}
onDismiss={() => this.setState({menuVisible: !this.state.menuVisible})}
anchor={
<Appbar.Action
ref={this.menuRef}
color="white"
icon="menu"
onPress={() => this.setState({menuVisible: !this.state.menuVisible})}
/>
}
>
<Menu.Item onPress={() => this.handleMenu('callMeMaybe')} icon="share" title="Call me, maybe?" />
{!this.state.syncConversations && !this.state.inCall ?
<Menu.Item onPress={() => this.handleMenu('displayName')} icon="rename-box" title="My account..." />
: null}
<Menu.Item onPress={() => this.handleMenu('addContact')} icon="account-plus" title="Add contact..."/>
- {!this.state.inCall ? <Menu.Item onPress={() => this.handleMenu('conference')} icon="account-group" title="Join conference..."/> :null}
+ {!this.state.inCall && false ? <Menu.Item onPress={() => this.handleMenu('conference')} icon="account-group" title="Join conference..."/> :null}
{!this.state.inCall && false ? <Menu.Item onPress={() => this.handleMenu('preview')} icon="video" title="Video preview" />:null}
{!this.state.inCall ? <Menu.Item onPress={() => this.handleMenu('exportPrivateKey')} icon="key" title={importKeyLabel} />:null}
{false ? <Menu.Item onPress={() => this.handleMenu('checkUpdate')} icon="update" title={updateTitle} /> :null}
{!this.state.inCall ? <Menu.Item onPress={() => this.handleMenu('deleteMessages')} icon="delete" title="Wipe device..."/> :null}
- {!this.state.inCall && __DEV__ ? <Menu.Item onPress={() => this.handleMenu('refetchMessages')} icon="delete" title="Refetch messages (DEV)"/> :null}
<Divider/>
{extraMenu ?
<View>
<Menu.Item onPress={() => this.handleMenu('settings')} icon="wrench" title="Server settings..." />
<Menu.Item onPress={() => this.handleMenu('proximity')} icon={proximityIcon} title={proximityTitle} />
</View>
: null}
<Menu.Item onPress={() => this.handleMenu('ssi')} icon="key" title={ssiTitle}/>
<Menu.Item onPress={() => this.handleMenu('logs')} icon="timeline-text-outline" title="Logs" />
{!this.state.inCall ?
<Menu.Item onPress={() => this.handleMenu('about')} icon="information" title="About Sylk"/> : null}
<Divider />
{!this.state.inCall ?
<Menu.Item onPress={() => this.handleMenu('logOut')} icon="logout" title="Sign out" /> : null}
</Menu>
}
<AboutModal
show={this.state.showAboutModal}
close={this.toggleAboutModal}
currentVersion={VersionNumber.appVersion}
appStoreVersion={this.state.appStoreVersion}
/>
<CallMeMaybeModal
show={this.state.showCallMeMaybeModal}
close={this.props.toggleCallMeMaybeModal}
callUrl={callUrl}
notificationCenter={this.props.notificationCenter}
/>
<DeleteHistoryModal
show={this.state.showDeleteHistoryModal}
close={this.closeDeleteHistoryModal}
uri={this.state.selectedContact ? this.state.selectedContact.uri : null}
displayName={this.state.displayName}
hasMessages={hasMessages}
deleteContactFunc={this.props.removeContact}
deleteMessages={this.props.deleteMessages}
filteredMessageIds={this.state.filteredMessageIds}
/>
<AddContactModal
show={this.state.showAddContactModal}
close={this.toggleAddContactModal}
saveContact={this.props.saveContact}
defaultDomain={this.props.defaultDomain}
/>
<EditContactModal
show={showEditModal}
close={this.hideEditContactModal}
uri={this.state.selectedContact ? this.state.selectedContact.uri : this.state.accountId}
displayName={this.state.displayName}
edit={this.state.email}
organization={this.state.organization}
email={this.state.email}
myself={!this.state.selectedContact || (this.state.selectedContact && this.state.selectedContact.uri === this.state.accountId) ? true : false}
saveContact={this.saveContact}
deleteContact={this.props.deleteContact}
deletePublicKey={this.props.deletePublicKey}
publicKey={this.state.showPublicKey ? this.state.publicKey: null}
myuuid={this.props.myuuid}
/>
<EditConferenceModal
show={this.state.showEditConferenceModal}
close={this.closeEditConferenceModal}
room={this.state.selectedContact ? this.state.selectedContact.uri.split('@')[0]: ''}
displayName={this.state.displayName}
participants={this.state.selectedContact ? this.state.selectedContact.participants : []}
selectedContact={this.state.selectedContact}
toggleFavorite={this.props.toggleFavorite}
saveConference={this.saveConference}
defaultDomain={this.props.defaultDomain}
accountId={this.state.accountId}
favoriteUris={this.props.favoriteUris}
/>
<ShareConferenceLinkModal
notificationCenter={this.props.notificationCenter}
show={this.state.showConferenceLinkModal}
close={this.hideConferenceLinkModal}
room={this.state.selectedContact ? this.state.selectedContact.uri: ''}
/>
<ExportPrivateKeyModal
show={this.state.showExportPrivateKeyModal}
password={this.state.privateKeyPassword}
close={this.props.hideExportPrivateKeyModalFunc}
saveFunc={this.props.replicateKey}
publicKeyHash={this.state.publicKeyHash}
publicKey={this.state.publicKey}
/>
</Appbar.Header>
);
}
}
NavigationBar.propTypes = {
notificationCenter : PropTypes.func.isRequired,
logout : PropTypes.func.isRequired,
preview : PropTypes.func.isRequired,
toggleSpeakerPhone : PropTypes.func.isRequired,
toggleProximity : PropTypes.func.isRequired,
showLogs : PropTypes.func.isRequired,
inCall : PropTypes.bool,
contactsLoaded : PropTypes.bool,
proximity : PropTypes.bool,
displayName : PropTypes.string,
myDisplayName : PropTypes.string,
email : PropTypes.string,
organization : PropTypes.string,
account : PropTypes.object,
accountId : PropTypes.string,
connection : PropTypes.object,
toggleMute : PropTypes.func,
orientation : PropTypes.string,
isTablet : PropTypes.bool,
selectedContact : PropTypes.object,
goBackFunc : PropTypes.func,
replicateKey : PropTypes.func,
publicKeyHash : PropTypes.string,
publicKey : PropTypes.string,
deleteMessages : PropTypes.func,
toggleBlocked : PropTypes.func,
toggleFavorite : PropTypes.func,
saveConference : PropTypes.func,
defaultDomain : PropTypes.string,
favoriteUris : PropTypes.array,
startCall : PropTypes.func,
startConference : PropTypes.func,
saveContact : PropTypes.func,
addContact : PropTypes.func,
deleteContact : PropTypes.func,
removeContact : PropTypes.func,
deletePublicKey : PropTypes.func,
sendPublicKey : PropTypes.func,
messages : PropTypes.object,
showImportModal : PropTypes.func,
syncConversations : PropTypes.bool,
showCallMeMaybeModal: PropTypes.bool,
toggleCallMeMaybeModal : PropTypes.func,
showConferenceModalFunc : PropTypes.func,
appStoreVersion : PropTypes.object,
checkVersionFunc: PropTypes.func,
toggleSSIFunc: PropTypes.func,
ssiRequired: PropTypes.bool,
refetchMessages: PropTypes.func,
showExportPrivateKeyModal: PropTypes.bool,
showExportPrivateKeyModalFunc: PropTypes.func,
hideExportPrivateKeyModalFunc: PropTypes.func,
blockedUris: PropTypes.array,
myuuid: PropTypes.string,
deleteSsiCredential: PropTypes.func,
resumeTransfers: PropTypes.func,
deleteSsiConnection: PropTypes.func,
filteredMessageIds: PropTypes.array,
contentTypes: PropTypes.object
};
export default NavigationBar;
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Feb 1, 2:15 PM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3489390
Default Alt Text
(29 KB)
Attached To
Mode
rSYLKWRTCM Sylk WebRTC mobile
Attached
Detach File
Event Timeline
Log In to Comment