Move feeds screen into common navigator, handle usages (#4365)

* Move feeds screen into common navigator, handle usages

* Add link to Feeds from home screen (#4366)

* Add link to feeds to home screen header

* Center logo

* Replace icons

* Tweak spacing

* Tweak spacing

* Swap icon, sizing

* Buttonize, size

* Make menu same alignment on all screens

* Remove FeedsTab support, enable drawer swipe on MessagesTab

* Add note

* Vertically align header

* Swap in Pin

* Use hashtag icon

* Remove png

* Fix reference

* Ensure alignment with home and other screens
This commit is contained in:
Eric Bailey 2024-06-11 13:08:06 -05:00 committed by GitHub
parent 3573f7ea40
commit 4b6609d48b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 155 additions and 167 deletions

View file

@ -5,7 +5,6 @@ import {usePalette} from '#/lib/hooks/usePalette'
import {FeedSourceInfo} from '#/state/queries/feed'
import {useSession} from '#/state/session'
import {NavigationProp} from 'lib/routes/types'
import {isWeb} from 'platform/detection'
import {RenderTabBarFnProps} from 'view/com/pager/Pager'
import {TabBar} from '../pager/TabBar'
import {HomeHeaderLayout} from './HomeHeaderLayout'
@ -39,12 +38,7 @@ export function HomeHeader(
}, [hasPinnedCustom, feeds])
const onPressFeedsLink = React.useCallback(() => {
if (isWeb) {
navigation.navigate('Feeds')
} else {
navigation.navigate('FeedsTab')
navigation.popToTop()
}
navigation.navigate('Feeds')
}, [navigation])
const onSelect = React.useCallback(

View file

@ -1,22 +1,18 @@
import React from 'react'
import {StyleSheet, View} from 'react-native'
import Animated from 'react-native-reanimated'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {CogIcon} from '#/lib/icons'
import {useSession} from '#/state/session'
import {useShellLayout} from '#/state/shell/shell-layout'
import {useMinimalShellHeaderTransform} from 'lib/hooks/useMinimalShellTransform'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {Logo} from '#/view/icons/Logo'
import {atoms as a, useTheme} from '#/alf'
import {Hashtag_Stroke2_Corner0_Rounded as FeedsIcon} from '#/components/icons/Hashtag'
import {Link} from '#/components/Link'
import {useKawaiiMode} from '../../../state/preferences/kawaii'
import {Link} from '../util/Link'
import {HomeHeaderLayoutMobile} from './HomeHeaderLayoutMobile'
export function HomeHeaderLayout(props: {
@ -38,7 +34,7 @@ function HomeHeaderLayoutDesktopAndTablet({
children: React.ReactNode
tabBarAnchor: JSX.Element | null | undefined
}) {
const pal = usePalette('default')
const t = useTheme()
const headerMinimalShellTransform = useMinimalShellHeaderTransform()
const {headerHeight} = useShellLayout()
const {hasSession} = useSession()
@ -51,31 +47,46 @@ function HomeHeaderLayoutDesktopAndTablet({
{hasSession && (
<View
style={[
pal.view,
pal.border,
a.relative,
a.flex_row,
a.justify_end,
a.align_center,
a.pt_lg,
a.px_md,
a.pb_2xs,
t.atoms.bg,
t.atoms.border_contrast_low,
styles.bar,
styles.topBar,
kawaii && {paddingTop: 4, paddingBottom: 0},
]}>
<View
style={[
a.absolute,
a.inset_0,
a.pt_lg,
a.m_auto,
kawaii && {paddingTop: 4, paddingBottom: 0},
{
width: kawaii ? 60 : 28,
},
]}>
<Logo width={kawaii ? 60 : 28} />
</View>
<Link
href="/settings/following-feed"
to="/feeds"
hitSlop={10}
accessibilityRole="button"
accessibilityLabel={_(msg`Following Feed Preferences`)}
accessibilityHint="">
<FontAwesomeIcon
icon="sliders"
style={pal.textLight as FontAwesomeIconStyle}
/>
</Link>
<Logo width={kawaii ? 60 : 28} />
<Link
href="/settings/saved-feeds"
hitSlop={10}
accessibilityRole="button"
accessibilityLabel={_(msg`Edit Saved Feeds`)}
accessibilityHint={_(msg`Opens screen to edit Saved Feeds`)}>
<CogIcon size={22} strokeWidth={2} style={pal.textLight} />
label={_(msg`View your feeds and explore more`)}
size="small"
variant="ghost"
color="secondary"
shape="square"
style={[
a.justify_center,
{
marginTop: -4,
},
]}>
<FeedsIcon size="md" fill={t.atoms.text_contrast_medium.color} />
</Link>
</View>
)}
@ -85,8 +96,8 @@ function HomeHeaderLayoutDesktopAndTablet({
headerHeight.value = e.nativeEvent.layout.height
}}
style={[
pal.view,
pal.border,
t.atoms.bg,
t.atoms.border_contrast_low,
styles.bar,
styles.tabBar,
headerMinimalShellTransform,

View file

@ -1,8 +1,6 @@
import React from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import Animated from 'react-native-reanimated'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
@ -15,10 +13,13 @@ import {usePalette} from 'lib/hooks/usePalette'
import {isWeb} from 'platform/detection'
import {Logo} from '#/view/icons/Logo'
import {atoms} from '#/alf'
import {useTheme} from '#/alf'
import {atoms as a} from '#/alf'
import {ColorPalette_Stroke2_Corner0_Rounded as ColorPalette} from '#/components/icons/ColorPalette'
import {Link as Link2} from '#/components/Link'
import {Hashtag_Stroke2_Corner0_Rounded as FeedsIcon} from '#/components/icons/Hashtag'
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
import {Link} from '#/components/Link'
import {IS_DEV} from '#/env'
import {Link} from '../util/Link'
export function HomeHeaderLayoutMobile({
children,
@ -26,6 +27,7 @@ export function HomeHeaderLayoutMobile({
children: React.ReactNode
tabBarAnchor: JSX.Element | null | undefined
}) {
const t = useTheme()
const pal = usePalette('default')
const {_} = useLingui()
const setDrawerOpen = useSetDrawerOpen()
@ -54,11 +56,7 @@ export function HomeHeaderLayoutMobile({
msg`Access profile and other navigation links`,
)}
hitSlop={HITSLOP_10}>
<FontAwesomeIcon
icon="bars"
size={18}
color={pal.colors.textLight}
/>
<Menu size="lg" fill={t.atoms.text_contrast_medium.color} />
</TouchableOpacity>
</View>
<View>
@ -74,22 +72,28 @@ export function HomeHeaderLayoutMobile({
{width: 100},
]}>
{IS_DEV && (
<Link2 to="/sys/debug">
<Link to="/sys/debug">
<ColorPalette size="md" />
</Link2>
</Link>
)}
{hasSession && (
<Link
testID="viewHeaderHomeFeedPrefsBtn"
href="/settings/following-feed"
to="/feeds"
hitSlop={HITSLOP_10}
accessibilityRole="button"
accessibilityLabel={_(msg`Following Feed Preferences`)}
accessibilityHint="">
<FontAwesomeIcon
icon="sliders"
style={pal.textLight as FontAwesomeIconStyle}
/>
label={_(msg`View your feeds and explore more`)}
size="small"
variant="ghost"
color="secondary"
shape="square"
style={[
a.justify_center,
{
marginTop: 2,
marginRight: -6,
},
]}>
<FeedsIcon size="lg" fill={t.atoms.text_contrast_medium.color} />
</Link>
)}
</View>
@ -113,8 +117,8 @@ const styles = StyleSheet.create({
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 18,
paddingVertical: 8,
paddingHorizontal: 16,
paddingVertical: 5,
width: '100%',
},
title: {

View file

@ -1,18 +1,19 @@
import React from 'react'
import {StyleSheet, View} from 'react-native'
import {useNavigation} from '@react-navigation/native'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {Text} from '../util/text/Text'
import {Button} from '../util/forms/Button'
import {Trans} from '@lingui/macro'
import {useNavigation} from '@react-navigation/native'
import {usePalette} from 'lib/hooks/usePalette'
import {MagnifyingGlassIcon} from 'lib/icons'
import {NavigationProp} from 'lib/routes/types'
import {usePalette} from 'lib/hooks/usePalette'
import {s} from 'lib/styles'
import {isWeb} from 'platform/detection'
import {Trans} from '@lingui/macro'
import {Button} from '../util/forms/Button'
import {Text} from '../util/text/Text'
export function FollowingEmptyState() {
const pal = usePalette('default')
@ -29,12 +30,7 @@ export function FollowingEmptyState() {
}, [navigation])
const onPressDiscoverFeeds = React.useCallback(() => {
if (isWeb) {
navigation.navigate('Feeds')
} else {
navigation.navigate('FeedsTab')
navigation.popToTop()
}
navigation.navigate('Feeds')
}, [navigation])
return (

View file

@ -1,17 +1,18 @@
import React from 'react'
import {StyleSheet, View, Dimensions} from 'react-native'
import {useNavigation} from '@react-navigation/native'
import {Dimensions, StyleSheet, View} from 'react-native'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {Text} from '../util/text/Text'
import {Button} from '../util/forms/Button'
import {NavigationProp} from 'lib/routes/types'
import {Trans} from '@lingui/macro'
import {useNavigation} from '@react-navigation/native'
import {usePalette} from 'lib/hooks/usePalette'
import {NavigationProp} from 'lib/routes/types'
import {s} from 'lib/styles'
import {isWeb} from 'platform/detection'
import {Trans} from '@lingui/macro'
import {Button} from '../util/forms/Button'
import {Text} from '../util/text/Text'
export function FollowingEndOfFeed() {
const pal = usePalette('default')
@ -28,12 +29,7 @@ export function FollowingEndOfFeed() {
}, [navigation])
const onPressDiscoverFeeds = React.useCallback(() => {
if (isWeb) {
navigation.navigate('Feeds')
} else {
navigation.navigate('FeedsTab')
navigation.popToTop()
}
navigation.navigate('Feeds')
}, [navigation])
return (

View file

@ -21,6 +21,7 @@ import {Text} from '../util/text/Text'
import {UserAvatar, UserAvatarType} from '../util/UserAvatar'
import {CenteredView} from '../util/Views'
import hairlineWidth = StyleSheet.hairlineWidth
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
export function ProfileSubpageHeader({
isLoading,
@ -103,11 +104,7 @@ export function ProfileSubpageHeader({
style={[styles.backIcon, pal.text]}
/>
) : (
<FontAwesomeIcon
size={18}
icon="bars"
style={[styles.backIcon, pal.textLight]}
/>
<Menu size="lg" style={[{marginTop: 4}, pal.textLight]} />
)}
</Pressable>
<View style={{flex: 1}} />
@ -194,7 +191,7 @@ const styles = StyleSheet.create({
backBtnWide: {
width: 20,
height: 30,
paddingHorizontal: 6,
marginRight: 4,
},
backIcon: {
marginTop: 6,

View file

@ -90,7 +90,7 @@ export function TestCtrls() {
/>
<Pressable
testID="e2eGotoFeeds"
onPress={() => navigate('FeedsTab')}
onPress={() => navigate('Feeds')}
accessibilityRole="button"
style={BTN}
/>

View file

@ -8,13 +8,15 @@ import {
} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {useNavigation} from '@react-navigation/native'
import {CenteredView} from './Views'
import {isWeb} from '#/platform/detection'
import {useSetDrawerOpen} from '#/state/shell'
import {useAnalytics} from 'lib/analytics/analytics'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {useAnalytics} from 'lib/analytics/analytics'
import {NavigationProp} from 'lib/routes/types'
import {useSetDrawerOpen} from '#/state/shell'
import {isWeb} from '#/platform/detection'
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
import {CenteredView} from './Views'
const BACK_HITSLOP = {left: 20, top: 20, right: 50, bottom: 20}
@ -72,11 +74,7 @@ export function SimpleViewHeader({
style={[styles.backIcon, pal.text]}
/>
) : (
<FontAwesomeIcon
size={18}
icon="bars"
style={[styles.backIcon, pal.textLight]}
/>
<Menu size="lg" style={[{marginTop: 4}, pal.textLight]} />
)}
</TouchableOpacity>
) : null}
@ -110,7 +108,8 @@ const styles = StyleSheet.create({
backBtnWide: {
width: 30,
height: 30,
paddingHorizontal: 6,
paddingLeft: 4,
marginRight: 4,
},
backIcon: {
marginTop: 6,

View file

@ -16,6 +16,7 @@ import {useTheme} from '#/alf'
import {Text} from './text/Text'
import {CenteredView} from './Views'
import hairlineWidth = StyleSheet.hairlineWidth
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
const BACK_HITSLOP = {left: 20, top: 20, right: 50, bottom: 20}
@ -98,11 +99,7 @@ export function ViewHeader({
style={[styles.backIcon, pal.text]}
/>
) : !isTablet ? (
<FontAwesomeIcon
size={18}
icon="bars"
style={[styles.backIcon, pal.textLight]}
/>
<Menu size="lg" style={[{marginTop: 3}, pal.textLight]} />
) : null}
</TouchableOpacity>
) : null}
@ -269,7 +266,8 @@ const styles = StyleSheet.create({
backBtnWide: {
width: 30,
height: 30,
paddingHorizontal: 6,
paddingLeft: 4,
marginRight: 4,
},
backIcon: {
marginTop: 6,

View file

@ -29,7 +29,7 @@ import {HITSLOP_10} from 'lib/constants'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {CogIcon, ComposeIcon2, MagnifyingGlassIcon2} from 'lib/icons'
import {FeedsTabNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
import {cleanError} from 'lib/strings/errors'
import {s} from 'lib/styles'
import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard'
@ -54,7 +54,7 @@ import {ListMagnifyingGlass_Stroke2_Corner0_Rounded} from '#/components/icons/Li
import {ListSparkle_Stroke2_Corner0_Rounded} from '#/components/icons/ListSparkle'
import hairlineWidth = StyleSheet.hairlineWidth
type Props = NativeStackScreenProps<FeedsTabNavigatorParams, 'Feeds'>
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Feeds'>
type FlatlistSlice =
| {
@ -594,7 +594,6 @@ export function FeedsScreen(_props: Props) {
{isMobile && (
<ViewHeader
title={_(msg`Feeds`)}
canGoBack={false}
renderButton={renderHeaderBtn}
showBorder
/>

View file

@ -163,7 +163,7 @@ export function NotificationsScreen({}: Props) {
return (
<CenteredView
testID="notificationsScreen"
style={s.hContentRegion}
style={[s.hContentRegion, {paddingTop: 2}]}
sideBorders={true}>
<ViewHeader
title={_(msg`Notifications`)}

View file

@ -59,6 +59,7 @@ import {CenteredView, ScrollView} from '#/view/com/util/Views'
import {SearchLinkCard, SearchProfileCard} from '#/view/shell/desktop/Search'
import {ProfileCardFeedLoadingPlaceholder} from 'view/com/util/LoadingPlaceholder'
import {atoms as a} from '#/alf'
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
function Loader() {
const pal = usePalette('default')
@ -712,11 +713,7 @@ export function SearchScreen(
accessibilityRole="button"
accessibilityLabel={_(msg`Menu`)}
accessibilityHint={_(msg`Access navigation links and settings`)}>
<FontAwesomeIcon
icon="bars"
size={18}
color={pal.colors.textLight}
/>
<Menu size="lg" fill={pal.colors.textLight} />
</Pressable>
)}
<SearchInputBox
@ -1073,13 +1070,14 @@ function scrollToTopWeb() {
}
}
const HEADER_HEIGHT = 50
const HEADER_HEIGHT = 46
const styles = StyleSheet.create({
header: {
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 12,
paddingLeft: 13,
paddingVertical: 4,
height: HEADER_HEIGHT,
// @ts-ignore web only
@ -1092,7 +1090,6 @@ const styles = StyleSheet.create({
height: 30,
borderRadius: 30,
marginRight: 6,
paddingBottom: 2,
alignItems: 'center',
justifyContent: 'center',
},

View file

@ -186,10 +186,11 @@ let DrawerContent = ({}: {}): React.ReactNode => {
onPressTab('MyProfile')
}, [onPressTab])
const onPressMyFeeds = React.useCallback(
() => onPressTab('Feeds'),
[onPressTab],
)
const onPressMyFeeds = React.useCallback(() => {
track('Menu:ItemClicked', {url: 'Feeds'})
navigation.navigate('Feeds')
setDrawerOpen(false)
}, [navigation, setDrawerOpen, track])
const onPressLists = React.useCallback(() => {
track('Menu:ItemClicked', {url: 'Lists'})