Some brand, some pwi (#2212)

* Add logo to left nav in logged out

* Protect last routes

* Hide links in left nav, hide nav

* Replace bottom bar for pwi

* Remove same links from drawer

* Hide reply prompt

* Allow search
zio/stable
Eric Bailey 2023-12-14 17:46:27 -06:00 committed by GitHub
parent 7897dd24a1
commit 1111108efe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 297 additions and 155 deletions

View File

@ -292,7 +292,11 @@ function HomeTabNavigator() {
animationDuration: 250, animationDuration: 250,
contentStyle, contentStyle,
}}> }}>
<HomeTab.Screen name="Home" getComponent={() => HomeScreen} /> <HomeTab.Screen
name="Home"
getComponent={() => HomeScreen}
options={{requireAuth: true}}
/>
{commonScreens(HomeTab)} {commonScreens(HomeTab)}
</HomeTab.Navigator> </HomeTab.Navigator>
) )
@ -402,7 +406,7 @@ const FlatNavigator = () => {
<Flat.Screen <Flat.Screen
name="Home" name="Home"
getComponent={() => HomeScreen} getComponent={() => HomeScreen}
options={{title: title('Home')}} options={{title: title('Home'), requireAuth: true}}
/> />
<Flat.Screen <Flat.Screen
name="Search" name="Search"
@ -412,7 +416,7 @@ const FlatNavigator = () => {
<Flat.Screen <Flat.Screen
name="Feeds" name="Feeds"
getComponent={() => FeedsScreen} getComponent={() => FeedsScreen}
options={{title: title('Feeds')}} options={{title: title('Feeds'), requireAuth: true}}
/> />
<Flat.Screen <Flat.Screen
name="Notifications" name="Notifications"

View File

@ -24,11 +24,13 @@ import {useResolveUriQuery} from '#/state/queries/resolve-uri'
import {ErrorMessage} from '../com/util/error/ErrorMessage' import {ErrorMessage} from '../com/util/error/ErrorMessage'
import {CenteredView} from '../com/util/Views' import {CenteredView} from '../com/util/Views'
import {useComposerControls} from '#/state/shell/composer' import {useComposerControls} from '#/state/shell/composer'
import {useSession} from '#/state/session'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostThread'> type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostThread'>
export function PostThreadScreen({route}: Props) { export function PostThreadScreen({route}: Props) {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const {_} = useLingui() const {_} = useLingui()
const {hasSession} = useSession()
const {fabMinimalShellTransform} = useMinimalShellMode() const {fabMinimalShellTransform} = useMinimalShellMode()
const setMinimalShellMode = useSetMinimalShellMode() const setMinimalShellMode = useSetMinimalShellMode()
const {openComposer} = useComposerControls() const {openComposer} = useComposerControls()
@ -89,7 +91,7 @@ export function PostThreadScreen({route}: Props) {
/> />
)} )}
</View> </View>
{isMobile && canReply && ( {isMobile && canReply && hasSession && (
<Animated.View <Animated.View
style={[ style={[
styles.prompt, styles.prompt,

View File

@ -221,18 +221,16 @@ let DrawerContent = ({}: {}): React.ReactNode => {
<NavSignupCard /> <NavSignupCard />
)} )}
{hasSession && <InviteCodes />} {hasSession ? (
{hasSession && <View style={{height: 10}} />}
<SearchMenuItem isActive={isAtSearch} onPress={onPressSearch} />
<HomeMenuItem isActive={isAtHome} onPress={onPressHome} />
{hasSession && (
<NotificationsMenuItem
isActive={isAtNotifications}
onPress={onPressNotifications}
/>
)}
{hasSession && (
<> <>
<InviteCodes />
<View style={{height: 10}} />
<SearchMenuItem isActive={isAtSearch} onPress={onPressSearch} />
<HomeMenuItem isActive={isAtHome} onPress={onPressHome} />
<NotificationsMenuItem
isActive={isAtNotifications}
onPress={onPressNotifications}
/>
<FeedsMenuItem isActive={isAtFeeds} onPress={onPressMyFeeds} /> <FeedsMenuItem isActive={isAtFeeds} onPress={onPressMyFeeds} />
<ListsMenuItem onPress={onPressLists} /> <ListsMenuItem onPress={onPressLists} />
<ModerationMenuItem onPress={onPressModeration} /> <ModerationMenuItem onPress={onPressModeration} />
@ -242,6 +240,8 @@ let DrawerContent = ({}: {}): React.ReactNode => {
/> />
<SettingsMenuItem onPress={onPressSettings} /> <SettingsMenuItem onPress={onPressSettings} />
</> </>
) : (
<SearchMenuItem isActive={isAtSearch} onPress={onPressSearch} />
)} )}
<View style={styles.smallSpacer} /> <View style={styles.smallSpacer} />

View File

@ -5,11 +5,11 @@ import {useLingui} from '@lingui/react'
import {s} from 'lib/styles' import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {DefaultAvatar} from '#/view/com/util/UserAvatar'
import {Text} from '#/view/com/util/text/Text' import {Text} from '#/view/com/util/text/Text'
import {Button} from '#/view/com/util/forms/Button' import {Button} from '#/view/com/util/forms/Button'
import {useLoggedOutViewControls} from '#/state/shell/logged-out' import {useLoggedOutViewControls} from '#/state/shell/logged-out'
import {useCloseAllActiveElements} from '#/state/util' import {useCloseAllActiveElements} from '#/state/util'
import {Logo} from '#/view/icons/Logo'
let NavSignupCard = ({}: {}): React.ReactNode => { let NavSignupCard = ({}: {}): React.ReactNode => {
const {_} = useLingui() const {_} = useLingui()
@ -35,10 +35,10 @@ let NavSignupCard = ({}: {}): React.ReactNode => {
paddingTop: 6, paddingTop: 6,
marginBottom: 24, marginBottom: 24,
}}> }}>
<DefaultAvatar type="user" size={48} /> <Logo width={48} />
<View style={{paddingTop: 12}}> <View style={{paddingTop: 18}}>
<Text type="md" style={[pal.text, s.bold]}> <Text type="md-bold" style={[pal.text]}>
<Trans>Sign up or sign in to join the conversation</Trans> <Trans>Sign up or sign in to join the conversation</Trans>
</Text> </Text>
</View> </View>

View File

@ -23,13 +23,19 @@ import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
import {useNavigationTabState} from 'lib/hooks/useNavigationTabState' import {useNavigationTabState} from 'lib/hooks/useNavigationTabState'
import {UserAvatar} from 'view/com/util/UserAvatar' import {UserAvatar} from 'view/com/util/UserAvatar'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {msg} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useModalControls} from '#/state/modals' import {useModalControls} from '#/state/modals'
import {useShellLayout} from '#/state/shell/shell-layout' import {useShellLayout} from '#/state/shell/shell-layout'
import {useUnreadNotifications} from '#/state/queries/notifications/unread' import {useUnreadNotifications} from '#/state/queries/notifications/unread'
import {emitSoftReset} from '#/state/events' import {emitSoftReset} from '#/state/events'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {useProfileQuery} from '#/state/queries/profile' import {useProfileQuery} from '#/state/queries/profile'
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
import {useCloseAllActiveElements} from '#/state/util'
import {Button} from '#/view/com/util/forms/Button'
import {s} from 'lib/styles'
import {Logo} from '#/view/icons/Logo'
import {Logotype} from '#/view/icons/Logotype'
type TabOptions = 'Home' | 'Search' | 'Notifications' | 'MyProfile' | 'Feeds' type TabOptions = 'Home' | 'Search' | 'Notifications' | 'MyProfile' | 'Feeds'
@ -46,6 +52,19 @@ export function BottomBar({navigation}: BottomTabBarProps) {
const numUnreadNotifications = useUnreadNotifications() const numUnreadNotifications = useUnreadNotifications()
const {footerMinimalShellTransform} = useMinimalShellMode() const {footerMinimalShellTransform} = useMinimalShellMode()
const {data: profile} = useProfileQuery({did: currentAccount?.did}) const {data: profile} = useProfileQuery({did: currentAccount?.did})
const {requestSwitchToAccount} = useLoggedOutViewControls()
const closeAllActiveElements = useCloseAllActiveElements()
const showSignIn = React.useCallback(() => {
closeAllActiveElements()
requestSwitchToAccount({requestedAccount: 'none'})
}, [requestSwitchToAccount, closeAllActiveElements])
const showCreateAccount = React.useCallback(() => {
closeAllActiveElements()
requestSwitchToAccount({requestedAccount: 'new'})
// setShowLoggedOut(true)
}, [requestSwitchToAccount, closeAllActiveElements])
const onPressTab = React.useCallback( const onPressTab = React.useCallback(
(tab: TabOptions) => { (tab: TabOptions) => {
@ -94,53 +113,52 @@ export function BottomBar({navigation}: BottomTabBarProps) {
onLayout={e => { onLayout={e => {
footerHeight.value = e.nativeEvent.layout.height footerHeight.value = e.nativeEvent.layout.height
}}> }}>
<Btn {hasSession ? (
testID="bottomBarHomeBtn"
icon={
isAtHome ? (
<HomeIconSolid
strokeWidth={4}
size={24}
style={[styles.ctrlIcon, pal.text, styles.homeIcon]}
/>
) : (
<HomeIcon
strokeWidth={4}
size={24}
style={[styles.ctrlIcon, pal.text, styles.homeIcon]}
/>
)
}
onPress={onPressHome}
accessibilityRole="tab"
accessibilityLabel={_(msg`Home`)}
accessibilityHint=""
/>
<Btn
testID="bottomBarSearchBtn"
icon={
isAtSearch ? (
<MagnifyingGlassIcon2Solid
size={25}
style={[styles.ctrlIcon, pal.text, styles.searchIcon]}
strokeWidth={1.8}
/>
) : (
<MagnifyingGlassIcon2
size={25}
style={[styles.ctrlIcon, pal.text, styles.searchIcon]}
strokeWidth={1.8}
/>
)
}
onPress={onPressSearch}
accessibilityRole="search"
accessibilityLabel={_(msg`Search`)}
accessibilityHint=""
/>
{hasSession && (
<> <>
<Btn
testID="bottomBarHomeBtn"
icon={
isAtHome ? (
<HomeIconSolid
strokeWidth={4}
size={24}
style={[styles.ctrlIcon, pal.text, styles.homeIcon]}
/>
) : (
<HomeIcon
strokeWidth={4}
size={24}
style={[styles.ctrlIcon, pal.text, styles.homeIcon]}
/>
)
}
onPress={onPressHome}
accessibilityRole="tab"
accessibilityLabel={_(msg`Home`)}
accessibilityHint=""
/>
<Btn
testID="bottomBarSearchBtn"
icon={
isAtSearch ? (
<MagnifyingGlassIcon2Solid
size={25}
style={[styles.ctrlIcon, pal.text, styles.searchIcon]}
strokeWidth={1.8}
/>
) : (
<MagnifyingGlassIcon2
size={25}
style={[styles.ctrlIcon, pal.text, styles.searchIcon]}
strokeWidth={1.8}
/>
)
}
onPress={onPressSearch}
accessibilityRole="search"
accessibilityLabel={_(msg`Search`)}
accessibilityHint=""
/>
<Btn <Btn
testID="bottomBarFeedsBtn" testID="bottomBarFeedsBtn"
icon={ icon={
@ -230,6 +248,49 @@ export function BottomBar({navigation}: BottomTabBarProps) {
accessibilityHint="" accessibilityHint=""
/> />
</> </>
) : (
<>
<View
style={{
width: '100%',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingTop: 14,
paddingBottom: 2,
paddingLeft: 14,
paddingRight: 6,
gap: 8,
}}>
<View style={{flexDirection: 'row', alignItems: 'center', gap: 8}}>
<Logo width={28} />
<View style={{paddingTop: 4}}>
<Logotype width={80} />
</View>
</View>
<View style={{flexDirection: 'row', alignItems: 'center', gap: 4}}>
<Button
onPress={showCreateAccount}
accessibilityHint={_(msg`Sign up`)}
accessibilityLabel={_(msg`Sign up`)}>
<Text type="md" style={[{color: 'white'}, s.bold]}>
<Trans>Sign up</Trans>
</Text>
</Button>
<Button
type="default"
onPress={showSignIn}
accessibilityHint={_(msg`Sign in`)}
accessibilityLabel={_(msg`Sign in`)}>
<Text type="md" style={[pal.text, s.bold]}>
<Trans>Sign in</Trans>
</Text>
</Button>
</View>
</View>
</>
)} )}
</Animated.View> </Animated.View>
) )

View File

@ -3,6 +3,9 @@ import {usePalette} from 'lib/hooks/usePalette'
import {useNavigationState} from '@react-navigation/native' import {useNavigationState} from '@react-navigation/native'
import Animated from 'react-native-reanimated' import Animated from 'react-native-reanimated'
import {useSafeAreaInsets} from 'react-native-safe-area-context' import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {getCurrentRoute, isTab} from 'lib/routes/helpers' import {getCurrentRoute, isTab} from 'lib/routes/helpers'
import {styles} from './BottomBarStyles' import {styles} from './BottomBarStyles'
import {clamp} from 'lib/numbers' import {clamp} from 'lib/numbers'
@ -22,12 +25,33 @@ import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
import {makeProfileLink} from 'lib/routes/links' import {makeProfileLink} from 'lib/routes/links'
import {CommonNavigatorParams} from 'lib/routes/types' import {CommonNavigatorParams} from 'lib/routes/types'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
import {useCloseAllActiveElements} from '#/state/util'
import {Button} from '#/view/com/util/forms/Button'
import {Text} from '#/view/com/util/text/Text'
import {s} from 'lib/styles'
import {Logo} from '#/view/icons/Logo'
import {Logotype} from '#/view/icons/Logotype'
export function BottomBarWeb() { export function BottomBarWeb() {
const {_} = useLingui()
const {hasSession, currentAccount} = useSession() const {hasSession, currentAccount} = useSession()
const pal = usePalette('default') const pal = usePalette('default')
const safeAreaInsets = useSafeAreaInsets() const safeAreaInsets = useSafeAreaInsets()
const {footerMinimalShellTransform} = useMinimalShellMode() const {footerMinimalShellTransform} = useMinimalShellMode()
const {requestSwitchToAccount} = useLoggedOutViewControls()
const closeAllActiveElements = useCloseAllActiveElements()
const showSignIn = React.useCallback(() => {
closeAllActiveElements()
requestSwitchToAccount({requestedAccount: 'none'})
}, [requestSwitchToAccount, closeAllActiveElements])
const showCreateAccount = React.useCallback(() => {
closeAllActiveElements()
requestSwitchToAccount({requestedAccount: 'new'})
// setShowLoggedOut(true)
}, [requestSwitchToAccount, closeAllActiveElements])
return ( return (
<Animated.View <Animated.View
@ -38,79 +62,126 @@ export function BottomBarWeb() {
{paddingBottom: clamp(safeAreaInsets.bottom, 15, 30)}, {paddingBottom: clamp(safeAreaInsets.bottom, 15, 30)},
footerMinimalShellTransform, footerMinimalShellTransform,
]}> ]}>
<NavItem routeName="Home" href="/"> {hasSession ? (
{({isActive}) => {
const Icon = isActive ? HomeIconSolid : HomeIcon
return (
<Icon
strokeWidth={4}
size={24}
style={[styles.ctrlIcon, pal.text, styles.homeIcon]}
/>
)
}}
</NavItem>
<NavItem routeName="Search" href="/search">
{({isActive}) => {
const Icon = isActive
? MagnifyingGlassIcon2Solid
: MagnifyingGlassIcon2
return (
<Icon
size={25}
style={[styles.ctrlIcon, pal.text, styles.searchIcon]}
strokeWidth={1.8}
/>
)
}}
</NavItem>
{hasSession && (
<> <>
<NavItem routeName="Feeds" href="/feeds"> <NavItem routeName="Home" href="/">
{({isActive}) => { {({isActive}) => {
return ( const Icon = isActive ? HomeIconSolid : HomeIcon
<HashtagIcon
size={22}
style={[styles.ctrlIcon, pal.text, styles.feedsIcon]}
strokeWidth={isActive ? 4 : 2.5}
/>
)
}}
</NavItem>
<NavItem routeName="Notifications" href="/notifications">
{({isActive}) => {
const Icon = isActive ? BellIconSolid : BellIcon
return ( return (
<Icon <Icon
strokeWidth={4}
size={24} size={24}
strokeWidth={1.9} style={[styles.ctrlIcon, pal.text, styles.homeIcon]}
style={[styles.ctrlIcon, pal.text, styles.bellIcon]}
/> />
) )
}} }}
</NavItem> </NavItem>
<NavItem <NavItem routeName="Search" href="/search">
routeName="Profile"
href={
currentAccount
? makeProfileLink({
did: currentAccount.did,
handle: currentAccount.handle,
})
: '/'
}>
{({isActive}) => { {({isActive}) => {
const Icon = isActive ? UserIconSolid : UserIcon const Icon = isActive
? MagnifyingGlassIcon2Solid
: MagnifyingGlassIcon2
return ( return (
<Icon <Icon
size={28} size={25}
strokeWidth={1.5} style={[styles.ctrlIcon, pal.text, styles.searchIcon]}
style={[styles.ctrlIcon, pal.text, styles.profileIcon]} strokeWidth={1.8}
/> />
) )
}} }}
</NavItem> </NavItem>
{hasSession && (
<>
<NavItem routeName="Feeds" href="/feeds">
{({isActive}) => {
return (
<HashtagIcon
size={22}
style={[styles.ctrlIcon, pal.text, styles.feedsIcon]}
strokeWidth={isActive ? 4 : 2.5}
/>
)
}}
</NavItem>
<NavItem routeName="Notifications" href="/notifications">
{({isActive}) => {
const Icon = isActive ? BellIconSolid : BellIcon
return (
<Icon
size={24}
strokeWidth={1.9}
style={[styles.ctrlIcon, pal.text, styles.bellIcon]}
/>
)
}}
</NavItem>
<NavItem
routeName="Profile"
href={
currentAccount
? makeProfileLink({
did: currentAccount.did,
handle: currentAccount.handle,
})
: '/'
}>
{({isActive}) => {
const Icon = isActive ? UserIconSolid : UserIcon
return (
<Icon
size={28}
strokeWidth={1.5}
style={[styles.ctrlIcon, pal.text, styles.profileIcon]}
/>
)
}}
</NavItem>
</>
)}
</>
) : (
<>
<View
style={{
width: '100%',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingTop: 14,
paddingBottom: 2,
paddingLeft: 14,
paddingRight: 6,
gap: 8,
}}>
<View style={{flexDirection: 'row', alignItems: 'center', gap: 12}}>
<Logo width={32} />
<View style={{paddingTop: 4}}>
<Logotype width={80} />
</View>
</View>
<View style={{flexDirection: 'row', alignItems: 'center', gap: 8}}>
<Button
onPress={showCreateAccount}
accessibilityHint={_(msg`Sign up`)}
accessibilityLabel={_(msg`Sign up`)}>
<Text type="md" style={[{color: 'white'}, s.bold]}>
<Trans>Sign up</Trans>
</Text>
</Button>
<Button
type="default"
onPress={showSignIn}
accessibilityHint={_(msg`Sign in`)}
accessibilityLabel={_(msg`Sign in`)}>
<Text type="md" style={[pal.text, s.bold]}>
<Trans>Sign in</Trans>
</Text>
</Button>
</View>
</View>
</> </>
)} )}
</Animated.View> </Animated.View>

View File

@ -266,6 +266,10 @@ export function DesktopLeftNav() {
const {isDesktop, isTablet} = useWebMediaQueries() const {isDesktop, isTablet} = useWebMediaQueries()
const numUnread = useUnreadNotifications() const numUnread = useUnreadNotifications()
if (!hasSession && !isDesktop) {
return null
}
return ( return (
<View <View
style={[ style={[
@ -282,40 +286,40 @@ export function DesktopLeftNav() {
</View> </View>
) : null} ) : null}
<BackBtn />
<NavItem
href="/"
icon={<HomeIcon size={isDesktop ? 24 : 28} style={pal.text} />}
iconFilled={
<HomeIconSolid
strokeWidth={4}
size={isDesktop ? 24 : 28}
style={pal.text}
/>
}
label={_(msg`Home`)}
/>
<NavItem
href="/search"
icon={
<MagnifyingGlassIcon2
strokeWidth={2}
size={isDesktop ? 24 : 26}
style={pal.text}
/>
}
iconFilled={
<MagnifyingGlassIcon2Solid
strokeWidth={2}
size={isDesktop ? 24 : 26}
style={pal.text}
/>
}
label={_(msg`Search`)}
/>
{hasSession && ( {hasSession && (
<> <>
<BackBtn />
<NavItem
href="/"
icon={<HomeIcon size={isDesktop ? 24 : 28} style={pal.text} />}
iconFilled={
<HomeIconSolid
strokeWidth={4}
size={isDesktop ? 24 : 28}
style={pal.text}
/>
}
label={_(msg`Home`)}
/>
<NavItem
href="/search"
icon={
<MagnifyingGlassIcon2
strokeWidth={2}
size={isDesktop ? 24 : 26}
style={pal.text}
/>
}
iconFilled={
<MagnifyingGlassIcon2Solid
strokeWidth={2}
size={isDesktop ? 24 : 26}
style={pal.text}
/>
}
label={_(msg`Search`)}
/>
<NavItem <NavItem
href="/feeds" href="/feeds"
icon={ icon={