mirror of
https://github.com/timepill/timepill-app.git
synced 2025-04-30 09:59:31 +08:00
1. splash用Modal实现
This commit is contained in:
parent
703da75c5f
commit
487aecdf96
13 changed files with 391 additions and 38 deletions
19
App.js
19
App.js
|
@ -23,6 +23,7 @@ import {Navigation} from 'react-native-navigation';
|
||||||
|
|
||||||
import Color from './src/style/color';
|
import Color from './src/style/color';
|
||||||
import Api from './src/util/api';
|
import Api from './src/util/api';
|
||||||
|
import BottomNav from './src/nav/bottomNav';
|
||||||
|
|
||||||
import Loading from './src/component/loading';
|
import Loading from './src/component/loading';
|
||||||
import LoginForm from './src/component/loginForm';
|
import LoginForm from './src/component/loginForm';
|
||||||
|
@ -55,14 +56,28 @@ export default class App extends Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onSucc() {
|
||||||
|
Api.getSplashByStore()
|
||||||
|
.then(splash => {
|
||||||
|
Navigation.setRoot(BottomNav.config(splash));
|
||||||
|
})
|
||||||
|
.done();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={localStyle.wrap}>
|
<View style={localStyle.wrap}>
|
||||||
<Loading visible={this.state.isLoading}></Loading>
|
<Loading visible={this.state.isLoading}></Loading>
|
||||||
<Animated.View style={localStyle.content}>
|
<Animated.View style={localStyle.content}>
|
||||||
{this.state.isLoginPage
|
{this.state.isLoginPage
|
||||||
? (<LoginForm setLoading={this._setLoading.bind(this)}></LoginForm>)
|
? (<LoginForm
|
||||||
: (<RegisterForm></RegisterForm>)}
|
setLoading={this._setLoading.bind(this)}
|
||||||
|
onLoginSucc={this._onSucc.bind(this)}
|
||||||
|
></LoginForm>)
|
||||||
|
: (<RegisterForm
|
||||||
|
setLoading={this._setLoading.bind(this)}
|
||||||
|
onRegisterSucc={this._onSucc.bind(this)}
|
||||||
|
></RegisterForm>)}
|
||||||
|
|
||||||
<View style={localStyle.bottom}>
|
<View style={localStyle.bottom}>
|
||||||
<TouchableOpacity onPress={this._switchForm.bind(this)}>
|
<TouchableOpacity onPress={this._switchForm.bind(this)}>
|
||||||
|
|
10
index.js
10
index.js
|
@ -9,10 +9,15 @@ import {Icon, loadIcon} from './src/style/icon';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
|
|
||||||
import Token from './src/util/token';
|
import Token from './src/util/token';
|
||||||
|
import Api from './src/util/api';
|
||||||
import PageList from './src/page/_list';
|
import PageList from './src/page/_list';
|
||||||
import BottomNav from './src/nav/bottomNav';
|
import BottomNav from './src/nav/bottomNav';
|
||||||
|
|
||||||
|
|
||||||
|
// for debug
|
||||||
|
// console.disableYellowBox = true;
|
||||||
|
|
||||||
|
|
||||||
Navigation.registerComponent('Timepill', () => App);
|
Navigation.registerComponent('Timepill', () => App);
|
||||||
// regist screens automatically
|
// regist screens automatically
|
||||||
for(let pageName in PageList) {
|
for(let pageName in PageList) {
|
||||||
|
@ -81,6 +86,11 @@ Navigation.events().registerAppLaunchedListener(async () => {
|
||||||
Alert.alert("loadIcon err: " + err.toString());
|
Alert.alert("loadIcon err: " + err.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Api.syncSplash();
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
let token = await Token.getUserToken();
|
let token = await Token.getUserToken();
|
||||||
// let token;
|
// let token;
|
||||||
if(!token) {
|
if(!token) {
|
||||||
|
|
|
@ -10,7 +10,6 @@ import {
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import {Navigation} from 'react-native-navigation';
|
import {Navigation} from 'react-native-navigation';
|
||||||
import {Divider} from "react-native-elements";
|
import {Divider} from "react-native-elements";
|
||||||
import ActionSheet from 'react-native-actionsheet-api';
|
|
||||||
|
|
||||||
import Color from '../../style/color';
|
import Color from '../../style/color';
|
||||||
import Msg from '../../util/msg';
|
import Msg from '../../util/msg';
|
||||||
|
@ -248,7 +247,7 @@ export default class DiaryList extends Component {
|
||||||
onEndReached={this.state.hasMore ? this.loadMore.bind(this) : null}
|
onEndReached={this.state.hasMore ? this.loadMore.bind(this) : null}
|
||||||
>
|
>
|
||||||
</FlatList>
|
</FlatList>
|
||||||
<ActionSheet/>
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ export default class LoginForm extends Component {
|
||||||
_checkResult(result) {
|
_checkResult(result) {
|
||||||
InteractionManager.runAfterInteractions(() => {
|
InteractionManager.runAfterInteractions(() => {
|
||||||
if(result.isLoginSucc) {
|
if(result.isLoginSucc) {
|
||||||
Navigation.setRoot(BottomNav.config());
|
this.props.onLoginSucc();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Color from '../style/color'
|
import Color from '../style/color'
|
||||||
import {Icon} from '../style/icon'
|
import {Icon} from '../style/icon'
|
||||||
|
|
||||||
function config() {
|
function config(splash) {
|
||||||
return {
|
return {
|
||||||
root: {
|
root: {
|
||||||
bottomTabs: {
|
bottomTabs: {
|
||||||
|
@ -19,11 +19,23 @@ function config() {
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
options: {
|
options: {
|
||||||
topBar: {
|
topBar: {
|
||||||
// visible: false,
|
visible: false,
|
||||||
|
animate: false
|
||||||
|
|
||||||
|
/*
|
||||||
title: {
|
title: {
|
||||||
text: '首页'
|
text: '首页'
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
bottomTabs: {
|
||||||
|
visible: false,
|
||||||
|
animate: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
passProps: {
|
||||||
|
splash: splash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
|
|
||||||
import Api from '../util/api';
|
import Api from '../util/api';
|
||||||
import TokenManager from '../util/token';
|
import Token from '../util/token';
|
||||||
import Event from '../util/event';
|
import Event from '../util/event';
|
||||||
import Color from '../style/color';
|
import Color from '../style/color';
|
||||||
import UpdateInfo from '../updateInfo';
|
import UpdateInfo from '../updateInfo';
|
||||||
|
@ -36,7 +36,7 @@ export default class AboutPage extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
TokenManager.setUpdateVersion(UpdateInfo.version)
|
Token.setUpdateVersion(UpdateInfo.version)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
DeviceEventEmitter.emit(Event.updateNewsRead);
|
DeviceEventEmitter.emit(Event.updateNewsRead);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,18 @@
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {StyleSheet, Text, View, TouchableOpacity, ImageBackground} from 'react-native';
|
import {
|
||||||
|
StyleSheet,
|
||||||
|
Text,
|
||||||
|
View,
|
||||||
|
TouchableOpacity,
|
||||||
|
ImageBackground,
|
||||||
|
Animated,
|
||||||
|
Modal,
|
||||||
|
TouchableWithoutFeedback,
|
||||||
|
InteractionManager
|
||||||
|
} from 'react-native';
|
||||||
import {Navigation} from 'react-native-navigation';
|
import {Navigation} from 'react-native-navigation';
|
||||||
|
import {Button} from 'react-native-elements';
|
||||||
|
import ActionSheet from 'react-native-actionsheet-api';
|
||||||
|
|
||||||
import Color from '../style/color'
|
import Color from '../style/color'
|
||||||
import Api from '../util/api';
|
import Api from '../util/api';
|
||||||
|
@ -15,11 +27,132 @@ export default class HomePage extends Component {
|
||||||
super(props);
|
super(props);
|
||||||
this.dataSource = new HomeDiaryData();
|
this.dataSource = new HomeDiaryData();
|
||||||
|
|
||||||
|
let splash = props.splash;
|
||||||
this.state = {
|
this.state = {
|
||||||
|
hasSplash: splash ? true : false,
|
||||||
|
|
||||||
|
showSplash: true,
|
||||||
|
fadeInOpacity: new Animated.Value(0),
|
||||||
|
|
||||||
|
splashTime : 3,
|
||||||
|
splashImage: splash ? splash.image_url : null,
|
||||||
|
splashLink: splash ? splash.link : null,
|
||||||
|
|
||||||
topic: null
|
topic: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
if(this.state.hasSplash) {
|
||||||
|
this.openSplash();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.closeSplash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startTimer() {
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
let newTime = this.state.splashTime - 1;
|
||||||
|
this.setState({
|
||||||
|
splashTime: newTime
|
||||||
|
});
|
||||||
|
|
||||||
|
if(newTime == 0) {
|
||||||
|
this.closeSplash();
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
openSplash() {
|
||||||
|
Animated.timing(
|
||||||
|
this.state.fadeInOpacity,
|
||||||
|
{
|
||||||
|
toValue: 1,
|
||||||
|
duration: 1000,
|
||||||
|
}
|
||||||
|
|
||||||
|
).start(() => {
|
||||||
|
this.startTimer();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
closeSplash() {
|
||||||
|
if(this.timer) {
|
||||||
|
clearTimeout(this.timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Animated.timing(
|
||||||
|
this.state.fadeInOpacity,
|
||||||
|
{
|
||||||
|
toValue: 0,
|
||||||
|
duration: 500,
|
||||||
|
}
|
||||||
|
|
||||||
|
).start(() => {
|
||||||
|
|
||||||
|
Navigation.mergeOptions(this.props.componentId, {
|
||||||
|
topBar: {
|
||||||
|
visible: true,
|
||||||
|
title: {
|
||||||
|
text: '首页'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bottomTabs: {
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
showSplash: false
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onSplashPress() {
|
||||||
|
if(this.state.splashLink) {
|
||||||
|
if(this.timer) {
|
||||||
|
clearTimeout(this.timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigation.mergeOptions(this.props.componentId, {
|
||||||
|
topBar: {
|
||||||
|
visible: true,
|
||||||
|
title: {
|
||||||
|
text: '首页'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bottomTabs: {
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Navigation.push(this.props.componentId, {
|
||||||
|
component: {
|
||||||
|
name: 'WebView',
|
||||||
|
options: {
|
||||||
|
bottomTabs: {
|
||||||
|
visible: false,
|
||||||
|
|
||||||
|
// hide bottom tab for android
|
||||||
|
drawBehind: true,
|
||||||
|
animate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
passProps: this.state.splashLink.passProps
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
showSplash: false,
|
||||||
|
fadeInOpacity: new Animated.Value(0)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
refreshTopic() {
|
refreshTopic() {
|
||||||
Api.getTodayTopic()
|
Api.getTodayTopic()
|
||||||
.then(topic => {
|
.then(topic => {
|
||||||
|
@ -54,12 +187,17 @@ export default class HomePage extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={localStyle.wrap}>
|
<View style={localStyle.wrap}>
|
||||||
|
{
|
||||||
|
this.state.showSplash ? this.renderModal() : (
|
||||||
<DiaryList ref={(r) => this.list = r}
|
<DiaryList ref={(r) => this.list = r}
|
||||||
dataSource={this.dataSource}
|
dataSource={this.dataSource}
|
||||||
listHeader={this.renderHeader.bind(this)}
|
listHeader={this.renderHeader.bind(this)}
|
||||||
refreshHeader={this.refreshTopic.bind(this)}
|
refreshHeader={this.refreshTopic.bind(this)}
|
||||||
{...this.props}
|
{...this.props}
|
||||||
></DiaryList>
|
></DiaryList>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<ActionSheet/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -78,6 +216,36 @@ export default class HomePage extends Component {
|
||||||
</View>
|
</View>
|
||||||
) : null;
|
) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderModal() {
|
||||||
|
return (
|
||||||
|
<Modal visible={this.state.hasSplash}
|
||||||
|
onShow={() => {}}
|
||||||
|
onRequestClose={() => {}}
|
||||||
|
>
|
||||||
|
<Animated.View style={{flex: 1, opacity: this.state.fadeInOpacity}}>
|
||||||
|
<TouchableWithoutFeedback style={{flex: 1}} onPress={this.onSplashPress.bind(this)}>
|
||||||
|
<ImageBackground
|
||||||
|
style={{flex: 1, width: '100%', height: '100%'}}
|
||||||
|
source={{uri: this.state.splashImage}}
|
||||||
|
>
|
||||||
|
|
||||||
|
<View style={localStyle.closeButtonWrap}>
|
||||||
|
<View style={localStyle.closeButtonContainer}>
|
||||||
|
<Button
|
||||||
|
buttonStyle={localStyle.closeButton}
|
||||||
|
title={'关闭 ' + this.state.splashTime}
|
||||||
|
onPress={this.closeSplash.bind(this)}
|
||||||
|
textStyle={localStyle.closeButtonText}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</ImageBackground>
|
||||||
|
</TouchableWithoutFeedback>
|
||||||
|
</Animated.View>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const localStyle = StyleSheet.create({
|
const localStyle = StyleSheet.create({
|
||||||
|
@ -116,5 +284,30 @@ const localStyle = StyleSheet.create({
|
||||||
textShadowOffset: { width: 1, height: 1 },
|
textShadowOffset: { width: 1, height: 1 },
|
||||||
textShadowRadius: 2,
|
textShadowRadius: 2,
|
||||||
shadowOpacity: 0.5
|
shadowOpacity: 0.5
|
||||||
|
},
|
||||||
|
|
||||||
|
closeButtonWrap: {
|
||||||
|
flexDirection: 'row-reverse',
|
||||||
|
marginTop: Api.IS_IOS ? (Api.IS_IPHONEX ? 50 : 30) : 20
|
||||||
|
},
|
||||||
|
closeButtonContainer: {
|
||||||
|
width: 80,
|
||||||
|
backgroundColor: 'black',
|
||||||
|
opacity: 0.75,
|
||||||
|
borderRadius: 40,
|
||||||
|
marginRight: 15
|
||||||
|
},
|
||||||
|
closeButton: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: 'black',
|
||||||
|
paddingVertical: 5,
|
||||||
|
paddingHorizontal: 0,
|
||||||
|
backgroundColor: 'black'
|
||||||
|
},
|
||||||
|
closeButtonText: {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
fontSize: 14,
|
||||||
|
color: 'white',
|
||||||
|
fontFamily: 'Helvetica'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {Navigation} from 'react-native-navigation';
|
||||||
|
|
||||||
import Color from '../style/color';
|
import Color from '../style/color';
|
||||||
import Api from '../util/api'
|
import Api from '../util/api'
|
||||||
import TokenManager from '../util/token';
|
import Token from '../util/token';
|
||||||
import Event from '../util/event';
|
import Event from '../util/event';
|
||||||
import Msg from '../util/msg';
|
import Msg from '../util/msg';
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ export default class PasswordPage extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
TokenManager.getLoginPassword()
|
Token.getLoginPassword()
|
||||||
.then(pwd => {
|
.then(pwd => {
|
||||||
if(this.props.type == 'setting') {
|
if(this.props.type == 'setting') {
|
||||||
if(this.props.operation == 'setnew') {
|
if(this.props.operation == 'setnew') {
|
||||||
|
@ -99,7 +99,7 @@ export default class PasswordPage extends Component {
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
TokenManager.setLoginPassword(password)
|
Token.setLoginPassword(password)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
Keyboard.dismiss();
|
Keyboard.dismiss();
|
||||||
Msg.showMsg('密码已设置');
|
Msg.showMsg('密码已设置');
|
||||||
|
@ -142,7 +142,7 @@ export default class PasswordPage extends Component {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenManager.setLoginPassword('')
|
Token.setLoginPassword('')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
Keyboard.dismiss();
|
Keyboard.dismiss();
|
||||||
Msg.showMsg('密码已清除');
|
Msg.showMsg('密码已清除');
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {Navigation} from 'react-native-navigation';
|
||||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||||
|
|
||||||
import Api from '../util/api';
|
import Api from '../util/api';
|
||||||
import TokenManager from '../util/token';
|
import Token from '../util/token';
|
||||||
import Color from '../style/color';
|
import Color from '../style/color';
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ export default class SettingPage extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshPasswordState() {
|
refreshPasswordState() {
|
||||||
TokenManager.getLoginPassword()
|
Token.getLoginPassword()
|
||||||
.then((pwd) => this.setState({
|
.then((pwd) => this.setState({
|
||||||
hasPassword: pwd != null && pwd.length > 0
|
hasPassword: pwd != null && pwd.length > 0
|
||||||
}));
|
}));
|
||||||
|
|
93
src/page/WebViewPage.js
Normal file
93
src/page/WebViewPage.js
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import {
|
||||||
|
WebView,
|
||||||
|
Linking,
|
||||||
|
BackHandler
|
||||||
|
} from 'react-native';
|
||||||
|
import {Navigation} from 'react-native-navigation';
|
||||||
|
|
||||||
|
import {Icon} from '../style/icon'
|
||||||
|
|
||||||
|
|
||||||
|
export default class WebViewPage extends Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
Navigation.events().bindComponent(this);
|
||||||
|
|
||||||
|
this.webViewState = {
|
||||||
|
canGoBack: false,
|
||||||
|
canGoForward: false,
|
||||||
|
loading: true,
|
||||||
|
target: 0,
|
||||||
|
url: this.props.uri
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static options(passProps) {
|
||||||
|
return {
|
||||||
|
topBar: {
|
||||||
|
title: {
|
||||||
|
text: '加载中...'
|
||||||
|
},
|
||||||
|
leftButtons: [{
|
||||||
|
id: 'back', icon: Icon.navButtonBack
|
||||||
|
}],
|
||||||
|
rightButtons: [{
|
||||||
|
id: "open",
|
||||||
|
icon: Icon.navButtonOpen
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
BackHandler.addEventListener('hardwareBackPress', this.goBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
BackHandler.removeEventListener('hardwareBackPress', this.goBack)
|
||||||
|
}
|
||||||
|
|
||||||
|
navigationButtonPressed({buttonId}) {
|
||||||
|
if(buttonId == 'back') {
|
||||||
|
this.goBack();
|
||||||
|
|
||||||
|
} else if(buttonId == 'open') {
|
||||||
|
Linking.openURL(this.webViewState.url);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
goBack() {
|
||||||
|
if (this.webViewState.canGoBack) {
|
||||||
|
this.webView.injectJavaScript('window.history.back();');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Navigation.pop(this.props.componentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onNavigationStateChange(event) {
|
||||||
|
this.webViewState = event;
|
||||||
|
|
||||||
|
Navigation.mergeOptions(this.props.componentId, {
|
||||||
|
topBar: {
|
||||||
|
title: {
|
||||||
|
text: event.title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<WebView ref={(r) => this.webView = r}
|
||||||
|
style={{flex: 1}}
|
||||||
|
source={{uri: this.props.uri}}
|
||||||
|
onNavigationStateChange={this.onNavigationStateChange.bind(this)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,6 @@ import {Navigation} from 'react-native-navigation';
|
||||||
import KeyboardSpacer from "react-native-keyboard-spacer";
|
import KeyboardSpacer from "react-native-keyboard-spacer";
|
||||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||||
|
|
||||||
import BottomNav from '../nav/bottomNav';
|
|
||||||
import {Icon} from '../style/icon';
|
import {Icon} from '../style/icon';
|
||||||
import Color from '../style/color';
|
import Color from '../style/color';
|
||||||
import Api from '../util/api';
|
import Api from '../util/api';
|
||||||
|
|
|
@ -18,5 +18,6 @@ UserInfoEdit: require("./UserInfoEditPage.js").default,
|
||||||
UserIntroEdit: require("./UserIntroEditPage.js").default,
|
UserIntroEdit: require("./UserIntroEditPage.js").default,
|
||||||
UserNameEdit: require("./UserNameEditPage.js").default,
|
UserNameEdit: require("./UserNameEditPage.js").default,
|
||||||
User: require("./UserPage.js").default,
|
User: require("./UserPage.js").default,
|
||||||
|
WebView: require("./WebViewPage.js").default,
|
||||||
Write: require("./WritePage.js").default
|
Write: require("./WritePage.js").default
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ import {Platform, Dimensions} from 'react-native'
|
||||||
import DeviceInfo from 'react-native-device-info';
|
import DeviceInfo from 'react-native-device-info';
|
||||||
import {isIphoneX} from 'react-native-iphone-x-helper'
|
import {isIphoneX} from 'react-native-iphone-x-helper'
|
||||||
|
|
||||||
import TokenManager from './token'
|
import Token from './token'
|
||||||
|
|
||||||
|
|
||||||
const IS_ANDROID = Platform.OS === 'android';
|
const IS_ANDROID = Platform.OS === 'android';
|
||||||
|
@ -22,19 +22,19 @@ const v2Url = 'http://v2.timepill.net/api';
|
||||||
|
|
||||||
|
|
||||||
async function login(username, password) {
|
async function login(username, password) {
|
||||||
const token = TokenManager.generateToken(username, password);
|
const token = Token.generateToken(username, password);
|
||||||
await TokenManager.setUserToken(token);
|
await Token.setUserToken(token);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const userInfo = await getSelfInfo();
|
const userInfo = await getSelfInfo();
|
||||||
|
|
||||||
await TokenManager.setUserInfo(userInfo);
|
await Token.setUserInfo(userInfo);
|
||||||
await TokenManager.setLoginPassword('');
|
await Token.setLoginPassword('');
|
||||||
|
|
||||||
return userInfo;
|
return userInfo;
|
||||||
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
await TokenManager.setUserToken('');
|
await Token.setUserToken('');
|
||||||
if (err.code && err.code === 401) {
|
if (err.code && err.code === 401) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,38 @@ async function login(username, password) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function logout() {
|
async function logout() {
|
||||||
TokenManager.setUserToken('');
|
Token.setUserToken('');
|
||||||
TokenManager.setUserInfo(false);
|
Token.setUserInfo(false);
|
||||||
TokenManager.setLoginPassword('');
|
Token.setLoginPassword('');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getSplashByStore() {
|
||||||
|
try {
|
||||||
|
let info = await Token.get('splash');
|
||||||
|
console.log('api get splash:', info);
|
||||||
|
if(info) {
|
||||||
|
const splash = JSON.parse(info);
|
||||||
|
|
||||||
|
const now = Date.parse(new Date()) / 1000;
|
||||||
|
if((splash.start_time && splash.start_time > now) ||
|
||||||
|
(splash.end_time && now > splash.end_time)) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return splash;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function syncSplash() {
|
||||||
|
const splash = await callV2('GET', '/splash');
|
||||||
|
await Token.set('splash', JSON.stringify(splash));
|
||||||
|
|
||||||
|
return splash;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getSelfInfo() {
|
async function getSelfInfo() {
|
||||||
|
@ -54,7 +83,7 @@ async function getSelfInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getSelfInfoByStore() {
|
async function getSelfInfoByStore() {
|
||||||
return await TokenManager.getUserInfo();
|
return await Token.getUserInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getUserInfo(id) {
|
async function getUserInfo(id) {
|
||||||
|
@ -258,7 +287,7 @@ async function feedback(content) {
|
||||||
|
|
||||||
|
|
||||||
async function upload(method, api, body) {
|
async function upload(method, api, body) {
|
||||||
let token = await TokenManager.getUserToken();
|
let token = await Token.getUserToken();
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
for(let prop of Object.keys(body)) {
|
for(let prop of Object.keys(body)) {
|
||||||
formData.append(prop, body[prop]);
|
formData.append(prop, body[prop]);
|
||||||
|
@ -286,7 +315,7 @@ async function upload(method, api, body) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function call(method, api, body = null, _timeout = 10000) {
|
async function call(method, api, body = null, _timeout = 10000) {
|
||||||
let token = await TokenManager.getUserToken();
|
let token = await Token.getUserToken();
|
||||||
return timeout(fetch(baseUrl + api, {
|
return timeout(fetch(baseUrl + api, {
|
||||||
method: method,
|
method: method,
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -308,7 +337,7 @@ async function call(method, api, body = null, _timeout = 10000) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function callV2(method, api, body = null, _timeout = 10000) {
|
async function callV2(method, api, body = null, _timeout = 10000) {
|
||||||
let token = await TokenManager.getToken();
|
let token = await Token.getUserToken();
|
||||||
return timeout(fetch(v2Url + api, {
|
return timeout(fetch(v2Url + api, {
|
||||||
method: method,
|
method: method,
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -397,6 +426,8 @@ export default {
|
||||||
|
|
||||||
login,
|
login,
|
||||||
logout,
|
logout,
|
||||||
|
getSplashByStore,
|
||||||
|
syncSplash,
|
||||||
getSelfInfoByStore,
|
getSelfInfoByStore,
|
||||||
getUserInfo,
|
getUserInfo,
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue