diff options
author | Paul Frazee <pfrazee@gmail.com> | 2023-12-14 10:31:49 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-14 10:31:49 -0800 |
commit | 075ffdf583c5393b896d22dd179d03208311ef4a (patch) | |
tree | ad86e90d2e2f0dd5a9e2f9f72292e5dcec6a59a0 /src/view | |
parent | 7fd79702371e3d7829be2188c2212c090bf76670 (diff) | |
download | voidsky-075ffdf583c5393b896d22dd179d03208311ef4a.tar.zst |
PWI behavior updates (#2207)
* Enable PWI * Disable access to feeds on PWI * Remove feeds nav item from drawer when signed out * Replace discover feed on home with a CTA * Wire up the sign in and create account buttons to go straight to their respective screens * Give a custom ScreenHider interface for no-pwi * Add side borders on desktop to the screen hider * Filter accounts in the autocomplete according to mod settings * Trim replies in the post thread that are pwi opt-out * Show 'learn more' on the content hider when no-override is enabled * Apply the moderation filter on profile cards * Disable post search on logged-out view * Update locale files * Bump api pkg * Ensure feeds with no posts don't show as NSFPublic * Fix types --------- Co-authored-by: Eric Bailey <git@esb.lol>
Diffstat (limited to 'src/view')
-rw-r--r-- | src/view/com/auth/HomeLoggedOutCTA.tsx | 165 | ||||
-rw-r--r-- | src/view/com/auth/LoggedOut.tsx | 4 | ||||
-rw-r--r-- | src/view/com/post-thread/PostThread.tsx | 18 | ||||
-rw-r--r-- | src/view/com/profile/ProfileCard.tsx | 3 | ||||
-rw-r--r-- | src/view/com/util/moderation/ContentHider.tsx | 20 | ||||
-rw-r--r-- | src/view/com/util/moderation/ScreenHider.tsx | 64 | ||||
-rw-r--r-- | src/view/screens/Home.tsx | 8 | ||||
-rw-r--r-- | src/view/screens/Profile.tsx | 2 | ||||
-rw-r--r-- | src/view/screens/Search/Search.tsx | 99 | ||||
-rw-r--r-- | src/view/shell/Drawer.tsx | 2 | ||||
-rw-r--r-- | src/view/shell/NavSignupCard.tsx | 18 | ||||
-rw-r--r-- | src/view/shell/bottom-bar/BottomBar.tsx | 44 | ||||
-rw-r--r-- | src/view/shell/bottom-bar/BottomBarWeb.tsx | 22 | ||||
-rw-r--r-- | src/view/shell/desktop/LeftNav.tsx | 37 |
14 files changed, 371 insertions, 135 deletions
diff --git a/src/view/com/auth/HomeLoggedOutCTA.tsx b/src/view/com/auth/HomeLoggedOutCTA.tsx new file mode 100644 index 000000000..32b873ac6 --- /dev/null +++ b/src/view/com/auth/HomeLoggedOutCTA.tsx @@ -0,0 +1,165 @@ +import React from 'react' +import {StyleSheet, TouchableOpacity, View} from 'react-native' +import {useLingui} from '@lingui/react' +import {Trans, msg} from '@lingui/macro' +import {ScrollView} from '../util/Views' +import {Text} from '../util/text/Text' +import {usePalette} from '#/lib/hooks/usePalette' +import {colors, s} from '#/lib/styles' +import {TextLink} from '../util/Link' +import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' +import {useLoggedOutViewControls} from '#/state/shell/logged-out' + +export function HomeLoggedOutCTA() { + const pal = usePalette('default') + const {_} = useLingui() + const {isMobile} = useWebMediaQueries() + const {requestSwitchToAccount} = useLoggedOutViewControls() + + const showCreateAccount = React.useCallback(() => { + requestSwitchToAccount({requestedAccount: 'new'}) + }, [requestSwitchToAccount]) + + const showSignIn = React.useCallback(() => { + requestSwitchToAccount({requestedAccount: 'none'}) + }, [requestSwitchToAccount]) + + return ( + <ScrollView style={styles.container} testID="loggedOutCTA"> + <View style={[styles.hero, isMobile && styles.heroMobile]}> + <Text style={[styles.title, pal.link]}> + <Trans>Bluesky</Trans> + </Text> + <Text + style={[ + styles.subtitle, + isMobile && styles.subtitleMobile, + pal.textLight, + ]}> + <Trans>See what's next</Trans> + </Text> + </View> + <View + testID="signinOrCreateAccount" + style={isMobile ? undefined : styles.btnsDesktop}> + <TouchableOpacity + testID="createAccountButton" + style={[ + styles.btn, + isMobile && styles.btnMobile, + {backgroundColor: colors.blue3}, + ]} + onPress={showCreateAccount} + accessibilityRole="button" + accessibilityLabel={_(msg`Create new account`)} + accessibilityHint="Opens flow to create a new Bluesky account"> + <Text + style={[ + s.white, + styles.btnLabel, + isMobile && styles.btnLabelMobile, + ]}> + <Trans>Create a new account</Trans> + </Text> + </TouchableOpacity> + <TouchableOpacity + testID="signInButton" + style={[styles.btn, isMobile && styles.btnMobile, pal.btn]} + onPress={showSignIn} + accessibilityRole="button" + accessibilityLabel={_(msg`Sign in`)} + accessibilityHint="Opens flow to sign into your existing Bluesky account"> + <Text + style={[ + pal.text, + styles.btnLabel, + isMobile && styles.btnLabelMobile, + ]}> + <Trans>Sign In</Trans> + </Text> + </TouchableOpacity> + </View> + + <View style={[styles.footer, pal.view, pal.border]}> + <TextLink + type="2xl" + href="https://blueskyweb.xyz" + text={_(msg`Business`)} + style={[styles.footerLink, pal.link]} + /> + <TextLink + type="2xl" + href="https://blueskyweb.xyz/blog" + text={_(msg`Blog`)} + style={[styles.footerLink, pal.link]} + /> + <TextLink + type="2xl" + href="https://blueskyweb.xyz/join" + text={_(msg`Jobs`)} + style={[styles.footerLink, pal.link]} + /> + </View> + </ScrollView> + ) +} + +const styles = StyleSheet.create({ + container: { + height: '100%', + }, + hero: { + justifyContent: 'center', + paddingTop: 100, + paddingBottom: 30, + }, + heroMobile: { + paddingBottom: 50, + }, + title: { + textAlign: 'center', + fontSize: 68, + fontWeight: 'bold', + }, + subtitle: { + textAlign: 'center', + fontSize: 48, + fontWeight: 'bold', + }, + subtitleMobile: { + fontSize: 42, + }, + btnsDesktop: { + flexDirection: 'row', + justifyContent: 'center', + gap: 20, + marginHorizontal: 20, + }, + btn: { + borderRadius: 32, + width: 230, + paddingVertical: 12, + marginBottom: 20, + }, + btnMobile: { + flex: 1, + width: 'auto', + marginHorizontal: 20, + paddingVertical: 16, + }, + btnLabel: { + textAlign: 'center', + fontSize: 18, + }, + btnLabelMobile: { + textAlign: 'center', + fontSize: 21, + }, + + footer: { + flexDirection: 'row', + gap: 20, + justifyContent: 'center', + }, + footerLink: {}, +}) diff --git a/src/view/com/auth/LoggedOut.tsx b/src/view/com/auth/LoggedOut.tsx index fcff4f782..b0b2bf7ed 100644 --- a/src/view/com/auth/LoggedOut.tsx +++ b/src/view/com/auth/LoggedOut.tsx @@ -33,7 +33,9 @@ export function LoggedOut({onDismiss}: {onDismiss?: () => void}) { const {requestedAccountSwitchTo} = useLoggedOutView() const [screenState, setScreenState] = React.useState<ScreenState>( requestedAccountSwitchTo - ? ScreenState.S_Login + ? requestedAccountSwitchTo === 'new' + ? ScreenState.S_CreateAccount + : ScreenState.S_Login : ScreenState.S_LoginOrCreateAccount, ) const {isMobile} = useWebMediaQueries() diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index f27da331f..917550884 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -157,7 +157,9 @@ function PostThreadLoaded({ // construct content const posts = React.useMemo(() => { let arr = [TOP_COMPONENT].concat( - Array.from(flattenThreadSkeleton(sortThread(thread, threadViewPrefs))), + Array.from( + flattenThreadSkeleton(sortThread(thread, threadViewPrefs), hasSession), + ), ) if (arr.length > maxVisible) { arr = arr.slice(0, maxVisible).concat([LOAD_MORE]) @@ -166,7 +168,7 @@ function PostThreadLoaded({ arr.push(BOTTOM_COMPONENT) } return arr - }, [thread, maxVisible, threadViewPrefs]) + }, [thread, maxVisible, threadViewPrefs, hasSession]) /** * NOTE @@ -468,20 +470,24 @@ function isThreadPost(v: unknown): v is ThreadPost { function* flattenThreadSkeleton( node: ThreadNode, + hasSession: boolean, ): Generator<YieldedItem, void> { if (node.type === 'post') { if (node.parent) { - yield* flattenThreadSkeleton(node.parent) + yield* flattenThreadSkeleton(node.parent, hasSession) } else if (node.ctx.isParentLoading) { yield PARENT_SPINNER } + if (!hasSession && node.ctx.depth > 0 && hasPwiOptOut(node)) { + return + } yield node if (node.ctx.isHighlightedPost && !node.post.viewer?.replyDisabled) { yield REPLY_PROMPT } if (node.replies?.length) { for (const reply of node.replies) { - yield* flattenThreadSkeleton(reply) + yield* flattenThreadSkeleton(reply, hasSession) } } else if (node.ctx.isChildLoading) { yield CHILD_SPINNER @@ -493,6 +499,10 @@ function* flattenThreadSkeleton( } } +function hasPwiOptOut(node: ThreadPost) { + return !!node.post.author.labels?.find(l => l.val === '!no-unauthenticated') +} + function hasBranchingReplies(node: ThreadNode) { if (node.type !== 'post') { return false diff --git a/src/view/com/profile/ProfileCard.tsx b/src/view/com/profile/ProfileCard.tsx index 21972f274..c5b2dc528 100644 --- a/src/view/com/profile/ProfileCard.tsx +++ b/src/view/com/profile/ProfileCard.tsx @@ -50,6 +50,9 @@ export function ProfileCard({ return null } const moderation = moderateProfile(profile, moderationOpts) + if (moderation.account.filter) { + return null + } return ( <Link diff --git a/src/view/com/util/moderation/ContentHider.tsx b/src/view/com/util/moderation/ContentHider.tsx index b1ea76621..1269b7ebf 100644 --- a/src/view/com/util/moderation/ContentHider.tsx +++ b/src/view/com/util/moderation/ContentHider.tsx @@ -7,7 +7,7 @@ import {Text} from '../text/Text' import {ShieldExclamation} from 'lib/icons' import {describeModerationCause} from 'lib/moderation' import {useLingui} from '@lingui/react' -import {msg} from '@lingui/macro' +import {msg, Trans} from '@lingui/macro' import {useModalControls} from '#/state/modals' import {isPostMediaBlurred} from 'lib/moderation' @@ -95,13 +95,17 @@ export function ContentHider({ <Text type="md" style={pal.text}> {desc.name} </Text> - {!moderation.noOverride && ( - <View style={styles.showBtn}> - <Text type="lg" style={pal.link}> - {override ? 'Hide' : 'Show'} - </Text> - </View> - )} + <View style={styles.showBtn}> + <Text type="lg" style={pal.link}> + {moderation.noOverride ? ( + <Trans>Learn more</Trans> + ) : override ? ( + <Trans>Hide</Trans> + ) : ( + <Trans>Show</Trans> + )} + </Text> + </View> </Pressable> {override && <View style={childContainerStyle}>{children}</View>} </View> diff --git a/src/view/com/util/moderation/ScreenHider.tsx b/src/view/com/util/moderation/ScreenHider.tsx index 946f937e9..86f0cbf7b 100644 --- a/src/view/com/util/moderation/ScreenHider.tsx +++ b/src/view/com/util/moderation/ScreenHider.tsx @@ -22,6 +22,7 @@ import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useModalControls} from '#/state/modals' import {s} from '#/lib/styles' +import {CenteredView} from '../Views' export function ScreenHider({ testID, @@ -53,41 +54,58 @@ export function ScreenHider({ ) } + const isNoPwi = + moderation.cause?.type === 'label' && + moderation.cause?.labelDef.id === '!no-unauthenticated' const desc = describeModerationCause(moderation.cause, 'account') return ( - <View style={[styles.container, pal.view, containerStyle]}> + <CenteredView + style={[styles.container, pal.view, containerStyle]} + sideBorders> <View style={styles.iconContainer}> <View style={[styles.icon, palInverted.view]}> <FontAwesomeIcon - icon="exclamation" + icon={isNoPwi ? ['far', 'eye-slash'] : 'exclamation'} style={pal.textInverted as FontAwesomeIconStyle} size={24} /> </View> </View> <Text type="title-2xl" style={[styles.title, pal.text]}> - <Trans>Content Warning</Trans> + {isNoPwi ? ( + <Trans>Sign-in Required</Trans> + ) : ( + <Trans>Content Warning</Trans> + )} </Text> <Text type="2xl" style={[styles.description, pal.textLight]}> - <Trans>This {screenDescription} has been flagged:</Trans> - <Text type="2xl-medium" style={[pal.text, s.ml5]}> - {desc.name}. - </Text> - <TouchableWithoutFeedback - onPress={() => { - openModal({ - name: 'moderation-details', - context: 'account', - moderation, - }) - }} - accessibilityRole="button" - accessibilityLabel={_(msg`Learn more about this warning`)} - accessibilityHint=""> - <Text type="2xl" style={pal.link}> - <Trans>Learn More</Trans> - </Text> - </TouchableWithoutFeedback> + {isNoPwi ? ( + <Trans> + This account has requested that users sign in to view their profile. + </Trans> + ) : ( + <> + <Trans>This {screenDescription} has been flagged:</Trans> + <Text type="2xl-medium" style={[pal.text, s.ml5]}> + {desc.name}. + </Text> + <TouchableWithoutFeedback + onPress={() => { + openModal({ + name: 'moderation-details', + context: 'account', + moderation, + }) + }} + accessibilityRole="button" + accessibilityLabel={_(msg`Learn more about this warning`)} + accessibilityHint=""> + <Text type="2xl" style={pal.link}> + <Trans>Learn More</Trans> + </Text> + </TouchableWithoutFeedback> + </> + )}{' '} </Text> {isMobile && <View style={styles.spacer} />} <View style={styles.btnContainer}> @@ -116,7 +134,7 @@ export function ScreenHider({ </Button> )} </View> - </View> + </CenteredView> ) } diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx index 42a958b95..bfe440265 100644 --- a/src/view/screens/Home.tsx +++ b/src/view/screens/Home.tsx @@ -9,6 +9,7 @@ import {CustomFeedEmptyState} from 'view/com/posts/CustomFeedEmptyState' import {FeedsTabBar} from '../com/pager/FeedsTabBar' import {Pager, RenderTabBarFnProps} from 'view/com/pager/Pager' import {FeedPage} from 'view/com/feeds/FeedPage' +import {HomeLoggedOutCTA} from '../com/auth/HomeLoggedOutCTA' import {useSetMinimalShellMode, useSetDrawerSwipeDisabled} from '#/state/shell' import {usePreferencesQuery} from '#/state/queries/preferences' import {UsePreferencesQueryResponse} from '#/state/queries/preferences/types' @@ -199,12 +200,7 @@ function HomeScreenReady({ onPageScrollStateChanged={onPageScrollStateChanged} renderTabBar={renderTabBar} tabBarPosition="top"> - <FeedPage - testID="customFeedPage" - isPageFocused={true} - feed={`feedgen|at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot`} - renderEmptyState={renderCustomFeedEmptyState} - /> + <HomeLoggedOutCTA /> </Pager> ) } diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx index 3f2dd773e..f1c648a67 100644 --- a/src/view/screens/Profile.tsx +++ b/src/view/screens/Profile.tsx @@ -153,7 +153,7 @@ function ProfileScreenLoaded({ const isMe = profile.did === currentAccount?.did const showRepliesTab = hasSession const showLikesTab = isMe - const showFeedsTab = isMe || extraInfoQuery.data?.hasFeedgens + const showFeedsTab = hasSession && (isMe || extraInfoQuery.data?.hasFeedgens) const showListsTab = hasSession && (isMe || extraInfoQuery.data?.hasLists) const sectionTitles = useMemo<string[]>(() => { return [ diff --git a/src/view/screens/Search/Search.tsx b/src/view/screens/Search/Search.tsx index 7d7b4098f..efd8507a7 100644 --- a/src/view/screens/Search/Search.tsx +++ b/src/view/screens/Search/Search.tsx @@ -304,7 +304,8 @@ function SearchScreenUserResults({query}: {query: string}) { ) } -const SECTIONS = ['Posts', 'Users'] +const SECTIONS_LOGGEDOUT = ['Users'] +const SECTIONS_LOGGEDIN = ['Posts', 'Users'] export function SearchScreenInner({query}: {query?: string}) { const pal = usePalette('default') const setMinimalShellMode = useSetMinimalShellMode() @@ -320,44 +321,62 @@ export function SearchScreenInner({query}: {query?: string}) { [setDrawerSwipeDisabled, setMinimalShellMode], ) + if (hasSession) { + return query ? ( + <Pager + tabBarPosition="top" + onPageSelected={onPageSelected} + renderTabBar={props => ( + <CenteredView sideBorders style={pal.border}> + <TabBar items={SECTIONS_LOGGEDIN} {...props} /> + </CenteredView> + )} + initialPage={0}> + <View> + <SearchScreenPostResults query={query} /> + </View> + <View> + <SearchScreenUserResults query={query} /> + </View> + </Pager> + ) : ( + <View> + <CenteredView sideBorders style={pal.border}> + <Text + type="title" + style={[ + pal.text, + pal.border, + { + display: 'flex', + paddingVertical: 12, + paddingHorizontal: 18, + fontWeight: 'bold', + }, + ]}> + <Trans>Suggested Follows</Trans> + </Text> + </CenteredView> + + <SearchScreenSuggestedFollows /> + </View> + ) + } + return query ? ( <Pager tabBarPosition="top" onPageSelected={onPageSelected} renderTabBar={props => ( <CenteredView sideBorders style={pal.border}> - <TabBar items={SECTIONS} {...props} /> + <TabBar items={SECTIONS_LOGGEDOUT} {...props} /> </CenteredView> )} initialPage={0}> <View> - <SearchScreenPostResults query={query} /> - </View> - <View> <SearchScreenUserResults query={query} /> </View> </Pager> - ) : hasSession ? ( - <View> - <CenteredView sideBorders style={pal.border}> - <Text - type="title" - style={[ - pal.text, - pal.border, - { - display: 'flex', - paddingVertical: 12, - paddingHorizontal: 18, - fontWeight: 'bold', - }, - ]}> - <Trans>Suggested Follows</Trans> - </Text> - </CenteredView> - - <SearchScreenSuggestedFollows /> - </View> ) : ( <CenteredView sideBorders style={pal.border}> <View @@ -383,13 +402,27 @@ export function SearchScreenInner({query}: {query?: string}) { </Text> )} - <Text - style={[ - pal.textLight, - {textAlign: 'center', paddingVertical: 12, paddingHorizontal: 18}, - ]}> - <Trans>Search for posts and users.</Trans> - </Text> + <View + style={{ + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + paddingVertical: 30, + gap: 15, + }}> + <MagnifyingGlassIcon + strokeWidth={3} + size={isDesktop ? 60 : 60} + style={pal.textLight} + /> + <Text type="xl" style={[pal.textLight, {paddingHorizontal: 18}]}> + {isDesktop ? ( + <Trans>Find users with the search tool on the right</Trans> + ) : ( + <Trans>Find users on Bluesky</Trans> + )} + </Text> + </View> </View> </CenteredView> ) diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index 4d3a9531d..4fb8565e8 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -231,9 +231,9 @@ let DrawerContent = ({}: {}): React.ReactNode => { onPress={onPressNotifications} /> )} - <FeedsMenuItem isActive={isAtFeeds} onPress={onPressMyFeeds} /> {hasSession && ( <> + <FeedsMenuItem isActive={isAtFeeds} onPress={onPressMyFeeds} /> <ListsMenuItem onPress={onPressLists} /> <ModerationMenuItem onPress={onPressModeration} /> <ProfileMenuItem diff --git a/src/view/shell/NavSignupCard.tsx b/src/view/shell/NavSignupCard.tsx index 11dd7ffee..8c0e2075d 100644 --- a/src/view/shell/NavSignupCard.tsx +++ b/src/view/shell/NavSignupCard.tsx @@ -14,13 +14,19 @@ import {useCloseAllActiveElements} from '#/state/util' let NavSignupCard = ({}: {}): React.ReactNode => { const {_} = useLingui() const pal = usePalette('default') - const {setShowLoggedOut} = useLoggedOutViewControls() + const {requestSwitchToAccount} = useLoggedOutViewControls() const closeAllActiveElements = useCloseAllActiveElements() - const showLoggedOut = React.useCallback(() => { + const showSignIn = React.useCallback(() => { closeAllActiveElements() - setShowLoggedOut(true) - }, [setShowLoggedOut, closeAllActiveElements]) + requestSwitchToAccount({requestedAccount: 'none'}) + }, [requestSwitchToAccount, closeAllActiveElements]) + + const showCreateAccount = React.useCallback(() => { + closeAllActiveElements() + requestSwitchToAccount({requestedAccount: 'new'}) + // setShowLoggedOut(true) + }, [requestSwitchToAccount, closeAllActiveElements]) return ( <View @@ -39,7 +45,7 @@ let NavSignupCard = ({}: {}): React.ReactNode => { <View style={{flexDirection: 'row', paddingTop: 12, gap: 8}}> <Button - onPress={showLoggedOut} + onPress={showCreateAccount} accessibilityHint={_(msg`Sign up`)} accessibilityLabel={_(msg`Sign up`)}> <Text type="md" style={[{color: 'white'}, s.bold]}> @@ -48,7 +54,7 @@ let NavSignupCard = ({}: {}): React.ReactNode => { </Button> <Button type="default" - onPress={showLoggedOut} + onPress={showSignIn} accessibilityHint={_(msg`Sign in`)} accessibilityLabel={_(msg`Sign in`)}> <Text type="md" style={[pal.text, s.bold]}> diff --git a/src/view/shell/bottom-bar/BottomBar.tsx b/src/view/shell/bottom-bar/BottomBar.tsx index 7f1ba8a5f..ef147f27e 100644 --- a/src/view/shell/bottom-bar/BottomBar.tsx +++ b/src/view/shell/bottom-bar/BottomBar.tsx @@ -138,32 +138,32 @@ export function BottomBar({navigation}: BottomTabBarProps) { accessibilityLabel={_(msg`Search`)} accessibilityHint="" /> - <Btn - testID="bottomBarFeedsBtn" - icon={ - isAtFeeds ? ( - <HashtagIcon - size={24} - style={[styles.ctrlIcon, pal.text, styles.feedsIcon]} - strokeWidth={4} - /> - ) : ( - <HashtagIcon - size={24} - style={[styles.ctrlIcon, pal.text, styles.feedsIcon]} - strokeWidth={2.25} - /> - ) - } - onPress={onPressFeeds} - accessibilityRole="tab" - accessibilityLabel={_(msg`Feeds`)} - accessibilityHint="" - /> {hasSession && ( <> <Btn + testID="bottomBarFeedsBtn" + icon={ + isAtFeeds ? ( + <HashtagIcon + size={24} + style={[styles.ctrlIcon, pal.text, styles.feedsIcon]} + strokeWidth={4} + /> + ) : ( + <HashtagIcon + size={24} + style={[styles.ctrlIcon, pal.text, styles.feedsIcon]} + strokeWidth={2.25} + /> + ) + } + onPress={onPressFeeds} + accessibilityRole="tab" + accessibilityLabel={_(msg`Feeds`)} + accessibilityHint="" + /> + <Btn testID="bottomBarNotificationsBtn" icon={ isAtNotifications ? ( diff --git a/src/view/shell/bottom-bar/BottomBarWeb.tsx b/src/view/shell/bottom-bar/BottomBarWeb.tsx index 3a60bd3b1..6ed0a99f5 100644 --- a/src/view/shell/bottom-bar/BottomBarWeb.tsx +++ b/src/view/shell/bottom-bar/BottomBarWeb.tsx @@ -64,20 +64,20 @@ export function BottomBarWeb() { ) }} </NavItem> - <NavItem routeName="Feeds" href="/feeds"> - {({isActive}) => { - return ( - <HashtagIcon - size={22} - style={[styles.ctrlIcon, pal.text, styles.feedsIcon]} - strokeWidth={isActive ? 4 : 2.5} - /> - ) - }} - </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 diff --git a/src/view/shell/desktop/LeftNav.tsx b/src/view/shell/desktop/LeftNav.tsx index e294431f3..8078df802 100644 --- a/src/view/shell/desktop/LeftNav.tsx +++ b/src/view/shell/desktop/LeftNav.tsx @@ -314,28 +314,27 @@ export function DesktopLeftNav() { } label={_(msg`Search`)} /> - <NavItem - href="/feeds" - icon={ - <HashtagIcon - strokeWidth={2.25} - style={pal.text as FontAwesomeIconStyle} - size={isDesktop ? 24 : 28} - /> - } - iconFilled={ - <HashtagIcon - strokeWidth={2.5} - style={pal.text as FontAwesomeIconStyle} - size={isDesktop ? 24 : 28} - /> - } - label={_(msg`Feeds`)} - /> - {hasSession && ( <> <NavItem + href="/feeds" + icon={ + <HashtagIcon + strokeWidth={2.25} + style={pal.text as FontAwesomeIconStyle} + size={isDesktop ? 24 : 28} + /> + } + iconFilled={ + <HashtagIcon + strokeWidth={2.5} + style={pal.text as FontAwesomeIconStyle} + size={isDesktop ? 24 : 28} + /> + } + label={_(msg`Feeds`)} + /> + <NavItem href="/notifications" count={numUnread} icon={ |