From 4ca9fcddb850148fb15eb04283d441c565f9b850 Mon Sep 17 00:00:00 2001
From: Diego Mello <diegolmello@gmail.com>
Date: Mon, 13 Nov 2017 11:53:45 -0200
Subject: [PATCH] Add servers (#61)

* - Add server from logged session working
---
 app/actions/actionsTypes.js |  8 +++++++-
 app/actions/server.js       |  6 ++++++
 app/containers/Routes.js    |  1 +
 app/containers/Sidebar.js   | 17 ++++++++++++++---
 app/lib/rocketchat.js       |  3 +++
 app/sagas/login.js          |  9 ++++-----
 app/sagas/selectServer.js   | 13 +++++++++++--
 app/views/LoginView.js      | 11 +++++++----
 app/views/RegisterView.js   | 16 +++++++++-------
 9 files changed, 62 insertions(+), 22 deletions(-)

diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js
index fa841ad85..d0a621d6c 100644
--- a/app/actions/actionsTypes.js
+++ b/app/actions/actionsTypes.js
@@ -40,7 +40,13 @@ export const CREATE_CHANNEL = createRequestTypes('CREATE_CHANNEL', [
 	'RESET'
 ]);
 export const NAVIGATION = createRequestTypes('NAVIGATION', ['SET']);
-export const SERVER = createRequestTypes('SERVER', [...defaultTypes, 'SELECT', 'CHANGED', 'ADD']);
+export const SERVER = createRequestTypes('SERVER', [
+	...defaultTypes,
+	'SELECT',
+	'CHANGED',
+	'ADD',
+	'GOTO_ADD'
+]);
 export const METEOR = createRequestTypes('METEOR_CONNECT', [...defaultTypes, 'DISCONNECT']);
 export const LOGOUT = 'LOGOUT'; // logout is always success
 
diff --git a/app/actions/server.js b/app/actions/server.js
index cfc46ad89..b334981b5 100644
--- a/app/actions/server.js
+++ b/app/actions/server.js
@@ -41,3 +41,9 @@ export function changedServer(server) {
 		server
 	};
 }
