From e596749ca0c7ff5ea99b85aa637a915ce11e1e1d Mon Sep 17 00:00:00 2001 From: Fernanda Toledo Date: Fri, 4 Sep 2026 17:17:51 -0300 Subject: [PATCH 1/2] refactor(router): move screen options from layouts into screen files --- src/app/(app)/_layout.tsx | 48 ++----------------------------------- src/app/(app)/index.tsx | 28 +++++++++++++++++++++- src/app/(app)/settings.tsx | 11 +++++++-- src/app/(app)/style.tsx | 9 +++++++ src/app/_layout.tsx | 23 ++++-------------- src/app/onboarding.tsx | 3 ++- src/app/sign-in.tsx | 2 ++ src/app/update-password.tsx | 3 ++- src/app/www.tsx | 17 ++++++------- 9 files changed, 64 insertions(+), 80 deletions(-) diff --git a/src/app/(app)/_layout.tsx b/src/app/(app)/_layout.tsx index 66e3b8b7d..f16f4b856 100644 --- a/src/app/(app)/_layout.tsx +++ b/src/app/(app)/_layout.tsx @@ -1,13 +1,7 @@ -import { Link, Redirect, SplashScreen, Tabs } from 'expo-router'; +import { Redirect, SplashScreen, Tabs } from 'expo-router'; import { useCallback, useEffect } from 'react'; import { useAuth } from '@/components/providers/auth'; -import { Pressable, Text } from '@/components/ui'; -import { - Feed as FeedIcon, - Settings as SettingsIcon, - Style as StyleIcon, -} from '@/components/ui/icons'; import { useIsFirstTime } from '@/lib'; export default function TabLayout() { @@ -29,43 +23,5 @@ export default function TabLayout() { if (!isAuthenticated && ready) { return ; } - return ( - - , - headerRight: () => , - tabBarButtonTestID: 'feed-tab', - }} - /> - , - tabBarButtonTestID: 'style-tab', - }} - /> - , - tabBarButtonTestID: 'settings-tab', - }} - /> - - ); -} - -function CreateNewPostLink() { - return ( - - - Create - - - ); + return ; } diff --git a/src/app/(app)/index.tsx b/src/app/(app)/index.tsx index b5ca90b4c..917e3f3ac 100644 --- a/src/app/(app)/index.tsx +++ b/src/app/(app)/index.tsx @@ -1,9 +1,35 @@ -import { FocusAwareStatusBar, View } from '@/components/ui'; +import { Link, Tabs } from 'expo-router'; + +import { + FocusAwareStatusBar, + Pressable, + Text, + View, +} from '@/components/ui'; +import { Feed as FeedIcon } from '@/components/ui/icons'; export default function Feed() { return ( + , + headerRight: () => , + tabBarButtonTestID: 'feed-tab', + }} + /> ); } + +function CreateNewPostLink() { + return ( + + + Create + + + ); +} diff --git a/src/app/(app)/settings.tsx b/src/app/(app)/settings.tsx index 2ad5ed049..a43183d47 100644 --- a/src/app/(app)/settings.tsx +++ b/src/app/(app)/settings.tsx @@ -1,5 +1,5 @@ /* eslint-disable max-lines-per-function */ -import { Link } from 'expo-router'; +import { Link, Tabs } from 'expo-router'; import { useColorScheme } from 'nativewind'; import * as React from 'react'; import { showMessage } from 'react-native-flash-message'; @@ -18,7 +18,7 @@ import { Text, View, } from '@/components/ui'; -import { Website } from '@/components/ui/icons'; +import { Settings as SettingsIcon, Website } from '@/components/ui/icons'; import { translate } from '@/lib'; import { Env } from '@/lib/env'; @@ -44,6 +44,13 @@ export default function Settings() { return ( <> + , + tabBarButtonTestID: 'settings-tab', + }} + /> diff --git a/src/app/(app)/style.tsx b/src/app/(app)/style.tsx index 2731161e6..23bab5ead 100644 --- a/src/app/(app)/style.tsx +++ b/src/app/(app)/style.tsx @@ -1,3 +1,4 @@ +import { Tabs } from 'expo-router'; import * as React from 'react'; import { Buttons } from '@/components/buttons'; @@ -5,10 +6,18 @@ import { Colors } from '@/components/colors'; import { Inputs } from '@/components/inputs'; import { Typography } from '@/components/typography'; import { FocusAwareStatusBar, SafeAreaView, ScrollView } from '@/components/ui'; +import { Style as StyleIcon } from '@/components/ui/icons'; export default function Style() { return ( <> + , + tabBarButtonTestID: 'style-tab', + }} + /> diff --git a/src/app/_layout.tsx b/src/app/_layout.tsx index a105f26b8..5cf425777 100644 --- a/src/app/_layout.tsx +++ b/src/app/_layout.tsx @@ -4,7 +4,6 @@ import { ThemeProvider } from '@react-navigation/native'; import { Stack } from 'expo-router'; import * as SplashScreen from 'expo-splash-screen'; import * as React from 'react'; -import { useTranslation } from 'react-i18next'; import { StyleSheet } from 'react-native'; import FlashMessage from 'react-native-flash-message'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; @@ -37,38 +36,24 @@ SplashScreen.setOptions({ function GuardedStack() { const { isAuthenticated } = useAuth(); - const { t } = useTranslation(); const [isFirstTime] = useIsFirstTime(); return ( - + - - + + - + - - ); } diff --git a/src/app/onboarding.tsx b/src/app/onboarding.tsx index 308b7088d..db22264e0 100644 --- a/src/app/onboarding.tsx +++ b/src/app/onboarding.tsx @@ -1,4 +1,4 @@ -import { useRouter } from 'expo-router'; +import { Stack, useRouter } from 'expo-router'; import { Cover } from '@/components/cover'; import { @@ -17,6 +17,7 @@ export default function Onboarding() { return ( + diff --git a/src/app/sign-in.tsx b/src/app/sign-in.tsx index a12412c8f..69f50a712 100644 --- a/src/app/sign-in.tsx +++ b/src/app/sign-in.tsx @@ -1,4 +1,5 @@ import type { LoginFormProps } from '@/components/login-form'; +import { Stack } from 'expo-router'; import * as React from 'react'; import { showMessage } from 'react-native-flash-message'; @@ -16,6 +17,7 @@ export default function Login() { }; return ( <> + diff --git a/src/app/update-password.tsx b/src/app/update-password.tsx index 923f0740b..b8f9121af 100644 --- a/src/app/update-password.tsx +++ b/src/app/update-password.tsx @@ -1,5 +1,5 @@ import { zodResolver } from '@hookform/resolvers/zod'; -import { useNavigation } from 'expo-router'; +import { Stack, useNavigation } from 'expo-router'; import * as React from 'react'; import { useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; @@ -64,6 +64,7 @@ export default function UpdatePassword() { return ( <> + diff --git a/src/app/www.tsx b/src/app/www.tsx index 6c24b3268..b871c70a2 100644 --- a/src/app/www.tsx +++ b/src/app/www.tsx @@ -1,6 +1,5 @@ -import { useLocalSearchParams, useNavigation, useRouter } from 'expo-router'; +import { Stack, useLocalSearchParams, useRouter } from 'expo-router'; import * as React from 'react'; -import { useEffect } from 'react'; import { View } from 'react-native'; import { WebView } from 'react-native-webview'; @@ -10,19 +9,16 @@ import { translate } from '@/lib'; export default function WWW() { const router = useRouter(); const { url, title } = useLocalSearchParams(); - const navigation = useNavigation(); - useEffect(() => { - if (title !== undefined) { - navigation.setOptions({ - title, - }); - } - }, [navigation, title]); + const screenOptions = { + presentation: 'modal', + title: typeof title === 'string' ? title : '', + } as const; if (url === undefined || typeof url !== 'string') { return ( + {translate('www.invalidUrl')} @@ -32,6 +28,7 @@ export default function WWW() { return ( + Date: Thu, 15 Oct 2026 13:30:37 -0300 Subject: [PATCH 2/2] fix(router): address review feedback on screen options refactor Translate tab titles and the Create link, keep the (app) header hidden, and render a single Stack.Screen in www. --- src/app/(app)/_layout.tsx | 9 +++++++-- src/app/(app)/index.tsx | 9 +++++++-- src/app/(app)/settings.tsx | 2 +- src/app/(app)/style.tsx | 5 ++++- src/app/www.tsx | 37 +++++++++++++++++++------------------ src/translations/en.json | 5 +++++ 6 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/app/(app)/_layout.tsx b/src/app/(app)/_layout.tsx index f16f4b856..1c5e6a3d2 100644 --- a/src/app/(app)/_layout.tsx +++ b/src/app/(app)/_layout.tsx @@ -1,4 +1,4 @@ -import { Redirect, SplashScreen, Tabs } from 'expo-router'; +import { Redirect, SplashScreen, Stack, Tabs } from 'expo-router'; import { useCallback, useEffect } from 'react'; import { useAuth } from '@/components/providers/auth'; @@ -23,5 +23,10 @@ export default function TabLayout() { if (!isAuthenticated && ready) { return ; } - return ; + return ( + <> + + + + ); } diff --git a/src/app/(app)/index.tsx b/src/app/(app)/index.tsx index 917e3f3ac..9550ca1b3 100644 --- a/src/app/(app)/index.tsx +++ b/src/app/(app)/index.tsx @@ -1,4 +1,5 @@ import { Link, Tabs } from 'expo-router'; +import { useTranslation } from 'react-i18next'; import { FocusAwareStatusBar, @@ -9,11 +10,13 @@ import { import { Feed as FeedIcon } from '@/components/ui/icons'; export default function Feed() { + const { t } = useTranslation(); + return ( , headerRight: () => , tabBarButtonTestID: 'feed-tab', @@ -25,10 +28,12 @@ export default function Feed() { } function CreateNewPostLink() { + const { t } = useTranslation(); + return ( - Create + {t('tabs.create')} ); diff --git a/src/app/(app)/settings.tsx b/src/app/(app)/settings.tsx index a43183d47..3207fe1fb 100644 --- a/src/app/(app)/settings.tsx +++ b/src/app/(app)/settings.tsx @@ -46,7 +46,7 @@ export default function Settings() { <> , tabBarButtonTestID: 'settings-tab', }} diff --git a/src/app/(app)/style.tsx b/src/app/(app)/style.tsx index 23bab5ead..128d1a3bb 100644 --- a/src/app/(app)/style.tsx +++ b/src/app/(app)/style.tsx @@ -1,5 +1,6 @@ import { Tabs } from 'expo-router'; import * as React from 'react'; +import { useTranslation } from 'react-i18next'; import { Buttons } from '@/components/buttons'; import { Colors } from '@/components/colors'; @@ -9,11 +10,13 @@ import { FocusAwareStatusBar, SafeAreaView, ScrollView } from '@/components/ui'; import { Style as StyleIcon } from '@/components/ui/icons'; export default function Style() { + const { t } = useTranslation(); + return ( <> , tabBarButtonTestID: 'style-tab', }} diff --git a/src/app/www.tsx b/src/app/www.tsx index b871c70a2..8e38d49e9 100644 --- a/src/app/www.tsx +++ b/src/app/www.tsx @@ -15,25 +15,26 @@ export default function WWW() { title: typeof title === 'string' ? title : '', } as const; - if (url === undefined || typeof url !== 'string') { - return ( - - - - {translate('www.invalidUrl')} - - - ); - } - return ( - + <> - router.back()} - /> - + {typeof url === 'string' + ? ( + + router.back()} + /> + + ) + : ( + + + {translate('www.invalidUrl')} + + + )} + ); } diff --git a/src/translations/en.json b/src/translations/en.json index 58d57b6eb..d4df1f96f 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -103,6 +103,11 @@ "version": "Version", "website": "Website" }, + "tabs": { + "create": "Create", + "feed": "Feed", + "style": "Style" + }, "updatePassword": { "buttonLabel": "Update Password", "confirmPasswordLabel": "Confirm Password",