diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js
index ef66104a60847cf913c9aaae4b208bd48601b06e..308c4baa6f373b7482b749bd61151a52487f8af8 100644
--- a/app/actions/actionsTypes.js
+++ b/app/actions/actionsTypes.js
@@ -9,7 +9,17 @@ function createRequestTypes(base, types = defaultTypes) {
 }
 
 // Login events
-export const LOGIN = createRequestTypes('LOGIN', [...defaultTypes, 'SET_TOKEN', 'SUBMIT']);
+export const LOGIN = createRequestTypes('LOGIN', [
+	...defaultTypes,
+	'SET_TOKEN',
+	'SUBMIT',
+	'REGISTER_SUBMIT',
+	'REGISTER_REQUEST',
+	'REGISTER_SUCCESS',
+	'SET_USERNAME_SUBMIT',
+	'SET_USERNAME_REQUEST',
+	'SET_USERNAME_SUCCESS'
+]);
 export const ROOMS = createRequestTypes('ROOMS');
 export const APP = createRequestTypes('APP', ['READY', 'INIT']);
 export const MESSAGES = createRequestTypes('MESSAGES');
diff --git a/app/actions/login.js b/app/actions/login.js
index 7969c80904daa767ba454905b339a668d27264b2..1a8f753e82111b6141b23dc1f4fa996c92c9215b 100644
--- a/app/actions/login.js
+++ b/app/actions/login.js
@@ -13,6 +13,46 @@ export function loginRequest(credentials) {
 	};
 }
 
