1
- import {
2
- Button ,
3
- Flex ,
4
- HeartIcon ,
5
- Spacer ,
6
- Text ,
7
- useScreenDimensions ,
8
- useSpace ,
9
- } from "@artsy/palette-mobile"
1
+ import { Flex , LinkText , Spacer , Text , useSpace } from "@artsy/palette-mobile"
2
+ import { InfiniteDiscoveryArtworkCard } from "app/Scenes/InfiniteDiscovery/Components/InfiniteDiscoveryArtworkCard"
3
+ import { Swiper , SwiperRefProps } from "app/Scenes/InfiniteDiscovery/Components/Swiper/Swiper"
4
+ import { InfiniteDiscoveryArtwork } from "app/Scenes/InfiniteDiscovery/InfiniteDiscovery"
10
5
import { GlobalStore } from "app/store/GlobalStore"
11
- import { useEffect , useRef , useState } from "react"
6
+ import { useEffect , useMemo , useRef , useState } from "react"
12
7
import { Modal } from "react-native"
13
- import { FlatList } from "react-native-gesture-handler"
14
8
import LinearGradient from "react-native-linear-gradient"
9
+ import { useSharedValue } from "react-native-reanimated"
15
10
import { SafeAreaView } from "react-native-safe-area-context"
16
11
17
- export const InfiniteDiscoveryOnboarding : React . FC < { } > = ( ) => {
12
+ interface InfiniteDiscoveryOnboardingProps {
13
+ artworks : InfiniteDiscoveryArtwork [ ]
14
+ }
15
+
16
+ const ONBOARDING_SWIPE_ANIMATION_DURATION = 1500
17
+ const ONBOARDING_ANIMATION_DELAY = 500
18
+ const ONBOARDING_SAVED_HINT_DURATION = 1500
19
+
20
+ export const InfiniteDiscoveryOnboarding : React . FC < InfiniteDiscoveryOnboardingProps > = ( {
21
+ artworks,
22
+ } ) => {
23
+ const space = useSpace ( )
24
+ const [ showSavedHint , setShowSavedHint ] = useState ( false )
25
+
26
+ const swiperRef = useRef < SwiperRefProps > ( null )
27
+
28
+ const cards = useMemo ( ( ) => {
29
+ return artworks . map ( ( artwork , i ) => (
30
+ < InfiniteDiscoveryArtworkCard
31
+ artwork = { artwork }
32
+ key = { artwork . internalID }
33
+ containerStyle = { {
34
+ paddingVertical : space ( 1 ) ,
35
+ borderRadius : 10 ,
36
+ shadowRadius : 3 ,
37
+ shadowColor : "black" ,
38
+ shadowOpacity : 0.2 ,
39
+ shadowOffset : { height : 0 , width : 0 } ,
40
+ } }
41
+ // Only show the saved hint for the upper card - since the cards are reverted in the swiper,
42
+ // the upper card index is the last in the array
43
+ isSaved = { i === artworks . length - 1 ? showSavedHint : false }
44
+ />
45
+ ) )
46
+ } , [ artworks , showSavedHint ] )
47
+
18
48
const [ isVisible , setIsVisible ] = useState ( false )
49
+ const isRewindRequested = useSharedValue ( false )
19
50
20
51
const hasInteractedWithOnboarding = GlobalStore . useAppState (
21
52
( state ) => state . infiniteDiscovery . hasInteractedWithOnboarding
22
53
)
23
54
24
- console . log ( { hasInteractedWithOnboarding } )
25
55
useEffect ( ( ) => {
26
56
setTimeout ( ( ) => {
27
57
if ( ! hasInteractedWithOnboarding ) {
28
58
setIsVisible ( true )
29
59
}
30
- } , 2000 )
60
+ } , 1000 )
31
61
} , [ hasInteractedWithOnboarding ] )
32
62
33
- const space = useSpace ( )
34
- const { width } = useScreenDimensions ( )
35
- const flatlistRef = useRef < FlatList > ( null )
36
- const [ index , setIndex ] = useState ( 0 )
37
-
38
- const handleNext = ( ) => {
39
- const newIndex = index + 1
40
-
41
- if ( newIndex < STEPS . length ) {
42
- setIndex ( newIndex )
43
- flatlistRef . current ?. scrollToIndex ( { animated : true , index : newIndex } )
44
- } else {
45
- setIsVisible ( false )
46
- }
63
+ const showOnboardingAnimation = ( ) => {
64
+ setShowSavedHint ( true )
65
+
66
+ setTimeout ( ( ) => {
67
+ swiperRef . current ?. swipeLeftThenRight ( ONBOARDING_SWIPE_ANIMATION_DURATION )
68
+ } , ONBOARDING_ANIMATION_DELAY + ONBOARDING_SAVED_HINT_DURATION )
69
+
70
+ setTimeout (
71
+ ( ) => {
72
+ setShowSavedHint ( false )
73
+ } ,
74
+ ONBOARDING_SWIPE_ANIMATION_DURATION +
75
+ ONBOARDING_SAVED_HINT_DURATION +
76
+ ONBOARDING_ANIMATION_DELAY
77
+ )
47
78
}
48
79
80
+ useEffect ( ( ) => {
81
+ if ( ! isVisible ) {
82
+ return
83
+ }
84
+
85
+ // Wait for a second before showing the animation
86
+ setTimeout ( ( ) => {
87
+ showOnboardingAnimation ( )
88
+ // Show the animation every 5 seconds afterwards
89
+ setInterval ( ( ) => {
90
+ showOnboardingAnimation ( )
91
+ } , 5000 )
92
+ } , 1000 )
93
+ } , [ setShowSavedHint , isVisible ] )
94
+
49
95
return (
50
96
< Modal animationType = "fade" visible = { isVisible } transparent >
51
97
< Flex flex = { 1 } backgroundColor = "transparent" >
@@ -63,39 +109,47 @@ export const InfiniteDiscoveryOnboarding: React.FC<{}> = () => {
63
109
< SafeAreaView
64
110
style = { { flex : 1 , justifyContent : "flex-end" , backgroundColor : "transparent" } }
65
111
>
66
- < Flex
67
- flex = { 1 }
68
- width = "100%"
69
- backgroundColor = "black15"
70
- alignSelf = "center"
71
- justifyContent = "center"
72
- alignItems = "center"
73
- opacity = { 0.7 }
74
- > </ Flex >
75
- < Flex justifyContent = "flex-end" px = { 2 } >
76
- < FlatList
77
- ref = { flatlistRef }
78
- data = { STEPS }
79
- scrollEnabled = { false }
80
- style = { { marginHorizontal : - space ( 2 ) , flexGrow : 0 } }
81
- renderItem = { ( { item } ) => (
82
- < Flex width = { width } px = { 2 } justifyContent = "flex-end" >
83
- { item . title }
84
- { item . description }
85
- </ Flex >
86
- ) }
87
- keyExtractor = { ( item ) => item . key }
88
- horizontal
89
- showsHorizontalScrollIndicator = { false }
90
- pagingEnabled
112
+ < Flex flex = { 1 } pointerEvents = "none" >
113
+ < Swiper
114
+ containerStyle = { { flex : 1 , transform : [ { scale : 0.8 } ] } }
115
+ cards = { cards }
116
+ isRewindRequested = { isRewindRequested }
117
+ onTrigger = { ( ) => { } }
118
+ swipedIndexCallsOnTrigger = { 2 }
119
+ onNewCardReached = { ( ) => { } }
120
+ onRewind = { ( ) => { } }
121
+ onSwipe = { ( ) => { } }
122
+ ref = { swiperRef }
91
123
/>
124
+ </ Flex >
125
+
126
+ < Flex justifyContent = "flex-end" px = { 2 } >
127
+ < Text > Welcome to Discovery Daily</ Text >
128
+
129
+ < Spacer y = { 1 } />
130
+
131
+ < Text variant = "lg-display" >
132
+ Start{ " " }
133
+ < Text variant = "lg-display" fontWeight = "500" >
134
+ swiping
135
+ </ Text > { " " }
136
+ to discover art, and{ " " }
137
+ < Text variant = "lg-display" fontWeight = "500" >
138
+ save
139
+ </ Text > { " " }
140
+ the works you love.
141
+ </ Text >
92
142
93
143
< Spacer y = { 2 } />
94
144
95
145
< Flex alignItems = "flex-end" >
96
- < Button variant = "outline" onPress = { handleNext } >
97
- { index === STEPS . length - 1 ? "Done" : "Next" }
98
- </ Button >
146
+ < LinkText
147
+ onPress = { ( ) => {
148
+ setIsVisible ( false )
149
+ } }
150
+ >
151
+ Tap to get started
152
+ </ LinkText >
99
153
</ Flex >
100
154
</ Flex >
101
155
</ SafeAreaView >
@@ -104,27 +158,3 @@ export const InfiniteDiscoveryOnboarding: React.FC<{}> = () => {
104
158
</ Modal >
105
159
)
106
160
}
107
-
108
- const STEPS = [
109
- {
110
- key : "introduction" ,
111
- title : (
112
- < Text variant = "sm-display" color = "black60" mb = { 0.5 } >
113
- Welcome to Discover Daily
114
- </ Text >
115
- ) ,
116
- description : < Text variant = "lg-display" > A new way of browsing works on Artsy.</ Text > ,
117
- } ,
118
- {
119
- key : "swipeArtworks" ,
120
- description : < Text variant = "lg-display" > Swipe artworks to the left to see the next work</ Text > ,
121
- } ,
122
- {
123
- key : "favouriteArtworks" ,
124
- description : (
125
- < Text variant = "lg-display" >
126
- Press < HeartIcon height = { 24 } width = { 24 } /> when you like an artwork you see
127
- </ Text >
128
- ) ,
129
- } ,
130
- ]
0 commit comments