From d65b3a98093f706c1cd99548c7e77d5579f9877c Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Mon, 6 Nov 2017 15:25:24 -0200 Subject: [PATCH] Removed username from register and placed on a new view --- app/actions/actionsTypes.js | 12 +- app/actions/login.js | 20 ++++ app/containers/Routes.js | 2 +- app/lib/rocketchat.js | 26 +++-- app/reducers/login.js | 7 ++ app/sagas/login.js | 66 +++++++---- app/sagas/rooms.js | 2 +- app/views/RegisterView.js | 225 ++++++++++++++++++++---------------- 8 files changed, 229 insertions(+), 131 deletions(-) diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js index 14f55347a..308c4baa6 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', 'REGISTER_SUBMIT', 'REGISTER_REQUEST', 'REGISTER_SUCCESS']); +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 aa96cc528..1a8f753e8 100644 --- a/app/actions/login.js +++ b/app/actions/login.js @@ -33,6 +33,26 @@ export function registerSuccess(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 07450e267..83268096c 100644 --- a/app/containers/Routes.js +++ b/app/containers/Routes.js @@ -34,7 +34,7 @@ export default class Routes extends React.Component { return (); } - if ((login.token && !login.failure) || app.ready) { + if ((login.token && !login.failure && !login.isRegistering) || app.ready) { return (); } diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 773859fd9..4847aad95 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -122,13 +122,25 @@ const RocketChat = { }); }, - register({ server, credentials }) { - return fetch(`${ server }/api/v1/users.register`, { - method: 'post', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(credentials) + register({ credentials }) { + return new Promise((resolve, reject) => { + return Meteor.call('registerUser', credentials, (err, userId) => { + if (err) { + reject(err); + } + resolve(userId); + }); + }); + }, + + setUsername({ credentials }) { + return new Promise((resolve, reject) => { + return Meteor.call('setUsername', credentials.username, (err, result) => { + if (err) { + reject(err); + } + resolve(result); + }); }); }, diff --git a/app/reducers/login.js b/app/reducers/login.js index 2898508b6..b2c5ffcec 100644 --- a/app/reducers/login.js +++ b/app/reducers/login.js @@ -3,6 +3,7 @@ import * as types from '../actions/actionsTypes'; const initialState = { isAuthenticated: false, isFetching: false, + isRegistering: false, token: '', user: {}, error: '' @@ -45,6 +46,7 @@ export default function login(state = initialState, action) { ...state, isFetching: true, isAuthenticated: false, + isRegistering: true, failure: false, error: '' }; @@ -56,6 +58,11 @@ export default function login(state = initialState, action) { failure: false, error: '' }; + case types.LOGIN.SET_USERNAME_SUCCESS: + return { + ...state, + isRegistering: false + }; default: return state; } diff --git a/app/sagas/login.js b/app/sagas/login.js index 15780dafb..8995c3994 100644 --- a/app/sagas/login.js +++ b/app/sagas/login.js @@ -1,14 +1,28 @@ import { AsyncStorage } from 'react-native'; import { take, put, call, takeEvery, select, all, race } from 'redux-saga/effects'; import * as types from '../actions/actionsTypes'; -import { loginRequest, loginSubmit, registerRequest, loginSuccess, loginFailure, setToken, logout, registerSuccess } from '../actions/login'; +import { + loginRequest, + loginSubmit, + registerRequest, + loginSuccess, + loginFailure, + setToken, + logout, + registerSuccess, + setUsernameRequest, + setUsernameSuccess +} from '../actions/login'; import RocketChat from '../lib/rocketchat'; +AsyncStorage.clear() + 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); @@ -78,42 +92,48 @@ const handleLoginRequest = function* handleLoginRequest({ credentials }) { }; const handleLoginSubmit = function* handleLoginSubmit({ credentials }) { - // put a login request yield put(loginRequest(credentials)); - // wait for a response - yield race({ - success: take(types.LOGIN.SUCCESS), - error: take(types.LOGIN.FAILURE) - }); -}; - -const handleRegisterRequest = function* handleRegisterRequest({ credentials }) { - try { - const server = yield select(getServer); - yield call(registerCall, { server, credentials }); - yield put(registerSuccess(credentials)); - } catch (err) { - yield put(loginFailure(err)); - } }; const handleRegisterSubmit = function* handleRegisterSubmit({ credentials }) { // put a login request yield put(registerRequest(credentials)); // wait for a response - yield race({ - success: take(types.LOGIN.REGISTER_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.username, + 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); @@ -122,5 +142,7 @@ const root = function* root() { yield takeEvery(types.LOGIN.REGISTER_REQUEST, handleRegisterRequest); yield takeEvery(types.LOGIN.REGISTER_SUBMIT, handleRegisterSubmit); yield takeEvery(types.LOGIN.REGISTER_SUCCESS, handleRegisterSuccess); + yield takeEvery(types.LOGIN.SET_USERNAME_SUBMIT, handleSetUsernameSubmit); + yield takeEvery(types.LOGIN.SET_USERNAME_REQUEST, handleSetUsernameRequest); }; export default root; diff --git a/app/sagas/rooms.js b/app/sagas/rooms.js index 472f3e5d3..1307b60ff 100644 --- a/app/sagas/rooms.js +++ b/app/sagas/rooms.js @@ -18,6 +18,6 @@ const watchRoomsRequest = function* watchRoomsRequest() { } }; const root = function* root() { - yield takeEvery(types.LOGIN.SUCCESS, watchRoomsRequest); + yield takeEvery(types.ROOMS.REQUEST, watchRoomsRequest); }; export default root; diff --git a/app/views/RegisterView.js b/app/views/RegisterView.js index a28836b47..72bd194ea 100644 --- a/app/views/RegisterView.js +++ b/app/views/RegisterView.js @@ -16,13 +16,13 @@ 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, - navigation: PropTypes.object.isRequired + login: PropTypes.object } constructor(props) { @@ -30,36 +30,147 @@ class RegisterView extends React.Component { this.state = { name: '', - username: '', email: '', password: '', confirmPassword: '' }; } - componentDidUpdate(prevProps) { - if (!this.props.login.isFetching && prevProps.login.isFetching && - !this.props.login.failure) { - this.props.navigation.goBack(); - } - } _valid() { - const { name, username, email, password, confirmPassword } = this.state; - return name.trim() && username.trim() && email.trim() && + 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, username, email, password, code } = this.state; + const { name, email, password, code } = this.state; if (!this._valid()) { return; } - this.props.registerSubmit({ name, username, email, pass: password, code }); + 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 ( + + { this.name = e; }} + placeholderTextColor={placeholderTextColor} + style={styles.input} + onChangeText={name => this.setState({ name })} + autoCorrect={false} + autoFocus + returnKeyType='next' + autoCapitalize='none' + + underlineColorAndroid='transparent' + onSubmitEditing={() => { this.email.focus(); }} + placeholder={this.props.Accounts_NamePlaceholder || 'Name'} + /> + + { this.email = e; }} + placeholderTextColor={placeholderTextColor} + style={[styles.input, 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'} + /> + { this.password = e; }} + placeholderTextColor={placeholderTextColor} + style={styles.input} + onChangeText={password => this.setState({ password })} + secureTextEntry + autoCorrect={false} + returnKeyType='next' + autoCapitalize='none' + + underlineColorAndroid='transparent' + onSubmitEditing={() => { this.confirmPassword.focus(); }} + placeholder={this.props.Accounts_PasswordPlaceholder || 'Password'} + /> + { this.confirmPassword = e; }} + placeholderTextColor={placeholderTextColor} + style={[styles.input, 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'} + /> + + + REGISTER + + + {this.props.login.failure && {this.props.login.error.reason}} + + ); + } + + _renderUsername() { + if (!this.props.login.token) { + return null; + } + return ( + + { this.username = e; }} + placeholderTextColor={'rgba(255,255,255,.2)'} + style={styles.input} + onChangeText={username => this.setState({ username })} + autoCorrect={false} + returnKeyType='next' + autoCapitalize='none' + underlineColorAndroid='transparent' + onSubmitEditing={() => { this.usernameSubmit(); }} + placeholder={this.props.Accounts_UsernamePlaceholder || 'Username'} + /> + + + REGISTER + + + {this.props.login.failure && {this.props.login.error.reason}} + + ); + } render() { return ( @@ -71,90 +182,8 @@ class RegisterView extends React.Component { /> - - { this.name = e; }} - placeholderTextColor={placeholderTextColor} - style={styles.input} - onChangeText={name => this.setState({ name })} - autoCorrect={false} - autoFocus - returnKeyType='next' - autoCapitalize='none' - - underlineColorAndroid='transparent' - onSubmitEditing={() => { this.username.focus(); }} - placeholder={this.props.Accounts_NamePlaceholder || 'Name'} - /> - - { this.username = e; }} - placeholderTextColor={'rgba(255,255,255,.2)'} - style={styles.input} - onChangeText={username => this.setState({ username })} - autoCorrect={false} - returnKeyType='next' - autoCapitalize='none' - - underlineColorAndroid='transparent' - onSubmitEditing={() => { this.email.focus(); }} - placeholder={this.props.Accounts_UsernamePlaceholder || 'Username'} - /> - - { this.email = e; }} - placeholderTextColor={placeholderTextColor} - style={[styles.input, 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'} - /> - { this.password = e; }} - placeholderTextColor={placeholderTextColor} - style={styles.input} - onChangeText={password => this.setState({ password })} - secureTextEntry - autoCorrect={false} - returnKeyType='next' - autoCapitalize='none' - - underlineColorAndroid='transparent' - onSubmitEditing={() => { this.confirmPassword.focus(); }} - placeholder={this.props.Accounts_PasswordPlaceholder || 'Password'} - /> - { this.confirmPassword = e; }} - placeholderTextColor={placeholderTextColor} - style={[styles.input, 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'} - /> - - - REGISTER - - - {this.props.login.failure && {this.props.login.error.reason}} - + {this._renderRegister()} + {this._renderUsername()} @@ -163,10 +192,8 @@ class RegisterView extends React.Component { } function mapStateToProps(state) { - // console.log(Object.keys(state)); return { server: state.server.server, - Accounts_UsernamePlaceholder: state.settings.Accounts_UsernamePlaceholder, Accounts_NamePlaceholder: state.settings.Accounts_NamePlaceholder, Accounts_EmailOrUsernamePlaceholder: state.settings.Accounts_EmailOrUsernamePlaceholder, Accounts_PasswordPlaceholder: state.settings.Accounts_PasswordPlaceholder,