pr feedback, reorganize styles, move types to correct folder, remove unnecesary values

This commit is contained in:
Pablo Velez Vidal
2022-11-16 18:07:05 +01:00
parent bdbbd2cb36
commit 0d5f86b0ab
8 changed files with 70 additions and 74 deletions

View File

@@ -5,8 +5,8 @@ import React from 'react';
import {Pressable, useWindowDimensions, View} from 'react-native';
import Animated, {Extrapolate, interpolate, useAnimatedStyle} from 'react-native-reanimated';
import CompassIcon from '@app/components/compass_icon';
import FormattedText from '@app/components/formatted_text';
import CompassIcon from '@components/compass_icon';
import FormattedText from '@components/formatted_text';
import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles';
import {makeStyleSheetFromTheme} from '@utils/theme';
@@ -28,9 +28,25 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
marginLeft: 5,
marginTop: 2,
},
nextButtonText: {
flexDirection: 'row',
position: 'absolute',
},
signInButtonText: {
flexDirection: 'row',
},
footerButtonsContainer: {
flexDirection: 'column',
height: 150,
marginTop: 15,
width: '100%',
marginHorizontal: 10,
alignItems: 'center',
},
}));
const AnimatedButton = Animated.createAnimatedComponent(Pressable);
const BUTTON_SIZE = 80;
const FooterButtons = ({
theme,
@@ -41,7 +57,6 @@ const FooterButtons = ({
}: Props) => {
const {width} = useWindowDimensions();
const styles = getStyleSheet(theme);
const BUTTON_SIZE = 80;
// keep in mind penultimate and ultimate slides to run buttons text/opacity/size animations
const penultimateSlide = lastSlideIndex - 1;
@@ -96,7 +111,7 @@ const FooterButtons = ({
});
const nextButtonText = (
<Animated.View style={[{flexDirection: 'row', position: 'absolute'}, opacityNextTextStyle]}>
<Animated.View style={[styles.nextButtonText, opacityNextTextStyle]}>
<FormattedText
id='mobile.onboarding.next'
defaultMessage='Next'
@@ -110,7 +125,7 @@ const FooterButtons = ({
);
const signInButtonText = (
<Animated.View style={[{flexDirection: 'row'}, opacitySignInTextStyle]}>
<Animated.View style={[styles.signInButtonText, opacitySignInTextStyle]}>
<FormattedText
id='mobile.onboarding.sign_in_to_get_started'
defaultMessage='Sign in to get started'
@@ -120,10 +135,10 @@ const FooterButtons = ({
);
return (
<View style={{flexDirection: 'column', height: 150, marginTop: 15, width: '100%', marginHorizontal: 10, alignItems: 'center'}}>
<View style={styles.footerButtonsContainer}>
<AnimatedButton
testID='mobile.onboaring.next'
onPress={() => nextSlideHandler()}
onPress={nextSlideHandler}
style={[styles.button, buttonBackgroundStyle(theme, 'm', 'primary', 'default'), resizeStyle]}
>
{nextButtonText}
@@ -131,7 +146,7 @@ const FooterButtons = ({
</AnimatedButton>
<AnimatedButton
testID='mobile.onboaring.sign_in'
onPress={() => signInHandler()}
onPress={signInHandler}
style={[styles.button, buttonBackgroundStyle(theme, 'm', 'link', 'default'), opacitySignInButton]}
>
<FormattedText

File diff suppressed because one or more lines are too long

View File

@@ -2,19 +2,19 @@
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useRef} from 'react';
import {View, ListRenderItemInfo, useWindowDimensions, SafeAreaView, ScrollView, Animated as AnimatedRN} from 'react-native';
import {View, ListRenderItemInfo, useWindowDimensions, SafeAreaView, ScrollView, Animated as AnimatedRN, StyleSheet} from 'react-native';
import Animated, {Easing, useAnimatedRef, useAnimatedScrollHandler, useDerivedValue, useSharedValue} from 'react-native-reanimated';
import {storeOnboardingViewedValue} from '@actions/app/global';
import {Screens} from '@app/constants';
import Background from '@screens/background';
import {goToScreen, loginAnimationOptions} from '@screens/navigation';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {OnboardingItem} from '@typings/screens/onboarding';
import FooterButtons from './footer_buttons';
import Paginator from './paginator';
import SlideItem from './slide';
import useSlidesData, {OnboardingItem} from './slides_data';
import useSlidesData from './slides_data';
import type {LaunchProps} from '@typings/launch';
@@ -22,9 +22,7 @@ interface OnboardingProps extends LaunchProps {
theme: Theme;
}
const AnimatedSafeArea = Animated.createAnimatedComponent(SafeAreaView);
const getStyleSheet = makeStyleSheetFromTheme(() => ({
const styles = StyleSheet.create({
onBoardingContainer: {
flex: 1,
alignItems: 'center',
@@ -34,17 +32,15 @@ const getStyleSheet = makeStyleSheetFromTheme(() => ({
scrollContainer: {
flex: 1,
alignItems: 'center',
height: '100%',
justifyContent: 'center',
},
}));
});
const Onboarding = ({
theme,
}: OnboardingProps) => {
const {width} = useWindowDimensions();
const styles = getStyleSheet(theme);
const slidesData = useSlidesData().slidesData;
const {slidesData} = useSlidesData();
const lastSlideIndex = slidesData.length - 1;
const slidesRef = useAnimatedRef<ScrollView>();
@@ -63,14 +59,14 @@ const Onboarding = ({
return () => scrollAnimation.current.removeAllListeners();
}, []);
const moveToSlide = (slideIndexToMove: number) => {
const moveToSlide = useCallback((slideIndexToMove: number) => {
AnimatedRN.timing(scrollAnimation.current, {
toValue: (slideIndexToMove * width),
duration: Math.abs(currentIndex.value - slideIndexToMove) * 200,
useNativeDriver: true,
easing: Easing.linear,
}).start();
};
}, [currentIndex.value]);
const nextSlide = useCallback(() => {
const nextSlideIndex = currentIndex.value + 1;
@@ -95,7 +91,7 @@ const Onboarding = ({
theme={theme}
scrollX={scrollX}
index={index}
key={item.id}
key={`key-${index.toString()}`}
/>
);
}, []);
@@ -112,12 +108,11 @@ const Onboarding = ({
testID='onboarding.screen'
>
<Background theme={theme}/>
<AnimatedSafeArea
<SafeAreaView
key={'onboarding_content'}
style={[styles.scrollContainer]}
style={styles.scrollContainer}
>
<Animated.ScrollView
scrollEventThrottle={16}
horizontal={true}
showsHorizontalScrollIndicator={false}
pagingEnabled={true}
@@ -130,7 +125,7 @@ const Onboarding = ({
})}
</Animated.ScrollView>
<Paginator
data={slidesData}
dataLength={slidesData.length}
theme={theme}
scrollX={scrollX}
moveToSlide={moveToSlide}
@@ -142,7 +137,7 @@ const Onboarding = ({
scrollX={scrollX}
lastSlideIndex={lastSlideIndex}
/>
</AnimatedSafeArea>
</SafeAreaView>
</View>
);
};

View File

@@ -7,10 +7,8 @@ import Animated, {interpolate, useAnimatedStyle} from 'react-native-reanimated';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {OnboardingItem} from './slides_data';
type Props = {
data: OnboardingItem[];
dataLength: number;
theme: Theme;
scrollX: Animated.SharedValue<number>;
moveToSlide: (slideIndexToMove: number) => void;
@@ -46,20 +44,25 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
width: DOT_SIZE,
opacity: 0.15,
},
paginatorContainer: {
flexDirection: 'row',
height: 15,
},
}));
const Paginator = ({
theme,
data,
dataLength,
scrollX,
moveToSlide,
}: Props) => {
const styles = getStyleSheet(theme);
return (
<View style={{flexDirection: 'row', height: 15}}>
{data.map((item: OnboardingItem, index: number) => {
<View style={styles.paginatorContainer}>
{[...Array(dataLength)].map((item: number, index: number) => {
return (
<Dot
key={`${item.id}-${index.toString()}`}
key={`key-${index.toString()}`}
theme={theme}
moveToSlide={moveToSlide}
index={index}
@@ -105,18 +108,10 @@ const Dot = ({index, scrollX, theme, moveToSlide}: DotProps) => {
});
return (
<TouchableOpacity
onPress={() => moveToSlide(index)}
>
<Animated.View
style={[styles.fixedDot]}
/>
<Animated.View
style={[styles.outerDot, outerDotOpacity]}
/>
<Animated.View
style={[styles.dot, dotOpacity]}
/>
<TouchableOpacity onPress={() => moveToSlide(index)}>
<Animated.View style={styles.fixedDot}/>
<Animated.View style={[styles.outerDot, outerDotOpacity]}/>
<Animated.View style={[styles.dot, dotOpacity]}/>
</TouchableOpacity>
);
};

View File

@@ -5,11 +5,10 @@ import React, {useEffect, useState} from 'react';
import {View, useWindowDimensions} from 'react-native';
import Animated, {Extrapolate, interpolate, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
import {OnboardingItem} from '@typings/screens/onboarding';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
import {OnboardingItem} from './slides_data';
type Props = {
item: OnboardingItem;
theme: Theme;
@@ -24,6 +23,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
height: 100,
color: theme.centerChannelColor,
textAlign: 'center',
fontFamily: 'Metropolis-SemiBold',
paddingHorizontal: 20,
},
fontTitle: {
fontSize: 40,
@@ -36,10 +37,9 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
opacity: 0,
},
description: {
fontWeight: '400',
fontSize: 16,
textAlign: 'center',
paddingHorizontal: 20,
fontFamily: 'Open Sans',
height: 80,
color: changeOpacity(theme.centerChannelColor, 0.64),
...typography('Body', 200, 'Regular'),
@@ -57,15 +57,16 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
},
}));
const FIRST_SLIDE = 0;
const FIRST_LOAD_ELEMENTS_POSITION = 400;
const SlideItem = ({theme, item, scrollX, index}: Props) => {
const {width} = useWindowDimensions();
const styles = getStyleSheet(theme);
const FIRST_SLIDE = 0;
/**
* Code used to animate the first image load
*/
const FIRST_LOAD_ELEMENTS_POSITION = 400;
const [firstLoad, setFirstLoad] = useState(true);
const initialImagePosition = useSharedValue(FIRST_LOAD_ELEMENTS_POSITION);
@@ -182,7 +183,7 @@ const SlideItem = ({theme, item, scrollX, index}: Props) => {
>
{item.image}
</Animated.View>
<View style={{flex: 0.3}}>
<View>
<Animated.Text
style={[
styles.title,
@@ -211,4 +212,4 @@ const SlideItem = ({theme, item, scrollX, index}: Props) => {
);
};
export default SlideItem;
export default React.memo(SlideItem);

View File

@@ -5,18 +5,13 @@ import React from 'react';
import {useIntl} from 'react-intl';
import {StyleSheet} from 'react-native';
import {OnboardingItem} from '@typings/screens/onboarding';
import CallsSvg from './illustrations/calls';
import ChatSvg from './illustrations/chat';
import IntegrationsSvg from './illustrations/integrations';
import TeamCommunicationSvg from './illustrations/team_communication';
export type OnboardingItem = {
id: string;
title: string;
description: string;
image: React.ReactElement;
}
const styles = StyleSheet.create({
image: {
justifyContent: 'center',
@@ -35,25 +30,21 @@ const useSalidesData = () => {
const slidesData: OnboardingItem[] = [
{
id: '1',
title: intl.formatMessage({id: 'onboarding_screen.welcome', defaultMessage: 'Welcome'}),
title: intl.formatMessage({id: 'onboarding.welcome', defaultMessage: 'Welcome'}),
description: intl.formatMessage({id: 'onboaring.welcome_description', defaultMessage: 'Mattermost is an open source platform for developer collaboration. Secure, flexible, and integrated with your tools.'}),
image: chatSvg,
},
{
id: '2',
title: intl.formatMessage({id: 'onboarding.realtime_collaboration', defaultMessage: 'Collaborate in real-time'}),
description: intl.formatMessage({id: 'onboarding.realtime_collaboration_description', defaultMessage: 'Persistent channels, direct messaging, and file sharing works seamlessly so you can stay connected, wherever you are.'}),
image: teamCommunicationSvg,
},
{
id: '3',
title: intl.formatMessage({id: 'onboarding.calls', defaultMessage: 'Start secure audio calls instantly'}),
description: intl.formatMessage({id: 'onboarding.calls_description', defaultMessage: 'When typing isnt fast enough, switch from channel-based chat to secure audio calls with a single tap.'}),
image: callsSvg,
},
{
id: '4',
title: intl.formatMessage({id: 'onboarding.integrations', defaultMessage: 'Integrate with tools you love'}),
description: intl.formatMessage({id: 'onboarding.integrations_description', defaultMessage: 'Go beyond chat with tightly-integratedproduct solutions matched to common development processes.'}),
image: integrationsSvg,

View File

@@ -63,7 +63,7 @@
"*": ["./*", "node_modules/*"],
}
},
"include": ["app/**/*", "share_extensionn/**/*", "test/**/*", "types/**/*"],
"include": ["app/**/*", "share_extension/**/*", "test/**/*", "types/**/*"],
"exclude": [
"node_modules",
"build",

View File

@@ -0,0 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
export type OnboardingItem = {
title: string;
description: string;
image: React.ReactElement;
};