1512 lines
62 KiB
Diff
1512 lines
62 KiB
Diff
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<AllNavigatorParams>()
|
|
|
|
@@ -164,32 +165,32 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) {
|
|
<Stack.Screen
|
|
name="NotFound"
|
|
getComponent={() => NotFoundScreen}
|
|
- options={{title: title(msg`Not Found`)}}
|
|
+ options={{ title: title(msg`Not Found`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="Lists"
|
|
component={ListsScreen}
|
|
- options={{title: title(msg`Lists`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Lists`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="Moderation"
|
|
getComponent={() => ModerationScreen}
|
|
- options={{title: title(msg`Moderation`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Moderation`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="ModerationModlists"
|
|
getComponent={() => ModerationModlistsScreen}
|
|
- options={{title: title(msg`Moderation Lists`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Moderation Lists`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="ModerationMutedAccounts"
|
|
getComponent={() => ModerationMutedAccounts}
|
|
- options={{title: title(msg`Muted Accounts`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Muted Accounts`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="ModerationBlockedAccounts"
|
|
getComponent={() => ModerationBlockedAccounts}
|
|
- options={{title: title(msg`Blocked Accounts`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Blocked Accounts`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="ModerationInteractionSettings"
|
|
@@ -210,150 +211,150 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) {
|
|
<Stack.Screen
|
|
name="Settings"
|
|
getComponent={() => SettingsScreen}
|
|
- options={{title: title(msg`Settings`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Settings`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="LanguageSettings"
|
|
getComponent={() => LanguageSettingsScreen}
|
|
- options={{title: title(msg`Language Settings`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Language Settings`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="Profile"
|
|
getComponent={() => ProfileScreen}
|
|
- options={({route}) => ({
|
|
+ options={({ route }) => ({
|
|
title: bskyTitle(`@${route.params.name}`, unreadCountLabel),
|
|
})}
|
|
/>
|
|
<Stack.Screen
|
|
name="ProfileFollowers"
|
|
getComponent={() => ProfileFollowersScreen}
|
|
- options={({route}) => ({
|
|
+ options={({ route }) => ({
|
|
title: title(msg`People following @${route.params.name}`),
|
|
})}
|
|
/>
|
|
<Stack.Screen
|
|
name="ProfileFollows"
|
|
getComponent={() => ProfileFollowsScreen}
|
|
- options={({route}) => ({
|
|
+ options={({ route }) => ({
|
|
title: title(msg`People followed by @${route.params.name}`),
|
|
})}
|
|
/>
|
|
<Stack.Screen
|
|
name="ProfileKnownFollowers"
|
|
getComponent={() => ProfileKnownFollowersScreen}
|
|
- options={({route}) => ({
|
|
+ options={({ route }) => ({
|
|
title: title(msg`Followers of @${route.params.name} that you know`),
|
|
})}
|
|
/>
|
|
<Stack.Screen
|
|
name="ProfileList"
|
|
getComponent={() => ProfileListScreen}
|
|
- options={{title: title(msg`List`), requireAuth: true}}
|
|
+ options={{ title: title(msg`List`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="ProfileSearch"
|
|
getComponent={() => ProfileSearchScreen}
|
|
- options={({route}) => ({
|
|
+ options={({ route }) => ({
|
|
title: title(msg`Search @${route.params.name}'s posts`),
|
|
})}
|
|
/>
|
|
<Stack.Screen
|
|
name="PostThread"
|
|
getComponent={() => PostThreadScreen}
|
|
- options={({route}) => ({
|
|
+ options={({ route }) => ({
|
|
title: title(msg`Post by @${route.params.name}`),
|
|
})}
|
|
/>
|
|
<Stack.Screen
|
|
name="PostLikedBy"
|
|
getComponent={() => PostLikedByScreen}
|
|
- options={({route}) => ({
|
|
+ options={({ route }) => ({
|
|
title: title(msg`Post by @${route.params.name}`),
|
|
})}
|
|
/>
|
|
<Stack.Screen
|
|
name="PostRepostedBy"
|
|
getComponent={() => PostRepostedByScreen}
|
|
- options={({route}) => ({
|
|
+ options={({ route }) => ({
|
|
title: title(msg`Post by @${route.params.name}`),
|
|
})}
|
|
/>
|
|
<Stack.Screen
|
|
name="PostQuotes"
|
|
getComponent={() => PostQuotesScreen}
|
|
- options={({route}) => ({
|
|
+ options={({ route }) => ({
|
|
title: title(msg`Post by @${route.params.name}`),
|
|
})}
|
|
/>
|
|
<Stack.Screen
|
|
name="ProfileFeed"
|
|
getComponent={() => ProfileFeedScreen}
|
|
- options={{title: title(msg`Feed`)}}
|
|
+ options={{ title: title(msg`Feed`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="ProfileFeedLikedBy"
|
|
getComponent={() => ProfileFeedLikedByScreen}
|
|
- options={{title: title(msg`Liked by`)}}
|
|
+ options={{ title: title(msg`Liked by`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="ProfileLabelerLikedBy"
|
|
getComponent={() => ProfileLabelerLikedByScreen}
|
|
- options={{title: title(msg`Liked by`)}}
|
|
+ options={{ title: title(msg`Liked by`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="Debug"
|
|
getComponent={() => Storybook}
|
|
- options={{title: title(msg`Storybook`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Storybook`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="DebugMod"
|
|
getComponent={() => DebugModScreen}
|
|
- options={{title: title(msg`Moderation states`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Moderation states`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="SharedPreferencesTester"
|
|
getComponent={() => SharedPreferencesTesterScreen}
|
|
- options={{title: title(msg`Shared Preferences Tester`)}}
|
|
+ options={{ title: title(msg`Shared Preferences Tester`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="Log"
|
|
getComponent={() => LogScreen}
|
|
- options={{title: title(msg`Log`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Log`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="Support"
|
|
getComponent={() => SupportScreen}
|
|
- options={{title: title(msg`Support`)}}
|
|
+ options={{ title: title(msg`Support`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="PrivacyPolicy"
|
|
getComponent={() => PrivacyPolicyScreen}
|
|
- options={{title: title(msg`Privacy Policy`)}}
|
|
+ options={{ title: title(msg`Privacy Policy`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="TermsOfService"
|
|
getComponent={() => TermsOfServiceScreen}
|
|
- options={{title: title(msg`Terms of Service`)}}
|
|
+ options={{ title: title(msg`Terms of Service`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="CommunityGuidelines"
|
|
getComponent={() => CommunityGuidelinesScreen}
|
|
- options={{title: title(msg`Community Guidelines`)}}
|
|
+ options={{ title: title(msg`Community Guidelines`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="CopyrightPolicy"
|
|
getComponent={() => CopyrightPolicyScreen}
|
|
- options={{title: title(msg`Copyright Policy`)}}
|
|
+ options={{ title: title(msg`Copyright Policy`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="AppPasswords"
|
|
getComponent={() => AppPasswordsScreen}
|
|
- options={{title: title(msg`App Passwords`), requireAuth: true}}
|
|
+ options={{ title: title(msg`App Passwords`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="SavedFeeds"
|
|
getComponent={() => SavedFeeds}
|
|
- options={{title: title(msg`Edit My Feeds`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Edit My Feeds`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="PreferencesFollowingFeed"
|
|
@@ -366,7 +367,7 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) {
|
|
<Stack.Screen
|
|
name="PreferencesThreads"
|
|
getComponent={() => ThreadPreferencesScreen}
|
|
- options={{title: title(msg`Threads Preferences`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Threads Preferences`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="PreferencesExternalEmbeds"
|
|
@@ -419,7 +420,7 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) {
|
|
<Stack.Screen
|
|
name="NotificationSettings"
|
|
getComponent={() => NotificationSettingsScreen}
|
|
- options={{title: title(msg`Notification settings`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Notification settings`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="ReplyNotificationSettings"
|
|
@@ -536,62 +537,62 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) {
|
|
<Stack.Screen
|
|
name="Hashtag"
|
|
getComponent={() => HashtagScreen}
|
|
- options={{title: title(msg`Hashtag`)}}
|
|
+ options={{ title: title(msg`Hashtag`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="Topic"
|
|
getComponent={() => TopicScreen}
|
|
- options={{title: title(msg`Topic`)}}
|
|
+ options={{ title: title(msg`Topic`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="MessagesConversation"
|
|
getComponent={() => MessagesConversationScreen}
|
|
- options={{title: title(msg`Chat`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Chat`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="MessagesSettings"
|
|
getComponent={() => MessagesSettingsScreen}
|
|
- options={{title: title(msg`Chat settings`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Chat settings`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="MessagesInbox"
|
|
getComponent={() => MessagesInboxScreen}
|
|
- options={{title: title(msg`Chat request inbox`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Chat request inbox`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="NotificationsActivityList"
|
|
getComponent={() => NotificationsActivityListScreen}
|
|
- options={{title: title(msg`Notifications`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Notifications`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="LegacyNotificationSettings"
|
|
getComponent={() => LegacyNotificationSettingsScreen}
|
|
- options={{title: title(msg`Notification settings`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Notification settings`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="Feeds"
|
|
getComponent={() => FeedsScreen}
|
|
- options={{title: title(msg`Feeds`)}}
|
|
+ options={{ title: title(msg`Feeds`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="StarterPack"
|
|
getComponent={() => StarterPackScreen}
|
|
- options={{title: title(msg`Starter Pack`)}}
|
|
+ options={{ title: title(msg`Starter Pack`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="StarterPackShort"
|
|
getComponent={() => StarterPackScreenShort}
|
|
- options={{title: title(msg`Starter Pack`)}}
|
|
+ options={{ title: title(msg`Starter Pack`) }}
|
|
/>
|
|
<Stack.Screen
|
|
name="StarterPackWizard"
|
|
getComponent={() => Wizard}
|
|
- options={{title: title(msg`Create a starter pack`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Create a starter pack`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="StarterPackEdit"
|
|
getComponent={() => Wizard}
|
|
- options={{title: title(msg`Edit your starter pack`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Edit your starter pack`), requireAuth: true }}
|
|
/>
|
|
<Stack.Screen
|
|
name="VideoFeed"
|
|
@@ -629,7 +630,7 @@ function TabsNavigator() {
|
|
<Tab.Navigator
|
|
initialRouteName="HomeTab"
|
|
backBehavior="initialRoute"
|
|
- screenOptions={{headerShown: false, lazy: true}}
|
|
+ screenOptions={{ headerShown: false, lazy: true }}
|
|
tabBar={tabBar}>
|
|
<Tab.Screen name="HomeTab" getComponent={() => HomeTabNavigator} />
|
|
<Tab.Screen name="SearchTab" getComponent={() => SearchTabNavigator} />
|
|
@@ -663,6 +664,8 @@ function HomeTabNavigator() {
|
|
return (
|
|
<HomeTab.Navigator screenOptions={screenOptions(t)} initialRouteName="Home">
|
|
<HomeTab.Screen name="Home" getComponent={() => HomeScreen} />
|
|
+ <HomeTab.Screen name="TermsOfService" component={TermsOfServiceScreen} />
|
|
+ <HomeTab.Screen name="License" component={LicenseScreen} />
|
|
<HomeTab.Screen name="Start" getComponent={() => HomeScreen} />
|
|
{commonScreens(HomeTab as typeof Flat)}
|
|
</HomeTab.Navigator>
|
|
@@ -690,7 +693,7 @@ function NotificationsTabNavigator() {
|
|
<NotificationsTab.Screen
|
|
name="Notifications"
|
|
getComponent={() => NotificationsScreen}
|
|
- options={{requireAuth: true}}
|
|
+ options={{ requireAuth: true }}
|
|
/>
|
|
{commonScreens(NotificationsTab as typeof Flat)}
|
|
</NotificationsTab.Navigator>
|
|
@@ -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)}
|
|
</MyProfileTab.Navigator>
|
|
@@ -724,7 +727,7 @@ function MessagesTabNavigator() {
|
|
<MessagesTab.Screen
|
|
name="Messages"
|
|
getComponent={() => MessagesScreen}
|
|
- options={({route}) => ({
|
|
+ options={({ route }) => ({
|
|
requireAuth: true,
|
|
animationTypeForReplace: route.params?.animation ?? 'push',
|
|
})}
|
|
@@ -751,27 +754,27 @@ const FlatNavigator = () => {
|
|
<Flat.Screen
|
|
name="Home"
|
|
getComponent={() => HomeScreen}
|
|
- options={{title: title(msg`Home`)}}
|
|
+ options={{ title: title(msg`Home`) }}
|
|
/>
|
|
<Flat.Screen
|
|
name="Search"
|
|
getComponent={() => SearchScreen}
|
|
- options={{title: title(msg`Explore`)}}
|
|
+ options={{ title: title(msg`Explore`) }}
|
|
/>
|
|
<Flat.Screen
|
|
name="Notifications"
|
|
getComponent={() => NotificationsScreen}
|
|
- options={{title: title(msg`Notifications`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Notifications`), requireAuth: true }}
|
|
/>
|
|
<Flat.Screen
|
|
name="Messages"
|
|
getComponent={() => MessagesScreen}
|
|
- options={{title: title(msg`Messages`), requireAuth: true}}
|
|
+ options={{ title: title(msg`Messages`), requireAuth: true }}
|
|
/>
|
|
<Flat.Screen
|
|
name="Start"
|
|
getComponent={() => HomeScreen}
|
|
- options={{title: title(msg`Home`)}}
|
|
+ options={{ title: title(msg`Home`) }}
|
|
/>
|
|
{commonScreens(Flat, numUnread)}
|
|
</Flat.Navigator>
|
|
@@ -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<string | undefined>(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<NotificationPayload, {reason: 'chat-message'}>) => {
|
|
- notyLogger.debug(`handleChatMessage`, {payload})
|
|
+ (payload: Extract<NotificationPayload, { reason: 'chat-message' }>) => {
|
|
+ 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<void> {
|
|
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<PartialState<NavigationState>, 'stale'>
|
|
|
|
export type RouteParams = Record<string, string>
|
|
-export type MatchResult = {params: RouteParams}
|
|
+export type MatchResult = { params: RouteParams }
|
|
export type Route = {
|
|
match: (path: string) => MatchResult | undefined
|
|
build: (params?: Record<string, any>) => 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<AllNavigatableRoutes>({
|
|
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 (
|
|
<TouchableOpacity
|
|
@@ -81,7 +71,6 @@ let DrawerProfileCard = ({
|
|
<UserAvatar
|
|
size={52}
|
|
avatar={profile?.avatar}
|
|
- // See https://github.com/bluesky-social/social-app/pull/1801:
|
|
usePlainRNImage={true}
|
|
type={profile?.associated?.labeler ? 'labeler' : 'user'}
|
|
live={live}
|
|
@@ -140,9 +129,9 @@ let DrawerProfileCard = ({
|
|
)
|
|
}
|
|
DrawerProfileCard = React.memo(DrawerProfileCard)
|
|
-export {DrawerProfileCard}
|
|
+export { DrawerProfileCard }
|
|
|
|
-let DrawerContent = ({}: React.PropsWithoutRef<{}>): 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 (
|
|
<View
|
|
testID="drawer"
|
|
style={[a.flex_1, a.border_r, t.atoms.bg, t.atoms.border_contrast_low]}>
|
|
<ScrollView
|
|
style={[a.flex_1]}
|
|
- contentContainerStyle={[
|
|
- {
|
|
- paddingTop: Math.max(
|
|
- insets.top + a.pt_xl.paddingTop,
|
|
- a.pt_xl.paddingTop,
|
|
- ),
|
|
- },
|
|
- ]}>
|
|
+ contentContainerStyle={[{ paddingTop: Math.max(insets.top + a.pt_xl.paddingTop, a.pt_xl.paddingTop) }]}>
|
|
<View style={[a.px_xl]}>
|
|
{hasSession && currentAccount ? (
|
|
<DrawerProfileCard
|
|
@@ -284,7 +201,6 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => {
|
|
<NavSignupCard />
|
|
</View>
|
|
)}
|
|
-
|
|
<Divider style={[a.mt_xl, a.mb_sm]} />
|
|
</View>
|
|
|
|
@@ -292,17 +208,10 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => {
|
|
<>
|
|
<SearchMenuItem isActive={isAtSearch} onPress={onPressSearch} />
|
|
<HomeMenuItem isActive={isAtHome} onPress={onPressHome} />
|
|
- <ChatMenuItem isActive={isAtMessages} onPress={onPressMessages} />
|
|
<NotificationsMenuItem
|
|
isActive={isAtNotifications}
|
|
onPress={onPressNotifications}
|
|
/>
|
|
- <FeedsMenuItem isActive={isAtFeeds} onPress={onPressMyFeeds} />
|
|
- <ListsMenuItem onPress={onPressLists} />
|
|
- <BookmarksMenuItem
|
|
- isActive={isAtBookmarks}
|
|
- onPress={onPressBookmarks}
|
|
- />
|
|
<ProfileMenuItem
|
|
isActive={isAtMyProfile}
|
|
onPress={onPressProfile}
|
|
@@ -312,7 +221,6 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => {
|
|
) : (
|
|
<>
|
|
<HomeMenuItem isActive={isAtHome} onPress={onPressHome} />
|
|
- <FeedsMenuItem isActive={isAtFeeds} onPress={onPressMyFeeds} />
|
|
<SearchMenuItem isActive={isAtSearch} onPress={onPressSearch} />
|
|
</>
|
|
)}
|
|
@@ -322,69 +230,11 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => {
|
|
<ExtraLinks />
|
|
</View>
|
|
</ScrollView>
|
|
-
|
|
- <DrawerFooter
|
|
- onPressFeedback={onPressFeedback}
|
|
- onPressHelp={onPressHelp}
|
|
- />
|
|
</View>
|
|
)
|
|
}
|
|
DrawerContent = React.memo(DrawerContent)
|
|
-export {DrawerContent}
|
|
-
|
|
-let DrawerFooter = ({
|
|
- onPressFeedback,
|
|
- onPressHelp,
|
|
-}: {
|
|
- onPressFeedback: () => void
|
|
- onPressHelp: () => void
|
|
-}): React.ReactNode => {
|
|
- const {_} = useLingui()
|
|
- const insets = useSafeAreaInsets()
|
|
- return (
|
|
- <View
|
|
- style={[
|
|
- a.flex_row,
|
|
- a.gap_sm,
|
|
- a.flex_wrap,
|
|
- a.pl_xl,
|
|
- a.pt_md,
|
|
- {
|
|
- paddingBottom: Math.max(
|
|
- insets.bottom + tokens.space.xs,
|
|
- tokens.space.xl,
|
|
- ),
|
|
- },
|
|
- ]}>
|
|
- <Button
|
|
- label={_(msg`Send feedback`)}
|
|
- size="small"
|
|
- variant="solid"
|
|
- color="secondary"
|
|
- onPress={onPressFeedback}>
|
|
- <ButtonIcon icon={Message} position="left" />
|
|
- <ButtonText>
|
|
- <Trans>Feedback</Trans>
|
|
- </ButtonText>
|
|
- </Button>
|
|
- <Button
|
|
- label={_(msg`Get help`)}
|
|
- size="small"
|
|
- variant="outline"
|
|
- color="secondary"
|
|
- onPress={onPressHelp}
|
|
- style={{
|
|
- backgroundColor: 'transparent',
|
|
- }}>
|
|
- <ButtonText>
|
|
- <Trans>Help</Trans>
|
|
- </ButtonText>
|
|
- </Button>
|
|
- </View>
|
|
- )
|
|
-}
|
|
-DrawerFooter = React.memo(DrawerFooter)
|
|
+export { DrawerContent }
|
|
|
|
interface MenuItemProps extends ComponentProps<typeof PressableScale> {
|
|
icon: JSX.Element
|
|
@@ -400,7 +250,7 @@ let SearchMenuItem = ({
|
|
isActive: boolean
|
|
onPress: () => void
|
|
}): React.ReactNode => {
|
|
- const {_} = useLingui()
|
|
+ const { _ } = useLingui()
|
|
const t = useTheme()
|
|
return (
|
|
<MenuItem
|
|
@@ -426,7 +276,7 @@ let HomeMenuItem = ({
|
|
isActive: boolean
|
|
onPress: () => void
|
|
}): React.ReactNode => {
|
|
- const {_} = useLingui()
|
|
+ const { _ } = useLingui()
|
|
const t = useTheme()
|
|
return (
|
|
<MenuItem
|
|
@@ -445,32 +295,6 @@ let HomeMenuItem = ({
|
|
}
|
|
HomeMenuItem = React.memo(HomeMenuItem)
|
|
|
|
-let ChatMenuItem = ({
|
|
- isActive,
|
|
- onPress,
|
|
-}: {
|
|
- isActive: boolean
|
|
- onPress: () => void
|
|
-}): React.ReactNode => {
|
|
- const {_} = useLingui()
|
|
- const t = useTheme()
|
|
- return (
|
|
- <MenuItem
|
|
- icon={
|
|
- isActive ? (
|
|
- <MessageFilled style={[t.atoms.text]} width={iconWidth} />
|
|
- ) : (
|
|
- <Message style={[t.atoms.text]} width={iconWidth} />
|
|
- )
|
|
- }
|
|
- 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 (
|
|
- <MenuItem
|
|
- icon={
|
|
- isActive ? (
|
|
- <HashtagFilled width={iconWidth} style={[t.atoms.text]} />
|
|
- ) : (
|
|
- <Hashtag width={iconWidth} style={[t.atoms.text]} />
|
|
- )
|
|
- }
|
|
- label={_(msg`Feeds`)}
|
|
- bold={isActive}
|
|
- onPress={onPress}
|
|
- />
|
|
- )
|
|
-}
|
|
-FeedsMenuItem = React.memo(FeedsMenuItem)
|
|
-
|
|
-let ListsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => {
|
|
- const {_} = useLingui()
|
|
- const t = useTheme()
|
|
-
|
|
- return (
|
|
- <MenuItem
|
|
- icon={<List style={[t.atoms.text]} width={iconWidth} />}
|
|
- 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 (
|
|
- <MenuItem
|
|
- icon={
|
|
- isActive ? (
|
|
- <BookmarkFilled style={[t.atoms.text]} width={iconWidth} />
|
|
- ) : (
|
|
- <Bookmark style={[t.atoms.text]} width={iconWidth} />
|
|
- )
|
|
- }
|
|
- 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 (
|
|
<MenuItem
|
|
@@ -600,8 +358,8 @@ let ProfileMenuItem = ({
|
|
}
|
|
ProfileMenuItem = React.memo(ProfileMenuItem)
|
|
|
|
-let SettingsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => {
|
|
- const {_} = useLingui()
|
|
+let SettingsMenuItem = ({ onPress }: { onPress: () => void }): React.ReactNode => {
|
|
+ const { _ } = useLingui()
|
|
const t = useTheme()
|
|
return (
|
|
<MenuItem
|
|
@@ -613,7 +371,7 @@ let SettingsMenuItem = ({onPress}: {onPress: () => 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 (
|
|
<Button
|
|
@@ -621,7 +379,7 @@ function MenuItem({icon, label, count, bold, onPress}: MenuItemProps) {
|
|
onPress={onPress}
|
|
accessibilityRole="tab"
|
|
label={label}>
|
|
- {({hovered, pressed}) => (
|
|
+ {({ hovered, pressed }) => (
|
|
<View
|
|
style={[
|
|
a.flex_1,
|
|
@@ -640,7 +398,7 @@ function MenuItem({icon, label, count, bold, onPress}: MenuItemProps) {
|
|
a.absolute,
|
|
a.inset_0,
|
|
a.align_end,
|
|
- {top: -4, right: a.gap_sm.gap * -1},
|
|
+ { top: -4, right: a.gap_sm.gap * -1 },
|
|
]}>
|
|
<View
|
|
style={[
|
|
@@ -686,37 +444,28 @@ function MenuItem({icon, label, count, bold, onPress}: MenuItemProps) {
|
|
}
|
|
|
|
function ExtraLinks() {
|
|
- const {_} = useLingui()
|
|
+ const { _ } = useLingui()
|
|
const t = useTheme()
|
|
const kawaii = useKawaiiMode()
|
|
+ const navigation = useNavigation<NavigationProp>()
|
|
|
|
return (
|
|
<View style={[a.flex_col, a.gap_md, a.flex_wrap]}>
|
|
- <InlineLinkText
|
|
- style={[a.text_md]}
|
|
- label={_(msg`Terms of Service`)}
|
|
- to="https://bsky.social/about/support/tos">
|
|
- <Trans>Terms of Service</Trans>
|
|
- </InlineLinkText>
|
|
- <InlineLinkText
|
|
- style={[a.text_md]}
|
|
- to="https://bsky.social/about/support/privacy-policy"
|
|
- label={_(msg`Privacy Policy`)}>
|
|
- <Trans>Privacy Policy</Trans>
|
|
- </InlineLinkText>
|
|
- {kawaii && (
|
|
- <Text style={t.atoms.text_contrast_medium}>
|
|
- <Trans>
|
|
- Logo by{' '}
|
|
- <InlineLinkText
|
|
- style={[a.text_md]}
|
|
- to="/profile/sawaratsuki.bsky.social"
|
|
- label="@sawaratsuki.bsky.social">
|
|
- @sawaratsuki.bsky.social
|
|
- </InlineLinkText>
|
|
- </Trans>
|
|
+ <TouchableOpacity onPress={() => navigation.navigate('TermsOfService')}>
|
|
+ <Text style={[a.text_md, t.atoms.text_contrast_medium]}>
|
|
+ <Trans>Terms of Service</Trans>
|
|
</Text>
|
|
- )}
|
|
+ </TouchableOpacity>
|
|
+ <TouchableOpacity onPress={() => navigation.navigate('PrivacyPolicy')}>
|
|
+ <Text style={[a.text_md, t.atoms.text_contrast_medium]}>
|
|
+ <Trans>Privacy Policy</Trans>
|
|
+ </Text>
|
|
+ </TouchableOpacity>
|
|
+ <TouchableOpacity onPress={() => navigation.navigate('License')}>
|
|
+ <Text style={[a.text_md, t.atoms.text_contrast_medium]}>
|
|
+ <Trans>License</Trans>
|
|
+ </Text>
|
|
+ </TouchableOpacity>
|
|
</View>
|
|
)
|
|
}
|