+
+export function gotoAddServer() {
+	return {
+		type: SERVER.GOTO_ADD
+	};
+}
diff --git a/app/containers/Routes.js b/app/containers/Routes.js
index 2255e3021..e1e57e950 100644
--- a/app/containers/Routes.js
+++ b/app/containers/Routes.js
@@ -32,6 +32,7 @@ export default class Routes extends React.Component {
 	componentDidUpdate() {
 		NavigationService.setNavigator(this.navigator);
 	}
+
 	render() {
 		const { login, app } = this.props;
 
diff --git a/app/containers/Sidebar.js b/app/containers/Sidebar.js
index b9a289e9e..303f02ab6 100644
--- a/app/containers/Sidebar.js
+++ b/app/containers/Sidebar.js
@@ -5,7 +5,7 @@ import { DrawerItems } from 'react-navigation';
 import { connect } from 'react-redux';
 
 import realm from '../lib/realm';
-import { setServer } from '../actions/server';
+import { setServer, gotoAddServer } from '../actions/server';
 import { logout } from '../actions/login';
 
 const styles = StyleSheet.create({
@@ -41,14 +41,16 @@ const styles = StyleSheet.create({
 	server: state.server.server
 }), dispatch => ({
 	selectServer: server => dispatch(setServer(server)),
-	logout: () => dispatch(logout())
+	logout: () => dispatch(logout()),
+	gotoAddServer: () => dispatch(gotoAddServer())
 }))
 export default class Sidebar extends Component {
 	static propTypes = {
 		server: PropTypes.string.isRequired,
 		selectServer: PropTypes.func.isRequired,
 		navigation: PropTypes.object.isRequired,
-		logout: PropTypes.func.isRequired
+		logout: PropTypes.func.isRequired,
+		gotoAddServer: PropTypes.func.isRequired
 	}
 
 	componentWillMount() {
@@ -117,6 +119,15 @@ export default class Sidebar extends Component {
 							</Text>
 						</View>
 					</TouchableHighlight>
+					<TouchableHighlight
+						onPress={() => { this.props.gotoAddServer(); }}
+					>
+						<View style={styles.serverItem}>
+							<Text>
+								Add Server
+							</Text>
+						</View>
+					</TouchableHighlight>
 				</View>
 			</ScrollView>
 		);
diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js
index 60aec3413..22585a6ff 100644
--- a/app/lib/rocketchat.js
+++ b/app/lib/rocketchat.js
@@ -23,6 +23,8 @@ const call = (method, ...params) => new Promise((resolve, reject) => {
 const TOKEN_KEY = 'reactnativemeteor_usertoken';
 
 const RocketChat = {
+	TOKEN_KEY,
+
 	createChannel({ name, users, type }) {
 		return new Promise((resolve, reject) => {
 			Meteor.call(type ? 'createChannel' : 'createPrivateGroup', name, users, type, (err, res) => (err ? reject(err) : resolve(res)));
@@ -449,6 +451,7 @@ const RocketChat = {
 	},
 	logout({ server }) {
 		Meteor.logout();
+		Meteor.disconnect();
 		AsyncStorage.removeItem(TOKEN_KEY);
 		AsyncStorage.removeItem(`${ TOKEN_KEY }-${ server }`);
 	}
diff --git a/app/sagas/login.js b/app/sagas/login.js
index 302b56042..bd9b5287a 100644
--- a/app/sagas/login.js
+++ b/app/sagas/login.js
@@ -19,7 +19,6 @@ import {
 import RocketChat from '../lib/rocketchat';
 import * as NavigationService from '../containers/routes/NavigationService';
 
-const TOKEN_KEY = 'reactnativemeteor_usertoken';
 const getUser = state => state.login;
 const getServer = state => state.server.server;
 const loginCall = args => (args.resume ? RocketChat.login(args) : RocketChat.loginWithPassword(args));
@@ -31,11 +30,11 @@ const forgotPasswordCall = args => RocketChat.forgotPassword(args);
 
 const getToken = function* getToken() {
 	const currentServer = yield select(getServer);
-	const user = yield call([AsyncStorage, 'getItem'], `${ TOKEN_KEY }-${ currentServer }`);
+	const user = yield call([AsyncStorage, 'getItem'], `${ RocketChat.TOKEN_KEY }-${ currentServer }`);
 	if (user) {
 		try {
 			yield put(setToken(JSON.parse(user)));
-			yield call([AsyncStorage, 'setItem'], TOKEN_KEY, JSON.parse(user).token || '');
+			yield call([AsyncStorage, 'setItem'], RocketChat.TOKEN_KEY, JSON.parse(user).token || '');
 			return JSON.parse(user);
 		} catch (e) {
 			console.log('getTokenerr', e);
@@ -61,8 +60,8 @@ const handleLoginWhenServerChanges = function* handleLoginWhenServerChanges() {
 
 const saveToken = function* saveToken() {
 	const [server, user] = yield all([select(getServer), select(getUser)]);
-	yield AsyncStorage.setItem(TOKEN_KEY, user.token);
-	yield AsyncStorage.setItem(`${ TOKEN_KEY }-${ server }`, JSON.stringify(user));
+	yield AsyncStorage.setItem(RocketChat.TOKEN_KEY, user.token);
+	yield AsyncStorage.setItem(`${ RocketChat.TOKEN_KEY }-${ server }`, JSON.stringify(user));
 };
 
 const handleLoginRequest = function* handleLoginRequest({ credentials }) {
diff --git a/app/sagas/selectServer.js b/app/sagas/selectServer.js
index dc9b039ec..84ad3a3ee 100644
--- a/app/sagas/selectServer.js
+++ b/app/sagas/selectServer.js
@@ -1,12 +1,13 @@
 import { put, takeEvery, call, takeLatest, race, take } from 'redux-saga/effects';
 import { delay } from 'redux-saga';
 import { AsyncStorage } from 'react-native';
-// import { Navigation } from 'react-native-navigation';
 import { SERVER } from '../actions/actionsTypes';
 import { connectRequest, disconnect } from '../actions/connect';
-import { changedServer, serverSuccess, serverFailure, serverRequest } from '../actions/server';
+import { changedServer, serverSuccess, serverFailure, serverRequest, setServer } from '../actions/server';
+import { logout } from '../actions/login';
 import RocketChat from '../lib/rocketchat';
 import realm from '../lib/realm';
+import * as NavigationService from '../containers/routes/NavigationService';
 
 const validate = function* validate(server) {
 	return yield RocketChat.testServer(server);
@@ -42,13 +43,21 @@ const addServer = function* addServer({ server }) {
 		realm.write(() => {
 			realm.create('servers', { id: server, current: false }, true);
 		});
+		yield put(setServer(server));
 	}
 };
 
+const handleGotoAddServer = function* handleGotoAddServer() {
+	yield put(logout());
+	yield call(AsyncStorage.removeItem, RocketChat.TOKEN_KEY);
+	yield delay(1000);
+	yield call(NavigationService.navigate, 'AddServer');
+};
 
 const root = function* root() {
 	yield takeLatest(SERVER.REQUEST, validateServer);
 	yield takeEvery(SERVER.SELECT, selectServer);
 	yield takeEvery(SERVER.ADD, addServer);
+	yield takeEvery(SERVER.GOTO_ADD, handleGotoAddServer);
 };
 export default root;
diff --git a/app/views/LoginView.js b/app/views/LoginView.js
index 4ee33cae8..2c66c6830 100644
--- a/app/views/LoginView.js
+++ b/app/views/LoginView.js
@@ -114,12 +114,15 @@ class LoginView extends React.Component {
 
 						{this.renderTOTP()}
 
-						<TouchableOpacity style={styles.buttonContainer}>
-							<Text style={styles.button} onPress={this.submit}>LOGIN</Text>
+						<TouchableOpacity
+							style={styles.buttonContainer}
+							onPress={this.submit}
+						>
+							<Text style={styles.button}>LOGIN</Text>
 						</TouchableOpacity>
 
-						<TouchableOpacity style={styles.buttonContainer}>
-							<Text style={styles.button} onPress={this.register}>REGISTER</Text>
+						<TouchableOpacity style={styles.buttonContainer} onPress={this.register}>
+							<Text style={styles.button}>REGISTER</Text>
 						</TouchableOpacity>
 
 						<TouchableOpacity style={styles.buttonContainer} onPress={this.termsService}>
diff --git a/app/views/RegisterView.js b/app/views/RegisterView.js
index 656605727..0f861efb8 100644
--- a/app/views/RegisterView.js
+++ b/app/views/RegisterView.js
@@ -119,12 +119,14 @@ class RegisterView extends React.Component {
 					placeholder={this.props.Accounts_RepeatPasswordPlaceholder || 'Repeat Password'}
 				/>
 
-				<TouchableOpacity style={[styles.buttonContainer, styles.registerContainer]}>
+				<TouchableOpacity
+					style={[styles.buttonContainer, styles.registerContainer]}
+					onPress={this.submit}
+				>
 					<Text
 						style={[styles.button, this._valid() ? {}
 							: { color: placeholderTextColor }
 						]}
-						onPress={this.submit}
 					>REGISTER</Text>
 				</TouchableOpacity>
 
@@ -151,11 +153,11 @@ class RegisterView extends React.Component {
 					placeholder={this.props.Accounts_UsernamePlaceholder || 'Username'}
 				/>
 
-				<TouchableOpacity style={[styles.buttonContainer, styles.registerContainer]}>
-					<Text
-						style={styles.button}
-						onPress={this.usernameSubmit}
-					>REGISTER</Text>
+				<TouchableOpacity
+					style={[styles.buttonContainer, styles.registerContainer]}
+					onPress={this.usernameSubmit}
+				>
+					<Text style={styles.button}>REGISTER</Text>
 				</TouchableOpacity>
 
 				{this.props.login.failure && <Text style={styles.error}>{this.props.login.error.reason}</Text>}
-- 
GitLab