diff --git a/src/components/dialogs/BirthDateSettings.tsx b/src/components/dialogs/BirthDateSettings.tsx index 9915d0a2d..4ae51215d 100644 --- a/src/components/dialogs/BirthDateSettings.tsx +++ b/src/components/dialogs/BirthDateSettings.tsx @@ -163,7 +163,7 @@ function BirthdayInner({ You must be at least 13 years old to use Bluesky. Read our{' '} Terms of Service {' '} diff --git a/src/components/dialogs/ServerInput.tsx b/src/components/dialogs/ServerInput.tsx index d7c02bb9f..fda1dfe4a 100644 --- a/src/components/dialogs/ServerInput.tsx +++ b/src/components/dialogs/ServerInput.tsx @@ -165,7 +165,7 @@ function DialogInner({ Bluesky is an open network where you can choose your own provider. If you're new here, we recommend sticking with the - default Bluesky Social option. + default syu.is option. diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index ed2a6cfb7..1dc7f9227 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 (