Commit 0309c6a0 by Prachpawee

add on-boarding screen

parent 36213c9b
import React, { Component } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export default class Button extends Component {
render({ onPress } = this.props) {
return (
<TouchableOpacity onPress={onPress}>
<View style={styles.button}>
{this.props.text ? (
<Text style={styles.text}>{this.props.text.toUpperCase()}</Text>
) : (
this.props.children
)}
</View>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
button: {
width: 85,
height: 50,
borderRadius: 30,
backgroundColor: 'rgba(255,255,255,0.3)',
alignItems: 'center',
justifyContent: 'center',
},
text: {
color: '#FFFFFF',
fontWeight: 'bold',
// fontFamily: 'Avenir',
},
});
import React, { Component } from 'react';
import { StyleSheet, Text, Image } from 'react-native';
import Swiper from './Swiper';
import { LinearGradient } from 'expo-linear-gradient';
const pages = [
{
img: 'https://www.tunnelbear.com/static/img/android@2x.b83f4df.png',
description:
'Coventry is a city with a thousand years of history that has plenty to offer the visiting tourist.',
},
{
img: 'https://www.tunnelbear.com/static/img/android@2x.b83f4df.png',
description:
'Coventry2 is a city with a thousand years of history that has plenty to offer the visiting tourist.',
},
{
img: 'https://www.tunnelbear.com/static/img/android@2x.b83f4df.png',
description:
'Coventry3 is a city with a thousand years of history that has plenty to offer the visiting tourist.',
},
{
img: 'https://www.tunnelbear.com/static/img/android@2x.b83f4df.png',
description:
'Coventry4 is a city with a thousand years of history that has plenty to offer the visiting tourist.',
},
];
export default class Onboarding extends Component {
render() {
return (
<Swiper>
{pages.map((page, index) => (
<LinearGradient
key={index}
colors={['#f66969', '#f44c4c']}
start={[0, 0]}
end={[1, 0]}
style={[styles.slide]}
>
<Image source={{ uri: page.img }} style={[styles.img]} />
<Text style={styles.text}>{page.description}</Text>
</LinearGradient>
))}
</Swiper>
);
}
}
const styles = StyleSheet.create({
slide: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
color: '#FFFFFF',
// fontFamily: 'Avenir',
fontSize: 18,
marginHorizontal: 30,
position: 'absolute',
top: '71%',
lineHeight: 24,
},
img: {
position: 'absolute',
top: '16%',
width: '50%',
height: '50%',
resizeMode: 'contain',
},
});
import React, { Component } from 'react';
import { Dimensions, Platform, ScrollView, View, StyleSheet } from 'react-native';
import ObButton from './Button';
import { Actions } from 'react-native-router-flux';
import { Icon } from 'native-base';
import { Button, Text } from 'native-base';
const { width, height } = Dimensions.get('window');
export default class OnboardingScreens extends Component {
static defaultProps = {
horizontal: true,
pagingEnabled: true,
showsHorizontalScrollIndicator: false,
showsVerticalScrollIndicator: false,
bounces: false,
scrollsToTop: false,
removeClippedSubviews: true,
automaticallyAdjustContentInsets: false,
index: 0,
};
state = this.initState(this.props);
initState(props) {
const total = props.children ? props.children.length || 1 : 0,
index = total > 1 ? Math.min(props.index, total - 1) : 0,
offset = width * index;
const state = {
total,
index,
offset,
width,
height,
};
this.internals = {
isScrolling: false,
offset,
};
return state;
}
onScrollBegin = e => {
this.internals.isScrolling = true;
};
onScrollEnd = e => {
this.internals.isScrolling = false;
this.updateIndex(
e.nativeEvent.contentOffset ? e.nativeEvent.contentOffset.x : e.nativeEvent.position * this.state.width
);
};
onScrollEndDrag = e => {
const {
contentOffset: { x: newOffset },
} = e.nativeEvent,
{ children } = this.props,
{ index } = this.state,
{ offset } = this.internals;
if (offset === newOffset && (index === 0 || index === children.length - 1)) {
this.internals.isScrolling = false;
}
};
updateIndex = offset => {
const state = this.state,
diff = offset - this.internals.offset,
step = state.width;
let index = state.index;
if (!diff) {
return;
}
index = parseInt(index + Math.round(diff / step), 10);
this.internals.offset = offset;
this.setState({
index,
});
};
swipe = () => {
if (this.internals.isScrolling || this.state.total < 2) {
return;
}
const state = this.state,
diff = this.state.index + 1,
x = diff * state.width,
y = 0;
this.scrollView && this.scrollView.scrollTo({ x, y, animated: true });
this.internals.isScrolling = true;
if (Platform.OS === 'android') {
setImmediate(() => {
this.onScrollEnd({
nativeEvent: {
position: diff,
},
});
});
}
};
renderScrollView = pages => {
return (
<ScrollView
ref={component => {
this.scrollView = component;
}}
{...this.props}
contentContainerStyle={[styles.wrapper, this.props.style]}
onScrollBeginDrag={this.onScrollBegin}
onMomentumScrollEnd={this.onScrollEnd}
onScrollEndDrag={this.onScrollEndDrag}
>
{pages.map((page, i) => (
<View style={[styles.fullScreen, styles.slide]} key={i}>
{page}
</View>
))}
</ScrollView>
);
};
renderPagination = () => {
if (this.state.total <= 1) {
return null;
}
const ActiveDot = (
<View style={[styles.activeDotBorder]}>
<View style={[styles.activeDot]} />
</View>
),
Dot = <View style={[styles.dot]} />;
let dots = [];
for (let key = 0; key < this.state.total; key++) {
dots.push(
key === this.state.index ? React.cloneElement(ActiveDot, { key }) : React.cloneElement(Dot, { key })
);
}
return (
<View pointerEvents="none" style={[styles.pagination, styles.fullScreen]}>
{dots}
</View>
);
};
renderButton = () => {
const lastScreen = this.state.index === this.state.total - 1;
return (
<View pointerEvents="box-none" style={[styles.buttonWrapper, styles.fullScreen]}>
{lastScreen ? (
<ObButton text="START" onPress={() => Actions.LoginPage()} />
) : (
<ObButton onPress={() => this.swipe()}>
<Icon style={{ color: 'white' }} name="arrow-forward" />
</ObButton>
)}
</View>
);
};
renderSkip = () => {
const lastScreen = this.state.index === this.state.total - 1;
return (
<View style={[styles.skipContainer]}>
{lastScreen ? null : (
<Button transparent onPress={() => Actions.LoginPage()}>
<Text style={[styles.skipText]}>SKIP</Text>
</Button>
)}
</View>
);
};
render = ({ children } = this.props) => {
return (
<View style={[styles.container, styles.fullScreen]}>
{this.renderScrollView(children)}
{this.renderPagination()}
{this.renderButton()}
{this.renderSkip()}
</View>
);
};
}
const styles = StyleSheet.create({
fullScreen: {
width: width,
height: height,
},
container: {
backgroundColor: 'transparent',
position: 'relative',
},
slide: {
backgroundColor: 'transparent',
},
pagination: {
position: 'absolute',
bottom: '10%',
left: 30,
right: 0,
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'flex-end',
backgroundColor: 'transparent',
},
dot: {
width: 9,
height: 9,
backgroundColor: 'white',
borderRadius: 100,
marginHorizontal: 6,
opacity: 0.2,
marginBottom: 6,
},
activeDot: {
width: 11,
height: 11,
backgroundColor: 'white',
borderRadius: 100,
},
activeDotBorder: {
width: 21,
height: 21,
borderWidth: 2,
borderColor: 'rgba(255, 255, 255, 0.3)',
borderRadius: 100,
marginHorizontal: 6,
alignItems: 'center',
justifyContent: 'center',
},
buttonWrapper: {
backgroundColor: 'transparent',
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-end',
alignItems: 'flex-end',
position: 'absolute',
bottom: '8%',
right: 30,
},
skipContainer: {
position: 'absolute',
top: '8%',
right: 15,
},
skipText: {
color: '#fff',
fontSize: 12,
},
});
......@@ -10,6 +10,7 @@ import HomePage from '../screens/private/HomePage';
import Register from '../screens/public/register';
import ForgotPass from '../screens/public/forgotPassword';
import SendEmail from '../screens/public/sendEmail';
import StartPage from '../screens/public/startPage';
class AppRouterComponent extends Component {
render() {
......@@ -20,7 +21,8 @@ class AppRouterComponent extends Component {
<Scene key="HomePage" component={HomePage} />
<Scene key="PageOne" component={PageOne} />
<Scene key="PageTwo" component={PageTwo} />
<Scene key="LoginPage" component={LoginPage} initial={true} />
<Scene key="Start" component={StartPage} initial={true} />
<Scene key="LoginPage" component={LoginPage} />
<Scene key="Register" component={Register} />
<Scene key="ForgotPass" component={ForgotPass} />
<Scene key="SendEmail" component={SendEmail} />
......
......@@ -87,6 +87,7 @@ class PageOne extends Component {
img={mt.img}
isOnline={mt.isOnline}
isOn={mt.isOn}
index={index + 1}
/>
))}
</Content>
......
import React, { Component } from 'react';
import { AsyncStorage } from 'react-native';
import Onboarding from '../../components/Onboarding/Onboarding';
import Login from '../public/login';
export default class startPage extends Component {
constructor(props) {
super(props);
this.state = {
firstLaunch: null,
isCheck: false,
};
}
componentDidMount() {
AsyncStorage.getItem('alreadyLaunched').then(value => {
if (value == null) {
AsyncStorage.setItem('alreadyLaunched', 'true');
this.setState({ firstLaunch: 'true' });
} else {
this.setState({ firstLaunch: 'false' });
}
});
}
render() {
if (this.state.firstLaunch === null) {
return null;
} else if (this.state.firstLaunch == 'true') {
return <Onboarding />;
} else {
return <Login />;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment