2018-08-31 16:46:33 +00:00
|
|
|
import React, { Component } from 'react';
|
2018-09-25 19:28:42 +00:00
|
|
|
import {
|
|
|
|
View, Text, Animated, Easing, TouchableWithoutFeedback, TouchableOpacity, FlatList, Image, AsyncStorage
|
|
|
|
} from 'react-native';
|
2018-08-31 16:46:33 +00:00
|
|
|
import PropTypes from 'prop-types';
|
2018-10-23 21:39:48 +00:00
|
|
|
import { connect } from 'react-redux';
|
2018-09-28 18:57:29 +00:00
|
|
|
import { Navigation } from 'react-native-navigation';
|
2018-10-15 20:22:42 +00:00
|
|
|
import * as SDK from '@rocket.chat/sdk';
|
2018-12-21 10:55:35 +00:00
|
|
|
import equal from 'deep-equal';
|
2018-08-31 16:46:33 +00:00
|
|
|
|
2018-09-25 19:28:42 +00:00
|
|
|
import { toggleServerDropdown as toggleServerDropdownAction } from '../../actions/rooms';
|
|
|
|
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
|
|
|
|
import { appStart as appStartAction } from '../../actions';
|
2018-08-31 16:46:33 +00:00
|
|
|
import styles from './styles';
|
|
|
|
import database from '../../lib/realm';
|
|
|
|
import Touch from '../../utils/touch';
|
|
|
|
import RocketChat from '../../lib/rocketchat';
|
|
|
|
import I18n from '../../i18n';
|
2018-10-23 21:39:48 +00:00
|
|
|
import EventEmitter from '../../utils/events';
|
2018-08-31 16:46:33 +00:00
|
|
|
|
|
|
|
const ROW_HEIGHT = 68;
|
|
|
|
const ANIMATION_DURATION = 200;
|
|
|
|
|
|
|
|
@connect(state => ({
|
|
|
|
closeServerDropdown: state.rooms.closeServerDropdown,
|
|
|
|
server: state.server.server
|
|
|
|
}), dispatch => ({
|
2018-09-25 19:28:42 +00:00
|
|
|
toggleServerDropdown: () => dispatch(toggleServerDropdownAction()),
|
|
|
|
selectServerRequest: server => dispatch(selectServerRequestAction(server)),
|
|
|
|
appStart: () => dispatch(appStartAction('outside'))
|
2018-08-31 16:46:33 +00:00
|
|
|
}))
|
|
|
|
export default class ServerDropdown extends Component {
|
|
|
|
static propTypes = {
|
|
|
|
closeServerDropdown: PropTypes.bool,
|
|
|
|
server: PropTypes.string,
|
|
|
|
toggleServerDropdown: PropTypes.func,
|
|
|
|
selectServerRequest: PropTypes.func,
|
|
|
|
appStart: PropTypes.func
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2018-12-21 10:55:35 +00:00
|
|
|
this.servers = database.databases.serversDB.objects('servers');
|
2018-08-31 16:46:33 +00:00
|
|
|
this.state = {
|
2018-12-21 10:55:35 +00:00
|
|
|
servers: this.servers
|
2018-08-31 16:46:33 +00:00
|
|
|
};
|
|
|
|
this.animatedValue = new Animated.Value(0);
|
2018-12-21 10:55:35 +00:00
|
|
|
this.servers.addListener(this.updateState);
|
2018-08-31 16:46:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
Animated.timing(
|
|
|
|
this.animatedValue,
|
|
|
|
{
|
|
|
|
toValue: 1,
|
|
|
|
duration: ANIMATION_DURATION,
|
2018-12-21 10:55:35 +00:00
|
|
|
easing: Easing.inOut(Easing.quad),
|
2018-08-31 16:46:33 +00:00
|
|
|
useNativeDriver: true
|
|
|
|
},
|
|
|
|
).start();
|
2018-12-21 10:55:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
shouldComponentUpdate(nextProps, nextState) {
|
|
|
|
const { servers } = this.state;
|
|
|
|
const { closeServerDropdown, server } = this.props;
|
|
|
|
if (nextProps.closeServerDropdown !== closeServerDropdown) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (nextProps.server !== server) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (!equal(nextState.servers, servers)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2018-08-31 16:46:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
componentDidUpdate(prevProps) {
|
2018-09-25 19:28:42 +00:00
|
|
|
const { closeServerDropdown } = this.props;
|
|
|
|
if (prevProps.closeServerDropdown !== closeServerDropdown) {
|
2018-08-31 16:46:33 +00:00
|
|
|
this.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
updateState = () => {
|
|
|
|
const { servers } = this;
|
|
|
|
this.setState({ servers });
|
|
|
|
}
|
|
|
|
|
|
|
|
close = () => {
|
2018-09-25 19:28:42 +00:00
|
|
|
const { toggleServerDropdown } = this.props;
|
2018-08-31 16:46:33 +00:00
|
|
|
Animated.timing(
|
|
|
|
this.animatedValue,
|
|
|
|
{
|
|
|
|
toValue: 0,
|
|
|
|
duration: ANIMATION_DURATION,
|
2018-12-21 10:55:35 +00:00
|
|
|
easing: Easing.inOut(Easing.quad),
|
2018-08-31 16:46:33 +00:00
|
|
|
useNativeDriver: true
|
|
|
|
}
|
2018-09-25 19:28:42 +00:00
|
|
|
).start(() => toggleServerDropdown());
|
2018-08-31 16:46:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
addServer = () => {
|
2018-10-23 21:39:48 +00:00
|
|
|
const { server } = this.props;
|
2018-09-25 19:28:42 +00:00
|
|
|
|
2018-08-31 16:46:33 +00:00
|
|
|
this.close();
|
|
|
|
setTimeout(() => {
|
2018-10-23 21:39:48 +00:00
|
|
|
Navigation.showModal({
|
|
|
|
stack: {
|
|
|
|
children: [{
|
|
|
|
component: {
|
|
|
|
name: 'OnboardingView',
|
|
|
|
passProps: {
|
|
|
|
previousServer: server
|
|
|
|
},
|
|
|
|
options: {
|
|
|
|
topBar: {
|
|
|
|
visible: false
|
|
|
|
},
|
|
|
|
layout: {
|
|
|
|
orientation: 'portrait'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}]
|
2018-08-31 16:46:33 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}, ANIMATION_DURATION);
|
|
|
|
}
|
|
|
|
|
|
|
|
select = async(server) => {
|
2018-09-25 19:28:42 +00:00
|
|
|
const {
|
2018-10-23 21:39:48 +00:00
|
|
|
server: currentServer, selectServerRequest, appStart
|
2018-09-25 19:28:42 +00:00
|
|
|
} = this.props;
|
|
|
|
|
2018-08-31 16:46:33 +00:00
|
|
|
this.close();
|
2018-10-15 20:22:42 +00:00
|
|
|
if (currentServer !== server) {
|
2018-08-31 16:46:33 +00:00
|
|
|
const token = await AsyncStorage.getItem(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
|
|
|
if (!token) {
|
2018-09-25 19:28:42 +00:00
|
|
|
appStart();
|
2018-10-15 20:22:42 +00:00
|
|
|
try {
|
|
|
|
SDK.driver.disconnect();
|
|
|
|
} catch (error) {
|
|
|
|
console.warn(error);
|
|
|
|
}
|
2018-08-31 16:46:33 +00:00
|
|
|
setTimeout(() => {
|
2018-10-23 21:39:48 +00:00
|
|
|
EventEmitter.emit('NewServer', { server });
|
2018-08-31 16:46:33 +00:00
|
|
|
}, 1000);
|
2018-10-15 20:22:42 +00:00
|
|
|
} else {
|
|
|
|
selectServerRequest(server);
|
2018-08-31 16:46:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
renderSeparator = () => <View style={styles.serverSeparator} />;
|
|
|
|
|
2018-09-25 19:28:42 +00:00
|
|
|
renderServer = ({ item }) => {
|
|
|
|
const { server } = this.props;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Touch onPress={() => this.select(item.id)} style={styles.serverItem} testID={`rooms-list-header-server-${ item.id }`}>
|
|
|
|
<View style={styles.serverItemContainer}>
|
|
|
|
{item.iconURL
|
|
|
|
? (
|
|
|
|
<Image
|
|
|
|
source={{ uri: item.iconURL }}
|
|
|
|
defaultSource={{ uri: 'logo' }}
|
|
|
|
style={styles.serverIcon}
|
2018-10-15 20:22:42 +00:00
|
|
|
onError={() => console.warn('error loading serverIcon')}
|
2018-09-25 19:28:42 +00:00
|
|
|
/>
|
|
|
|
)
|
|
|
|
: (
|
|
|
|
<Image
|
|
|
|
source={{ uri: 'logo' }}
|
|
|
|
style={styles.serverIcon}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
<View style={styles.serverTextContainer}>
|
|
|
|
<Text style={styles.serverName}>{item.name || item.id}</Text>
|
|
|
|
<Text style={styles.serverUrl}>{item.id}</Text>
|
|
|
|
</View>
|
|
|
|
{item.id === server ? <Image style={styles.checkIcon} source={{ uri: 'check' }} /> : null}
|
2018-08-31 16:46:33 +00:00
|
|
|
</View>
|
2018-09-25 19:28:42 +00:00
|
|
|
</Touch>
|
|
|
|
);
|
|
|
|
}
|
2018-08-31 16:46:33 +00:00
|
|
|
|
|
|
|
render() {
|
2018-09-25 19:28:42 +00:00
|
|
|
const { servers } = this.state;
|
2018-08-31 16:46:33 +00:00
|
|
|
const maxRows = 4;
|
2018-09-25 19:28:42 +00:00
|
|
|
const initialTop = 41 + (Math.min(servers.length, maxRows) * ROW_HEIGHT);
|
2018-08-31 16:46:33 +00:00
|
|
|
const translateY = this.animatedValue.interpolate({
|
|
|
|
inputRange: [0, 1],
|
|
|
|
outputRange: [-initialTop, 0]
|
|
|
|
});
|
|
|
|
const backdropOpacity = this.animatedValue.interpolate({
|
|
|
|
inputRange: [0, 1],
|
|
|
|
outputRange: [0, 0.3]
|
|
|
|
});
|
|
|
|
return (
|
|
|
|
[
|
|
|
|
<TouchableWithoutFeedback key='sort-backdrop' onPress={this.close}>
|
|
|
|
<Animated.View style={[styles.backdrop, { opacity: backdropOpacity }]} />
|
|
|
|
</TouchableWithoutFeedback>,
|
|
|
|
<Animated.View
|
|
|
|
key='sort-container'
|
|
|
|
style={[styles.dropdownContainer, { transform: [{ translateY }] }]}
|
|
|
|
testID='rooms-list-header-server-dropdown'
|
|
|
|
>
|
|
|
|
<View style={[styles.dropdownContainerHeader, styles.serverHeader]}>
|
|
|
|
<Text style={styles.serverHeaderText}>{I18n.t('Server')}</Text>
|
|
|
|
<TouchableOpacity onPress={this.addServer} testID='rooms-list-header-server-add'>
|
|
|
|
<Text style={styles.serverHeaderAdd}>{I18n.t('Add_Server')}</Text>
|
|
|
|
</TouchableOpacity>
|
|
|
|
</View>
|
|
|
|
<FlatList
|
|
|
|
style={{ maxHeight: maxRows * ROW_HEIGHT }}
|
2018-09-25 19:28:42 +00:00
|
|
|
data={servers}
|
2018-08-31 16:46:33 +00:00
|
|
|
keyExtractor={item => item.id}
|
|
|
|
renderItem={this.renderServer}
|
|
|
|
ItemSeparatorComponent={this.renderSeparator}
|
|
|
|
/>
|
|
|
|
</Animated.View>
|
|
|
|
]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|