Removed username from register and placed on a new view

This commit is contained in:
Diego Mello 2017-11-06 15:25:24 -02:00
parent f2fba8bd82
commit d65b3a9809
8 changed files with 229 additions and 131 deletions

View File

@ -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');

View File

@ -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,

View File

@ -34,7 +34,7 @@ export default class Routes extends React.Component {
return (<Loading />);
}
if ((login.token && !login.failure) || app.ready) {
if ((login.token && !login.failure && !login.isRegistering) || app.ready) {
return (<AuthRoutes />);
}

View File

@ -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);
});
});
},

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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 (
<View style={styles.formContainer}>
<TextInput
ref={(e) => { 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'}
/>
<TextInput
ref={(e) => { 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'}
/>
<TextInput
ref={(e) => { 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'}
/>
<TextInput
ref={(e) => { 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'}
/>
<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; }}
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'}
/>
<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 (
@ -71,90 +182,8 @@ class RegisterView extends React.Component {
/>
</View>
<View style={styles.loginView}>
<View style={styles.formContainer}>
<TextInput
ref={(e) => { 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'}
/>
<TextInput
ref={(e) => { 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'}
/>
<TextInput
ref={(e) => { 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'}
/>
<TextInput
ref={(e) => { 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'}
/>
<TextInput
ref={(e) => { 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'}
/>
<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>
{this._renderRegister()}
{this._renderUsername()}
<Spinner visible={this.props.login.isFetching} textContent={'Loading...'} textStyle={{ color: '#FFF' }} />
</View>
</KeyboardView>
@ -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,