@@ -2,40 +2,48 @@ import { useNavigation } from "@react-navigation/native";
2
2
import * as React from "react" ;
3
3
import { Alert , StyleSheet } from "react-native" ;
4
4
import { Button , Card , Text } from "react-native-paper" ;
5
- import Animated , { FadeIn , FadeOut } from "react-native-reanimated" ;
5
+ import Animated , {
6
+ AnimateProps ,
7
+ FadeIn ,
8
+ FadeOut ,
9
+ FadeInDown ,
10
+ } from "react-native-reanimated" ;
6
11
7
12
import type { StarshipProps } from "../../api/types" ;
8
13
import { useImage } from "../hooks/useImage" ;
9
14
import { Routes } from "../navigation/Routes" ;
10
15
11
16
import { Image } from "~/components/Image" ;
12
17
13
- export function createAnimatedComponentFrowardingRef < P , S > (
14
- Component : React . ComponentClass < P , S >
15
- ) {
16
- return React . forwardRef < React . Component < P , S > , P > ( ( props , ref ) => {
17
- class Wrapper extends React . Component < P , S > {
18
- render ( ) {
19
- return < Component { ...this . props } ref = { ref } /> ;
20
- }
18
+ export function withAnimated < T extends object > (
19
+ WrappedComponent : React . ComponentType < T >
20
+ ) : React . ComponentClass < AnimateProps < T > , any > {
21
+ const displayName =
22
+ WrappedComponent . displayName || WrappedComponent . name || "Component" ;
23
+
24
+ class WithAnimated extends React . Component < T , any > {
25
+ static displayName = `WithAnimated(${ displayName } )` ;
26
+
27
+ render ( ) : React . ReactNode {
28
+ return < WrappedComponent { ...this . props } /> ;
21
29
}
22
- const AnimatedWrapper = Animated . createAnimatedComponent ( Wrapper ) ;
23
- return < AnimatedWrapper { ...props } /> ;
24
- } ) ;
30
+ }
31
+ return Animated . createAnimatedComponent ( WithAnimated ) ;
25
32
}
26
33
27
- const AnimatedCard = createAnimatedComponentFrowardingRef ( Card ) ;
34
+ const AnimatedCard = withAnimated ( Card ) ;
28
35
29
36
export interface StarshipCardProps {
30
37
ship : StarshipProps ;
38
+ index : number ;
31
39
}
32
40
33
41
interface StarshipDetailsScreenParams {
34
42
// eslint-disable-next-line @typescript-eslint/no-explicit-any
35
43
navigate : any ;
36
44
}
37
45
38
- export const StarshipCard = ( { ship } : StarshipCardProps ) => {
46
+ export const StarshipCard = ( { ship, index } : StarshipCardProps ) => {
39
47
const title = ship . name ;
40
48
const price = ship . cost_in_credits ;
41
49
const { manufacturer } = ship ;
@@ -51,14 +59,19 @@ export const StarshipCard = ({ ship }: StarshipCardProps) => {
51
59
navigation . navigate ( Routes . STARSHIP_DETAILS_SCREEN , ship ) ;
52
60
} ;
53
61
62
+ // visibleIndex -> prop
63
+ // Range = if index belongs to this range [visibleIndex - 2, visibleIndex+ 2] -> animate
64
+ // otherwise don't animate
54
65
return (
55
66
< AnimatedCard
56
67
style = { styles . containerCard }
57
68
onPress = { handleGoToDetails }
58
69
// mounting
59
- entering = { FadeIn . duration ( 500 ) }
70
+ entering = { FadeInDown . duration ( index > 3 ? 0 : 250 ) . delay (
71
+ index > 3 ? 0 : 100 * index
72
+ ) }
60
73
// unmounting
61
- existing = { FadeOut . duration ( 500 ) }
74
+ exiting = { FadeOut . duration ( 250 ) }
62
75
>
63
76
< Image
64
77
style = { { width : "100%" , height : 200 , borderRadius : 12 } }
0 commit comments