Skip to content

Commit ea786f4

Browse files
authored
native app, updates, fixes (#1455)
* chore: use bun-overlay to support non-avx2 linux * chore: update flake * chore: refactor devShells in flake.nix for improved structure and macOS compatibility adjustments * feat: clean up home layout * chore: add maestro tests for iOS biometrics enrollment in TODO.md * feat: implement user session checks and redirect in drawer and tabs layout to ensure access control based on authentication * feat: add watchman to the development environment * chore: remove unused 'profile' tab from the drawer and tabs layout for a cleaner navigation experience * feat: set background color to black for improved aesthetics in splash screen and index component * fix: missing theme nextjs issue * fix: revert hard-coded black color, messes up web * fix: remove unnecessary edges in Container properties for improved layout management * fix: enhance navigation structure and layout consistency for Expo app, addressing core screens and authentication flow issues * fix: adjust IconSendLogo size in AuthLayout to improve layout appearance and maintain design consistency * fix: require cycles * fix: clean up whitespace in PLAN.md and add verification instructions for app functionality testing * feat(expo)!: wip layout navigation * fix(tilt): bundler needs more memory * fix(temporal): increase retry count and add randomness to backoff delay for transfer start handling * fix(tilt): improve environment variable check to handle None value correctly in require_env function * fix(temporal): enhance transfer handling with workflow initialization check and bundler receipt retrieval logic * fix(account): refactor imports for user operation constants in backup confirmation and index files * fix(temporal): refactor activity feed to track pending temporal events and invalidate queries when state changes * fix(playwright): improve token transfer history checks with retries and ensure UI updates reflect transaction status * fix(userOpConstants): streamline imports
1 parent 23675d4 commit ea786f4

34 files changed

+1351
-1189
lines changed

apps/expo/PLAN.md

Lines changed: 306 additions & 143 deletions
Large diffs are not rendered by default.

apps/expo/TODO.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@
1212
- do first dev build. https://docs.expo.dev/development/build/
1313
- finish `./PLAN.md`
1414
- review expo plugins
15+
- maestro tests:
16+
- iOS
17+
- enroll biometrics `xcrun simctl spawn 'iPhone X' notifyutil -s com.apple.BiometricKit.enrollmentChanged '1' && xcrun simctl spawn 'iPhone X' notifyutil -p com.apple.BiometricKit.enrollmentChanged` https://stackoverflow.com/questions/40117907/how-can-i-enroll-touch-id-in-simulator-from-the-command-line

apps/expo/app/(auth)/_layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default function AuthLayout() {
2929
position="absolute"
3030
top={headerHeight || top || '$4'}
3131
>
32-
<IconSendLogo size={'$4'} color={'$color12'} />
32+
<IconSendLogo size={'$8'} color={'$color12'} />
3333
</Anchor>
3434
<ScrollView
3535
pt="$2"

apps/expo/app/(drawer)/(tabs)/_layout.tsx

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,37 @@
1-
import { Button, useTheme } from '@my/ui'
1+
import { Button, useTheme, XStack } from '@my/ui'
22
import { DrawerActions } from '@react-navigation/native'
3-
import { Home, Menu, Plus, User } from '@tamagui/lucide-icons'
4-
import { router, Stack, Tabs, useNavigation, usePathname } from 'expo-router'
5-
import { useSafeAreaInsets } from 'react-native-safe-area-context'
3+
import { Activity, DollarSign, Home, Menu, Plus, User } from '@tamagui/lucide-icons'
4+
import { IconSendLogo } from 'app/components/icons'
5+
import { useUser } from 'app/utils/useUser'
6+
import { router, Stack, Tabs, useNavigation, Redirect } from 'expo-router'
7+
import { useSafeAreaInsets } from '@my/ui'
68

79
export default function Layout() {
810
const theme = useTheme()
911
const accentColor = theme.color10
1012
const navigation = useNavigation()
11-
const pathname = usePathname()
13+
const { session } = useUser()
1214
const insets = useSafeAreaInsets()
1315

14-
if (__DEV__) {
15-
console.log('pathname', pathname)
16+
// Redirect to root if not logged in - this ensures the tabs layout is only shown for logged-in users
17+
if (!session) {
18+
return <Redirect href="/" />
1619
}
20+
1721
return (
1822
<>
1923
<Stack.Screen
2024
options={{
21-
title: 'Home',
22-
headerShown: pathname === '/' || pathname === '/create',
25+
title: '/send',
26+
headerTitle: () => (
27+
<XStack ai="center" jc="center">
28+
<IconSendLogo size={'$2'} color={'$color12'} />
29+
</XStack>
30+
),
31+
headerShown: true,
32+
headerShadowVisible: false,
33+
headerTitleAlign: 'center',
34+
headerStyle: {},
2335
headerTintColor: accentColor.val,
2436
headerLeft: () => (
2537
<Button
@@ -53,13 +65,16 @@ export default function Layout() {
5365
<Tabs
5466
screenOptions={{
5567
tabBarShowLabel: false,
68+
headerShown: false, // Hide tab headers - use Stack.Screen header instead
5669
headerTintColor: accentColor.val,
5770
tabBarStyle: {
5871
paddingTop: 10,
59-
paddingBottom: insets.bottom + 20, // edit this with safe area insets
72+
paddingBottom: insets.bottom + 10, // reduce bottom padding
6073
height: 60,
6174
alignContent: 'center',
6275
justifyContent: 'center',
76+
borderTopWidth: 1,
77+
borderTopColor: '$borderColor',
6378
},
6479
tabBarItemStyle: {
6580
paddingBottom: 10,
@@ -77,18 +92,39 @@ export default function Layout() {
7792
),
7893
}}
7994
/>
95+
<Tabs.Screen
96+
name="activity"
97+
key="activity"
98+
options={{
99+
headerShown: false,
100+
title: 'Activity',
101+
tabBarIcon: ({ size, color, focused }) => (
102+
<Activity color={focused ? '$color12' : '$color10'} size={size} strokeWidth={2} />
103+
),
104+
}}
105+
/>
80106
<Tabs.Screen
81107
name="profile"
82108
key="profile"
83109
options={{
84110
headerShown: false,
85111
title: 'Profile',
86-
tabBarLabel: 'Profile',
87112
tabBarIcon: ({ size, color, focused }) => (
88113
<User color={focused ? '$color12' : '$color10'} size={size} strokeWidth={2} />
89114
),
90115
}}
91116
/>
117+
<Tabs.Screen
118+
name="earn"
119+
key="earn"
120+
options={{
121+
headerShown: false,
122+
title: 'Earn',
123+
tabBarIcon: ({ size, color, focused }) => (
124+
<DollarSign color={focused ? '$color12' : '$color10'} size={size} strokeWidth={2} />
125+
),
126+
}}
127+
/>
92128
</Tabs>
93129
</>
94130
)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Container, H4, Paragraph, Stack } from '@my/ui'
2+
import { Stack as StackRouter } from 'expo-router'
3+
4+
export default function ActivityTabScreen() {
5+
return (
6+
<>
7+
<StackRouter.Screen
8+
options={{
9+
title: 'Activity',
10+
headerShown: false, // We'll use the header from the tabs layout
11+
}}
12+
/>
13+
14+
<Container
15+
safeAreaProps={{
16+
edges: ['left', 'right'],
17+
style: { flex: 1 },
18+
}}
19+
flex={1}
20+
backgroundColor="$background"
21+
>
22+
<Stack f={1} ai="center" jc="center" p="$4">
23+
<H4 mb="$4">Activity Feed</H4>
24+
<Paragraph ta="center" color="$color10">
25+
This screen will display your transaction history and account activity.
26+
</Paragraph>
27+
</Stack>
28+
</Container>
29+
</>
30+
)
31+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { Button, Card, Container, H4, Paragraph, Stack, XStack, YStack } from '@my/ui'
2+
import { ArrowRight, DollarSign } from '@tamagui/lucide-icons'
3+
import { Stack as StackRouter, useRouter } from 'expo-router'
4+
5+
export default function EarnTabScreen() {
6+
const router = useRouter()
7+
8+
return (
9+
<>
10+
<StackRouter.Screen
11+
options={{
12+
title: 'Earn',
13+
headerShown: false, // We'll use the header from the tabs layout
14+
}}
15+
/>
16+
17+
<Container
18+
safeAreaProps={{
19+
edges: ['left', 'right'],
20+
style: { flex: 1 },
21+
}}
22+
flex={1}
23+
backgroundColor="$background"
24+
>
25+
<YStack f={1} p="$4" gap="$6">
26+
<H4 textAlign="center" mt="$4">
27+
Earn Rewards
28+
</H4>
29+
30+
<Card p="$4" my="$2">
31+
<YStack gap="$3">
32+
<XStack ai="center" gap="$3">
33+
<DollarSign size="$2" color="$color12" />
34+
<H4>Earn SEND</H4>
35+
</XStack>
36+
<Paragraph>Learn about ways to earn SEND rewards by using the app.</Paragraph>
37+
<Button
38+
alignSelf="flex-end"
39+
mt="$2"
40+
size="$3"
41+
icon={<ArrowRight size="$1" />}
42+
onPress={() => {
43+
// TODO: Navigate to earn details page
44+
}}
45+
>
46+
View Rewards
47+
</Button>
48+
</YStack>
49+
</Card>
50+
51+
<Card p="$4" my="$2">
52+
<YStack gap="$3">
53+
<Paragraph fontWeight="bold">Coming Soon</Paragraph>
54+
<Paragraph color="$color10">
55+
This screen will display all your earning opportunities and rewards history.
56+
</Paragraph>
57+
</YStack>
58+
</Card>
59+
</YStack>
60+
</Container>
61+
</>
62+
)
63+
}
Lines changed: 24 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,39 @@
1-
import { Paragraph, YStack } from '@my/ui'
2-
import { useQueryClient } from '@tanstack/react-query'
3-
import { AuthCarouselContext } from 'app/features/auth/AuthCarouselContext'
1+
import { Container, ScrollView, YStack } from '@my/ui'
42
import { HomeScreen } from 'app/features/home/screen'
5-
import { SplashScreen } from 'app/features/splash/screen'
6-
import type { GetPlaiceholderImage } from 'app/utils/getPlaiceholderImage'
7-
import { useSendAccount } from 'app/utils/send-accounts/useSendAccounts'
8-
import { useUser } from 'app/utils/useUser'
93
import { Stack } from 'expo-router'
10-
import { useCallback, useEffect, useState } from 'react'
11-
12-
// Hardcoded carousel images for mobile - using type assertion to avoid complexities with GetPlaiceholderImage type
13-
const mobileCarouselImages = [
14-
{
15-
img: {
16-
src: 'https://supabase.send.it/storage/v1/object/public/send-public/app_images/auth_image_3.jpg',
17-
height: 1080,
18-
width: 1920,
19-
},
20-
base64: '',
21-
color: [0, 0, 0],
22-
pixels: [],
23-
css: '',
24-
svg: '',
25-
},
26-
{
27-
img: {
28-
src: 'https://supabase.send.it/storage/v1/object/public/send-public/app_images/auth_image_2.jpg',
29-
height: 1080,
30-
width: 1920,
31-
},
32-
base64: '',
33-
color: [0, 0, 0],
34-
pixels: [],
35-
css: '',
36-
svg: '',
37-
},
38-
{
39-
img: {
40-
src: 'https://supabase.send.it/storage/v1/object/public/send-public/app_images/auth_image_1.jpg',
41-
height: 1080,
42-
width: 1920,
43-
},
44-
base64: '',
45-
color: [0, 0, 0],
46-
pixels: [],
47-
css: '',
48-
svg: '',
49-
},
50-
] as GetPlaiceholderImage[]
51-
52-
export default function Screen() {
53-
const { session } = useUser()
54-
const [carouselImages, setCarouselImages] = useState<GetPlaiceholderImage[]>([])
55-
const [carouselProgress, setCarouselProgress] = useState(0)
56-
const queryClient = useQueryClient()
57-
58-
const cancelAndRemoveAccountsQueries = useCallback(async () => {
59-
if (!session) {
60-
const options = { queryKey: [useSendAccount.queryKey] }
61-
await queryClient.cancelQueries(options)
62-
queryClient.removeQueries(options)
63-
}
64-
}, [session, queryClient])
65-
66-
useEffect(() => {
67-
if (carouselImages.length === 0) setCarouselImages(mobileCarouselImages)
68-
}, [carouselImages])
69-
70-
useEffect(() => {
71-
void cancelAndRemoveAccountsQueries()
72-
}, [cancelAndRemoveAccountsQueries])
734

5+
export default function HomeTabScreen() {
746
return (
757
<>
768
<Stack.Screen
779
options={{
78-
title: 'Home',
79-
headerShown: false,
10+
title: 'Send',
11+
headerShown: false, // We'll use the header from the tabs layout
8012
}}
8113
/>
8214

83-
{session ? (
84-
<YStack f={1}>
85-
<HomeScreen />
86-
</YStack>
87-
) : (
88-
<AuthCarouselContext.Provider
89-
value={{
90-
carouselImages,
91-
setCarouselImages,
92-
carouselProgress,
93-
setCarouselProgress,
15+
<Container
16+
safeAreaProps={{
17+
edges: ['left', 'right'],
18+
style: { flex: 1 },
19+
}}
20+
flex={1}
21+
backgroundColor="$background"
22+
>
23+
<ScrollView
24+
flex={1}
25+
contentContainerStyle={{
26+
flexGrow: 1,
27+
paddingTop: 10,
28+
paddingBottom: 20,
9429
}}
30+
showsVerticalScrollIndicator={false}
31+
bounces={true}
32+
overScrollMode="always" // Android scroll indicator
9533
>
96-
<YStack flex={1} jc="center" ai="center" f={1} height={'100%'} w={'100%'} bc="$red9Light">
97-
<Paragraph>hello too asdfa sdfasfasdsda</Paragraph>
98-
</YStack>
99-
{/* <SplashScreen /> */}
100-
</AuthCarouselContext.Provider>
101-
)}
34+
<HomeScreen />
35+
</ScrollView>
36+
</Container>
10237
</>
10338
)
10439
}

0 commit comments

Comments
 (0)