Skip to content

Commit 987d1be

Browse files
committedMay 4, 2020
Part 5 Files 🐛
1 parent 6410654 commit 987d1be

File tree

12 files changed

+671
-257
lines changed

12 files changed

+671
-257
lines changed
 

‎02-uber-login-screen/part-5/App.js

+157-26
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,172 @@
1-
import React, { useEffect, useState } from "react";
2-
import { StyleSheet, Text, View, SafeAreaView, Dimensions } from "react-native";
3-
import { AppLoading } from "expo";
4-
// import Card from "./components/Card";
5-
import SkeletonComp from "./components/Card";
1+
import React, { useRef } from "react";
2+
import { StyleSheet, Text, View, Image } from "react-native";
3+
import Logo from "./components/Logo";
4+
import Animated, {
5+
useCode,
6+
cond,
7+
eq,
8+
set,
9+
interpolate,
10+
SpringUtils,
11+
} from "react-native-reanimated";
12+
import {
13+
withTimingTransition,
14+
onGestureEvent,
15+
withSpringTransition,
16+
} from "react-native-redash";
17+
import { SCREEN_HEIGHT, LOGIN_VIEW_HEIGHT } from "./Constants";
18+
import {
19+
TextInput,
20+
TapGestureHandler,
21+
State,
22+
} from "react-native-gesture-handler";
23+
import OverlayBg from "./components/OverlayBg";
24+
import HeaderBackArrow from "./components/HeaderBackArrow";
25+
import AnimatedPlaceholder from "./components/AnimatedPlaceholder";
626

7-
const { width } = Dimensions.get("window");
827
export default function App() {
9-
const [isReady, setIsReady] = useState(false);
28+
const scale = useRef(new Animated.Value(0));
29+
const scaleAnimation = withTimingTransition(scale.current);
1030

11-
useEffect(() => {
12-
let timer1 = setTimeout(() => setIsReady(true), 2000);
13-
return () => {
14-
clearTimeout(timer1);
15-
};
16-
}, []);
31+
const innerLoginY = interpolate(scaleAnimation, {
32+
inputRange: [0, 1],
33+
outputRange: [LOGIN_VIEW_HEIGHT, 0],
34+
});
35+
36+
const gestureState = useRef(new Animated.Value(State.UNDETERMINED));
37+
const gestureHandler = onGestureEvent({ state: gestureState.current });
38+
39+
const backArrowGestureState = useRef(new Animated.Value(State.UNDETERMINED));
40+
const backArrowGestureHandler = onGestureEvent({
41+
state: backArrowGestureState.current,
42+
});
43+
44+
const isOpen = useRef(new Animated.Value(0));
45+
const isOpenAnimation = withSpringTransition(isOpen.current, {
46+
...SpringUtils.makeDefaultConfig(),
47+
overshootClamping: true,
48+
damping: new Animated.Value(20),
49+
});
50+
51+
const outerLoginY = interpolate(isOpenAnimation, {
52+
inputRange: [0, 1],
53+
outputRange: [SCREEN_HEIGHT - LOGIN_VIEW_HEIGHT, LOGIN_VIEW_HEIGHT / 2],
54+
});
55+
56+
const headingOpacity = interpolate(isOpenAnimation, {
57+
inputRange: [0, 1],
58+
outputRange: [1, 0],
59+
});
60+
61+
useCode(() =>
62+
cond(
63+
eq(gestureState.current, State.END),
64+
[cond(eq(isOpen.current, 0), set(isOpen.current, 1))],
65+
[gestureState.current],
66+
),
67+
);
68+
useCode(() => cond(eq(scale.current, 0), set(scale.current, 1)), []);
69+
70+
useCode(
71+
() =>
72+
cond(eq(backArrowGestureState.current, State.END), [
73+
set(gestureState.current, State.UNDETERMINED),
74+
set(isOpen.current, 0),
75+
]),
76+
[backArrowGestureState.current],
77+
);
1778

1879
return (
1980
<View style={styles.container}>
20-
<SafeAreaView style={{ backgroundColor: "#5f5f5f" }} />
21-
{isReady ? (
22-
<View
23-
style={{ height: 200, width: width, backgroundColor: "grey" }}
24-
></View>
25-
) : (
26-
<SkeletonComp
27-
height={200}
28-
width={width}
29-
style={{ marginVertical: 20 }}
30-
></SkeletonComp>
31-
)}
81+
<View style={{ ...styles.logoContainer }}>
82+
<Logo scale={scaleAnimation} />
83+
</View>
84+
<HeaderBackArrow
85+
isOpenAnimation={isOpenAnimation}
86+
gestureHandler={{ ...backArrowGestureHandler }}
87+
/>
88+
89+
<Animated.View
90+
style={{
91+
backgroundColor: "white",
92+
...StyleSheet.absoluteFill,
93+
transform: [{ translateY: outerLoginY }],
94+
}}
95+
>
96+
<OverlayBg isOpenAnimation={isOpenAnimation} />
97+
<Animated.View>
98+
<Animated.View
99+
style={{
100+
height: LOGIN_VIEW_HEIGHT,
101+
102+
backgroundColor: "white",
103+
104+
transform: [{ translateY: innerLoginY }],
105+
}}
106+
>
107+
<Animated.View
108+
style={{ ...styles.heading, opacity: headingOpacity }}
109+
>
110+
<Text style={{ fontSize: 24 }}>Get moving with Uber</Text>
111+
</Animated.View>
112+
113+
<TapGestureHandler {...gestureHandler}>
114+
<Animated.View>
115+
<Animated.View
116+
pointerEvents="none"
117+
style={{ ...styles.textInputContainer }}
118+
>
119+
<AnimatedPlaceholder isOpenAnimation={isOpenAnimation} />
120+
<Image
121+
source={require("./assets/india.png")}
122+
style={{ ...styles.image }}
123+
/>
124+
<Text style={{ ...styles.prefix }}>+91</Text>
125+
<TextInput
126+
keyboardType="number-pad"
127+
style={{ ...styles.textInput }}
128+
placeholder="Enter your mobile number"
129+
/>
130+
</Animated.View>
131+
</Animated.View>
132+
</TapGestureHandler>
133+
</Animated.View>
134+
</Animated.View>
135+
</Animated.View>
32136
</View>
33137
);
34138
}
35139

