diff --git a/App.js b/App.js
index 14832d3..85ba986 100644
--- a/App.js
+++ b/App.js
@@ -27,7 +27,8 @@ import BottomNav from './src/nav/bottomNav';
import Loading from './src/component/loading';
import LoginForm from './src/component/loginForm';
-import RegisterForm from './src/component/registerForm';
+import RegisterEmailForm from './src/component/registerEmailForm';
+import RegisterMobileForm from './src/component/registerMobileForm';
export default class App extends Component {
@@ -36,26 +37,53 @@ export default class App extends Component {
super(props);
this.state = ({
- isLoginPage: true,
- isLoading: false
+ page: App.pageLogin,
+
+ isLoading: false,
+ paddingAnim: new Animated.Value(100)
+
});
}
+ componentWillMount () {
+ this.keyboardDidShowListener =
+ Keyboard.addListener(Api.IS_IOS ? 'keyboardWillShow' : 'keyboardDidShow', this._keyboardDidShow);
+ this.keyboardDidHideListener =
+ Keyboard.addListener(Api.IS_IOS ? 'keyboardWillHide' : 'keyboardDidHide', this._keyboardDidHide);
+ }
+
+ componentWillUnmount () {
+ this.keyboardDidShowListener.remove();
+ this.keyboardDidHideListener.remove();
+ }
+
+ _keyboardDidShow = () => {
+ Animated.timing(
+ this.state.paddingAnim,
+ {
+ toValue: Api.IS_IOS ? 65 : 35,
+ duration: 250
+ }
+ ).start();
+ };
+
+ _keyboardDidHide = () => {
+ InteractionManager.runAfterInteractions(() => {
+ Animated.timing(
+ this.state.paddingAnim,
+ {toValue: 100, duration: 250 }
+ ).start();
+ });
+ };
+
+ static pageLogin = 1;
+ static pageRegisterMobile = 2;
+ static pageRegisterEmail = 3;
+
_setLoading(value) {
this.setState({isLoading: value});
}
- _toWeb() {
- Linking.openURL("https://timepill.net/home/forgot_password");
- }
-
- _switchForm() {
- LayoutAnimation.easeInEaseOut();
- this.setState({
- isLoginPage: !this.state.isLoginPage
- });
- }
-
_onSucc() {
Api.getSplashByStore()
.then(splash => {
@@ -68,34 +96,97 @@ export default class App extends Component {
return (
-
- {this.state.isLoginPage
- ? ()
- : ()}
+
+ {this.renderForm()}
-
+ {
+ LayoutAnimation.easeInEaseOut();
+ if(this.state.page == App.pageLogin) {
+ this.setState({page: App.pageRegisterMobile});
+ } else {
+ this.setState({page: App.pageLogin});
+ }
+ }}>
- {this.state.isLoginPage ? '没有账号?注册一个' : '已有账号?马上登录'}
+ {this.state.page == App.pageLogin ? '没有账号?注册一个' : '已有账号?马上登录'}
-
-
- 忘记密码?
-
-
-
+ {this.renderActionLink()}
+
+
);
}
+
+ renderForm() {
+ if(this.state.page == App.pageLogin) {
+ return (
+
+ );
+
+ } else if(this.state.page == App.pageRegisterMobile) {
+ return (
+
+ );
+
+ } else if(this.state.page == App.pageRegisterEmail) {
+ return (
+
+ );
+ }
+
+ return null;
+ }
+
+ renderActionLink() {
+ if(this.state.page == App.pageLogin) {
+ return (
+ {
+ Linking.openURL("https://timepill.net/home/forgot_password");
+ }}>
+
+ 忘记密码?
+
+
+ );
+ } else if(this.state.page == App.pageRegisterMobile) {
+ return (
+ {
+ LayoutAnimation.easeInEaseOut();
+ this.setState({page: App.pageRegisterEmail});
+ }}>
+
+ 邮箱注册
+
+
+ );
+ } else if(this.state.page == App.pageRegisterEmail){
+ return (
+ {
+ LayoutAnimation.easeInEaseOut();
+ this.setState({page: App.pageRegisterMobile});
+ }}>
+
+ 手机注册
+
+
+ );
+ }
+
+ return null;
+ }
}
const localStyle = StyleSheet.create({
@@ -105,7 +196,6 @@ const localStyle = StyleSheet.create({
},
content: {
flex: 1,
- paddingTop: '30%',
paddingHorizontal: 15
},
bottom: {
diff --git a/index.js b/index.js
index d3c359e..96bc711 100644
--- a/index.js
+++ b/index.js
@@ -15,7 +15,7 @@ import BottomNav from './src/nav/bottomNav';
// for debug
-// console.disableYellowBox = true;
+console.disableYellowBox = true;
Navigation.registerComponent('Timepill', () => App);
diff --git a/src/component/loginForm.js b/src/component/loginForm.js
index 5f58e6b..c5cee24 100644
--- a/src/component/loginForm.js
+++ b/src/component/loginForm.js
@@ -3,9 +3,9 @@ import {Platform, StyleSheet, Text, View, InteractionManager, Alert} from 'react
import {FormInput, Button} from "react-native-elements";
import {Navigation} from 'react-native-navigation';
-import Color from '../style/color'
-import Api from '../util/api'
-import BottomNav from '../nav/bottomNav'
+import Color from '../style/color';
+import Api from '../util/api';
+import Msg from '../util/msg';
export default class LoginForm extends Component {
@@ -53,6 +53,15 @@ export default class LoginForm extends Component {
}
_clickLogin() {
+ if(!this.state.username) {
+ Msg.showMsg('请输入邮箱/手机');
+ return;
+ }
+ if(!this.state.password) {
+ Msg.showMsg('请输入密码');
+ return;
+ }
+
this.props.setLoading(true);
this.login().then(result => {
this.props.setLoading(false);
@@ -60,14 +69,6 @@ export default class LoginForm extends Component {
});
}
- _usernameSubmit() {
- this.refs.loginPw.focus();
- }
-
- _passwordSubmit() {
- this._clickLogin();
- }
-
render() {return (
{'欢迎来到胶囊日记'}
@@ -89,7 +90,7 @@ export default class LoginForm extends Component {
returnKeyType="next"
onChangeText={(text) => this.setState({username: text})}
- onSubmitEditing={this._usernameSubmit.bind(this)}
+ onSubmitEditing={() => {}}
/>
this.setState({password: text})}
- onSubmitEditing={this._passwordSubmit.bind(this)}
+ onSubmitEditing={this._clickLogin.bind(this)}
/>
diff --git a/src/component/registerForm.js b/src/component/registerEmailForm.js
similarity index 84%
rename from src/component/registerForm.js
rename to src/component/registerEmailForm.js
index eecee3a..7ee5243 100644
--- a/src/component/registerForm.js
+++ b/src/component/registerEmailForm.js
@@ -3,11 +3,12 @@ import {Platform, StyleSheet, Text, View, InteractionManager, Alert} from 'react
import {FormInput, Button} from "react-native-elements";
import {Navigation} from 'react-native-navigation';
-import Color from '../style/color'
-import Api from '../util/api'
+import Color from '../style/color';
+import Api from '../util/api';
+import Msg from '../util/msg';
-export default class RegisterForm extends Component {
+export default class RegisterEmailForm extends Component {
constructor(props) {
super(props);
@@ -37,7 +38,7 @@ export default class RegisterForm extends Component {
_checkResult(result) {
InteractionManager.runAfterInteractions(() => {
if(result.isRegisterSucc) {
- Navigation.setRoot(BottomNav.config());
+ this.props.onRegisterSucc();
} else {
Alert.alert(
@@ -53,6 +54,19 @@ export default class RegisterForm extends Component {
}
_clickRegister() {
+ if(!this.state.nickname) {
+ Msg.showMsg('请输入名字');
+ return;
+ }
+ if(!this.state.username) {
+ Msg.showMsg('请输入邮箱');
+ return;
+ }
+ if(!this.state.password) {
+ Msg.showMsg('请输入密码');
+ return;
+ }
+
this.props.setLoading(true);
this.register().then(result => {
this.props.setLoading(false);
@@ -60,18 +74,6 @@ export default class RegisterForm extends Component {
});
}
- _nicknameSubmit() {
- this.refs.inputEmail.focus();
- }
-
- _usernameSubmit() {
- this.refs.registerPw.focus();
- }
-
- _passwordSubmit() {
- this._clickRegister();
- }
-
render() {return (
{'注册胶囊日记账号'}
@@ -93,7 +95,7 @@ export default class RegisterForm extends Component {
returnKeyType='next'
onChangeText={(text) => this.setState({nickname: text})}
- onSubmitEditing={this._nicknameSubmit.bind(this)}
+ onSubmitEditing={() => {}}
/>
{}}
/>
- this.setState({password: text})}
- onSubmitEditing={this._passwordSubmit.bind(this)}
+ onSubmitEditing={this._clickRegister.bind(this)}
/>
diff --git a/src/component/registerMobileForm.js b/src/component/registerMobileForm.js
new file mode 100644
index 0000000..df767c2
--- /dev/null
+++ b/src/component/registerMobileForm.js
@@ -0,0 +1,230 @@
+import React, {Component} from 'react';
+import {Platform, StyleSheet, Text, View, InteractionManager, Alert} from 'react-native';
+import {FormInput, Button} from "react-native-elements";
+import {Navigation} from 'react-native-navigation';
+
+import Color from '../style/color';
+import Api from '../util/api';
+import Msg from '../util/msg';
+
+
+export default class RegisterMobileForm extends Component {
+
+ constructor(props) {
+ super(props);
+
+ this.state = ({
+ nickname: '',
+
+ mobile: '',
+ mobileSendTime: 0,
+ code: '',
+
+ password: ''
+ });
+
+ this.timer = setInterval(() => {
+ if(this.state.mobileSendTime > 0) {
+ this.setState({mobileSendTime: this.state.mobileSendTime - 1})
+ }
+ }, 1000)
+ }
+
+ componentWillUnmount () {
+ clearInterval(this.timer)
+ }
+
+ requestCode() {
+ if (!this.state.mobile) {
+ Msg.showMsg('请输入手机');
+ return;
+ }
+
+ Api.sendRegisterVerificationCode(this.state.mobile)
+ .then(() => {
+ this.setState({mobileSendTime: 60});
+ Msg.showMsg('验证码已发送');
+ })
+ .catch(e => {
+ Msg.showMsg('验证码发送失败');
+ })
+ .done();
+ };
+
+ async register() {
+ let isRegisterSucc, errMsg = '注册失败';
+
+ try {
+ isRegisterSucc = await Api.mobileRegister(this.state.nickname, this.state.mobile, this.state.password, this.state.code)
+ } catch (err) {
+ errMsg = err.message;
+ }
+
+ return {
+ isRegisterSucc,
+ errMsg
+ }
+ }
+
+ _checkResult(result) {
+ InteractionManager.runAfterInteractions(() => {
+ if(result.isRegisterSucc) {
+ this.props.onRegisterSucc();
+
+ } else {
+ Alert.alert(
+ result.errMsg,
+ '',
+ [
+ {text: '确定', onPress: () => {}},
+ ],
+ {cancelable: false}
+ )
+ }
+ })
+ }
+
+ _clickRegister() {
+ if(!this.state.nickname) {
+ Msg.showMsg('请输入名字');
+ return;
+ }
+ if(!this.state.mobile) {
+ Msg.showMsg('请输入手机');
+ return;
+ }
+ if(!this.state.code) {
+ Msg.showMsg('请输入验证码');
+ return;
+ }
+ if(!this.state.password) {
+ Msg.showMsg('请输入密码');
+ return;
+ }
+
+ this.props.setLoading(true);
+ this.register().then(result => {
+ this.props.setLoading(false);
+ this._checkResult(result);
+ });
+ }
+
+ render() {return (
+
+ {'注册胶囊日记账号'}
+
+
+ this.setState({nickname: text})}
+ onSubmitEditing={() => {}}
+ />
+
+
+ this.setState({mobile: text})}
+ onSubmitEditing={() => {}}
+ />
+
+
+ this.setState({code: text})}
+ onSubmitEditing={() => {}}
+ />
+
+ this.setState({password: text})}
+ onSubmitEditing={this._clickRegister.bind(this)}
+ />
+
+
+
+
+ );}
+}
+
+const localStyle = StyleSheet.create({
+ title: {
+ fontSize: 26,
+ paddingBottom: 35,
+ color: '#222',
+ textAlign: 'center'
+ },
+ form: {
+ paddingBottom: 20,
+ }
+});
\ No newline at end of file
diff --git a/src/util/api.js b/src/util/api.js
index fc240cf..2ed12f9 100644
--- a/src/util/api.js
+++ b/src/util/api.js
@@ -49,6 +49,52 @@ async function logout() {
Token.setLoginPassword('');
}
+async function sendRegisterVerificationCode(mobile) {
+ return callV2('POST', '/verification/register', {
+ 'type': 'mobile',
+ 'sendTo': mobile
+ });
+}
+
+async function register(nickname, username, password) {
+ const result = await call('POST', '/users', {
+ name: nickname,
+ email: username,
+ password: password
+ });
+
+ if(result) {
+ const token = Token.generateToken(username, password);
+ await Token.setUserToken(token);
+
+ const userInfo = await getSelfInfo();
+ await Token.setUserInfo(userInfo);
+ }
+
+ return result;
+}
+
+async function mobileRegister(nickname, mobile, password, code) {
+ const result = await callV2('POST', '/users', {
+ type: 'mobile',
+ name: nickname,
+ mobile: mobile,
+ password: password,
+ code: code
+ });
+
+ if(result) {
+ const token = Token.generateToken(mobile, password);
+ await Token.setUserToken(token);
+
+ const userInfo = await getSelfInfo();
+ await Token.setUserInfo(userInfo);
+ }
+
+ return result;
+}
+
+
async function getSplashByStore() {
try {
let info = await Token.get('splash');
@@ -426,6 +472,10 @@ export default {
login,
logout,
+ sendRegisterVerificationCode,
+ register,
+ mobileRegister,
+
getSplashByStore,
syncSplash,
getSelfInfoByStore,