extract the button to its own component; start text animations
This commit is contained in:
parent
50b832fbad
commit
f4abc5a20f
4 changed files with 105 additions and 69 deletions
91
app/screens/onboarding/footer_buttons.tsx
Normal file
91
app/screens/onboarding/footer_buttons.tsx
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import Button from 'react-native-button';
|
||||
|
||||
import CompassIcon from '@app/components/compass_icon';
|
||||
import FormattedText from '@app/components/formatted_text';
|
||||
import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
type Props = {
|
||||
theme: Theme;
|
||||
isLastSlide: boolean;
|
||||
nextSlideHandler: any;
|
||||
signInHandler: any;
|
||||
};
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
button: {
|
||||
marginTop: 5,
|
||||
},
|
||||
rowIcon: {
|
||||
color: theme.buttonColor,
|
||||
fontSize: 12,
|
||||
marginLeft: 5,
|
||||
marginTop: 2,
|
||||
},
|
||||
}));
|
||||
|
||||
const FooterButtons = ({
|
||||
theme,
|
||||
nextSlideHandler,
|
||||
signInHandler,
|
||||
isLastSlide,
|
||||
}: Props) => {
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
let mainButtonText = (
|
||||
<View style={{flexDirection: 'row'}}>
|
||||
<FormattedText
|
||||
id='mobile.onboarding.next'
|
||||
defaultMessage='Next'
|
||||
style={buttonTextStyle(theme, 'm', 'primary', 'default')}
|
||||
/>
|
||||
<CompassIcon
|
||||
name='arrow-forward-ios'
|
||||
style={styles.rowIcon}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
let mainButtonAction = nextSlideHandler;
|
||||
|
||||
if (isLastSlide) {
|
||||
mainButtonText = (
|
||||
<FormattedText
|
||||
id='mobile.onboarding.sign_in_to_get_started'
|
||||
defaultMessage='Sign in to get started'
|
||||
style={buttonTextStyle(theme, 's', 'primary', 'default')}
|
||||
/>
|
||||
);
|
||||
mainButtonAction = signInHandler;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{flexDirection: 'column', height: 150, marginTop: 15, width: '100%', marginHorizontal: 10, alignItems: 'center'}}>
|
||||
<Button
|
||||
testID='mobile.onboaring.next'
|
||||
onPress={() => mainButtonAction()}
|
||||
containerStyle={[styles.button, buttonBackgroundStyle(theme, 'm', 'primary', 'default'), {width: isLastSlide ? '90%' : 80}]}
|
||||
>
|
||||
{mainButtonText}
|
||||
</Button>
|
||||
<Button
|
||||
testID='mobile.onboaring.sign_in'
|
||||
onPress={() => signInHandler()}
|
||||
containerStyle={[styles.button, buttonBackgroundStyle(theme, 'm', 'link', 'default')]}
|
||||
>
|
||||
<FormattedText
|
||||
id='mobile.onboarding.sign_in'
|
||||
defaultMessage='Sign in'
|
||||
style={buttonTextStyle(theme, 's', 'primary', 'inverted')}
|
||||
/>
|
||||
</Button>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default FooterButtons;
|
||||
|
|
@ -15,6 +15,7 @@ import SlideItem from './slide';
|
|||
import slidesData from './slides_data';
|
||||
|
||||
import type {LaunchProps} from '@typings/launch';
|
||||
import FooterButtons from './footer_buttons';
|
||||
|
||||
interface OnboardingProps extends LaunchProps {
|
||||
theme: Theme;
|
||||
|
|
@ -34,18 +35,13 @@ const Onboarding = ({
|
|||
const nextSlide = () => {
|
||||
const nextSlideIndex = currentIndex + 1;
|
||||
if (slidesRef.current && currentIndex < lastSlideIndex) {
|
||||
console.log('*** current slide', currentIndex);
|
||||
console.log('*** next slide', nextSlideIndex);
|
||||
moveToSlide(nextSlideIndex);
|
||||
} else {
|
||||
console.log('*** end of slide', lastSlideIndex);
|
||||
}
|
||||
};
|
||||
|
||||
const moveToSlide = (slideIndexToMove: number) => {
|
||||
if (slideIndexToMove === lastSlideIndex) {
|
||||
setIsLastSlide(true);
|
||||
}
|
||||
setIsLastSlide(slideIndexToMove === lastSlideIndex);
|
||||
setCurrentIndex(slideIndexToMove);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
slidesRef?.current?.scrollToIndex({index: slideIndexToMove});
|
||||
|
|
@ -67,6 +63,7 @@ const Onboarding = ({
|
|||
<SlideItem
|
||||
item={i}
|
||||
theme={theme}
|
||||
scrollX={scrollX}
|
||||
/>
|
||||
);
|
||||
}, []);
|
||||
|
|
@ -75,6 +72,7 @@ const Onboarding = ({
|
|||
|
||||
const viewableItemsChanged = useRef(({viewableItems}: any) => {
|
||||
setCurrentIndex(viewableItems[0].index);
|
||||
setIsLastSlide(viewableItems[0].index === lastSlideIndex);
|
||||
}).current;
|
||||
|
||||
const viewConfig = useRef({viewAreaCoveragePercentThreshold: 50}).current;
|
||||
|
|
@ -89,7 +87,7 @@ const Onboarding = ({
|
|||
key={'onboarding_content'}
|
||||
style={[styles.scrollContainer, transform]}
|
||||
>
|
||||
<FlatList
|
||||
<Animated.FlatList
|
||||
keyExtractor={(item) => item.id}
|
||||
data={slidesData}
|
||||
renderItem={renderSlide}
|
||||
|
|
@ -99,7 +97,7 @@ const Onboarding = ({
|
|||
pagingEnabled={true}
|
||||
bounces={false}
|
||||
onScroll={Animated.event([{nativeEvent: {contentOffset: {x: scrollX}}}], {
|
||||
useNativeDriver: false,
|
||||
useNativeDriver: true,
|
||||
})}
|
||||
onViewableItemsChanged={viewableItemsChanged}
|
||||
viewabilityConfig={viewConfig}
|
||||
|
|
@ -111,10 +109,13 @@ const Onboarding = ({
|
|||
data={slidesData}
|
||||
theme={theme}
|
||||
scrollX={scrollX}
|
||||
moveToSlide={moveToSlide}
|
||||
/>
|
||||
<FooterButtons
|
||||
theme={theme}
|
||||
isLastSlide={isLastSlide}
|
||||
nextSlideHandler={nextSlide}
|
||||
signInHandler={signInHandler}
|
||||
moveToSlide={moveToSlide}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,20 +3,13 @@
|
|||
|
||||
import React from 'react';
|
||||
import {View, Animated, useWindowDimensions, TouchableOpacity} from 'react-native';
|
||||
import Button from 'react-native-button';
|
||||
|
||||
import CompassIcon from '@app/components/compass_icon';
|
||||
import FormattedText from '@app/components/formatted_text';
|
||||
import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
type Props = {
|
||||
data: any;
|
||||
theme: Theme;
|
||||
scrollX: any;
|
||||
isLastSlide: boolean;
|
||||
nextSlideHandler: any;
|
||||
signInHandler: any;
|
||||
moveToSlide: any;
|
||||
};
|
||||
|
||||
|
|
@ -49,43 +42,13 @@ const Paginator = ({
|
|||
theme,
|
||||
data,
|
||||
scrollX,
|
||||
nextSlideHandler,
|
||||
signInHandler,
|
||||
moveToSlide,
|
||||
isLastSlide,
|
||||
}: Props) => {
|
||||
const styles = getStyleSheet(theme);
|
||||
const {width} = useWindowDimensions();
|
||||
|
||||
let mainButtonText = (
|
||||
<>
|
||||
<FormattedText
|
||||
id='mobile.onboarding.next'
|
||||
defaultMessage='Next'
|
||||
style={buttonTextStyle(theme, 'm', 'primary', 'default')}
|
||||
/>
|
||||
<CompassIcon
|
||||
name='arrow-forward-ios'
|
||||
style={styles.rowIcon}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
let mainButtonAction = nextSlideHandler;
|
||||
|
||||
if (isLastSlide) {
|
||||
mainButtonText = (
|
||||
<FormattedText
|
||||
id='mobile.onboarding.sign_in_to_get_started'
|
||||
defaultMessage='Sign in to get started'
|
||||
style={buttonTextStyle(theme, 'm', 'primary', 'default')}
|
||||
/>
|
||||
);
|
||||
mainButtonAction = signInHandler;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{flexDirection: 'column', height: 150}}>
|
||||
<View style={{flexDirection: 'column', height: 10}}>
|
||||
<View style={{flexDirection: 'row', height: 5}}>
|
||||
{data.map((item: any, i: number) => {
|
||||
const inputRange = [(i - 1) * width, i * width, (i + 1) * width];
|
||||
|
|
@ -116,26 +79,6 @@ const Paginator = ({
|
|||
);
|
||||
})}
|
||||
</View>
|
||||
<View style={{marginTop: 15}}>
|
||||
<Button
|
||||
testID='mobile.onboaring.next'
|
||||
onPress={() => mainButtonAction()}
|
||||
containerStyle={[styles.button, buttonBackgroundStyle(theme, 'lg', 'primary', 'default')]}
|
||||
>
|
||||
{mainButtonText}
|
||||
</Button>
|
||||
<Button
|
||||
testID='mobile.onboaring.sign_in'
|
||||
onPress={() => signInHandler()}
|
||||
containerStyle={[styles.button, buttonBackgroundStyle(theme, 'lg', 'link', 'default')]}
|
||||
>
|
||||
<FormattedText
|
||||
id='mobile.onboarding.sign_in'
|
||||
defaultMessage='Sign in'
|
||||
style={buttonTextStyle(theme, 'm', 'primary', 'inverted')}
|
||||
/>
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {typography} from '@utils/typography';
|
|||
type Props = {
|
||||
item: any;
|
||||
theme: Theme;
|
||||
scrollX: any;
|
||||
};
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
|
|
@ -43,7 +44,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
},
|
||||
}));
|
||||
|
||||
const SlideItem = ({theme, item}: Props) => {
|
||||
const SlideItem = ({theme, item, scrollX}: Props) => {
|
||||
const {width} = useWindowDimensions();
|
||||
const styles = getStyleSheet(theme);
|
||||
const SvgImg = item.image;
|
||||
|
|
|
|||
Loading…
Reference in a new issue