11// src/features/home/screens/HomeScreen.tsx
22
3- import { FlashList } from '@shopify/flash-list'
43import { useNavigation } from '@react-navigation/native'
54import type { NativeStackNavigationProp } from '@react-navigation/native-stack'
5+ import { FlashList } from '@shopify/flash-list'
66import React , { memo , useCallback , useEffect , useRef } from 'react'
77import { Animated , Platform , Pressable , ScrollView , View } from 'react-native'
88import { useFeedQuery } from '@/features/home/hooks/useFeedQuery'
@@ -26,8 +26,16 @@ function useShimmer() {
2626 useEffect ( ( ) => {
2727 const loop = Animated . loop (
2828 Animated . sequence ( [
29- Animated . timing ( anim , { toValue : 1 , duration : 750 , useNativeDriver : true } ) ,
30- Animated . timing ( anim , { toValue : 0.4 , duration : 750 , useNativeDriver : true } ) ,
29+ Animated . timing ( anim , {
30+ toValue : 1 ,
31+ duration : 750 ,
32+ useNativeDriver : true ,
33+ } ) ,
34+ Animated . timing ( anim , {
35+ toValue : 0.4 ,
36+ duration : 750 ,
37+ useNativeDriver : true ,
38+ } ) ,
3139 ] ) ,
3240 )
3341 loop . start ( )
@@ -56,9 +64,30 @@ function SkeletonCard({ shimmer }: { shimmer: Animated.Value }) {
5664 } }
5765 >
5866 < Animated . View style = { { opacity : shimmer , gap : sp . xs } } >
59- < View style = { { height : 15 , width : '85%' , borderRadius : r . sm , backgroundColor : c . surfaceSecondary } } />
60- < View style = { { height : 13 , width : '60%' , borderRadius : r . sm , backgroundColor : c . surfaceSecondary } } />
61- < View style = { { height : 11 , width : '45%' , borderRadius : r . sm , backgroundColor : c . surfaceSecondary } } />
67+ < View
68+ style = { {
69+ height : 15 ,
70+ width : '85%' ,
71+ borderRadius : r . sm ,
72+ backgroundColor : c . surfaceSecondary ,
73+ } }
74+ />
75+ < View
76+ style = { {
77+ height : 13 ,
78+ width : '60%' ,
79+ borderRadius : r . sm ,
80+ backgroundColor : c . surfaceSecondary ,
81+ } }
82+ />
83+ < View
84+ style = { {
85+ height : 11 ,
86+ width : '45%' ,
87+ borderRadius : r . sm ,
88+ backgroundColor : c . surfaceSecondary ,
89+ } }
90+ />
6291 </ Animated . View >
6392 </ View >
6493 )
@@ -74,7 +103,10 @@ function HomeScreenSkeleton() {
74103 return (
75104 < ScrollView
76105 scrollEnabled = { false }
77- contentContainerStyle = { { paddingBottom : TAB_BAR_CLEARANCE , backgroundColor : c . background } }
106+ contentContainerStyle = { {
107+ paddingBottom : TAB_BAR_CLEARANCE ,
108+ backgroundColor : c . background ,
109+ } }
78110 showsVerticalScrollIndicator = { false }
79111 >
80112 { /* Greeting */ }
@@ -87,8 +119,22 @@ function HomeScreenSkeleton() {
87119 gap : sp . xs ,
88120 } }
89121 >
90- < View style = { { height : 12 , width : 100 , borderRadius : r . sm , backgroundColor : c . surfaceSecondary } } />
91- < View style = { { height : 28 , width : 200 , borderRadius : r . md , backgroundColor : c . surfaceSecondary } } />
122+ < View
123+ style = { {
124+ height : 12 ,
125+ width : 100 ,
126+ borderRadius : r . sm ,
127+ backgroundColor : c . surfaceSecondary ,
128+ } }
129+ />
130+ < View
131+ style = { {
132+ height : 28 ,
133+ width : 200 ,
134+ borderRadius : r . md ,
135+ backgroundColor : c . surfaceSecondary ,
136+ } }
137+ />
92138 </ Animated . View >
93139
94140 { /* Section header */ }
@@ -129,10 +175,14 @@ function accentColor(
129175 c : ReturnType < typeof useTheme > [ 'theme' ] [ 'colors' ] ,
130176) : string {
131177 switch ( type ) {
132- case 'success' : return c . success
133- case 'primary' : return c . primary
134- case 'info' : return c . info
135- case 'warning' : return c . warning
178+ case 'success' :
179+ return c . success
180+ case 'primary' :
181+ return c . primary
182+ case 'info' :
183+ return c . info
184+ case 'warning' :
185+ return c . warning
136186 }
137187}
138188
@@ -154,9 +204,18 @@ function GreetingSection({
154204 } )
155205
156206 return (
157- < View style = { { paddingHorizontal : sp . lg , paddingTop : sp . lg , paddingBottom : sp . md , gap : sp . xxs } } >
207+ < View
208+ style = { {
209+ paddingHorizontal : sp . lg ,
210+ paddingTop : sp . lg ,
211+ paddingBottom : sp . md ,
212+ gap : sp . xxs ,
213+ } }
214+ >
158215 < Text style = { [ ty . bodySmall , { color : c . textTertiary } ] } > { today } </ Text >
159- < Text style = { [ ty . displaySmall , { color : c . textPrimary } ] } > { t ( greetingKey ) } </ Text >
216+ < Text style = { [ ty . displaySmall , { color : c . textPrimary } ] } >
217+ { t ( greetingKey ) }
218+ </ Text >
160219 </ View >
161220 )
162221}
@@ -192,7 +251,9 @@ function SectionHeader({
192251 style = { {
193252 flexDirection : 'row' ,
194253 alignItems : 'center' ,
195- backgroundColor : sublabelIsOffline ? c . warning + '22' : c . success + '22' ,
254+ backgroundColor : sublabelIsOffline
255+ ? c . warning + '22'
256+ : c . success + '22' ,
196257 borderRadius : r . pill ,
197258 paddingHorizontal : sp . xs ,
198259 paddingVertical : 2 ,
@@ -207,7 +268,12 @@ function SectionHeader({
207268 backgroundColor : sublabelIsOffline ? c . warning : c . success ,
208269 } }
209270 />
210- < Text style = { [ ty . labelSmall , { color : sublabelIsOffline ? c . warning : c . success } ] } >
271+ < Text
272+ style = { [
273+ ty . labelSmall ,
274+ { color : sublabelIsOffline ? c . warning : c . success } ,
275+ ] }
276+ >
211277 { sublabel }
212278 </ Text >
213279 </ View >
@@ -254,35 +320,61 @@ const StoryCard = memo(function StoryCard({ item }: { item: FeedItem }) {
254320 paddingHorizontal : sp . md ,
255321 paddingVertical : sp . md ,
256322 gap : sp . xs ,
257- ...Platform . select ( { ios : { ...theme . elevation . card } , android : { elevation : 1 } } ) ,
323+ ...Platform . select ( {
324+ ios : { ...theme . elevation . card } ,
325+ android : { elevation : 1 } ,
326+ } ) ,
258327 } ) }
259328 >
260329 < Text
261- style = { [ ty . titleSmall , { color : c . textPrimary , lineHeight : ty . titleSmall . fontSize * 1.35 } ] }
330+ style = { [
331+ ty . titleSmall ,
332+ { color : c . textPrimary , lineHeight : ty . titleSmall . fontSize * 1.35 } ,
333+ ] }
262334 numberOfLines = { 2 }
263335 >
264336 { item . title }
265337 </ Text >
266338
267339 < View style = { { flexDirection : 'row' , alignItems : 'center' , gap : sp . xs } } >
268- < View style = { { width : 6 , height : 6 , borderRadius : 3 , backgroundColor : accent } } />
269- < Text style = { [ ty . labelSmall , { color : c . textTertiary , flex : 1 } ] } numberOfLines = { 1 } >
340+ < View
341+ style = { {
342+ width : 6 ,
343+ height : 6 ,
344+ borderRadius : 3 ,
345+ backgroundColor : accent ,
346+ } }
347+ />
348+ < Text
349+ style = { [ ty . labelSmall , { color : c . textTertiary , flex : 1 } ] }
350+ numberOfLines = { 1 }
351+ >
270352 { item . subtitle }
271353 </ Text >
272354 { item . points != null && (
273355 < >
274- < Text style = { [ ty . labelSmall , { color : c . textTertiary } ] } > { '·' } </ Text >
275- < Text style = { [ ty . labelSmall , { color : c . textTertiary } ] } > { `▲ ${ item . points } ` } </ Text >
356+ < Text style = { [ ty . labelSmall , { color : c . textTertiary } ] } >
357+ { '·' }
358+ </ Text >
359+ < Text
360+ style = { [ ty . labelSmall , { color : c . textTertiary } ] }
361+ > { `▲ ${ item . points } ` } </ Text >
276362 </ >
277363 ) }
278364 { item . numComments != null && (
279365 < >
280- < Text style = { [ ty . labelSmall , { color : c . textTertiary } ] } > { '·' } </ Text >
281- < Text style = { [ ty . labelSmall , { color : c . textTertiary } ] } > { `${ item . numComments } comments` } </ Text >
366+ < Text style = { [ ty . labelSmall , { color : c . textTertiary } ] } >
367+ { '·' }
368+ </ Text >
369+ < Text
370+ style = { [ ty . labelSmall , { color : c . textTertiary } ] }
371+ > { `${ item . numComments } comments` } </ Text >
282372 </ >
283373 ) }
284374 < Text style = { [ ty . labelSmall , { color : c . textTertiary } ] } > { '·' } </ Text >
285- < Text style = { [ ty . labelSmall , { color : c . textTertiary } ] } > { item . time } </ Text >
375+ < Text style = { [ ty . labelSmall , { color : c . textTertiary } ] } >
376+ { item . time }
377+ </ Text >
286378 </ View >
287379 </ Pressable >
288380 )
@@ -295,13 +387,23 @@ export default function HomeScreen() {
295387 const c = theme . colors
296388 const greetingKey = useGreetingKey ( )
297389
298- const { feed, isLoading : feedLoading , isRefetching, refetch, hasCache, syncedAtLabel } =
299- useFeedQuery ( )
390+ const {
391+ feed,
392+ isLoading : feedLoading ,
393+ isRefetching,
394+ refetch,
395+ hasCache,
396+ syncedAtLabel,
397+ } = useFeedQuery ( )
300398 const { isOffline } = useOnlineStatus ( )
301399
302400 const sublabel = isOffline
303- ? syncedAtLabel ? `Offline · ${ syncedAtLabel } ` : 'Offline'
304- : syncedAtLabel ? `Synced ${ syncedAtLabel } ` : null
401+ ? syncedAtLabel
402+ ? `Offline · ${ syncedAtLabel } `
403+ : 'Offline'
404+ : syncedAtLabel
405+ ? `Synced ${ syncedAtLabel } `
406+ : null
305407
306408 const ListHeader = useCallback (
307409 ( ) => (
0 commit comments