36140
const styles = StyleSheet.create({
37141
container: {
38142
flex: 1,
39-
backgroundColor: "#fff",
143+
backgroundColor: "#2289d6",
144+
},
145+
logoContainer: {
146+
flex: 1,
147+
alignItems: "center",
148+
justifyContent: "center",
149+
},
150+
heading: {
151+
alignItems: "flex-start",
152+
marginHorizontal: 25,
153+
marginTop: 50,
154+
},
155+
image: {
156+
height: 24,
157+
width: 24,
158+
resizeMode: "contain",
159+
},
160+
prefix: {
161+
fontSize: 20,
162+
paddingHorizontal: 10,
163+
},
164+
textInput: {
165+
flex: 1,
166+
fontSize: 20,
167+
},
168+
textInputContainer: {
169+
flexDirection: "row",
170+
margin: 25,
40171
},
41172
});
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Dimensions } from "react-native";
2+
3+
const { width, height } = Dimensions.get("window");
4+
5+
export const SCREEN_HEIGHT = height;
6+
export const SCREEN_WIDTH = width;
7+
8+
export const TEXT_INPUT_HEIGHT = 150;
9+
export const FOOTER_HEIGHT = 70;
10+
11+
export const LOGIN_VIEW_HEIGHT = TEXT_INPUT_HEIGHT + FOOTER_HEIGHT;