+
+export function registerSubmit(credentials) {
+	return {
+		type: types.LOGIN.REGISTER_SUBMIT,
+		credentials
+	};
+}
+export function registerRequest(credentials) {
+	return {
+		type: types.LOGIN.REGISTER_REQUEST,
+		credentials
+	};
+}
+export function registerSuccess(credentials) {
+	return {
+		type: types.LOGIN.REGISTER_SUCCESS,
+		credentials
+	};
+}
+
+export function setUsernameSubmit(credentials) {
+	return {
+		type: types.LOGIN.SET_USERNAME_SUBMIT,
+		credentials
+	};
+}
+
+export function setUsernameRequest(credentials) {
+	return {
+		type: types.LOGIN.SET_USERNAME_REQUEST,
+		credentials
+	};
+}
+
+export function setUsernameSuccess() {
+	return {
+		type: types.LOGIN.SET_USERNAME_SUCCESS
+	};
+}
+
 export function loginSuccess(user) {
 	return {
 		type: types.LOGIN.SUCCESS,
diff --git a/app/containers/Routes.js b/app/containers/Routes.js
index 485dd389d4e1dd5afeb7fa817aa049641a3d9030..83268096c16dbfd4919bce399802199b7f6a8944 100644
--- a/app/containers/Routes.js
+++ b/app/containers/Routes.js
@@ -1,15 +1,12 @@
 import PropTypes from 'prop-types';
 import React from 'react';
-import { View, Image } from 'react-native';
 import { bindActionCreators } from 'redux';
 import { connect } from 'react-redux';
-import * as Animatable from 'react-native-animatable';
 import { appInit } from '../actions';
 
-import styles from '../views/Styles';
-
 import AuthRoutes from './routes/AuthRoutes';
 import PublicRoutes from './routes/PublicRoutes';
+import Loading from '../presentation/Loading';
 
 @connect(
 	state => ({
@@ -34,21 +31,10 @@ export default class Routes extends React.Component {
 		const { login, app } = this.props;
 
 		if (app.starting) {
-			return (
-				<View style={styles.logoContainer}>
-					<Animatable.Text
-						animation='pulse'
-						easing='ease-out'
-						iterationCount='infinite'
-						style={{ textAlign: 'center' }}
-					>
-						<Image style={styles.logo} source={require('../images/logo.png')} />
-					</Animatable.Text>
-				</View>
-			);
+			return (<Loading />);
 		}
 
-		if ((login.token && !login.failure) || app.ready) {
+		if ((login.token && !login.failure && !login.isRegistering) || app.ready) {
 			return (<AuthRoutes />);
 		}
 
diff --git a/app/containers/routes/AuthRoutes.js b/app/containers/routes/AuthRoutes.js
index 6bef854552e4a286be1c8f513e076e04ea9d5389..2c1a9f35e08e41c3f957999c9d522f2f1222aa18 100644
--- a/app/containers/routes/AuthRoutes.js
+++ b/app/containers/routes/AuthRoutes.js
@@ -1,7 +1,5 @@
 import React from 'react';
-import { Button } from 'react-native';
-import { StackNavigator, DrawerNavigator, NavigationActions } from 'react-navigation';
-// import { Platform } from 'react-native';
+import { StackNavigator, DrawerNavigator, NavigationActions, HeaderBackButton } from 'react-navigation';
 
 import Sidebar from '../../containers/Sidebar';
 import DrawerMenuButton from '../../presentation/DrawerMenuButton';
@@ -39,7 +37,10 @@ const AuthRoutes = StackNavigator(
 				return {
 					title: navigation.state.params.title || 'Room',
 					headerLeft: (
-						<Button title={'Back'} onPress={() => backToScreen(navigation, 'RoomsList')} />
+						<HeaderBackButton
+							title={'Back'}
+							onPress={() => backToScreen(navigation, 'RoomsList')}
+						/>
 					)
 					// [drawerIconPosition]: (<DrawerMenuButton navigation={navigation} />)÷
 				};
diff --git a/app/containers/routes/PublicRoutes.js b/app/containers/routes/PublicRoutes.js
index 3cf851f5cb35453aae285e59e300aa2782fcfc87..a99583cd22a5d86546e98b4b46292cedb7b16f92 100644
--- a/app/containers/routes/PublicRoutes.js
+++ b/app/containers/routes/PublicRoutes.js
@@ -6,6 +6,7 @@ import Icon from 'react-native-vector-icons/FontAwesome';
 import ListServerView from '../../views/ListServerView';
 import NewServerView from '../../views/NewServerView';
 import LoginView from '../../views/LoginView';
+import RegisterView from '../../views/RegisterView';
 
 const PublicRoutes = StackNavigator(
 	{
@@ -36,6 +37,12 @@ const PublicRoutes = StackNavigator(
 			navigationOptions: {
 				title: 'Login'
 			}
+		},
+		Register: {
+			screen: RegisterView,
+			navigationOptions: {
+				title: 'Register'
+			}
 		}
 	},
 	{
diff --git a/app/images/logo_with_text.png b/app/images/logo_with_text.png
new file mode 100644
index 0000000000000000000000000000000000000000..623349a06ad0f2735cb64e6601481882ff4aa153
Binary files /dev/null and b/app/images/logo_with_text.png differ
diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js
index 71ddb447d8d71a115a19c4b837d92b6c2427766d..352eb00bbe60deccd48899a60a0a0d52982c5af2 100644
--- a/app/lib/rocketchat.js
+++ b/app/lib/rocketchat.js
@@ -122,6 +122,28 @@ const RocketChat = {
 		});
 	},
 
+	register({ credentials }) {
+		return new Promise((resolve, reject) => {
+			Meteor.call('registerUser', credentials, (err, userId) => {
+				if (err) {
+					reject(err);
+				}
+				resolve(userId);
+			});
+		});
+	},
+
+	setUsername({ credentials }) {
+		return new Promise((resolve, reject) => {
+			Meteor.call('setUsername', credentials.username, (err, result) => {
+				if (err) {
+					reject(err);
+				}
+				resolve(result);
+			});
+		});
+	},
+
 	loginWithPassword({ username, password, code }, callback) {
 		let params = {};
 		const state = reduxStore.getState();
diff --git a/app/presentation/KeyboardView.js b/app/presentation/KeyboardView.js
index 3a6ea5f66d8b770d6510a20f232a1ec767e8791f..f3e29d9c2c16f178985c2ad3cd7e21fb90b2b1fb 100644
--- a/app/presentation/KeyboardView.js
+++ b/app/presentation/KeyboardView.js
@@ -1,11 +1,14 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { KeyboardAvoidingView } from 'react-native';
+import { ViewPropTypes } from 'react-native';
+import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
 
 export default class KeyboardView extends React.PureComponent {
 	static propTypes = {
-		style: KeyboardAvoidingView.propTypes.style,
+		style: ViewPropTypes.style,
+		contentContainerStyle: ViewPropTypes.style,
 		keyboardVerticalOffset: PropTypes.number,
+		scrollEnabled: PropTypes.bool,
 		children: PropTypes.oneOfType([
 			PropTypes.arrayOf(PropTypes.node),
 			PropTypes.node
@@ -14,9 +17,18 @@ export default class KeyboardView extends React.PureComponent {
 
 	render() {
 		return (
-			<KeyboardAvoidingView style={this.props.style} behavior='padding' keyboardVerticalOffset={this.props.keyboardVerticalOffset}>
+			<KeyboardAwareScrollView
+				keyboardDismissMode='interactive'
+				keyboardShouldPersistTaps='always'
+				style={this.props.style}
+				contentContainerStyle={this.props.contentContainerStyle}
+				scrollEnabled={this.props.scrollEnabled}
+				alwaysBounceVertical={false}
+				extraHeight={this.props.keyboardVerticalOffset}
+				behavior='position'
+			>
 				{this.props.children}
-			</KeyboardAvoidingView>
+			</KeyboardAwareScrollView>
 		);
 	}
 }
diff --git a/app/presentation/Loading.js b/app/presentation/Loading.js
new file mode 100644
index 0000000000000000000000000000000000000000..ed92f1192169eb6279e33b5c11f457daaec50c17
--- /dev/null
+++ b/app/presentation/Loading.js
@@ -0,0 +1,77 @@
+import React, { Component } from 'react';
+import { View, StyleSheet, Animated, Dimensions } from 'react-native';
+
+const logo = require('../images/logo.png');
+
+
+const styles = StyleSheet.create({
+	container: {
+		flex: 1,
+		width: '100%',
+		alignItems: 'center',
+		justifyContent: 'center'
+	},
+	background: {
+		width: Dimensions.get('window').width,
+		height: Dimensions.get('window').height,
+		alignItems: 'center',
+		justifyContent: 'center'
+	},
+	logo: {
+		width: Dimensions.get('window').width - 100,
+		height: Dimensions.get('window').width - 100,
+		resizeMode: 'contain'
+	}
+});
+
+export default class Loading extends Component {
+	constructor(props) {
+		super(props);
+
+		this.scale = new Animated.Value(1.0);
+	}
+
+	componentDidMount() {
+		requestAnimationFrame(() => {
+			this.animate();
+		});
+	}
+
+	animate = () => {
+		Animated.sequence([
+			Animated.timing(
+				this.scale,
+				{
+					toValue: 0.8,
+					duration: 1000,
+					useNativeDriver: true
+				}),
+			Animated.timing(
+				this.scale,
+				{
+					toValue: 1,
+					duration: 1000,
+					useNativeDriver: true
+				})
+		]).start(() => {
+			this.animate();
+		});
+	}
+
+	render() {
+		return (
+			<View style={styles.container}>
+				<Animated.Image
+					style={[
+						styles.logo,
+						{
+							transform: [
+								{ scale: this.scale }
+							]
+						}]}
+					source={logo}
+				/>
+			</View>
+		);
+	}
+}
diff --git a/app/reducers/login.js b/app/reducers/login.js
index 72f36d52552cdcc51ae27508844d4cf878f08035..9a3c33de2457398444e09a3ed28cbcda99a3509f 100644
--- a/app/reducers/login.js
+++ b/app/reducers/login.js
@@ -3,19 +3,20 @@ import * as types from '../actions/actionsTypes';
 const initialState = {
 	isAuthenticated: false,
 	isFetching: false,
+	isRegistering: false,
 	token: '',
 	user: {},
-	errorMessage: ''
+	error: ''
 };
 
 export default function login(state = initialState, action) {
 	switch (action.type) {
 		case types.LOGIN.REQUEST:
-			console.log('types.LOGIN.REQUEST', action);
 			return { ...state,
 				isFetching: true,
 				isAuthenticated: false,
-				failure: false
+				failure: false,
+				error: ''
 			};
 		case types.LOGIN.SUCCESS:
 			return { ...state,
@@ -23,15 +24,15 @@ export default function login(state = initialState, action) {
 				isAuthenticated: true,
 				user: action.user,
 				token: action.user.token,
-				failure: false
-				// user: action.user
+				failure: false,
+				error: ''
 			};
 		case types.LOGIN.FAILURE:
 			return { ...state,
 				isFetching: false,
 				isAuthenticated: false,
 				failure: true,
-				errorMessage: action.err
+				error: action.err
 			};
 		case types.LOGOUT:
 			return initialState;
@@ -40,6 +41,34 @@ export default function login(state = initialState, action) {
 				token: action.token,
 				user: action.user
 			};
+		case types.LOGIN.REGISTER_SUBMIT:
+			return {
+				...state,
+				isFetching: true,
+				isAuthenticated: false,
+				isRegistering: true,
+				failure: false,
+				error: ''
+			};
+		case types.LOGIN.REGISTER_SUCCESS:
+			return {
+				...state,
+				isFetching: false,
+				isAuthenticated: false,
+				failure: false,
+				error: ''
+			};
+		case types.LOGIN.SET_USERNAME_SUBMIT:
+			return {
+				...state,
+				isFetching: true
+			};
+		case types.LOGIN.SET_USERNAME_SUCCESS:
+			return {
+				...state,
+				isFetching: false,
+				isRegistering: false
+			};
 		default:
 			return state;
 	}
diff --git a/app/sagas/login.js b/app/sagas/login.js
index 780655e7e2c9d9fdc2ed71cc605456705f658aae..a8608e79d847cbaed8b29f0cb8ac2b8c791e2b10 100644
--- a/app/sagas/login.js
+++ b/app/sagas/login.js
@@ -1,13 +1,26 @@
 import { AsyncStorage } from 'react-native';
-import { take, put, call, takeEvery, select, all, race } from 'redux-saga/effects';
+import { take, put, call, takeEvery, takeLatest, select, all } from 'redux-saga/effects';
 import * as types from '../actions/actionsTypes';
-import { loginRequest, loginSuccess, loginFailure, setToken, logout } from '../actions/login';
+import {
+	loginRequest,
+	loginSubmit,
+	registerRequest,
+	loginSuccess,
+	loginFailure,
+	setToken,
+	logout,
+	registerSuccess,
+	setUsernameRequest,
+	setUsernameSuccess
+} from '../actions/login';
 import RocketChat from '../lib/rocketchat';
 
 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));
+const registerCall = args => RocketChat.register(args);
+const setUsernameCall = args => RocketChat.setUsername(args);
 
 const getToken = function* getToken() {
 	const currentServer = yield select(getServer);
@@ -77,19 +90,57 @@ const handleLoginRequest = function* handleLoginRequest({ credentials }) {
 };
 
 const handleLoginSubmit = function* handleLoginSubmit({ credentials }) {
-	// put a login request
 	yield put(loginRequest(credentials));
+};
+
+const handleRegisterSubmit = function* handleRegisterSubmit({ credentials }) {
+	// put a login request
+	yield put(registerRequest(credentials));
 	// wait for a response
-	yield race({
-		success: take(types.LOGIN.SUCCESS),
-		error: take(types.LOGIN.FAILURE)
-	});
+	// yield race({
+	// 	success: take(types.LOGIN.REGISTER_SUCCESS),
+	// 	error: take(types.LOGIN.FAILURE)
+	// });
+};
+
+const handleRegisterRequest = function* handleRegisterRequest({ credentials }) {
+	try {
+		yield call(registerCall, { credentials });
+		yield put(registerSuccess(credentials));
+	} catch (err) {
+		yield put(loginFailure(err));
+	}
+};
+
+const handleRegisterSuccess = function* handleRegisterSuccess({ credentials }) {
+	yield put(loginSubmit({
+		username: credentials.email,
+		password: credentials.pass
+	}));
+};
+
+const handleSetUsernameSubmit = function* handleSetUsernameSubmit({ credentials }) {
+	yield put(setUsernameRequest(credentials));
+};
+
+const handleSetUsernameRequest = function* handleSetUsernameRequest({ credentials }) {
+	try {
+		yield call(setUsernameCall, { credentials });
+		yield put(setUsernameSuccess());
+	} catch (err) {
+		yield put(loginFailure(err));
+	}
 };
 
 const root = function* root() {
 	yield takeEvery(types.SERVER.CHANGED, handleLoginWhenServerChanges);
-	yield takeEvery(types.LOGIN.REQUEST, handleLoginRequest);
-	yield takeEvery(types.LOGIN.SUCCESS, saveToken);
-	yield takeEvery(types.LOGIN.SUBMIT, handleLoginSubmit);
+	yield takeLatest(types.LOGIN.REQUEST, handleLoginRequest);
+	yield takeLatest(types.LOGIN.SUCCESS, saveToken);
+	yield takeLatest(types.LOGIN.SUBMIT, handleLoginSubmit);
+	yield takeLatest(types.LOGIN.REGISTER_REQUEST, handleRegisterRequest);
+	yield takeLatest(types.LOGIN.REGISTER_SUBMIT, handleRegisterSubmit);
+	yield takeLatest(types.LOGIN.REGISTER_SUCCESS, handleRegisterSuccess);
+	yield takeLatest(types.LOGIN.SET_USERNAME_SUBMIT, handleSetUsernameSubmit);
+	yield takeLatest(types.LOGIN.SET_USERNAME_REQUEST, handleSetUsernameRequest);
 };
 export default root;
diff --git a/app/sagas/selectServer.js b/app/sagas/selectServer.js
index f03f2985f27332c6b15954fb6c68334bdd36bde7..dc9b039ec7ebc72ca957b573daf1049c1368da75 100644
--- a/app/sagas/selectServer.js
+++ b/app/sagas/selectServer.js
@@ -32,7 +32,7 @@ const validateServer = function* validateServer({ server }) {
 };
 
 const addServer = function* addServer({ server }) {
-	yield call(serverRequest, server);
+	yield put(serverRequest(server));
 
 	const { error } = yield race({
 		error: take(SERVER.FAILURE),
diff --git a/app/views/CreateChannelView.js b/app/views/CreateChannelView.js
index 01e5bb374d9b44392680b092cc182721f86fbda2..2041f8ab66d4a151e9e751aa5eb247b929da4c7c 100644
--- a/app/views/CreateChannelView.js
+++ b/app/views/CreateChannelView.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
-import { TextInput, View, Text, Switch, TouchableOpacity, ScrollView } from 'react-native';
+import { TextInput, View, Text, Switch, TouchableOpacity } from 'react-native';
 import { createChannelRequest } from '../actions/createChannel';
 import styles from './Styles';
 import KeyboardView from '../presentation/KeyboardView';
@@ -90,55 +90,56 @@ export default class CreateChannelView extends React.Component {
 
 	render() {
 		return (
-			<KeyboardView style={[styles.view_white, { flex: 1, justifyContent: 'flex-start' }]}>
-				<ScrollView>
-					<View style={styles.formContainer}>
-						<Text style={styles.label_white}>Channel Name</Text>
-						<TextInput
-							value={this.state.channelName}
-							style={styles.input_white}
-							onChangeText={channelName => this.setState({ channelName })}
-							autoCorrect={false}
-							returnKeyType='done'
-							autoCapitalize='none'
-							autoFocus
-							// onSubmitEditing={() => this.textInput.focus()}
-							placeholder='Type the channel name here'
-						/>
-						{this.renderChannelNameError()}
-						{this.renderTypeSwitch()}
-						<Text
-							style={[
-								styles.label_white,
-								{
-									color: '#9ea2a8',
-									flexGrow: 1,
-									paddingHorizontal: 0,
-									marginBottom: 20
-								}
-							]}
-						>
-							{this.state.type ? (
-								'Everyone can access this channel'
-							) : (
-								'Just invited people can access this channel'
-							)}
+			<KeyboardView
+				style={[styles.defaultViewBackground, { flex: 1 }]}
+				contentContainerStyle={styles.defaultView}
+			>
+				<View style={styles.formContainer}>
+					<Text style={styles.label_white}>Channel Name</Text>
+					<TextInput
+						value={this.state.channelName}
+						style={styles.input_white}
+						onChangeText={channelName => this.setState({ channelName })}
+						autoCorrect={false}
+						returnKeyType='done'
+						autoCapitalize='none'
+						autoFocus
+						// onSubmitEditing={() => this.textInput.focus()}
+						placeholder='Type the channel name here'
+					/>
+					{this.renderChannelNameError()}
+					{this.renderTypeSwitch()}
+					<Text
+						style={[
+							styles.label_white,
+							{
+								color: '#9ea2a8',
+								flexGrow: 1,
+								paddingHorizontal: 0,
+								marginBottom: 20
+							}
+						]}
+					>
+						{this.state.type ? (
+							'Everyone can access this channel'
+						) : (
+							'Just invited people can access this channel'
+						)}
+					</Text>
+					<TouchableOpacity
+						onPress={() => this.submit()}
+						style={[
+							styles.buttonContainer_white,
+							this.state.channelName.length === 0 || this.props.result.isFetching
+								? styles.disabledButton
+								: styles.enabledButton
+						]}
+					>
+						<Text style={styles.button_white}>
+							{this.props.result.isFetching ? 'LOADING' : 'CREATE'}!
 						</Text>
-						<TouchableOpacity
-							onPress={() => this.submit()}
-							style={[
-								styles.buttonContainer_white,
-								this.state.channelName.length === 0 || this.props.result.isFetching
-									? styles.disabledButton
-									: styles.enabledButton
-							]}
-						>
-							<Text style={styles.button_white}>
-								{this.props.result.isFetching ? 'LOADING' : 'CREATE'}!
-							</Text>
-						</TouchableOpacity>
-					</View>
-				</ScrollView>
+					</TouchableOpacity>
+				</View>
 			</KeyboardView>
 		);
 	}
diff --git a/app/views/LoginView.js b/app/views/LoginView.js
index 7f182b7cbeb76506507771894a5201bf69d5ffd6..2f259c3dc7165d19fe66b515619f22f6086debd1 100644
--- a/app/views/LoginView.js
+++ b/app/views/LoginView.js
@@ -3,7 +3,7 @@ import React from 'react';
 import Spinner from 'react-native-loading-spinner-overlay';
 
 import PropTypes from 'prop-types';
-import { Keyboard, Text, TextInput, View, Image, TouchableOpacity } from 'react-native';
+import { Keyboard, Text, TextInput, View, TouchableOpacity } from 'react-native';
 import { connect } from 'react-redux';
 import { bindActionCreators } from 'redux';
 // import * as actions from '../actions';
@@ -18,7 +18,8 @@ class LoginView extends React.Component {
 		loginSubmit: PropTypes.func.isRequired,
 		Accounts_EmailOrUsernamePlaceholder: PropTypes.string,
 		Accounts_PasswordPlaceholder: PropTypes.string,
-		login: PropTypes.object
+		login: PropTypes.object,
+		navigation: PropTypes.object.isRequired
 	}
 
 	static navigationOptions = () => ({
@@ -44,6 +45,10 @@ class LoginView extends React.Component {
 		Keyboard.dismiss();
 	}
 
+	register = () => {
+		this.props.navigation.navigate('Register');
+	}
+
 	renderTOTP = () => {
 		if (this.props.login.errorMessage && this.props.login.errorMessage.error === 'totp-required') {
 			return (
@@ -65,48 +70,47 @@ class LoginView extends React.Component {
 	// {this.props.login.isFetching && <Text> LOGANDO</Text>}
 	render() {
 		return (
-			<KeyboardView style={styles.container} keyboardVerticalOffset={128}>
-				<View style={{ alignItems: 'center' }}>
-					<Image
-						style={styles.logo}
-						source={require('../images/logo.png')}
-					/>
-				</View>
+			<KeyboardView
+				contentContainerStyle={styles.container}
+				keyboardVerticalOffset={128}
+			>
 				<View style={styles.loginView}>
 					<View style={styles.formContainer}>
 						<TextInput
-							placeholderTextColor={'rgba(255,255,255,.2)'}
-							style={styles.input}
+							style={styles.input_white}
 							onChangeText={username => this.setState({ username })}
 							keyboardType='email-address'
 							autoCorrect={false}
 							returnKeyType='next'
 							autoCapitalize='none'
-							autoFocus
-
 							underlineColorAndroid='transparent'
 							onSubmitEditing={() => { this.password.focus(); }}
 							placeholder={this.props.Accounts_EmailOrUsernamePlaceholder || 'Email or username'}
 						/>
 						<TextInput
 							ref={(e) => { this.password = e; }}
-							placeholderTextColor={'rgba(255,255,255,.2)'}
-							style={styles.input}
+							style={styles.input_white}
 							onChangeText={password => this.setState({ password })}
 							secureTextEntry
 							autoCorrect={false}
 							returnKeyType='done'
 							autoCapitalize='none'
-
 							underlineColorAndroid='transparent'
 							onSubmitEditing={this.submit}
 							placeholder={this.props.Accounts_PasswordPlaceholder || 'Password'}
 						/>
+
 						{this.renderTOTP()}
+
 						<TouchableOpacity style={styles.buttonContainer}>
 							<Text style={styles.button} onPress={this.submit}>LOGIN</Text>
 						</TouchableOpacity>
-						{this.props.login.error && <Text style={styles.error}>{this.props.login.error}</Text>}
+
+						<TouchableOpacity style={[styles.buttonContainer, styles.registerContainer]}>
+							<Text style={styles.button} onPress={this.register}>REGISTER</Text>
+						</TouchableOpacity>
+
+						{this.props.login.failure && <Text style={styles.error}>{this.props.login.error.reason}</Text>}
 					</View>
 					<Spinner visible={this.props.login.isFetching} textContent={'Loading...'} textStyle={{ color: '#FFF' }} />
 				</View>
diff --git a/app/views/NewServerView.js b/app/views/NewServerView.js
index 62ce32643f194f66bb2af8f4dfa40db7ea3e62fb..f022bc4eedc46185cfedef88d64b3833084b3bc5 100644
--- a/app/views/NewServerView.js
+++ b/app/views/NewServerView.js
@@ -1,6 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { Text, TextInput, View, StyleSheet } from 'react-native';
+import { Text, TextInput, View, StyleSheet, Dimensions } from 'react-native';
 import { connect } from 'react-redux';
 import { serverRequest, addServer } from '../actions/server';
 import KeyboardView from '../presentation/KeyboardView';
@@ -148,7 +148,11 @@ export default class NewServerView extends React.Component {
 
 	render() {
 		return (
-			<KeyboardView style={styles.view} keyboardVerticalOffset={64}>
+			<KeyboardView
+				scrollEnabled={false}
+				contentContainerStyle={[styles.view, { height: Dimensions.get('window').height }]}
+				keyboardVerticalOffset={128}
+			>
 				<View style={styles.spaceView} />
 				<TextInput
 					ref={ref => this.inputElement = ref}
diff --git a/app/views/RegisterView.js b/app/views/RegisterView.js
new file mode 100644
index 0000000000000000000000000000000000000000..656605727ecf4bf3154d016d40cd838dfda27b48
--- /dev/null
+++ b/app/views/RegisterView.js
@@ -0,0 +1,194 @@
+import React from 'react';
+
+import Spinner from 'react-native-loading-spinner-overlay';
+
+import PropTypes from 'prop-types';
+import { Keyboard, Text, TextInput, View, TouchableOpacity } from 'react-native';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import * as loginActions from '../actions/login';
+import KeyboardView from '../presentation/KeyboardView';
+
+import styles from './Styles';
+
+const placeholderTextColor = 'rgba(255,255,255,.2)';
+
+class RegisterView extends React.Component {
+	static propTypes = {
+		registerSubmit: PropTypes.func.isRequired,
+		setUsernameSubmit: PropTypes.func,
+		Accounts_UsernamePlaceholder: PropTypes.string,
+		Accounts_NamePlaceholder: PropTypes.string,
+		Accounts_EmailOrUsernamePlaceholder: PropTypes.string,
+		Accounts_PasswordPlaceholder: PropTypes.string,
+		Accounts_RepeatPasswordPlaceholder: PropTypes.string,
+		login: PropTypes.object
+	}
+
+	constructor(props) {
+		super(props);
+
+		this.state = {
+			name: '',
+			email: '',
+			password: '',
+			confirmPassword: ''
+		};
+	}
+
+	_valid() {
+		const { name, email, password, confirmPassword } = this.state;
+		return name.trim() && email.trim() &&
+			password && confirmPassword && password === confirmPassword;
+	}
+	_invalidEmail() {
+		return this.props.login.failure && /Email/.test(this.props.login.error.reason);
+	}
+	submit = () => {
+		const { name, email, password, code } = this.state;
+		if (!this._valid()) {
+			return;
+		}
+
+		this.props.registerSubmit({ name, email, pass: password, code });
+		Keyboard.dismiss();
+	}
+	usernameSubmit = () => {
+		const { username } = this.state;
+		if (!username) {
+			return;
+		}
+
+		this.props.setUsernameSubmit({ username });
+		Keyboard.dismiss();
+	}
+
+	_renderRegister() {
+		if (this.props.login.token) {
+			return null;
+		}
+		return (
+			<View style={styles.formContainer}>
+				<TextInput
+					ref={(e) => { this.name = e; }}
+					style={styles.input_white}
+					onChangeText={name => this.setState({ name })}
+					autoCorrect={false}
+					autoFocus
+					returnKeyType='next'
+					autoCapitalize='none'
+					underlineColorAndroid='transparent'
+					onSubmitEditing={() => { this.email.focus(); }}
+					placeholder={this.props.Accounts_NamePlaceholder || 'Name'}
+				/>
+
+				<TextInput
+					ref={(e) => { this.email = e; }}
+					style={[styles.input_white, this._invalidEmail() ? { borderColor: 'red' } : {}]}
+					onChangeText={email => this.setState({ email })}
+					keyboardType='email-address'
+					autoCorrect={false}
+					returnKeyType='next'
+					autoCapitalize='none'
+					underlineColorAndroid='transparent'
+					onSubmitEditing={() => { this.password.focus(); }}
+					placeholder={this.props.Accounts_EmailOrUsernamePlaceholder || 'Email'}
+				/>
+				<TextInput
+					ref={(e) => { this.password = e; }}
+					style={styles.input_white}
+					onChangeText={password => this.setState({ password })}
+					secureTextEntry
+					autoCorrect={false}
+					returnKeyType='next'
+					autoCapitalize='none'
+					underlineColorAndroid='transparent'
+					onSubmitEditing={() => { this.confirmPassword.focus(); }}
+					placeholder={this.props.Accounts_PasswordPlaceholder || 'Password'}
+				/>
+				<TextInput
+					ref={(e) => { this.confirmPassword = e; }}
+					style={[styles.input_white, this.state.password && this.state.confirmPassword && this.state.confirmPassword !== this.state.password ? { borderColor: 'red' } : {}]}
+					onChangeText={confirmPassword => this.setState({ confirmPassword })}
+					secureTextEntry
+					autoCorrect={false}
+					returnKeyType='done'
+					autoCapitalize='none'
+					underlineColorAndroid='transparent'
+					onSubmitEditing={this.submit}
+					placeholder={this.props.Accounts_RepeatPasswordPlaceholder || 'Repeat Password'}
+				/>
+
+				<TouchableOpacity style={[styles.buttonContainer, styles.registerContainer]}>
+					<Text
+						style={[styles.button, this._valid() ? {}
+							: { color: placeholderTextColor }
+						]}
+						onPress={this.submit}
+					>REGISTER</Text>
+				</TouchableOpacity>
+
+				{this.props.login.failure && <Text style={styles.error}>{this.props.login.error.reason}</Text>}
+			</View>
+		);
+	}
+
+	_renderUsername() {
+		if (!this.props.login.token) {
+			return null;
+		}
+		return (
+			<View style={styles.formContainer}>
+				<TextInput
+					ref={(e) => { this.username = e; }}
+					style={styles.input_white}
+					onChangeText={username => this.setState({ username })}
+					autoCorrect={false}
+					returnKeyType='next'
+					autoCapitalize='none'
+					underlineColorAndroid='transparent'
+					onSubmitEditing={() => { this.usernameSubmit(); }}
+					placeholder={this.props.Accounts_UsernamePlaceholder || 'Username'}
+				/>
+
+				<TouchableOpacity style={[styles.buttonContainer, styles.registerContainer]}>
+					<Text
+						style={styles.button}
+						onPress={this.usernameSubmit}
+					>REGISTER</Text>
+				</TouchableOpacity>
+
+				{this.props.login.failure && <Text style={styles.error}>{this.props.login.error.reason}</Text>}
+			</View>
+		);
+	}
+
+	render() {
+		return (
+			<KeyboardView contentContainerStyle={styles.container}>
+				<View style={styles.loginView}>
+					{this._renderRegister()}
+					{this._renderUsername()}
+					<Spinner visible={this.props.login.isFetching} textContent={'Loading...'} textStyle={{ color: '#FFF' }} />
+				</View>
+			</KeyboardView>
+		);
+	}
+}
+
+function mapStateToProps(state) {
+	return {
+		server: state.server.server,
+		Accounts_NamePlaceholder: state.settings.Accounts_NamePlaceholder,
+		Accounts_EmailOrUsernamePlaceholder: state.settings.Accounts_EmailOrUsernamePlaceholder,
+		Accounts_PasswordPlaceholder: state.settings.Accounts_PasswordPlaceholder,
+		Accounts_RepeatPasswordPlaceholder: state.settings.Accounts_RepeatPasswordPlaceholder,
+		login: state.login
+	};
+}
+
+function mapDispatchToProps(dispatch) {
+	return bindActionCreators(loginActions, dispatch);
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(RegisterView);
diff --git a/app/views/RoomView.js b/app/views/RoomView.js
index 3f6b473cc70e1d818211d9e4fdad002d7be6b168..6d1ee4f98c19867b556f009b8d1e10862d835466 100644
--- a/app/views/RoomView.js
+++ b/app/views/RoomView.js
@@ -193,7 +193,7 @@ export default class RoomView extends React.Component {
 
 	render() {
 		return (
-			<KeyboardView style={styles.container} keyboardVerticalOffset={64}>
+			<KeyboardView contentContainerStyle={styles.container} keyboardVerticalOffset={64}>
 				{this.renderBanner()}
 				<ListView
 					enableEmptySections
diff --git a/app/views/Styles.js b/app/views/Styles.js
index c4c040baa6de6753575baf3fd0a02e338d4887dd..6fb77cb66538d880c3987cdbf608531eddabd694 100644
--- a/app/views/Styles.js
+++ b/app/views/Styles.js
@@ -2,11 +2,8 @@ import { StyleSheet, Dimensions } from 'react-native';
 
 export default StyleSheet.create({
 	container: {
-		flex: 1,
-		backgroundColor: '#2f343d',
-		flexDirection: 'column',
-		justifyContent: 'center',
-		alignItems: 'stretch'
+		backgroundColor: 'white',
+		flex: 1
 	},
 	loginView: {
 		padding: 20
@@ -19,29 +16,31 @@ export default StyleSheet.create({
 		alignItems: 'stretch',
 		backgroundColor: '#2f343d'
 	},
-	view_white: {
-		flex: 1,
+	defaultView: {
 		flexDirection: 'column',
 		justifyContent: 'center',
 		padding: 20,
-		alignItems: 'stretch',
+		alignItems: 'stretch'
+	},
+	defaultViewBackground: {
 		backgroundColor: '#fff'
 	},
 	logoContainer: {
-		flex: 1,
 		alignItems: 'center',
-		flexGrow: 1,
-		justifyContent: 'center'
+		justifyContent: 'center',
+		flex: 1
 	},
-	logo: {
-		width: Dimensions.get('window').width - 30,
-		height: Dimensions.get('window').width - 30,
-		borderRadius: 5,
+	loginLogo: {
+		width: Dimensions.get('window').width - 150,
+		height: Dimensions.get('window').width - 150,
 		resizeMode: 'contain'
 	},
-	formContainer: {
-		// marginBottom: 20
+	registerLogo: {
+		width: Dimensions.get('window').width - 40,
+		height: 100,
+		resizeMode: 'contain'
 	},
+	formContainer: {},
 	label: {
 		lineHeight: 40,
 		height: 40,
@@ -94,6 +93,9 @@ export default StyleSheet.create({
 		backgroundColor: '#1d74f5',
 		marginBottom: 20
 	},
+	registerContainer: {
+		marginBottom: 0
+	},
 	button: {
 		textAlign: 'center',
 		color: 'white',
diff --git a/package.json b/package.json
index 4a1688e05876bba54cb6158d1ec8b3e655ff44da..2e1dbb94409e7e6943c646f511fb1558c3f89f81 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
     "react-native-fetch-blob": "^0.10.8",
     "react-native-image-picker": "^0.26.4",
     "react-native-img-cache": "^1.4.0",
+    "react-native-keyboard-aware-scroll-view": "^0.3.0",
     "react-native-loading-spinner-overlay": "^0.5.2",
     "react-native-meteor": "^1.1.0",
     "react-native-modal": "^3.1.0",
diff --git a/yarn.lock b/yarn.lock
index 8ad749b554319281f3b1f371386bf4a2df2f0ea2..aa5ba2d71262ec38aadece42261906ad935f2c88 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2055,7 +2055,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
     safe-buffer "^5.0.1"
     sha.js "^2.4.8"
 
-create-react-class@^15.5.2:
+create-react-class@^15.5.2, create-react-class@^15.6.0:
   version "15.6.0"
   resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4"
   dependencies:
@@ -5729,6 +5729,14 @@ react-native-img-cache@^1.4.0:
   dependencies:
     crypto-js "^3.1.9-1"
 
+react-native-keyboard-aware-scroll-view@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/react-native-keyboard-aware-scroll-view/-/react-native-keyboard-aware-scroll-view-0.3.0.tgz#b9d7b0d5b47d2bb4285fe50a3d274b10a3b5e1a7"
+  dependencies:
+    create-react-class "^15.6.0"
+    prop-types "^15.5.10"
+    react-timer-mixin "^0.13.3"
+
 react-native-loading-spinner-overlay@^0.5.2:
   version "0.5.2"
   resolved "https://registry.yarnpkg.com/react-native-loading-spinner-overlay/-/react-native-loading-spinner-overlay-0.5.2.tgz#b7bcd277476d596615fd7feee601789f9bdc7acc"
@@ -5943,7 +5951,7 @@ react-test-renderer@16.0.0-alpha.12:
     fbjs "^0.8.9"
     object-assign "^4.1.0"
 
-react-timer-mixin@^0.13.2:
+react-timer-mixin@^0.13.2, react-timer-mixin@^0.13.3:
   version "0.13.3"
   resolved "https://registry.yarnpkg.com/react-timer-mixin/-/react-timer-mixin-0.13.3.tgz#0da8b9f807ec07dc3e854d082c737c65605b3d22"