2018-08-31 16:46:33 +00:00
|
|
|
import React, { Component } from 'react';
|
2021-09-23 14:17:53 +00:00
|
|
|
import { View, Text, Animated, Easing, TouchableWithoutFeedback, TouchableOpacity, FlatList, Linking } from 'react-native';
|
2021-09-13 20:41:05 +00:00
|
|
|
import { batch, connect } from 'react-redux';
|
2020-06-15 14:00:46 +00:00
|
|
|
import { withSafeAreaInsets } from 'react-native-safe-area-context';
|
2022-02-25 18:59:39 +00:00
|
|
|
import { Subscription } from 'rxjs';
|
2018-08-31 16:46:33 +00:00
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
import * as List from '../../containers/List';
|
2021-09-23 14:17:53 +00:00
|
|
|
import Button from '../../containers/Button';
|
2022-01-14 22:06:55 +00:00
|
|
|
import { toggleServerDropdown } from '../../actions/rooms';
|
|
|
|
import { selectServerRequest, serverInitAdd } from '../../actions/server';
|
2022-02-02 18:27:10 +00:00
|
|
|
import { appStart } from '../../actions/app';
|
2018-08-31 16:46:33 +00:00
|
|
|
import I18n from '../../i18n';
|
2018-10-23 21:39:48 +00:00
|
|
|
import EventEmitter from '../../utils/events';
|
2022-04-07 17:07:16 +00:00
|
|
|
import ServerItem from '../../containers/ServerItem';
|
2019-09-16 20:26:32 +00:00
|
|
|
import database from '../../lib/database';
|
2022-04-28 20:37:25 +00:00
|
|
|
import { themes, TOKEN_KEY } from '../../lib/constants';
|
2019-12-04 16:39:53 +00:00
|
|
|
import { withTheme } from '../../theme';
|
2022-02-25 18:59:39 +00:00
|
|
|
import { KEY_COMMAND, handleCommandSelectServer, IKeyCommandEvent } from '../../commands';
|
2021-01-20 20:43:59 +00:00
|
|
|
import { isTablet } from '../../utils/deviceInfo';
|
2020-05-08 17:04:37 +00:00
|
|
|
import { localAuthenticate } from '../../utils/localAuthentication';
|
2020-05-04 20:20:45 +00:00
|
|
|
import { showConfirmationAlert } from '../../utils/info';
|
2021-09-23 14:17:53 +00:00
|
|
|
import log, { events, logEvent } from '../../utils/log';
|
2020-06-15 14:00:46 +00:00
|
|
|
import { headerHeight } from '../../containers/Header';
|
|
|
|
import { goRoom } from '../../utils/goRoom';
|
2022-04-07 13:13:19 +00:00
|
|
|
import UserPreferences from '../../lib/methods/userPreferences';
|
2022-02-25 18:59:39 +00:00
|
|
|
import { IApplicationState, IBaseScreen, RootEnum, TServerModel } from '../../definitions';
|
2021-09-13 20:41:05 +00:00
|
|
|
import styles from './styles';
|
2022-02-25 18:59:39 +00:00
|
|
|
import { ChatsStackParamList } from '../../stacks/types';
|
2022-04-28 20:37:25 +00:00
|
|
|
import { removeServer } from '../../lib/methods';
|
2018-08-31 16:46:33 +00:00
|
|
|
|
|
|
|
const ROW_HEIGHT = 68;
|
|
|
|
const ANIMATION_DURATION = 200;
|
|
|
|
|
2022-02-25 18:59:39 +00:00
|
|
|
interface IServerDropdownProps extends IBaseScreen<ChatsStackParamList, 'RoomsListView'> {
|
|
|
|
insets?: {
|
|
|
|
top: number;
|
2021-09-13 20:41:05 +00:00
|
|
|
};
|
2022-02-25 18:59:39 +00:00
|
|
|
closeServerDropdown: boolean;
|
|
|
|
server: string;
|
|
|
|
isMasterDetail: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface IServerDropdownState {
|
|
|
|
servers: TServerModel[];
|
|
|
|
}
|
|
|
|
|
|
|
|
class ServerDropdown extends Component<IServerDropdownProps, IServerDropdownState> {
|
|
|
|
private animatedValue: Animated.Value;
|
|
|
|
private subscription?: Subscription;
|
|
|
|
private newServerTimeout?: ReturnType<typeof setTimeout> | false;
|
2018-08-31 16:46:33 +00:00
|
|
|
|
2022-02-25 18:59:39 +00:00
|
|
|
constructor(props: IServerDropdownProps) {
|
2018-08-31 16:46:33 +00:00
|
|
|
super(props);
|
2019-09-16 20:26:32 +00:00
|
|
|
this.state = { servers: [] };
|
2018-08-31 16:46:33 +00:00
|
|
|
this.animatedValue = new Animated.Value(0);
|
|
|
|
}
|
|
|
|
|
2019-09-16 20:26:32 +00:00
|
|
|
async componentDidMount() {
|
|
|
|
const serversDB = database.servers;
|
2022-02-01 13:39:09 +00:00
|
|
|
const observable = await serversDB.get('servers').query().observeWithColumns(['name']);
|
2019-09-16 20:26:32 +00:00
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
this.subscription = observable.subscribe(data => {
|
2019-09-16 20:26:32 +00:00
|
|
|
this.setState({ servers: data });
|
|
|
|
});
|
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
Animated.timing(this.animatedValue, {
|
|
|
|
toValue: 1,
|
|
|
|
duration: ANIMATION_DURATION,
|
|
|
|
easing: Easing.inOut(Easing.quad),
|
|
|
|
useNativeDriver: true
|
|
|
|
}).start();
|
2019-11-25 20:01:17 +00:00
|
|
|
if (isTablet) {
|
|
|
|
EventEmitter.addEventListener(KEY_COMMAND, this.handleCommands);
|
|
|
|
}
|
2018-12-21 10:55:35 +00:00
|
|
|
}
|
|
|
|
|
2022-02-25 18:59:39 +00:00
|
|
|
componentDidUpdate(prevProps: IServerDropdownProps) {
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-27 14:26:40 +00:00
|
|
|
componentWillUnmount() {
|
|
|
|
if (this.newServerTimeout) {
|
|
|
|
clearTimeout(this.newServerTimeout);
|
|
|
|
this.newServerTimeout = false;
|
|
|
|
}
|
2019-09-16 20:26:32 +00:00
|
|
|
if (this.subscription && this.subscription.unsubscribe) {
|
|
|
|
this.subscription.unsubscribe();
|
|
|
|
}
|
2019-11-25 20:01:17 +00:00
|
|
|
if (isTablet) {
|
|
|
|
EventEmitter.removeListener(KEY_COMMAND, this.handleCommands);
|
|
|
|
}
|
2018-08-31 16:46:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
close = () => {
|
2022-01-14 22:06:55 +00:00
|
|
|
const { dispatch } = this.props;
|
2021-09-13 20:41:05 +00:00
|
|
|
Animated.timing(this.animatedValue, {
|
|
|
|
toValue: 0,
|
|
|
|
duration: ANIMATION_DURATION,
|
|
|
|
easing: Easing.inOut(Easing.quad),
|
|
|
|
useNativeDriver: true
|
2022-01-14 22:06:55 +00:00
|
|
|
}).start(() => dispatch(toggleServerDropdown()));
|
2021-09-13 20:41:05 +00:00
|
|
|
};
|
|
|
|
|
2021-09-23 14:17:53 +00:00
|
|
|
createWorkspace = async () => {
|
|
|
|
logEvent(events.RL_CREATE_NEW_WORKSPACE);
|
|
|
|
try {
|
|
|
|
await Linking.openURL('https://cloud.rocket.chat/trial');
|
|
|
|
} catch (e) {
|
|
|
|
log(e);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-02-25 18:59:39 +00:00
|
|
|
navToNewServer = (previousServer: string) => {
|
2022-01-14 22:06:55 +00:00
|
|
|
const { dispatch } = this.props;
|
2020-06-15 14:00:46 +00:00
|
|
|
batch(() => {
|
2022-02-02 18:27:10 +00:00
|
|
|
dispatch(appStart({ root: RootEnum.ROOT_OUTSIDE }));
|
2022-01-14 22:06:55 +00:00
|
|
|
dispatch(serverInitAdd(previousServer));
|
2020-06-15 14:00:46 +00:00
|
|
|
});
|
2021-09-13 20:41:05 +00:00
|
|
|
};
|
2018-09-25 19:28:42 +00:00
|
|
|
|
2020-06-15 14:00:46 +00:00
|
|
|
addServer = () => {
|
2020-07-30 13:26:17 +00:00
|
|
|
logEvent(events.RL_ADD_SERVER);
|
2020-06-15 14:00:46 +00:00
|
|
|
const { server } = this.props;
|
2018-08-31 16:46:33 +00:00
|
|
|
this.close();
|
|
|
|
setTimeout(() => {
|
2020-06-15 14:00:46 +00:00
|
|
|
this.navToNewServer(server);
|
2018-08-31 16:46:33 +00:00
|
|
|
}, ANIMATION_DURATION);
|
2021-09-13 20:41:05 +00:00
|
|
|
};
|
2018-08-31 16:46:33 +00:00
|
|
|
|
2022-02-25 18:59:39 +00:00
|
|
|
select = async (server: string, version?: string) => {
|
2022-01-14 22:06:55 +00:00
|
|
|
const { server: currentServer, dispatch, isMasterDetail } = this.props;
|
2018-08-31 16:46:33 +00:00
|
|
|
this.close();
|
2018-10-15 20:22:42 +00:00
|
|
|
if (currentServer !== server) {
|
2020-07-30 13:26:17 +00:00
|
|
|
logEvent(events.RL_CHANGE_SERVER);
|
2022-04-28 20:37:25 +00:00
|
|
|
const userId = UserPreferences.getString(`${TOKEN_KEY}-${server}`);
|
2020-06-15 14:00:46 +00:00
|
|
|
if (isMasterDetail) {
|
|
|
|
goRoom({ item: {}, isMasterDetail });
|
2019-11-25 20:01:17 +00:00
|
|
|
}
|
2019-06-26 19:50:03 +00:00
|
|
|
if (!userId) {
|
2020-04-01 15:56:08 +00:00
|
|
|
setTimeout(() => {
|
2020-06-15 14:00:46 +00:00
|
|
|
this.navToNewServer(currentServer);
|
2020-04-01 15:56:08 +00:00
|
|
|
this.newServerTimeout = setTimeout(() => {
|
|
|
|
EventEmitter.emit('NewServer', { server });
|
|
|
|
}, ANIMATION_DURATION);
|
|
|
|
}, ANIMATION_DURATION);
|
2018-10-15 20:22:42 +00:00
|
|
|
} else {
|
2020-05-08 17:04:37 +00:00
|
|
|
await localAuthenticate(server);
|
2022-01-20 17:45:40 +00:00
|
|
|
dispatch(selectServerRequest(server, version, true, true));
|
2018-08-31 16:46:33 +00:00
|
|
|
}
|
|
|
|
}
|
2021-09-13 20:41:05 +00:00
|
|
|
};
|
|
|
|
|
2022-02-25 18:59:39 +00:00
|
|
|
remove = (server: string) =>
|
2021-09-13 20:41:05 +00:00
|
|
|
showConfirmationAlert({
|
|
|
|
message: I18n.t('This_will_remove_all_data_from_this_server'),
|
|
|
|
confirmationText: I18n.t('Delete'),
|
|
|
|
onPress: async () => {
|
|
|
|
this.close();
|
|
|
|
try {
|
2022-04-28 20:37:25 +00:00
|
|
|
await removeServer({ server });
|
2021-09-13 20:41:05 +00:00
|
|
|
} catch {
|
|
|
|
// do nothing
|
|
|
|
}
|
2020-05-04 20:20:45 +00:00
|
|
|
}
|
2021-09-13 20:41:05 +00:00
|
|
|
});
|
2020-05-04 20:20:45 +00:00
|
|
|
|
2022-02-25 18:59:39 +00:00
|
|
|
handleCommands = ({ event }: { event: IKeyCommandEvent }) => {
|
2019-11-25 20:01:17 +00:00
|
|
|
const { servers } = this.state;
|
|
|
|
const { navigation } = this.props;
|
2022-02-25 18:59:39 +00:00
|
|
|
const { input } = event as unknown as { input: number };
|
2019-11-25 20:01:17 +00:00
|
|
|
if (handleCommandSelectServer(event)) {
|
|
|
|
if (servers[input - 1]) {
|
|
|
|
this.select(servers[input - 1].id);
|
|
|
|
navigation.navigate('RoomView');
|
|
|
|
}
|
|
|
|
}
|
2021-09-13 20:41:05 +00:00
|
|
|
};
|
2019-11-25 20:01:17 +00:00
|
|
|
|
2022-02-25 18:59:39 +00:00
|
|
|
renderServer = ({ item }: { item: { id: string; iconURL: string; name: string; version: string } }) => {
|
2022-04-07 17:07:16 +00:00
|
|
|
const { server } = this.props;
|
2018-09-25 19:28:42 +00:00
|
|
|
|
|
|
|
return (
|
2021-01-20 20:43:59 +00:00
|
|
|
<ServerItem
|
|
|
|
item={item}
|
2021-01-21 17:20:28 +00:00
|
|
|
onPress={() => this.select(item.id, item.version)}
|
2021-09-13 20:41:05 +00:00
|
|
|
onLongPress={() => item.id === server || this.remove(item.id)}
|
2021-01-20 20:43:59 +00:00
|
|
|
hasCheck={item.id === server}
|
|
|
|
/>
|
2018-09-25 19:28:42 +00:00
|
|
|
);
|
2021-09-13 20:41:05 +00:00
|
|
|
};
|
2018-08-31 16:46:33 +00:00
|
|
|
|
|
|
|
render() {
|
2018-09-25 19:28:42 +00:00
|
|
|
const { servers } = this.state;
|
2020-06-15 14:00:46 +00:00
|
|
|
const { theme, isMasterDetail, insets } = this.props;
|
2018-08-31 16:46:33 +00:00
|
|
|
const maxRows = 4;
|
2021-09-23 14:17:53 +00:00
|
|
|
const initialTop = 87 + Math.min(servers.length, maxRows) * ROW_HEIGHT;
|
2020-06-15 14:00:46 +00:00
|
|
|
const statusBarHeight = insets?.top ?? 0;
|
|
|
|
const heightDestination = isMasterDetail ? headerHeight + statusBarHeight : 0;
|
2018-08-31 16:46:33 +00:00
|
|
|
const translateY = this.animatedValue.interpolate({
|
|
|
|
inputRange: [0, 1],
|
2020-06-15 14:00:46 +00:00
|
|
|
outputRange: [-initialTop, heightDestination]
|
2018-08-31 16:46:33 +00:00
|
|
|
});
|
|
|
|
const backdropOpacity = this.animatedValue.interpolate({
|
|
|
|
inputRange: [0, 1],
|
2021-02-19 18:05:47 +00:00
|
|
|
outputRange: [0, themes[theme].backdropOpacity]
|
2018-08-31 16:46:33 +00:00
|
|
|
});
|
|
|
|
return (
|
2019-12-04 16:39:53 +00:00
|
|
|
<>
|
|
|
|
<TouchableWithoutFeedback onPress={this.close}>
|
2021-09-13 20:41:05 +00:00
|
|
|
<Animated.View
|
|
|
|
style={[
|
|
|
|
styles.backdrop,
|
|
|
|
{
|
|
|
|
backgroundColor: themes[theme].backdropColor,
|
|
|
|
opacity: backdropOpacity,
|
|
|
|
top: heightDestination
|
|
|
|
}
|
|
|
|
]}
|
2020-06-15 14:00:46 +00:00
|
|
|
/>
|
2019-12-04 16:39:53 +00:00
|
|
|
</TouchableWithoutFeedback>
|
2018-08-31 16:46:33 +00:00
|
|
|
<Animated.View
|
2019-12-04 16:39:53 +00:00
|
|
|
style={[
|
|
|
|
styles.dropdownContainer,
|
|
|
|
{
|
|
|
|
transform: [{ translateY }],
|
|
|
|
backgroundColor: themes[theme].backgroundColor,
|
|
|
|
borderColor: themes[theme].separatorColor
|
|
|
|
}
|
|
|
|
]}
|
2021-09-13 20:41:05 +00:00
|
|
|
testID='rooms-list-header-server-dropdown'>
|
|
|
|
<View style={[styles.dropdownContainerHeader, styles.serverHeader, { borderColor: themes[theme].separatorColor }]}>
|
2019-12-04 16:39:53 +00:00
|
|
|
<Text style={[styles.serverHeaderText, { color: themes[theme].auxiliaryText }]}>{I18n.t('Server')}</Text>
|
2018-08-31 16:46:33 +00:00
|
|
|
<TouchableOpacity onPress={this.addServer} testID='rooms-list-header-server-add'>
|
2019-12-04 16:39:53 +00:00
|
|
|
<Text style={[styles.serverHeaderAdd, { color: themes[theme].tintColor }]}>{I18n.t('Add_Server')}</Text>
|
2018-08-31 16:46:33 +00:00
|
|
|
</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}
|
2021-02-26 16:27:04 +00:00
|
|
|
ItemSeparatorComponent={List.Separator}
|
2019-11-25 20:01:17 +00:00
|
|
|
keyboardShouldPersistTaps='always'
|
2018-08-31 16:46:33 +00:00
|
|
|
/>
|
2021-09-23 14:17:53 +00:00
|
|
|
<List.Separator />
|
|
|
|
<Button
|
|
|
|
title={I18n.t('Create_a_new_workspace')}
|
|
|
|
type='secondary'
|
|
|
|
onPress={this.createWorkspace}
|
|
|
|
theme={theme}
|
|
|
|
testID='rooms-list-header-create-workspace-button'
|
|
|
|
style={styles.buttonCreateWorkspace}
|
|
|
|
color={themes[theme].tintColor}
|
|
|
|
styleText={[styles.serverHeaderAdd, { textAlign: 'center' }]}
|
|
|
|
/>
|
2018-08-31 16:46:33 +00:00
|
|
|
</Animated.View>
|
2019-12-04 16:39:53 +00:00
|
|
|
</>
|
2018-08-31 16:46:33 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2019-08-07 13:51:34 +00:00
|
|
|
|
2022-02-25 18:59:39 +00:00
|
|
|
const mapStateToProps = (state: IApplicationState) => ({
|
2019-08-07 13:51:34 +00:00
|
|
|
closeServerDropdown: state.rooms.closeServerDropdown,
|
2020-06-15 14:00:46 +00:00
|
|
|
server: state.server.server,
|
|
|
|
isMasterDetail: state.app.isMasterDetail
|
2019-08-07 13:51:34 +00:00
|
|
|
});
|
|
|
|
|
2022-01-14 22:06:55 +00:00
|
|
|
export default connect(mapStateToProps)(withSafeAreaInsets(withTheme(ServerDropdown)));
|