diff --git a/ios/patching/005-social-app-ios-screens.patch b/ios/patching/005-social-app-ios-screens.patch index cd535a0..492e263 100644 --- a/ios/patching/005-social-app-ios-screens.patch +++ b/ios/patching/005-social-app-ios-screens.patch @@ -39,7 +39,7 @@ index 77f219e55..53f5e0cc0 100644 . You have been sent an email outlining the specific violation and suspension period, if applicable. You can appeal this diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx -index e058e2883..7a355cf6c 100644 +index e058e2883..8daf41089 100644 --- a/src/view/screens/Home.tsx +++ b/src/view/screens/Home.tsx @@ -1,23 +1,16 @@ @@ -81,7 +81,7 @@ index e058e2883..7a355cf6c 100644 import {CustomFeedEmptyState} from '#/view/com/posts/CustomFeedEmptyState' import {FollowingEmptyState} from '#/view/com/posts/FollowingEmptyState' import {FollowingEndOfFeed} from '#/view/com/posts/FollowingEndOfFeed' -@@ -39,97 +28,87 @@ import {NoFeedsPinned} from '#/screens/Home/NoFeedsPinned' +@@ -39,97 +28,90 @@ import {NoFeedsPinned} from '#/screens/Home/NoFeedsPinned' import * as Layout from '#/components/Layout' import {useDemoMode} from '#/storage/hooks/demo-mode' @@ -129,9 +129,12 @@ index e058e2883..7a355cf6c 100644 + const {data: pinnedFeedInfos} = usePinnedFeedsInfos() + + const safePreferences = preferences || { feedViewPrefs: { lab_mergeFeedEnabled: false }, savedFeeds: [] } as any ++ // Use user's pinned feeds when logged in and available, otherwise use defaults + const safePinnedFeedInfos = !currentAccount + ? DEFAULT_PINNED_FEEDS.filter(f => f.feedDescriptor !== 'following') -+ : DEFAULT_PINNED_FEEDS ++ : (pinnedFeedInfos && pinnedFeedInfos.length > 0) ++ ? pinnedFeedInfos ++ : DEFAULT_PINNED_FEEDS React.useEffect(() => { if (isWeb && !currentAccount) { @@ -233,7 +236,7 @@ index e058e2883..7a355cf6c 100644 if (selectedIndex !== lastPagerReportedIndexRef.current) { lastPagerReportedIndexRef.current = selectedIndex pagerRef.current?.setPage(selectedIndex) -@@ -138,205 +117,43 @@ function HomeScreenReady({ +@@ -138,205 +120,43 @@ function HomeScreenReady({ const {hasSession} = useSession() const setMinimalShellMode = useSetMinimalShellMode() diff --git a/ios/patching/005-social-app-ios-screens.patch.new b/ios/patching/005-social-app-ios-screens.patch.new new file mode 100644 index 0000000..2b92cca --- /dev/null +++ b/ios/patching/005-social-app-ios-screens.patch.new @@ -0,0 +1,431 @@ +diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx +index e058e2883..8daf41089 100644 +--- a/src/view/screens/Home.tsx ++++ b/src/view/screens/Home.tsx +@@ -1,23 +1,16 @@ + import React from 'react' + import {ActivityIndicator, StyleSheet} from 'react-native' + import {useFocusEffect} from '@react-navigation/native' +- + import {PROD_DEFAULT_FEED} from '#/lib/constants' + import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' + import {useOTAUpdates} from '#/lib/hooks/useOTAUpdates' + import {useSetTitle} from '#/lib/hooks/useSetTitle' + import {useRequestNotificationsPermission} from '#/lib/notifications/notifications' +-import { +- type HomeTabNavigatorParams, +- type NativeStackScreenProps, +-} from '#/lib/routes/types' ++import {type HomeTabNavigatorParams, type NativeStackScreenProps} from '#/lib/routes/types' + import {logEvent} from '#/lib/statsig/statsig' + import {isWeb} from '#/platform/detection' + import {emitSoftReset} from '#/state/events' +-import { +- type SavedFeedSourceInfo, +- usePinnedFeedsInfos, +-} from '#/state/queries/feed' ++import {type SavedFeedSourceInfo, usePinnedFeedsInfos} from '#/state/queries/feed' + import {type FeedDescriptor, type FeedParams} from '#/state/queries/post-feed' + import {usePreferencesQuery} from '#/state/queries/preferences' + import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types' +@@ -27,11 +20,7 @@ import {useLoggedOutViewControls} from '#/state/shell/logged-out' + import {useSelectedFeed, useSetSelectedFeed} from '#/state/shell/selected-feed' + import {FeedPage} from '#/view/com/feeds/FeedPage' + import {HomeHeader} from '#/view/com/home/HomeHeader' +-import { +- Pager, +- type PagerRef, +- type RenderTabBarFnProps, +-} from '#/view/com/pager/Pager' ++import {Pager, type PagerRef, type RenderTabBarFnProps} from '#/view/com/pager/Pager' + import {CustomFeedEmptyState} from '#/view/com/posts/CustomFeedEmptyState' + import {FollowingEmptyState} from '#/view/com/posts/FollowingEmptyState' + import {FollowingEndOfFeed} from '#/view/com/posts/FollowingEndOfFeed' +@@ -39,97 +28,90 @@ import {NoFeedsPinned} from '#/screens/Home/NoFeedsPinned' + import * as Layout from '#/components/Layout' + import {useDemoMode} from '#/storage/hooks/demo-mode' + ++const SYU_IS_FEED_URI = 'at://did:plc:6qyecktefllvenje24fcxnie/app.bsky.feed.generator/app' ++ ++const DEFAULT_PINNED_FEEDS: any[] = [{ ++ feedDescriptor: 'following', ++ displayName: 'Following', ++ id: 'following', ++ uri: 'following', ++ type: 'feed', ++ savedFeed: undefined, ++ pinned: true, ++ route: { href: '/', name: 'Home', params: {} }, ++ cid: '', ++ avatar: '', ++ creatorDid: '', ++ creatorHandle: '', ++}, { ++ feedDescriptor: `feedgen|${SYU_IS_FEED_URI}`, ++ displayName: 'Feeds', ++ id: SYU_IS_FEED_URI, ++ uri: SYU_IS_FEED_URI, ++ type: 'feed', ++ savedFeed: { ++ type: 'feed', ++ value: SYU_IS_FEED_URI, ++ pinned: true, ++ }, ++ pinned: true, ++ route: { href: '/', name: 'Home', params: {} }, ++ cid: '', ++ avatar: '', ++ creatorDid: '', ++ creatorHandle: '', ++}] ++ + type Props = NativeStackScreenProps + export function HomeScreen(props: Props) { + const {setShowLoggedOut} = useLoggedOutViewControls() + const {data: preferences} = usePreferencesQuery() + const {currentAccount} = useSession() +- const {data: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} = +- usePinnedFeedsInfos() ++ const {data: pinnedFeedInfos} = usePinnedFeedsInfos() ++ ++ const safePreferences = preferences || { feedViewPrefs: { lab_mergeFeedEnabled: false }, savedFeeds: [] } as any ++ // Use user's pinned feeds when logged in and available, otherwise use defaults ++ const safePinnedFeedInfos = !currentAccount ++ ? DEFAULT_PINNED_FEEDS.filter(f => f.feedDescriptor !== 'following') ++ : (pinnedFeedInfos && pinnedFeedInfos.length > 0) ++ ? pinnedFeedInfos ++ : DEFAULT_PINNED_FEEDS + + React.useEffect(() => { + if (isWeb && !currentAccount) { + const getParams = new URLSearchParams(window.location.search) + const splash = getParams.get('splash') +- if (splash === 'true') { +- setShowLoggedOut(true) +- return +- } ++ if (splash === 'true') { setShowLoggedOut(true); return } + } +- + const params = props.route.params +- if ( +- currentAccount && +- props.route.name === 'Start' && +- params?.name && +- params?.rkey +- ) { +- props.navigation.navigate('StarterPack', { +- rkey: params.rkey, +- name: params.name, +- }) ++ if (currentAccount && props.route.name === 'Start' && params?.name && params?.rkey) { ++ props.navigation.navigate('StarterPack', { rkey: params.rkey, name: params.name }) + } +- }, [ +- currentAccount, +- props.navigation, +- props.route.name, +- props.route.params, +- setShowLoggedOut, +- ]) ++ }, [currentAccount, props.navigation, props.route.name, props.route.params, setShowLoggedOut]) + +- if (preferences && pinnedFeedInfos && !isPinnedFeedsLoading) { +- return ( +- +- +- +- ) +- } else { +- return ( +- +- +- +- +- +- ) +- } ++ return ( ++ ++ ++ ++ ) + } + +-function HomeScreenReady({ +- preferences, +- pinnedFeedInfos, +-}: Props & { +- preferences: UsePreferencesQueryResponse +- pinnedFeedInfos: SavedFeedSourceInfo[] +-}) { +- const allFeeds = React.useMemo( +- () => pinnedFeedInfos.map(f => f.feedDescriptor), +- [pinnedFeedInfos], +- ) +- const maybeRawSelectedFeed: FeedDescriptor | undefined = +- useSelectedFeed() ?? allFeeds[0] ++function HomeScreenReady({preferences, pinnedFeedInfos}: any) { ++ const allFeeds = React.useMemo(() => pinnedFeedInfos.map(f => f.feedDescriptor), [pinnedFeedInfos]) ++ const maybeRawSelectedFeed = useSelectedFeed() ?? allFeeds[0] + const setSelectedFeed = useSetSelectedFeed() + const maybeFoundIndex = allFeeds.indexOf(maybeRawSelectedFeed) + const selectedIndex = Math.max(0, maybeFoundIndex) +- const maybeSelectedFeed: FeedDescriptor | undefined = allFeeds[selectedIndex] ++ const maybeSelectedFeed = allFeeds[selectedIndex] + const requestNotificationsPermission = useRequestNotificationsPermission() + + useSetTitle(pinnedFeedInfos[selectedIndex]?.displayName) + useOTAUpdates() +- +- React.useEffect(() => { +- requestNotificationsPermission('Home') +- }, [requestNotificationsPermission]) ++ React.useEffect(() => { requestNotificationsPermission('Home') }, [requestNotificationsPermission]) + + const pagerRef = React.useRef(null) + const lastPagerReportedIndexRef = React.useRef(selectedIndex) + React.useLayoutEffect(() => { +- // Since the pager is not a controlled component, adjust it imperatively +- // if the selected index gets out of sync with what it last reported. +- // This is supposed to only happen on the web when you use the right nav. + if (selectedIndex !== lastPagerReportedIndexRef.current) { + lastPagerReportedIndexRef.current = selectedIndex + pagerRef.current?.setPage(selectedIndex) +@@ -138,205 +120,43 @@ function HomeScreenReady({ + + const {hasSession} = useSession() + const setMinimalShellMode = useSetMinimalShellMode() +- useFocusEffect( +- React.useCallback(() => { +- setMinimalShellMode(false) +- }, [setMinimalShellMode]), +- ) ++ useFocusEffect(React.useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode])) + +- useFocusEffect( +- useNonReactiveCallback(() => { +- if (maybeSelectedFeed) { +- logEvent('home:feedDisplayed', { +- index: selectedIndex, +- feedType: maybeSelectedFeed.split('|')[0], +- feedUrl: maybeSelectedFeed, +- reason: 'focus', +- }) +- } +- }), +- ) +- +- const onPageSelected = React.useCallback( +- (index: number) => { +- setMinimalShellMode(false) +- const maybeFeed = allFeeds[index] ++ const onPageSelected = React.useCallback((index) => { ++ setMinimalShellMode(false) ++ const maybeFeed = allFeeds[index] ++ lastPagerReportedIndexRef.current = index ++ setSelectedFeed(maybeFeed) ++ }, [setSelectedFeed, setMinimalShellMode, allFeeds]) + +- // Mutate the ref before setting state to avoid the imperative syncing effect +- // above from starting a loop on Android when swiping back and forth. +- lastPagerReportedIndexRef.current = index +- setSelectedFeed(maybeFeed) +- +- if (maybeFeed) { +- logEvent('home:feedDisplayed', { +- index, +- feedType: maybeFeed.split('|')[0], +- feedUrl: maybeFeed, +- }) +- } +- }, +- [setSelectedFeed, setMinimalShellMode, allFeeds], +- ) +- +- const onPressSelected = React.useCallback(() => { +- emitSoftReset() +- }, []) +- +- const onPageScrollStateChanged = React.useCallback( +- (state: 'idle' | 'dragging' | 'settling') => { +- 'worklet' +- if (state === 'dragging') { +- setMinimalShellMode(false) +- } +- }, +- [setMinimalShellMode], +- ) ++ const onPressSelected = React.useCallback(() => { emitSoftReset() }, []) ++ const onPageScrollStateChanged = React.useCallback((state) => { ++ 'worklet' ++ if (state === 'dragging') setMinimalShellMode(false) ++ }, [setMinimalShellMode]) + + const [demoMode] = useDemoMode() ++ const renderTabBar = React.useCallback((props) => { ++ return ++ }, [onPressSelected, pinnedFeedInfos]) + +- const renderTabBar = React.useCallback( +- (props: RenderTabBarFnProps) => { +- if (demoMode) { +- return ( +- +- ) +- } +- return ( +- +- ) +- }, +- [onPressSelected, pinnedFeedInfos, demoMode], +- ) +- +- const renderFollowingEmptyState = React.useCallback(() => { +- return +- }, []) ++ const renderFollowingEmptyState = React.useCallback(() => , []) ++ const renderCustomFeedEmptyState = React.useCallback(() => , []) + +- const renderCustomFeedEmptyState = React.useCallback(() => { +- return +- }, []) ++ const homeFeedParams = React.useMemo(() => ({ ++ mergeFeedEnabled: false, mergeFeedSources: [] ++ }), [preferences]) + +- const homeFeedParams = React.useMemo(() => { +- return { +- mergeFeedEnabled: Boolean(preferences.feedViewPrefs.lab_mergeFeedEnabled), +- mergeFeedSources: preferences.feedViewPrefs.lab_mergeFeedEnabled +- ? preferences.savedFeeds +- .filter(f => f.type === 'feed' || f.type === 'list') +- .map(f => f.value) +- : [], +- } +- }, [preferences]) +- +- if (demoMode) { +- return ( +- +- +- +- +- ) +- } +- +- return hasSession ? ( +- +- {pinnedFeedInfos.length ? ( +- pinnedFeedInfos.map((feedInfo, index) => { ++ return ( ++ ++ {pinnedFeedInfos.map((feedInfo, index) => { + const feed = feedInfo.feedDescriptor + if (feed === 'following') { +- return ( +- +- ) ++ return + } +- const savedFeedConfig = feedInfo.savedFeed +- return ( +- +- ) +- }) +- ) : ( +- +- )} +- +- ) : ( +- +- ++ return ++ })} + + ) + } +- +-const styles = StyleSheet.create({ +- loading: { +- height: '100%', +- alignContent: 'center', +- justifyContent: 'center', +- paddingBottom: 100, +- }, +-}) ++const styles = StyleSheet.create({ loading: { height: '100%', alignContent: 'center', justifyContent: 'center', paddingBottom: 100 } }) diff --git a/ios/patching/006-social-app-ios-shell.patch b/ios/patching/006-social-app-ios-shell.patch index d2154d2..fefb57d 100644 --- a/ios/patching/006-social-app-ios-shell.patch +++ b/ios/patching/006-social-app-ios-shell.patch @@ -1,8 +1,8 @@ diff --git a/src/components/dialogs/BirthDateSettings.tsx b/src/components/dialogs/BirthDateSettings.tsx -index 9915d0a2d..4ae51215d 100644 +index c5205bf71..3fccb9dfd 100644 --- a/src/components/dialogs/BirthDateSettings.tsx +++ b/src/components/dialogs/BirthDateSettings.tsx -@@ -163,7 +163,7 @@ function BirthdayInner({ +@@ -165,7 +165,7 @@ function BirthdayInner({ You must be at least 13 years old to use Bluesky. Read our{' '} {' '} diff --git a/src/components/dialogs/ServerInput.tsx b/src/components/dialogs/ServerInput.tsx -index d7c02bb9f..fda1dfe4a 100644 +index d7c02bb9f..99b98781f 100644 --- a/src/components/dialogs/ServerInput.tsx +++ b/src/components/dialogs/ServerInput.tsx +@@ -144,9 +144,9 @@ function DialogInner({ + ++ label={_(msg`syu.is`)}> + +- {_(msg`Bluesky`)} ++ {_(msg`syu.is`)} + + + Bluesky is an open network where you can choose your own @@ -25,676 +37,24 @@ index d7c02bb9f..fda1dfe4a 100644 diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx -index ed2a6cfb7..1dc7f9227 100644 +index f76147ccf..96a2ac337 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 ( -