diff --git a/src/Navigation.tsx b/src/Navigation.tsx index fa33a9d56..c48d078d4 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -1,8 +1,8 @@ -import {type JSX, useCallback, useRef} from 'react' -import {Linking} from 'react-native' +import { type JSX, useCallback, useRef } from 'react' +import { Linking } from 'react-native' import * as Notifications from 'expo-notifications' -import {i18n, type MessageDescriptor} from '@lingui/core' -import {msg} from '@lingui/macro' +import { i18n, type MessageDescriptor } from '@lingui/core' +import { msg } from '@lingui/macro' import { type BottomTabBarProps, createBottomTabNavigator, @@ -17,17 +17,17 @@ import { StackActions, } from '@react-navigation/native' -import {timeout} from '#/lib/async/timeout' -import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle' +import { timeout } from '#/lib/async/timeout' +import { useColorSchemeStyle } from '#/lib/hooks/useColorSchemeStyle' import { getNotificationPayload, type NotificationPayload, notificationToURL, storePayloadForAccountSwitch, } from '#/lib/hooks/useNotificationHandler' -import {useWebScrollRestoration} from '#/lib/hooks/useWebScrollRestoration' -import {logger as notyLogger} from '#/lib/notifications/util' -import {buildStateObject} from '#/lib/routes/helpers' +import { useWebScrollRestoration } from '#/lib/hooks/useWebScrollRestoration' +import { logger as notyLogger } from '#/lib/notifications/util' +import { buildStateObject } from '#/lib/routes/helpers' import { type AllNavigatorParams, type BottomTabNavigatorParams, @@ -38,106 +38,107 @@ import { type NotificationsTabNavigatorParams, type SearchTabNavigatorParams, } from '#/lib/routes/types' -import {type RouteParams, type State} from '#/lib/routes/types' -import {attachRouteToLogEvents, logEvent} from '#/lib/statsig/statsig' -import {bskyTitle} from '#/lib/strings/headings' -import {logger} from '#/logger' -import {isNative, isWeb} from '#/platform/detection' -import {useUnreadNotifications} from '#/state/queries/notifications/unread' -import {useSession} from '#/state/session' +import { type RouteParams, type State } from '#/lib/routes/types' +import { attachRouteToLogEvents, logEvent } from '#/lib/statsig/statsig' +import { bskyTitle } from '#/lib/strings/headings' +import { logger } from '#/logger' +import { isNative, isWeb } from '#/platform/detection' +import { useUnreadNotifications } from '#/state/queries/notifications/unread' +import { useSession } from '#/state/session' import { shouldRequestEmailConfirmation, snoozeEmailConfirmationPrompt, } from '#/state/shell/reminders' -import {CommunityGuidelinesScreen} from '#/view/screens/CommunityGuidelines' -import {CopyrightPolicyScreen} from '#/view/screens/CopyrightPolicy' -import {DebugModScreen} from '#/view/screens/DebugMod' -import {FeedsScreen} from '#/view/screens/Feeds' -import {HomeScreen} from '#/view/screens/Home' -import {ListsScreen} from '#/view/screens/Lists' -import {ModerationBlockedAccounts} from '#/view/screens/ModerationBlockedAccounts' -import {ModerationModlistsScreen} from '#/view/screens/ModerationModlists' -import {ModerationMutedAccounts} from '#/view/screens/ModerationMutedAccounts' -import {NotFoundScreen} from '#/view/screens/NotFound' -import {NotificationsScreen} from '#/view/screens/Notifications' -import {PostThreadScreen} from '#/view/screens/PostThread' -import {PrivacyPolicyScreen} from '#/view/screens/PrivacyPolicy' -import {ProfileScreen} from '#/view/screens/Profile' -import {ProfileFeedLikedByScreen} from '#/view/screens/ProfileFeedLikedBy' -import {Storybook} from '#/view/screens/Storybook' -import {SupportScreen} from '#/view/screens/Support' -import {TermsOfServiceScreen} from '#/view/screens/TermsOfService' -import {BottomBar} from '#/view/shell/bottom-bar/BottomBar' -import {createNativeStackNavigatorWithAuth} from '#/view/shell/createNativeStackNavigatorWithAuth' -import {BookmarksScreen} from '#/screens/Bookmarks' -import {SharedPreferencesTesterScreen} from '#/screens/E2E/SharedPreferencesTesterScreen' +import { LicenseScreen } from '#/view/screens/License' +import { CommunityGuidelinesScreen } from '#/view/screens/CommunityGuidelines' +import { CopyrightPolicyScreen } from '#/view/screens/CopyrightPolicy' +import { DebugModScreen } from '#/view/screens/DebugMod' +import { FeedsScreen } from '#/view/screens/Feeds' +import { HomeScreen } from '#/view/screens/Home' +import { ListsScreen } from '#/view/screens/Lists' +import { ModerationBlockedAccounts } from '#/view/screens/ModerationBlockedAccounts' +import { ModerationModlistsScreen } from '#/view/screens/ModerationModlists' +import { ModerationMutedAccounts } from '#/view/screens/ModerationMutedAccounts' +import { NotFoundScreen } from '#/view/screens/NotFound' +import { NotificationsScreen } from '#/view/screens/Notifications' +import { PostThreadScreen } from '#/view/screens/PostThread' +import { PrivacyPolicyScreen } from '#/view/screens/PrivacyPolicy' +import { ProfileScreen } from '#/view/screens/Profile' +import { ProfileFeedLikedByScreen } from '#/view/screens/ProfileFeedLikedBy' +import { Storybook } from '#/view/screens/Storybook' +import { SupportScreen } from '#/view/screens/Support' +import { TermsOfServiceScreen } from '#/view/screens/TermsOfService' +import { BottomBar } from '#/view/shell/bottom-bar/BottomBar' +import { createNativeStackNavigatorWithAuth } from '#/view/shell/createNativeStackNavigatorWithAuth' +import { BookmarksScreen } from '#/screens/Bookmarks' +import { SharedPreferencesTesterScreen } from '#/screens/E2E/SharedPreferencesTesterScreen' import HashtagScreen from '#/screens/Hashtag' -import {LogScreen} from '#/screens/Log' -import {MessagesScreen} from '#/screens/Messages/ChatList' -import {MessagesConversationScreen} from '#/screens/Messages/Conversation' -import {MessagesInboxScreen} from '#/screens/Messages/Inbox' -import {MessagesSettingsScreen} from '#/screens/Messages/Settings' -import {ModerationScreen} from '#/screens/Moderation' -import {Screen as ModerationVerificationSettings} from '#/screens/Moderation/VerificationSettings' -import {Screen as ModerationInteractionSettings} from '#/screens/ModerationInteractionSettings' -import {NotificationsActivityListScreen} from '#/screens/Notifications/ActivityList' -import {PostLikedByScreen} from '#/screens/Post/PostLikedBy' -import {PostQuotesScreen} from '#/screens/Post/PostQuotes' -import {PostRepostedByScreen} from '#/screens/Post/PostRepostedBy' -import {ProfileKnownFollowersScreen} from '#/screens/Profile/KnownFollowers' -import {ProfileFeedScreen} from '#/screens/Profile/ProfileFeed' -import {ProfileFollowersScreen} from '#/screens/Profile/ProfileFollowers' -import {ProfileFollowsScreen} from '#/screens/Profile/ProfileFollows' -import {ProfileLabelerLikedByScreen} from '#/screens/Profile/ProfileLabelerLikedBy' -import {ProfileSearchScreen} from '#/screens/Profile/ProfileSearch' -import {ProfileListScreen} from '#/screens/ProfileList' -import {SavedFeeds} from '#/screens/SavedFeeds' -import {SearchScreen} from '#/screens/Search' -import {AboutSettingsScreen} from '#/screens/Settings/AboutSettings' -import {AccessibilitySettingsScreen} from '#/screens/Settings/AccessibilitySettings' -import {AccountSettingsScreen} from '#/screens/Settings/AccountSettings' -import {ActivityPrivacySettingsScreen} from '#/screens/Settings/ActivityPrivacySettings' -import {AppearanceSettingsScreen} from '#/screens/Settings/AppearanceSettings' -import {AppIconSettingsScreen} from '#/screens/Settings/AppIconSettings' -import {AppPasswordsScreen} from '#/screens/Settings/AppPasswords' -import {ContentAndMediaSettingsScreen} from '#/screens/Settings/ContentAndMediaSettings' -import {ExternalMediaPreferencesScreen} from '#/screens/Settings/ExternalMediaPreferences' -import {FollowingFeedPreferencesScreen} from '#/screens/Settings/FollowingFeedPreferences' -import {InterestsSettingsScreen} from '#/screens/Settings/InterestsSettings' -import {LanguageSettingsScreen} from '#/screens/Settings/LanguageSettings' -import {LegacyNotificationSettingsScreen} from '#/screens/Settings/LegacyNotificationSettings' -import {NotificationSettingsScreen} from '#/screens/Settings/NotificationSettings' -import {ActivityNotificationSettingsScreen} from '#/screens/Settings/NotificationSettings/ActivityNotificationSettings' -import {LikeNotificationSettingsScreen} from '#/screens/Settings/NotificationSettings/LikeNotificationSettings' -import {LikesOnRepostsNotificationSettingsScreen} from '#/screens/Settings/NotificationSettings/LikesOnRepostsNotificationSettings' -import {MentionNotificationSettingsScreen} from '#/screens/Settings/NotificationSettings/MentionNotificationSettings' -import {MiscellaneousNotificationSettingsScreen} from '#/screens/Settings/NotificationSettings/MiscellaneousNotificationSettings' -import {NewFollowerNotificationSettingsScreen} from '#/screens/Settings/NotificationSettings/NewFollowerNotificationSettings' -import {QuoteNotificationSettingsScreen} from '#/screens/Settings/NotificationSettings/QuoteNotificationSettings' -import {ReplyNotificationSettingsScreen} from '#/screens/Settings/NotificationSettings/ReplyNotificationSettings' -import {RepostNotificationSettingsScreen} from '#/screens/Settings/NotificationSettings/RepostNotificationSettings' -import {RepostsOnRepostsNotificationSettingsScreen} from '#/screens/Settings/NotificationSettings/RepostsOnRepostsNotificationSettings' -import {PrivacyAndSecuritySettingsScreen} from '#/screens/Settings/PrivacyAndSecuritySettings' -import {SettingsScreen} from '#/screens/Settings/Settings' -import {ThreadPreferencesScreen} from '#/screens/Settings/ThreadPreferences' +import { LogScreen } from '#/screens/Log' +import { MessagesScreen } from '#/screens/Messages/ChatList' +import { MessagesConversationScreen } from '#/screens/Messages/Conversation' +import { MessagesInboxScreen } from '#/screens/Messages/Inbox' +import { MessagesSettingsScreen } from '#/screens/Messages/Settings' +import { ModerationScreen } from '#/screens/Moderation' +import { Screen as ModerationVerificationSettings } from '#/screens/Moderation/VerificationSettings' +import { Screen as ModerationInteractionSettings } from '#/screens/ModerationInteractionSettings' +import { NotificationsActivityListScreen } from '#/screens/Notifications/ActivityList' +import { PostLikedByScreen } from '#/screens/Post/PostLikedBy' +import { PostQuotesScreen } from '#/screens/Post/PostQuotes' +import { PostRepostedByScreen } from '#/screens/Post/PostRepostedBy' +import { ProfileKnownFollowersScreen } from '#/screens/Profile/KnownFollowers' +import { ProfileFeedScreen } from '#/screens/Profile/ProfileFeed' +import { ProfileFollowersScreen } from '#/screens/Profile/ProfileFollowers' +import { ProfileFollowsScreen } from '#/screens/Profile/ProfileFollows' +import { ProfileLabelerLikedByScreen } from '#/screens/Profile/ProfileLabelerLikedBy' +import { ProfileSearchScreen } from '#/screens/Profile/ProfileSearch' +import { ProfileListScreen } from '#/screens/ProfileList' +import { SavedFeeds } from '#/screens/SavedFeeds' +import { SearchScreen } from '#/screens/Search' +import { AboutSettingsScreen } from '#/screens/Settings/AboutSettings' +import { AccessibilitySettingsScreen } from '#/screens/Settings/AccessibilitySettings' +import { AccountSettingsScreen } from '#/screens/Settings/AccountSettings' +import { ActivityPrivacySettingsScreen } from '#/screens/Settings/ActivityPrivacySettings' +import { AppearanceSettingsScreen } from '#/screens/Settings/AppearanceSettings' +import { AppIconSettingsScreen } from '#/screens/Settings/AppIconSettings' +import { AppPasswordsScreen } from '#/screens/Settings/AppPasswords' +import { ContentAndMediaSettingsScreen } from '#/screens/Settings/ContentAndMediaSettings' +import { ExternalMediaPreferencesScreen } from '#/screens/Settings/ExternalMediaPreferences' +import { FollowingFeedPreferencesScreen } from '#/screens/Settings/FollowingFeedPreferences' +import { InterestsSettingsScreen } from '#/screens/Settings/InterestsSettings' +import { LanguageSettingsScreen } from '#/screens/Settings/LanguageSettings' +import { LegacyNotificationSettingsScreen } from '#/screens/Settings/LegacyNotificationSettings' +import { NotificationSettingsScreen } from '#/screens/Settings/NotificationSettings' +import { ActivityNotificationSettingsScreen } from '#/screens/Settings/NotificationSettings/ActivityNotificationSettings' +import { LikeNotificationSettingsScreen } from '#/screens/Settings/NotificationSettings/LikeNotificationSettings' +import { LikesOnRepostsNotificationSettingsScreen } from '#/screens/Settings/NotificationSettings/LikesOnRepostsNotificationSettings' +import { MentionNotificationSettingsScreen } from '#/screens/Settings/NotificationSettings/MentionNotificationSettings' +import { MiscellaneousNotificationSettingsScreen } from '#/screens/Settings/NotificationSettings/MiscellaneousNotificationSettings' +import { NewFollowerNotificationSettingsScreen } from '#/screens/Settings/NotificationSettings/NewFollowerNotificationSettings' +import { QuoteNotificationSettingsScreen } from '#/screens/Settings/NotificationSettings/QuoteNotificationSettings' +import { ReplyNotificationSettingsScreen } from '#/screens/Settings/NotificationSettings/ReplyNotificationSettings' +import { RepostNotificationSettingsScreen } from '#/screens/Settings/NotificationSettings/RepostNotificationSettings' +import { RepostsOnRepostsNotificationSettingsScreen } from '#/screens/Settings/NotificationSettings/RepostsOnRepostsNotificationSettings' +import { PrivacyAndSecuritySettingsScreen } from '#/screens/Settings/PrivacyAndSecuritySettings' +import { SettingsScreen } from '#/screens/Settings/Settings' +import { ThreadPreferencesScreen } from '#/screens/Settings/ThreadPreferences' import { StarterPackScreen, StarterPackScreenShort, } from '#/screens/StarterPack/StarterPackScreen' -import {Wizard} from '#/screens/StarterPack/Wizard' +import { Wizard } from '#/screens/StarterPack/Wizard' import TopicScreen from '#/screens/Topic' -import {VideoFeed} from '#/screens/VideoFeed' -import {type Theme, useTheme} from '#/alf' +import { VideoFeed } from '#/screens/VideoFeed' +import { type Theme, useTheme } from '#/alf' import { EmailDialogScreenID, useEmailDialogControl, } from '#/components/dialogs/EmailDialog' -import {router} from '#/routes' -import {Referrer} from '../modules/expo-bluesky-swiss-army' -import {useAccountSwitcher} from './lib/hooks/useAccountSwitcher' -import {useNonReactiveCallback} from './lib/hooks/useNonReactiveCallback' -import {useLoggedOutViewControls} from './state/shell/logged-out' -import {useCloseAllActiveElements} from './state/util' +import { router } from '#/routes' +import { Referrer } from '../modules/expo-bluesky-swiss-army' +import { useAccountSwitcher } from './lib/hooks/useAccountSwitcher' +import { useNonReactiveCallback } from './lib/hooks/useNonReactiveCallback' +import { useLoggedOutViewControls } from './state/shell/logged-out' +import { useCloseAllActiveElements } from './state/util' const navigationRef = createNavigationContainerRef() @@ -164,32 +165,32 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) { NotFoundScreen} - options={{title: title(msg`Not Found`)}} + options={{ title: title(msg`Not Found`) }} /> ModerationScreen} - options={{title: title(msg`Moderation`), requireAuth: true}} + options={{ title: title(msg`Moderation`), requireAuth: true }} /> ModerationModlistsScreen} - options={{title: title(msg`Moderation Lists`), requireAuth: true}} + options={{ title: title(msg`Moderation Lists`), requireAuth: true }} /> ModerationMutedAccounts} - options={{title: title(msg`Muted Accounts`), requireAuth: true}} + options={{ title: title(msg`Muted Accounts`), requireAuth: true }} /> ModerationBlockedAccounts} - options={{title: title(msg`Blocked Accounts`), requireAuth: true}} + options={{ title: title(msg`Blocked Accounts`), requireAuth: true }} /> SettingsScreen} - options={{title: title(msg`Settings`), requireAuth: true}} + options={{ title: title(msg`Settings`), requireAuth: true }} /> LanguageSettingsScreen} - options={{title: title(msg`Language Settings`), requireAuth: true}} + options={{ title: title(msg`Language Settings`), requireAuth: true }} /> ProfileScreen} - options={({route}) => ({ + options={({ route }) => ({ title: bskyTitle(`@${route.params.name}`, unreadCountLabel), })} /> ProfileFollowersScreen} - options={({route}) => ({ + options={({ route }) => ({ title: title(msg`People following @${route.params.name}`), })} /> ProfileFollowsScreen} - options={({route}) => ({ + options={({ route }) => ({ title: title(msg`People followed by @${route.params.name}`), })} /> ProfileKnownFollowersScreen} - options={({route}) => ({ + options={({ route }) => ({ title: title(msg`Followers of @${route.params.name} that you know`), })} /> ProfileListScreen} - options={{title: title(msg`List`), requireAuth: true}} + options={{ title: title(msg`List`), requireAuth: true }} /> ProfileSearchScreen} - options={({route}) => ({ + options={({ route }) => ({ title: title(msg`Search @${route.params.name}'s posts`), })} /> PostThreadScreen} - options={({route}) => ({ + options={({ route }) => ({ title: title(msg`Post by @${route.params.name}`), })} /> PostLikedByScreen} - options={({route}) => ({ + options={({ route }) => ({ title: title(msg`Post by @${route.params.name}`), })} /> PostRepostedByScreen} - options={({route}) => ({ + options={({ route }) => ({ title: title(msg`Post by @${route.params.name}`), })} /> PostQuotesScreen} - options={({route}) => ({ + options={({ route }) => ({ title: title(msg`Post by @${route.params.name}`), })} /> ProfileFeedScreen} - options={{title: title(msg`Feed`)}} + options={{ title: title(msg`Feed`) }} /> ProfileFeedLikedByScreen} - options={{title: title(msg`Liked by`)}} + options={{ title: title(msg`Liked by`) }} /> ProfileLabelerLikedByScreen} - options={{title: title(msg`Liked by`)}} + options={{ title: title(msg`Liked by`) }} /> Storybook} - options={{title: title(msg`Storybook`), requireAuth: true}} + options={{ title: title(msg`Storybook`), requireAuth: true }} /> DebugModScreen} - options={{title: title(msg`Moderation states`), requireAuth: true}} + options={{ title: title(msg`Moderation states`), requireAuth: true }} /> SharedPreferencesTesterScreen} - options={{title: title(msg`Shared Preferences Tester`)}} + options={{ title: title(msg`Shared Preferences Tester`) }} /> LogScreen} - options={{title: title(msg`Log`), requireAuth: true}} + options={{ title: title(msg`Log`), requireAuth: true }} /> SupportScreen} - options={{title: title(msg`Support`)}} + options={{ title: title(msg`Support`) }} /> PrivacyPolicyScreen} - options={{title: title(msg`Privacy Policy`)}} + options={{ title: title(msg`Privacy Policy`) }} /> TermsOfServiceScreen} - options={{title: title(msg`Terms of Service`)}} + options={{ title: title(msg`Terms of Service`) }} /> CommunityGuidelinesScreen} - options={{title: title(msg`Community Guidelines`)}} + options={{ title: title(msg`Community Guidelines`) }} /> CopyrightPolicyScreen} - options={{title: title(msg`Copyright Policy`)}} + options={{ title: title(msg`Copyright Policy`) }} /> AppPasswordsScreen} - options={{title: title(msg`App Passwords`), requireAuth: true}} + options={{ title: title(msg`App Passwords`), requireAuth: true }} /> SavedFeeds} - options={{title: title(msg`Edit My Feeds`), requireAuth: true}} + options={{ title: title(msg`Edit My Feeds`), requireAuth: true }} /> ThreadPreferencesScreen} - options={{title: title(msg`Threads Preferences`), requireAuth: true}} + options={{ title: title(msg`Threads Preferences`), requireAuth: true }} /> NotificationSettingsScreen} - options={{title: title(msg`Notification settings`), requireAuth: true}} + options={{ title: title(msg`Notification settings`), requireAuth: true }} /> HashtagScreen} - options={{title: title(msg`Hashtag`)}} + options={{ title: title(msg`Hashtag`) }} /> TopicScreen} - options={{title: title(msg`Topic`)}} + options={{ title: title(msg`Topic`) }} /> MessagesConversationScreen} - options={{title: title(msg`Chat`), requireAuth: true}} + options={{ title: title(msg`Chat`), requireAuth: true }} /> MessagesSettingsScreen} - options={{title: title(msg`Chat settings`), requireAuth: true}} + options={{ title: title(msg`Chat settings`), requireAuth: true }} /> MessagesInboxScreen} - options={{title: title(msg`Chat request inbox`), requireAuth: true}} + options={{ title: title(msg`Chat request inbox`), requireAuth: true }} /> NotificationsActivityListScreen} - options={{title: title(msg`Notifications`), requireAuth: true}} + options={{ title: title(msg`Notifications`), requireAuth: true }} /> LegacyNotificationSettingsScreen} - options={{title: title(msg`Notification settings`), requireAuth: true}} + options={{ title: title(msg`Notification settings`), requireAuth: true }} /> FeedsScreen} - options={{title: title(msg`Feeds`)}} + options={{ title: title(msg`Feeds`) }} /> StarterPackScreen} - options={{title: title(msg`Starter Pack`)}} + options={{ title: title(msg`Starter Pack`) }} /> StarterPackScreenShort} - options={{title: title(msg`Starter Pack`)}} + options={{ title: title(msg`Starter Pack`) }} /> Wizard} - options={{title: title(msg`Create a starter pack`), requireAuth: true}} + options={{ title: title(msg`Create a starter pack`), requireAuth: true }} /> Wizard} - options={{title: title(msg`Edit your starter pack`), requireAuth: true}} + options={{ title: title(msg`Edit your starter pack`), requireAuth: true }} /> HomeTabNavigator} /> SearchTabNavigator} /> @@ -663,6 +664,8 @@ function HomeTabNavigator() { return ( HomeScreen} /> + + HomeScreen} /> {commonScreens(HomeTab as typeof Flat)} @@ -690,7 +693,7 @@ function NotificationsTabNavigator() { NotificationsScreen} - options={{requireAuth: true}} + options={{ requireAuth: true }} /> {commonScreens(NotificationsTab as typeof Flat)} @@ -708,7 +711,7 @@ function MyProfileTabNavigator() { // gives us typechecking for initialParams -sfn name={'MyProfile' as 'Profile'} getComponent={() => ProfileScreen} - initialParams={{name: 'me', hideBackButton: true}} + initialParams={{ name: 'me', hideBackButton: true }} /> {commonScreens(MyProfileTab as unknown as typeof Flat)} @@ -724,7 +727,7 @@ function MessagesTabNavigator() { MessagesScreen} - options={({route}) => ({ + options={({ route }) => ({ requireAuth: true, animationTypeForReplace: route.params?.animation ?? 'push', })} @@ -751,27 +754,27 @@ const FlatNavigator = () => { HomeScreen} - options={{title: title(msg`Home`)}} + options={{ title: title(msg`Home`) }} /> SearchScreen} - options={{title: title(msg`Explore`)}} + options={{ title: title(msg`Explore`) }} /> NotificationsScreen} - options={{title: title(msg`Notifications`), requireAuth: true}} + options={{ title: title(msg`Notifications`), requireAuth: true }} /> MessagesScreen} - options={{title: title(msg`Messages`), requireAuth: true}} + options={{ title: title(msg`Messages`), requireAuth: true }} /> HomeScreen} - options={{title: title(msg`Home`)}} + options={{ title: title(msg`Home`) }} /> {commonScreens(Flat, numUnread)} @@ -849,11 +852,11 @@ const LINKING = { */ let lastHandledNotificationDateDedupe: number | undefined -function RoutesContainer({children}: React.PropsWithChildren<{}>) { +function RoutesContainer({ children }: React.PropsWithChildren<{}>) { const theme = useColorSchemeStyle(DefaultTheme, DarkTheme) - const {currentAccount, accounts} = useSession() - const {onPressSwitchAccount} = useAccountSwitcher() - const {setShowLoggedOut} = useLoggedOutViewControls() + const { currentAccount, accounts } = useSession() + const { onPressSwitchAccount } = useAccountSwitcher() + const { setShowLoggedOut } = useLoggedOutViewControls() const prevLoggedRouteName = useRef(undefined) const emailDialogControl = useEmailDialogControl() const closeAllActiveElements = useCloseAllActiveElements() @@ -865,8 +868,8 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) { * after an async call - sfn */ const handleChatMessage = useNonReactiveCallback( - (payload: Extract) => { - notyLogger.debug(`handleChatMessage`, {payload}) + (payload: Extract) => { + notyLogger.debug(`handleChatMessage`, { payload }) if (payload.recipientDid !== currentAccount?.did) { // handled in useNotificationHandler after account switch finishes @@ -907,7 +910,7 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) { const response = await Notifications.getLastNotificationResponseAsync() if (response) { - notyLogger.debug(`handlePushNotificationEntry: response`, {response}) + notyLogger.debug(`handlePushNotificationEntry: response`, { response }) if (response.notification.date === lastHandledNotificationDateDedupe) return @@ -918,8 +921,8 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) { if (payload) { notyLogger.metric( 'notifications:openApp', - {reason: payload.reason, causedBoot: true}, - {statsig: false}, + { reason: payload.reason, causedBoot: true }, + { statsig: false }, ) if (payload.reason === 'chat-message') { @@ -933,7 +936,7 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) { } else if (path) { const [screen, params] = router.matchPath(path) // @ts-expect-error nested navigators aren't typed -sfn - navigate('HomeTab', {screen, params}) + navigate('HomeTab', { screen, params }) notyLogger.debug(`handlePushNotificationEntry: navigate`, { screen, params, @@ -963,8 +966,8 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) { onStateChange={() => { logger.metric( 'router:navigate', - {from: prevLoggedRouteName.current}, - {statsig: false}, + { from: prevLoggedRouteName.current }, + { statsig: false }, ) prevLoggedRouteName.current = getCurrentRouteName() }} @@ -972,7 +975,7 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) { attachRouteToLogEvents(getCurrentRouteName) logModuleInitTime() onReady() - logger.metric('router:navigate', {}, {statsig: false}) + logger.metric('router:navigate', {}, { statsig: false }) handlePushNotificationEntry() }} // WARNING: Implicit navigation to nested navigators is depreciated in React Navigation 7.x @@ -1040,7 +1043,7 @@ function reset(): Promise { navigationRef.dispatch( CommonActions.reset({ index: 0, - routes: [{name: isNative ? 'HomeTab' : 'Home'}], + routes: [{ name: isNative ? 'HomeTab' : 'Home' }], }), ) return Promise.race([ diff --git a/src/lib/routes/types.ts b/src/lib/routes/types.ts index c315a8341..dc84545f7 100644 --- a/src/lib/routes/types.ts +++ b/src/lib/routes/types.ts @@ -1,9 +1,9 @@ -import {type NavigationState, type PartialState} from '@react-navigation/native' -import {type NativeStackNavigationProp} from '@react-navigation/native-stack' +import { type NavigationState, type PartialState } from '@react-navigation/native' +import { type NativeStackNavigationProp } from '@react-navigation/native-stack' -import {type VideoFeedSourceContext} from '#/screens/VideoFeed/types' +import { type VideoFeedSourceContext } from '#/screens/VideoFeed/types' -export type {NativeStackScreenProps} from '@react-navigation/native-stack' +export type { NativeStackScreenProps } from '@react-navigation/native-stack' export type CommonNavigatorParams = { NotFound: undefined @@ -15,23 +15,23 @@ export type CommonNavigatorParams = { ModerationInteractionSettings: undefined ModerationVerificationSettings: undefined Settings: undefined - Profile: {name: string; hideBackButton?: boolean} - ProfileFollowers: {name: string} - ProfileFollows: {name: string} - ProfileKnownFollowers: {name: string} - ProfileSearch: {name: string; q?: string} - ProfileList: {name: string; rkey: string} - PostThread: {name: string; rkey: string} - PostLikedBy: {name: string; rkey: string} - PostRepostedBy: {name: string; rkey: string} - PostQuotes: {name: string; rkey: string} + Profile: { name: string; hideBackButton?: boolean } + ProfileFollowers: { name: string } + ProfileFollows: { name: string } + ProfileKnownFollowers: { name: string } + ProfileSearch: { name: string; q?: string } + ProfileList: { name: string; rkey: string } + PostThread: { name: string; rkey: string } + PostLikedBy: { name: string; rkey: string } + PostRepostedBy: { name: string; rkey: string } + PostQuotes: { name: string; rkey: string } ProfileFeed: { name: string rkey: string feedCacheKey?: 'discover' | 'explore' | undefined } - ProfileFeedLikedBy: {name: string; rkey: string} - ProfileLabelerLikedBy: {name: string} + ProfileFeedLikedBy: { name: string; rkey: string } + ProfileLabelerLikedBy: { name: string } Debug: undefined DebugMod: undefined SharedPreferencesTester: undefined @@ -39,6 +39,7 @@ export type CommonNavigatorParams = { Support: undefined PrivacyPolicy: undefined TermsOfService: undefined + License: undefined CommunityGuidelines: undefined CopyrightPolicy: undefined LanguageSettings: undefined @@ -67,24 +68,24 @@ export type CommonNavigatorParams = { InterestsSettings: undefined AboutSettings: undefined AppIconSettings: undefined - Search: {q?: string; tab?: 'user' | 'profile' | 'feed'} - Hashtag: {tag: string; author?: string} - Topic: {topic: string} - MessagesConversation: {conversation: string; embed?: string; accept?: true} + Search: { q?: string; tab?: 'user' | 'profile' | 'feed' } + Hashtag: { tag: string; author?: string } + Topic: { topic: string } + MessagesConversation: { conversation: string; embed?: string; accept?: true } MessagesSettings: undefined MessagesInbox: undefined - NotificationsActivityList: {posts: string} + NotificationsActivityList: { posts: string } LegacyNotificationSettings: undefined Feeds: undefined - Start: {name: string; rkey: string} - StarterPack: {name: string; rkey: string; new?: boolean} - StarterPackShort: {code: string} + Start: { name: string; rkey: string } + StarterPack: { name: string; rkey: string; new?: boolean } + StarterPackShort: { code: string } StarterPackWizard: { fromDialog?: boolean targetDid?: string onSuccess?: () => void } - StarterPackEdit: {rkey?: string} + StarterPackEdit: { rkey?: string } VideoFeed: VideoFeedSourceContext Bookmarks: undefined } @@ -102,7 +103,7 @@ export type HomeTabNavigatorParams = CommonNavigatorParams & { } export type SearchTabNavigatorParams = CommonNavigatorParams & { - Search: {q?: string; tab?: 'user' | 'profile' | 'feed'} + Search: { q?: string; tab?: 'user' | 'profile' | 'feed' } } export type NotificationsTabNavigatorParams = CommonNavigatorParams & { @@ -110,32 +111,32 @@ export type NotificationsTabNavigatorParams = CommonNavigatorParams & { } export type MyProfileTabNavigatorParams = CommonNavigatorParams & { - MyProfile: {name: 'me'; hideBackButton: true} + MyProfile: { name: 'me'; hideBackButton: true } } export type MessagesTabNavigatorParams = CommonNavigatorParams & { - Messages: {pushToConversation?: string; animation?: 'push' | 'pop'} + Messages: { pushToConversation?: string; animation?: 'push' | 'pop' } } export type FlatNavigatorParams = CommonNavigatorParams & { Home: undefined - Search: {q?: string; tab?: 'user' | 'profile' | 'feed'} + Search: { q?: string; tab?: 'user' | 'profile' | 'feed' } Feeds: undefined Notifications: undefined - Messages: {pushToConversation?: string; animation?: 'push' | 'pop'} + Messages: { pushToConversation?: string; animation?: 'push' | 'pop' } } export type AllNavigatorParams = CommonNavigatorParams & { HomeTab: undefined Home: undefined SearchTab: undefined - Search: {q?: string; tab?: 'user' | 'profile' | 'feed'} + Search: { q?: string; tab?: 'user' | 'profile' | 'feed' } Feeds: undefined NotificationsTab: undefined Notifications: undefined MyProfileTab: undefined MessagesTab: undefined - Messages: {animation?: 'push' | 'pop'} + Messages: { animation?: 'push' | 'pop' } } // NOTE @@ -149,7 +150,7 @@ export type State = | Omit, 'stale'> export type RouteParams = Record -export type MatchResult = {params: RouteParams} +export type MatchResult = { params: RouteParams } export type Route = { match: (path: string) => MatchResult | undefined build: (params?: Record) => string diff --git a/src/routes.ts b/src/routes.ts index 1ed913bb2..3fe7041da 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -1,5 +1,5 @@ -import {Router} from '#/lib/routes/router' -import {type FlatNavigatorParams} from './lib/routes/types' +import { Router } from '#/lib/routes/router' +import { type FlatNavigatorParams } from './lib/routes/types' type AllNavigatableRoutes = Omit< FlatNavigatorParams, @@ -71,8 +71,9 @@ export const router = new Router({ MiscellaneousNotificationSettings: '/settings/notifications/miscellaneous', // support Support: '/support', - PrivacyPolicy: '/support/privacy', + PrivacyPolicy: 'https://syu.is/about/support/privacy-policy', TermsOfService: '/support/tos', + License: '/support/license', CommunityGuidelines: '/support/community-guidelines', CopyrightPolicy: '/support/copyright', // hashtags diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index ed2a6cfb7..982c40b55 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -1,60 +1,50 @@ -import React, {type ComponentProps, type JSX} from 'react' -import {Linking, ScrollView, TouchableOpacity, View} from 'react-native' -import {useSafeAreaInsets} from 'react-native-safe-area-context' -import {msg, Plural, plural, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {StackActions, useNavigation} from '@react-navigation/native' - -import {useActorStatus} from '#/lib/actor-status' -import {FEEDBACK_FORM_URL, HELP_DESK_URL} from '#/lib/constants' -import {type PressableScale} from '#/lib/custom-animations/PressableScale' -import {useNavigationTabState} from '#/lib/hooks/useNavigationTabState' -import {getTabState, TabState} from '#/lib/routes/helpers' -import {type NavigationProp} from '#/lib/routes/types' -import {sanitizeHandle} from '#/lib/strings/handles' -import {colors} from '#/lib/styles' -import {isWeb} from '#/platform/detection' -import {emitSoftReset} from '#/state/events' -import {useKawaiiMode} from '#/state/preferences/kawaii' -import {useUnreadNotifications} from '#/state/queries/notifications/unread' -import {useProfileQuery} from '#/state/queries/profile' -import {type SessionAccount, useSession} from '#/state/session' -import {useSetDrawerOpen} from '#/state/shell' -import {formatCount} from '#/view/com/util/numeric/format' -import {UserAvatar} from '#/view/com/util/UserAvatar' -import {NavSignupCard} from '#/view/shell/NavSignupCard' -import {atoms as a, tokens, useTheme, web} from '#/alf' -import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import {Divider} from '#/components/Divider' +import React, { type ComponentProps, type JSX } from 'react' +import { Linking, ScrollView, TouchableOpacity, View } from 'react-native' +import { useSafeAreaInsets } from 'react-native-safe-area-context' +import { msg, Plural, plural, Trans } from '@lingui/macro' +import { useLingui } from '@lingui/react' +import { StackActions, useNavigation } from '@react-navigation/native' + +import { useActorStatus } from '#/lib/actor-status' +import { FEEDBACK_FORM_URL, HELP_DESK_URL } from '#/lib/constants' +import { type PressableScale } from '#/lib/custom-animations/PressableScale' +import { useNavigationTabState } from '#/lib/hooks/useNavigationTabState' +import { getTabState, TabState } from '#/lib/routes/helpers' +import { type NavigationProp } from '#/lib/routes/types' +import { sanitizeHandle } from '#/lib/strings/handles' +import { colors } from '#/lib/styles' +import { isWeb } from '#/platform/detection' +import { emitSoftReset } from '#/state/events' +import { useKawaiiMode } from '#/state/preferences/kawaii' +import { useUnreadNotifications } from '#/state/queries/notifications/unread' +import { useProfileQuery } from '#/state/queries/profile' +import { type SessionAccount, useSession } from '#/state/session' +import { useSetDrawerOpen } from '#/state/shell' +import { formatCount } from '#/view/com/util/numeric/format' +import { UserAvatar } from '#/view/com/util/UserAvatar' +import { NavSignupCard } from '#/view/shell/NavSignupCard' +import { atoms as a, tokens, useTheme, web } from '#/alf' +import { Button } from '#/components/Button' +import { Divider } from '#/components/Divider' import { Bell_Filled_Corner0_Rounded as BellFilled, Bell_Stroke2_Corner0_Rounded as Bell, } from '#/components/icons/Bell' -import {Bookmark, BookmarkFilled} from '#/components/icons/Bookmark' -import {BulletList_Stroke2_Corner0_Rounded as List} from '#/components/icons/BulletList' -import { - Hashtag_Filled_Corner0_Rounded as HashtagFilled, - Hashtag_Stroke2_Corner0_Rounded as Hashtag, -} from '#/components/icons/Hashtag' import { HomeOpen_Filled_Corner0_Rounded as HomeFilled, HomeOpen_Stoke2_Corner0_Rounded as Home, } from '#/components/icons/HomeOpen' -import {MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled} from '#/components/icons/MagnifyingGlass' -import {MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass2' -import { - Message_Stroke2_Corner0_Rounded as Message, - Message_Stroke2_Corner0_Rounded_Filled as MessageFilled, -} from '#/components/icons/Message' -import {SettingsGear2_Stroke2_Corner0_Rounded as Settings} from '#/components/icons/SettingsGear2' +import { MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled } from '#/components/icons/MagnifyingGlass' +import { MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass } from '#/components/icons/MagnifyingGlass2' +import { SettingsGear2_Stroke2_Corner0_Rounded as Settings } from '#/components/icons/SettingsGear2' import { UserCircle_Filled_Corner0_Rounded as UserCircleFilled, UserCircle_Stroke2_Corner0_Rounded as UserCircle, } from '#/components/icons/UserCircle' -import {InlineLinkText} from '#/components/Link' -import {Text} from '#/components/Typography' -import {useSimpleVerificationState} from '#/components/verification' -import {VerificationCheck} from '#/components/verification/VerificationCheck' +import { InlineLinkText } from '#/components/Link' +import { Text } from '#/components/Typography' +import { useSimpleVerificationState } from '#/components/verification' +import { VerificationCheck } from '#/components/verification/VerificationCheck' const iconWidth = 26 @@ -65,11 +55,11 @@ let DrawerProfileCard = ({ account: SessionAccount onPressProfile: () => void }): React.ReactNode => { - const {_, i18n} = useLingui() + const { _, i18n } = useLingui() const t = useTheme() - const {data: profile} = useProfileQuery({did: account.did}) - const verification = useSimpleVerificationState({profile}) - const {isActive: live} = useActorStatus(profile) + const { data: profile } = useProfileQuery({ did: account.did }) + const verification = useSimpleVerificationState({ profile }) + const { isActive: live } = useActorStatus(profile) return ( ): React.ReactNode => { +let DrawerContent = ({ }: React.PropsWithoutRef<{}>): React.ReactNode => { const t = useTheme() const insets = useSafeAreaInsets() const setDrawerOpen = useSetDrawerOpen() @@ -150,27 +139,20 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { const { isAtHome, isAtSearch, - isAtFeeds, - isAtBookmarks, isAtNotifications, isAtMyProfile, - isAtMessages, } = useNavigationTabState() - const {hasSession, currentAccount} = useSession() - - // events - // = + const { hasSession, currentAccount } = useSession() const onPressTab = React.useCallback( (tab: 'Home' | 'Search' | 'Messages' | 'Notifications' | 'MyProfile') => { const state = navigation.getState() setDrawerOpen(false) if (isWeb) { - // hack because we have flat navigator for web and MyProfile does not exist on the web navigator -ansh if (tab === 'MyProfile') { - navigation.navigate('Profile', {name: currentAccount!.handle}) + navigation.navigate('Profile', { name: currentAccount!.handle }) } else { - // @ts-expect-error struggles with string unions, apparently + // @ts-expect-error struggles with string unions navigation.navigate(tab) } } else { @@ -178,21 +160,11 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { if (tabState === TabState.InsideAtRoot) { emitSoftReset() } else if (tabState === TabState.Inside) { - // find the correct navigator in which to pop-to-top - const target = state.routes.find(route => route.name === `${tab}Tab`) - ?.state?.key + const target = state.routes.find(route => route.name === `${tab}Tab`)?.state?.key if (target) { - // if we found it, trigger pop-to-top - navigation.dispatch({ - ...StackActions.popToTop(), - target, - }) + navigation.dispatch({ ...StackActions.popToTop(), target }) } else { - // fallback: reset navigation - navigation.reset({ - index: 0, - routes: [{name: `${tab}Tab`}], - }) + navigation.reset({ index: 0, routes: [{ name: `${tab}Tab` }] }) } } else { navigation.navigate(`${tab}Tab`) @@ -203,76 +175,21 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { ) const onPressHome = React.useCallback(() => onPressTab('Home'), [onPressTab]) - - const onPressSearch = React.useCallback( - () => onPressTab('Search'), - [onPressTab], - ) - - const onPressMessages = React.useCallback( - () => onPressTab('Messages'), - [onPressTab], - ) - - const onPressNotifications = React.useCallback( - () => onPressTab('Notifications'), - [onPressTab], - ) - - const onPressProfile = React.useCallback(() => { - onPressTab('MyProfile') - }, [onPressTab]) - - const onPressMyFeeds = React.useCallback(() => { - navigation.navigate('Feeds') - setDrawerOpen(false) - }, [navigation, setDrawerOpen]) - - const onPressLists = React.useCallback(() => { - navigation.navigate('Lists') - setDrawerOpen(false) - }, [navigation, setDrawerOpen]) - - const onPressBookmarks = React.useCallback(() => { - navigation.navigate('Bookmarks') - setDrawerOpen(false) - }, [navigation, setDrawerOpen]) - + const onPressSearch = React.useCallback(() => onPressTab('Search'), [onPressTab]) + const onPressNotifications = React.useCallback(() => onPressTab('Notifications'), [onPressTab]) + const onPressProfile = React.useCallback(() => { onPressTab('MyProfile') }, [onPressTab]) const onPressSettings = React.useCallback(() => { navigation.navigate('Settings') setDrawerOpen(false) }, [navigation, setDrawerOpen]) - const onPressFeedback = React.useCallback(() => { - Linking.openURL( - FEEDBACK_FORM_URL({ - email: currentAccount?.email, - handle: currentAccount?.handle, - }), - ) - }, [currentAccount]) - - const onPressHelp = React.useCallback(() => { - Linking.openURL(HELP_DESK_URL) - }, []) - - // rendering - // = - return ( + contentContainerStyle={[{ paddingTop: Math.max(insets.top + a.pt_xl.paddingTop, a.pt_xl.paddingTop) }]}> {hasSession && currentAccount ? ( ): React.ReactNode => { )} - @@ -292,17 +208,10 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { <> - - - - ): React.ReactNode => { ) : ( <> - )} @@ -322,69 +230,11 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { - - ) } DrawerContent = React.memo(DrawerContent) -export {DrawerContent} - -let DrawerFooter = ({ - onPressFeedback, - onPressHelp, -}: { - onPressFeedback: () => void - onPressHelp: () => void -}): React.ReactNode => { - const {_} = useLingui() - const insets = useSafeAreaInsets() - return ( - - - - - ) -} -DrawerFooter = React.memo(DrawerFooter) +export { DrawerContent } interface MenuItemProps extends ComponentProps { icon: JSX.Element @@ -400,7 +250,7 @@ let SearchMenuItem = ({ isActive: boolean onPress: () => void }): React.ReactNode => { - const {_} = useLingui() + const { _ } = useLingui() const t = useTheme() return ( void }): React.ReactNode => { - const {_} = useLingui() + const { _ } = useLingui() const t = useTheme() return ( void -}): React.ReactNode => { - const {_} = useLingui() - const t = useTheme() - return ( - - ) : ( - - ) - } - label={_(msg`Chat`)} - bold={isActive} - onPress={onPress} - /> - ) -} -ChatMenuItem = React.memo(ChatMenuItem) - let NotificationsMenuItem = ({ isActive, onPress, @@ -478,7 +302,7 @@ let NotificationsMenuItem = ({ isActive: boolean onPress: () => void }): React.ReactNode => { - const {_} = useLingui() + const { _ } = useLingui() const t = useTheme() const numUnreadNotifications = useUnreadNotifications() return ( @@ -495,11 +319,11 @@ let NotificationsMenuItem = ({ numUnreadNotifications === '' ? '' : _( - msg`${plural(numUnreadNotifications ?? 0, { - one: '# unread item', - other: '# unread items', - })}` || '', - ) + msg`${plural(numUnreadNotifications ?? 0, { + one: '# unread item', + other: '# unread items', + })}` || '', + ) } count={numUnreadNotifications} bold={isActive} @@ -509,72 +333,6 @@ let NotificationsMenuItem = ({ } NotificationsMenuItem = React.memo(NotificationsMenuItem) -let FeedsMenuItem = ({ - isActive, - onPress, -}: { - isActive: boolean - onPress: () => void -}): React.ReactNode => { - const {_} = useLingui() - const t = useTheme() - return ( - - ) : ( - - ) - } - label={_(msg`Feeds`)} - bold={isActive} - onPress={onPress} - /> - ) -} -FeedsMenuItem = React.memo(FeedsMenuItem) - -let ListsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => { - const {_} = useLingui() - const t = useTheme() - - return ( - } - label={_(msg`Lists`)} - onPress={onPress} - /> - ) -} -ListsMenuItem = React.memo(ListsMenuItem) - -let BookmarksMenuItem = ({ - isActive, - onPress, -}: { - isActive: boolean - onPress: () => void -}): React.ReactNode => { - const {_} = useLingui() - const t = useTheme() - - return ( - - ) : ( - - ) - } - label={_(msg({message: 'Saved', context: 'link to bookmarks screen'}))} - onPress={onPress} - /> - ) -} -BookmarksMenuItem = React.memo(BookmarksMenuItem) - let ProfileMenuItem = ({ isActive, onPress, @@ -582,7 +340,7 @@ let ProfileMenuItem = ({ isActive: boolean onPress: () => void }): React.ReactNode => { - const {_} = useLingui() + const { _ } = useLingui() const t = useTheme() return ( void}): React.ReactNode => { - const {_} = useLingui() +let SettingsMenuItem = ({ onPress }: { onPress: () => void }): React.ReactNode => { + const { _ } = useLingui() const t = useTheme() return ( void}): React.ReactNode => { } SettingsMenuItem = React.memo(SettingsMenuItem) -function MenuItem({icon, label, count, bold, onPress}: MenuItemProps) { +function MenuItem({ icon, label, count, bold, onPress }: MenuItemProps) { const t = useTheme() return (