Skip to content

Commit 46c0223

Browse files
authored
style(layout): setup splash screen and cleanup auth ui (#128)
* style(layout): setup splash screen and cleanup auth ui * apply review changes * add review changes * prettier fix * apply changes
1 parent 3003375 commit 46c0223

23 files changed

+320
-217
lines changed

mobile/app.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@
2222
},
2323
"edgeToEdgeEnabled": true,
2424
"predictiveBackGestureEnabled": false,
25-
"package": "com.eni.koinoniadaily"
25+
"package": "org.koinoniadaily.mobile"
2626
},
2727
"plugins": [
2828
"expo-router",
2929
[
3030
"expo-splash-screen",
3131
{
32-
"image": "./assets/images/splash-icon.png",
32+
"image": "./assets/images/icon.png",
3333
"imageWidth": 200,
3434
"resizeMode": "contain",
3535
"backgroundColor": "#ffffff",
@@ -39,7 +39,8 @@
3939
}
4040
],
4141
"expo-secure-store",
42-
"@sentry/react-native"
42+
"@sentry/react-native",
43+
"expo-font"
4344
],
4445
"experiments": {
4546
"typedRoutes": true,

mobile/app/(auth)/_layout.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
import { useScreenOptions } from '@/hooks/use-screen-options';
12
import { Stack, useRouter } from 'expo-router';
23
import { useEffect } from 'react';
34
import { useAuth } from '../../features/auth/auth-context';
4-
import { screenOptions } from '../_layout';
55

66
const GuestLayout = () => {
77
const { isAuthenticated } = useAuth();
8+
const { screenOptions } = useScreenOptions();
89
const router = useRouter();
910

1011
useEffect(() => {

mobile/app/+not-found.tsx

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,30 @@
1-
import { ThemedText } from '@/components/themed-text';
2-
import { ThemedView } from '@/components/themed-view';
1+
import { Text } from '@/components/reusables/ui/text';
2+
import { Link, Stack } from 'expo-router';
3+
import { StyleSheet, View } from 'react-native';
34

4-
const NotFoundScreen = () => {
5+
export default function NotFoundScreen() {
56
return (
6-
<ThemedView className="flex-1 justify-center align-center">
7-
<ThemedText type="title">Page Not Found</ThemedText>
8-
</ThemedView>
7+
<>
8+
<Stack.Screen options={{ title: 'Oops!' }} />
9+
<View style={styles.container}>
10+
<Text variant="h3">This screen does not exist.</Text>
11+
<Link href="/(tabs)/home" style={styles.link}>
12+
<Text variant="default">Go to home screen!</Text>
13+
</Link>
14+
</View>
15+
</>
916
);
10-
};
11-
export default NotFoundScreen;
17+
}
18+
19+
const styles = StyleSheet.create({
20+
container: {
21+
flex: 1,
22+
alignItems: 'center',
23+
justifyContent: 'center',
24+
padding: 20,
25+
},
26+
link: {
27+
marginTop: 15,
28+
paddingVertical: 15,
29+
},
30+
});

mobile/app/_layout.tsx

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,72 @@
11
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
2-
import { Stack } from 'expo-router';
3-
import { StatusBar } from 'expo-status-bar';
42
import { PortalHost } from '@rn-primitives/portal';
3+
import * as Sentry from '@sentry/react-native';
4+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
5+
import { SplashScreen, Stack } from 'expo-router';
6+
import { StatusBar } from 'expo-status-bar';
57
import 'react-native-reanimated';
68
import '../global.css';
7-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
89

9-
import { useColorScheme } from '@/hooks/use-color-scheme';
10-
import { StyleSheet } from 'react-native';
1110
import { AuthProvider } from '@/features/auth/auth-context';
11+
import { useAppTheme } from '@/hooks/use-app-theme';
12+
import { useSplashScreenReady } from '@/hooks/use-splash-screen-ready';
13+
import { useEffect, useRef } from 'react';
14+
import { Animated, View } from 'react-native';
15+
16+
void SplashScreen.preventAutoHideAsync().catch((err) => {
17+
Sentry.captureException(err);
18+
});
1219

1320
const queryClient = new QueryClient();
1421

22+
function AppLayout() {
23+
const { isAppReady, setLayoutReady } = useSplashScreenReady();
24+
25+
const opacity = useRef(new Animated.Value(0));
26+
27+
useEffect(() => {
28+
if (isAppReady) {
29+
Animated.timing(opacity.current, {
30+
toValue: 1,
31+
duration: 350,
32+
useNativeDriver: true,
33+
}).start();
34+
}
35+
}, [isAppReady]);
36+
37+
return (
38+
<View className="flex-1" onLayout={() => setLayoutReady(true)} accessibilityLabel="app-root-view">
39+
{isAppReady && (
40+
<Animated.View style={{ flex: 1, opacity: opacity.current }}>
41+
<Navigation />
42+
<StatusBar style="auto" />
43+
<PortalHost />
44+
</Animated.View>
45+
)}
46+
</View>
47+
);
48+
}
49+
50+
function Navigation() {
51+
return (
52+
<Stack>
53+
<Stack.Screen name="(auth)" options={{ headerShown: false }} />
54+
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
55+
<Stack.Screen name="+not-found" />
56+
</Stack>
57+
);
58+
}
59+
1560
export default function RootLayout() {
16-
const colorScheme = useColorScheme();
61+
const { theme } = useAppTheme();
1762

1863
return (
1964
<QueryClientProvider client={queryClient}>
2065
<AuthProvider>
21-
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
22-
<Stack>
23-
<Stack.Screen name="(auth)" options={{ headerShown: false }} />
24-
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
25-
<Stack.Screen name="+not-found" />
26-
</Stack>
27-
<StatusBar style="auto" />
28-
<PortalHost />
66+
<ThemeProvider value={theme === 'dark' ? DarkTheme : DefaultTheme}>
67+
<AppLayout />
2968
</ThemeProvider>
3069
</AuthProvider>
3170
</QueryClientProvider>
3271
);
3372
}
34-
35-
const styles = StyleSheet.create({
36-
header: {
37-
backgroundColor: '#000',
38-
},
39-
});
40-
41-
export const screenOptions = {
42-
headerStyle: styles.header,
43-
headerTintColor: '#fff',
44-
headerTitleStyle: { fontSize: 20, fontWeight: 'bold' as 'bold' },
45-
headerTitleAlign: 'center' as 'center',
46-
};
91.1 KB
Binary file not shown.

mobile/components/reusables/social-connections.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export function SocialConnections({ handleSocialSignIn }: { handleSocialSignIn:
2222
<Button
2323
key={strategy.type}
2424
variant="outline"
25-
size="sm"
2625
className="sm:flex-1"
2726
accessibilityLabel={strategy.label}
2827
onPress={() => handleSocialSignIn(strategy.type)}

mobile/components/reusables/ui/button.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const buttonVariants = cva(
4141
link: '',
4242
},
4343
size: {
44-
default: cn('h-10 px-4 py-2 sm:h-9', Platform.select({ web: 'has-[>svg]:px-3' })),
44+
default: cn('h-12 px-4 py-2 sm:h-9', Platform.select({ web: 'has-[>svg]:px-3' })),
4545
sm: cn('h-9 gap-1.5 rounded-md px-3 sm:h-8', Platform.select({ web: 'has-[>svg]:px-2.5' })),
4646
lg: cn('h-11 rounded-md px-6 sm:h-10', Platform.select({ web: 'has-[>svg]:px-4' })),
4747
icon: 'h-10 w-10 sm:h-9 sm:w-9',
@@ -104,4 +104,3 @@ function Button({ className, variant, size, ...props }: ButtonProps) {
104104

105105
export { Button, buttonTextVariants, buttonVariants };
106106
export type { ButtonProps };
107-

mobile/components/reusables/ui/input.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,10 @@ function Input({ className, ...props }: TextInputProps & React.RefAttributes<Tex
55
return (
66
<TextInput
77
className={cn(
8-
'dark:bg-input/30 border-input bg-background text-foreground flex h-10 w-full min-w-0 flex-row items-center rounded-md border px-3 py-1 text-base leading-5 shadow-sm shadow-black/5 sm:h-9',
8+
'dark:bg-input/30 border-input bg-background text-foreground flex h-12 w-full min-w-0 flex-row items-center rounded-md border px-3 py-1 text-lg leading-5 shadow-sm shadow-black/5 sm:h-9',
99
props.editable === false &&
1010
cn('opacity-50', Platform.select({ web: 'disabled:pointer-events-none disabled:cursor-not-allowed' })),
1111
Platform.select({
12-
web: cn(
13-
'placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground outline-none transition-[color,box-shadow] md:text-sm',
14-
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
15-
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive'
16-
),
1712
native: 'placeholder:text-muted-foreground/50',
1813
}),
1914
className

mobile/components/reusables/ui/label.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,15 @@ function Label({
1313
}: LabelPrimitive.TextProps & React.RefAttributes<LabelPrimitive.TextRef>) {
1414
return (
1515
<LabelPrimitive.Root
16-
className={cn(
17-
'flex select-none flex-row items-center gap-2',
18-
Platform.select({
19-
web: 'cursor-default leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-50 group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50',
20-
}),
21-
disabled && 'opacity-50'
22-
)}
16+
className={cn('flex select-none flex-row items-center gap-2', disabled && 'opacity-50')}
2317
onPress={onPress}
2418
onLongPress={onLongPress}
2519
onPressIn={onPressIn}
2620
onPressOut={onPressOut}
2721
disabled={disabled}
2822
>
2923
<LabelPrimitive.Text
30-
className={cn('text-foreground text-sm font-medium', Platform.select({ web: 'leading-none' }), className)}
24+
className={cn('text-foreground text-base font-medium', Platform.select({ web: 'leading-none' }), className)}
3125
{...props}
3226
/>
3327
</LabelPrimitive.Root>

mobile/components/reusables/ui/text.tsx

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,27 @@ import { cva, type VariantProps } from 'class-variance-authority';
44
import * as React from 'react';
55
import { Platform, Text as RNText, type Role } from 'react-native';
66

7-
const textVariants = cva(
8-
cn(
9-
'text-foreground text-base',
10-
Platform.select({
11-
web: 'select-text',
12-
})
13-
),
14-
{
15-
variants: {
16-
variant: {
17-
default: '',
18-
h1: cn(
19-
'text-center text-4xl font-extrabold tracking-tight',
20-
Platform.select({ web: 'scroll-m-20 text-balance' })
21-
),
22-
h2: cn(
23-
'border-border border-b pb-2 text-3xl font-semibold tracking-tight',
24-
Platform.select({ web: 'scroll-m-20 first:mt-0' })
25-
),
26-
h3: cn('text-2xl font-semibold tracking-tight', Platform.select({ web: 'scroll-m-20' })),
27-
h4: cn('text-xl font-semibold tracking-tight', Platform.select({ web: 'scroll-m-20' })),
28-
p: 'mt-3 leading-7 sm:mt-6',
29-
blockquote: 'mt-4 border-l-2 pl-3 italic sm:mt-6 sm:pl-6',
30-
code: cn('bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold'),
31-
lead: 'text-muted-foreground text-xl',
32-
large: 'text-lg font-semibold',
33-
small: 'text-sm font-medium leading-none',
34-
muted: 'text-muted-foreground text-sm',
35-
},
7+
const textVariants = cva(cn('text-foreground text-base'), {
8+
variants: {
9+
variant: {
10+
default: '',
11+
h1: cn('text-center text-4xl font-extrabold tracking-tight'),
12+
h2: cn('border-border border-b pb-2 text-3xl font-semibold tracking-tight'),
13+
h3: cn('text-2xl font-semibold tracking-tight'),
14+
h4: cn('text-xl font-semibold tracking-tight'),
15+
p: 'mt-3 leading-7 sm:mt-6',
16+
blockquote: 'mt-4 border-l-2 pl-3 italic sm:mt-6 sm:pl-6',
17+
code: cn('bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold'),
18+
lead: 'text-muted-foreground text-xl',
19+
large: 'text-lg font-semibold',
20+
small: 'text-sm font-medium leading-none',
21+
muted: 'text-muted-foreground text-sm',
3622
},
37-
defaultVariants: {
38-
variant: 'default',
39-
},
40-
}
41-
);
23+
},
24+
defaultVariants: {
25+
variant: 'default',
26+
},
27+
});
4228

4329
type TextVariantProps = VariantProps<typeof textVariants>;
4430

0 commit comments

Comments
 (0)