From 3cd84a10f6e48d97062178c35b6ff38f820d5c9e Mon Sep 17 00:00:00 2001
From: Diego Mello <diegolmello@gmail.com>
Date: Wed, 5 Jun 2019 16:11:29 -0300
Subject: [PATCH] [FIX] Change server issue (#960)

* [FIX] Lazy fetch server info

* [FIX] Multiple servers issues
---
 app/lib/rocketchat.js                         | 116 +++++++++---------
 app/sagas/selectServer.js                     |   4 +-
 .../RoomsListView/Header/Header.android.js    |   6 +-
 app/views/RoomsListView/Header/Header.ios.js  |   8 +-
 app/views/RoomsListView/Header/index.js       |   2 +-
 5 files changed, 73 insertions(+), 63 deletions(-)

diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js
index b7ccf6c03..9b7e16e2c 100644
--- a/app/lib/rocketchat.js
+++ b/app/lib/rocketchat.js
@@ -174,71 +174,75 @@ const RocketChat = {
 		this.getUserPresence();
 	},
 	connect({ server, user }) {
-		database.setActiveDB(server);
-		reduxStore.dispatch(connectRequest());
-
-		if (this.connectTimeout) {
-			clearTimeout(this.connectTimeout);
-		}
+		return new Promise((resolve) => {
+			database.setActiveDB(server);
+			reduxStore.dispatch(connectRequest());
 
-		if (this.sdk) {
-			this.sdk.disconnect();
-			this.sdk = null;
-		}
+			if (this.connectTimeout) {
+				clearTimeout(this.connectTimeout);
+			}
 
-		// Use useSsl: false only if server url starts with http://
-		const useSsl = !/http:\/\//.test(server);
+			if (this.sdk) {
+				this.sdk.disconnect();
+				this.sdk = null;
+			}
 
-		this.sdk = new RocketchatClient({ host: server, protocol: 'ddp', useSsl });
-		this.getSettings();
+			// Use useSsl: false only if server url starts with http://
+			const useSsl = !/http:\/\//.test(server);
+
+			this.sdk = new RocketchatClient({ host: server, protocol: 'ddp', useSsl });
+			this.getSettings();
+
+			this.sdk.connect()
+				.then(() => {
+					if (user && user.token) {
+						reduxStore.dispatch(loginRequest({ resume: user.token }));
+					}
+				})
+				.catch((err) => {
+					console.log('connect error', err);
+
+					// when `connect` raises an error, we try again in 10 seconds
+					this.connectTimeout = setTimeout(() => {
+						this.connect({ server, user });
+					}, 10000);
+				});
 
-		this.sdk.connect()
-			.then(() => {
-				if (user && user.token) {
-					reduxStore.dispatch(loginRequest({ resume: user.token }));
+			this.sdk.onStreamData('connected', () => {
+				reduxStore.dispatch(connectSuccess());
+				const { isAuthenticated } = reduxStore.getState().login;
+				if (isAuthenticated) {
+					this.getUserPresence();
 				}
-			})
-			.catch((err) => {
-				console.log('connect error', err);
-
-				// when `connect` raises an error, we try again in 10 seconds
-				this.connectTimeout = setTimeout(() => {
-					this.connect({ server, user });
-				}, 10000);
 			});
 
-		this.sdk.onStreamData('connected', () => {
-			reduxStore.dispatch(connectSuccess());
-			const { isAuthenticated } = reduxStore.getState().login;
-			if (isAuthenticated) {
-				this.getUserPresence();
-			}
-		});
-
-		this.sdk.onStreamData('close', () => {
-			reduxStore.dispatch(disconnect());
-		});
-
-		this.sdk.onStreamData('users', protectedFunction(ddpMessage => RocketChat._setUser(ddpMessage)));
+			this.sdk.onStreamData('close', () => {
+				reduxStore.dispatch(disconnect());
+			});
 
-		this.sdk.onStreamData('stream-notify-logged', protectedFunction((ddpMessage) => {
-			const { eventName } = ddpMessage.fields;
-			if (eventName === 'user-status') {
-				const userStatus = ddpMessage.fields.args[0];
-				const [id, username, status] = userStatus;
-				if (username) {
-					database.memoryDatabase.write(() => {
-						try {
-							database.memoryDatabase.create('activeUsers', {
-								id, username, status: STATUSES[status]
-							}, true);
-						} catch (error) {
-							console.log(error);
-						}
-					});
+			this.sdk.onStreamData('users', protectedFunction(ddpMessage => RocketChat._setUser(ddpMessage)));
+
+			this.sdk.onStreamData('stream-notify-logged', protectedFunction((ddpMessage) => {
+				const { eventName } = ddpMessage.fields;
+				if (eventName === 'user-status') {
+					const userStatus = ddpMessage.fields.args[0];
+					const [id, username, status] = userStatus;
+					if (username) {
+						database.memoryDatabase.write(() => {
+							try {
+								database.memoryDatabase.create('activeUsers', {
+									id, username, status: STATUSES[status]
+								}, true);
+							} catch (error) {
+								console.log(error);
+							}
+						});
+					}
 				}
-			}
-		}));
+			}));
+
+			resolve();
+		});
 	},
 
 	register(credentials) {
diff --git a/app/sagas/selectServer.js b/app/sagas/selectServer.js
index 10aad2fad..859103901 100644
--- a/app/sagas/selectServer.js
+++ b/app/sagas/selectServer.js
@@ -39,11 +39,11 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch
 
 		if (userStringified) {
 			const user = JSON.parse(userStringified);
-			RocketChat.connect({ server, user });
+			yield RocketChat.connect({ server, user });
 			yield put(setUser(user));
 			yield put(actions.appStart('inside'));
 		} else {
-			RocketChat.connect({ server });
+			yield RocketChat.connect({ server });
 			yield put(actions.appStart('outside'));
 		}
 
diff --git a/app/views/RoomsListView/Header/Header.android.js b/app/views/RoomsListView/Header/Header.android.js
index a2393caf0..333677fc7 100644
--- a/app/views/RoomsListView/Header/Header.android.js
+++ b/app/views/RoomsListView/Header/Header.android.js
@@ -60,7 +60,11 @@ const Header = React.memo(({
 	}
 	return (
 		<View style={styles.container}>
-			<TouchableOpacity onPress={onPress} testID='rooms-list-header-server-dropdown-button'>
+			<TouchableOpacity
+				onPress={onPress}
+				testID='rooms-list-header-server-dropdown-button'
+				disabled={connecting || isFetching}
+			>
 				{connecting ? <Text style={styles.updating}>{I18n.t('Connecting')}</Text> : null}
 				{isFetching ? <Text style={styles.updating}>{I18n.t('Updating')}</Text> : null}
 				<View style={styles.button}>
diff --git a/app/views/RoomsListView/Header/Header.ios.js b/app/views/RoomsListView/Header/Header.ios.js
index 20d6f9b13..09adacfec 100644
--- a/app/views/RoomsListView/Header/Header.ios.js
+++ b/app/views/RoomsListView/Header/Header.ios.js
@@ -40,13 +40,14 @@ const styles = StyleSheet.create({
 });
 
 const HeaderTitle = React.memo(({ connecting, isFetching }) => {
+	let title = I18n.t('Messages');
 	if (connecting) {
-		return <Text style={styles.title}>{I18n.t('Connecting')}</Text>;
+		title = I18n.t('Connecting');
 	}
 	if (isFetching) {
-		return <Text style={styles.title}>{I18n.t('Updating')}</Text>;
+		title = I18n.t('Updating');
 	}
-	return <Text style={styles.title}>{I18n.t('Messages')}</Text>;
+	return <Text style={styles.title}>{title}</Text>;
 });
 
 const Header = React.memo(({
@@ -57,6 +58,7 @@ const Header = React.memo(({
 			onPress={onPress}
 			testID='rooms-list-header-server-dropdown-button'
 			style={styles.container}
+			disabled={connecting || isFetching}
 		>
 			<HeaderTitle connecting={connecting} isFetching={isFetching} />
 			<View style={styles.button}>
diff --git a/app/views/RoomsListView/Header/index.js b/app/views/RoomsListView/Header/index.js
index 853602b5a..74c679b58 100644
--- a/app/views/RoomsListView/Header/index.js
+++ b/app/views/RoomsListView/Header/index.js
@@ -11,7 +11,7 @@ import Header from './Header';
 	showServerDropdown: state.rooms.showServerDropdown,
 	showSortDropdown: state.rooms.showSortDropdown,
 	showSearchHeader: state.rooms.showSearchHeader,
-	connecting: state.meteor.connecting,
+	connecting: state.meteor.connecting || state.server.loading,
 	isFetching: state.rooms.isFetching,
 	serverName: state.settings.Site_Name
 }), dispatch => ({
-- 
GitLab