‎02-uber-login-screen/part-5/app.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"expo": {
33
"name": "HelloWorld",
4-
"slug": "skeleton-ui",
4+
"slug": "react-native-uber-ui",
55
"platforms": [
66
"ios",
77
"android",
15.9 KB
Loading

‎02-uber-login-screen/part-5/babel.config.js

-6
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from "react";
2+
import { View, Text, StyleSheet } from "react-native";
3+
import Animated, { interpolate } from "react-native-reanimated";
4+
5+
const AnimatedPlaceholder = ({ isOpenAnimation }) => {
6+
const translateX = interpolate(isOpenAnimation, {
7+
inputRange: [0, 1],
8+
outputRange: [80, 0],
9+
});
10+
11+
const translateY = interpolate(isOpenAnimation, {
12+
inputRange: [0, 0.5, 1],
13+
outputRange: [0, 0, -60],
14+
});
15+
16+
const opacity = interpolate(translateY, {
17+
inputRange: [-60, 0],
18+
outputRange: [1, 0],
19+
});
20+
21+
return (
22+
<Animated.Text
23+
style={{
24+
...styles.placeholder,
25+
transform: [
26+
{
27+
translateY,
28+
translateX,
29+
},
30+
],
31+
opacity,
32+
}}
33+
>
34+
Enter your mobile Number
35+
</Animated.Text>
36+
);
37+
};
38+
export default AnimatedPlaceholder;
39+
40+
const styles = StyleSheet.create({
41+
placeholder: {
42+
fontSize: 24,
43+
position: "absolute",
44+
},
45+
});

‎02-uber-login-screen/part-5/components/Card.js

-79
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React, { Component } from "react";
2+
import { View, Text, StyleSheet } from "react-native";
3+
import Animated, { interpolate } from "react-native-reanimated";
4+
import { Ionicons as Icon } from "@expo/vector-icons";
5+
import { TapGestureHandler } from "react-native-gesture-handler";
6+
const HeaderBackArrow = ({ isOpenAnimation, gestureHandler }) => {
7+
const opacity = interpolate(isOpenAnimation, {
8+
inputRange: [0, 0.7, 1],
9+
outputRange: [0, 0, 1],
10+
});
11+
12+
return (
13+
<TapGestureHandler {...gestureHandler}>
14+
<Animated.View style={{ ...styles.backArrow, opacity }}>
15+
<Icon name="md-arrow-back" size={24} />
16+
</Animated.View>
17+
</TapGestureHandler>
18+
);
19+
};
20+
export default HeaderBackArrow;
21+
22+
const styles = StyleSheet.create({
23+
backArrow: {
24+
position: "absolute",
25+
height: 60,
26+
width: 60,
27+
top: 60,
28+
left: 25,
29+
zIndex: 100,
30+
},
31+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from "react";
2+
import Animated from "react-native-reanimated";
3+
import { View, Text, StyleSheet } from "react-native";
4+
5+
const Logo = ({ scale }) => (
6+
<Animated.View style={{ ...styles.logo, transform: [{ scale }] }}>
7+
<Text style={{ fontWeight: "400", fontSize: 36 }}>Uber</Text>
8+
</Animated.View>
9+
);
10+
export default Logo;
11+
12+
const styles = StyleSheet.create({
13+
logo: {
14+
backgroundColor: "white",
15+
height: 120,
16+
width: 120,
17+
padding: 10,
18+
alignItems: "center",
19+
justifyContent: "center",
20+
},
21+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from "react";
2+
import { View, Text, StyleSheet } from "react-native";
3+
import Animated, { interpolate } from "react-native-reanimated";
4+
import { LOGIN_VIEW_HEIGHT, SCREEN_HEIGHT } from "../Constants";
5+
import { interpolateColor } from "react-native-redash";
6+
const OverlayBg = ({ isOpenAnimation }) => {
7+
const translateY = interpolate(isOpenAnimation, {
8+
inputRange: [0, 1],
9+
outputRange: [SCREEN_HEIGHT - LOGIN_VIEW_HEIGHT, -LOGIN_VIEW_HEIGHT],
10+
});
11+
12+
const backgroundColor = interpolateColor(isOpenAnimation, {
13+
inputRange: [0, 0.1, 1],
14+
outputRange: ["#2289d6", "#FFFF", "#FFFF"],
15+
});
16+
17+
return (
18+
<Animated.View
19+
style={{
20+
height: LOGIN_VIEW_HEIGHT,
21+
alignItems: "center",
22+
justifyContent: "center",
23+
backgroundColor,
24+
// backgroundColor: "grey",
25+
position: "absolute",
26+
top: 0,
27+
left: 0,
28+
right: 0,
29+
30+
transform: [{ translateY }],
31+
}}
32+
></Animated.View>
33+
);
34+
};
35+
export default OverlayBg;
36+
37+
const styles = StyleSheet.create({
38+
container: {
39+
flex: 1,
40+
alignItems: "center",
41+
justifyContent: "center",
42+
},
43+
});

‎02-uber-login-screen/part-5/package.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@
99
},
1010
"dependencies": {
1111
"expo": "~37.0.3",
12-
"linear-gradient": "^1.0.6",
13-
"prop-types": "^15.7.2",
1412
"react": "~16.9.0",
1513
"react-dom": "~16.9.0",
1614
"react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
15+
"react-native-gesture-handler": "^1.6.1",
16+
"react-native-reanimated": "^1.8.0",
17+
"react-native-redash": "^12.6.1",
1718
"react-native-web": "~0.11.7"
1819
},
1920
"devDependencies": {
2021
"@babel/core": "^7.8.6",
2122
"babel-preset-expo": "~8.1.0",
22-
"eslint-plugin-react-hooks": "^4.0.0"
23+
"eslint-config-react-native-up": "^1.0.7",
24+
"eslint-plugin-react-hooks": "^3.0.0"
2325
},
2426
"private": true
2527
}

‎02-uber-login-screen/part-5/yarn.lock

+357-142
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.