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
zio/stable
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

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4 5a1 1 0 0 0 0 2h16a1 1 0 1 0 0-2H4Zm0 12a1 1 0 1 0 0 2h3a1 1 0 1 0 0-2H4Zm-1-5a1 1 0 0 1 1-1h5a1 1 0 1 1 0 2H4a1 1 0 0 1-1-1Zm14-3c.552 0 1 .41 1 .917V13.5h3.583c.507 0 .917.448.917 1s-.41 1-.917 1H18v3.583c0 .507-.448.917-1 .917s-1-.41-1-.917V15.5h-3.583c-.507 0-.917-.448-.917-1s.41-1 .917-1H16V9.917C16 9.41 16.448 9 17 9Z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 471 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2 6a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm0 6a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm0 6a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 299 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M6.5 3a1 1 0 0 1 1-1h9a1 1 0 0 1 1 1v3.997a6.25 6.25 0 0 0 1.83 4.42l.377.376A1 1 0 0 1 20 12.5V15a1 1 0 0 1-1 1h-6v5a1 1 0 1 1-2 0v-5H5a1 1 0 0 1-1-1v-2.5a1 1 0 0 1 .293-.707l.376-.377A6.25 6.25 0 0 0 6.5 6.996V3.001Zm2 1v2.997a8.25 8.25 0 0 1-2.416 5.834L6 12.914V14h12v-1.086l-.084-.083A8.25 8.25 0 0 1 15.5 6.997V4h-7Z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 465 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M7 3a1 1 0 0 1 1 1v2h2a1 1 0 1 1 0 2H8v2a1 1 0 1 1-2 0V8H4a1 1 0 0 1 0-2h2V4a1 1 0 0 1 1-1Zm6 4a4 4 0 1 1 8 0 4 4 0 0 1-8 0Zm4-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4ZM3 14a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-6Zm2 1v4h4v-4H5Zm9.171-.829a1 1 0 0 1 1.415 0L17 15.585l1.414-1.414a1 1 0 1 1 1.414 1.414L18.414 17l1.414 1.414a1 1 0 0 1-1.414 1.414L17 18.414l-1.415 1.414a1 1 0 0 1-1.414-1.414l1.415-1.415-1.415-1.414a1 1 0 0 1 0-1.414Z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 590 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M12.902 1.568a1 1 0 0 0-1.804 0L8.455 7.085l-6.085.799a1 1 0 0 0-.557 1.718l4.45 4.207-1.117 6.008a1 1 0 0 0 1.458 1.063L12 17.962l5.396 2.918a1 1 0 0 0 1.459-1.063l-1.117-6.008 4.45-4.207a1 1 0 0 0-.558-1.718l-6.085-.8-2.643-5.516Z"/></svg>

After

Width:  |  Height:  |  Size: 335 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 1a1 1 0 0 1 .902.568l2.643 5.517 6.085.799a1 1 0 0 1 .557 1.718l-4.45 4.207 1.118 6.008a1 1 0 0 1-1.46 1.063L12 17.962 6.604 20.88a1 1 0 0 1-1.459-1.063l1.117-6.008-4.45-4.207a1 1 0 0 1 .558-1.718l6.085-.8 2.643-5.516A1 1 0 0 1 12 1Zm0 3.315-1.975 4.123a1 1 0 0 1-.772.56l-4.538.595 3.317 3.137a1 1 0 0 1 .296.91l-.834 4.485 4.03-2.179a1 1 0 0 1 .952 0l4.03 2.179-.834-4.485a1 1 0 0 1 .296-.91l3.317-3.137-4.538-.596a1 1 0 0 1-.772-.56L12 4.316Z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 592 B

View File

@ -22,7 +22,6 @@ import {buildStateObject} from 'lib/routes/helpers'
import { import {
AllNavigatorParams, AllNavigatorParams,
BottomTabNavigatorParams, BottomTabNavigatorParams,
FeedsTabNavigatorParams,
FlatNavigatorParams, FlatNavigatorParams,
HomeTabNavigatorParams, HomeTabNavigatorParams,
MessagesTabNavigatorParams, MessagesTabNavigatorParams,
@ -91,7 +90,6 @@ const navigationRef = createNavigationContainerRef<AllNavigatorParams>()
const HomeTab = createNativeStackNavigatorWithAuth<HomeTabNavigatorParams>() const HomeTab = createNativeStackNavigatorWithAuth<HomeTabNavigatorParams>()
const SearchTab = createNativeStackNavigatorWithAuth<SearchTabNavigatorParams>() const SearchTab = createNativeStackNavigatorWithAuth<SearchTabNavigatorParams>()
const FeedsTab = createNativeStackNavigatorWithAuth<FeedsTabNavigatorParams>()
const NotificationsTab = const NotificationsTab =
createNativeStackNavigatorWithAuth<NotificationsTabNavigatorParams>() createNativeStackNavigatorWithAuth<NotificationsTabNavigatorParams>()
const MyProfileTab = const MyProfileTab =
@ -306,6 +304,7 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) {
getComponent={() => MessagesSettingsScreen} getComponent={() => MessagesSettingsScreen}
options={{title: title(msg`Chat settings`), requireAuth: true}} options={{title: title(msg`Chat settings`), requireAuth: true}}
/> />
<Stack.Screen name="Feeds" getComponent={() => FeedsScreen} />
</> </>
) )
} }
@ -330,7 +329,6 @@ function TabsNavigator() {
tabBar={tabBar}> tabBar={tabBar}>
<Tab.Screen name="HomeTab" getComponent={() => HomeTabNavigator} /> <Tab.Screen name="HomeTab" getComponent={() => HomeTabNavigator} />
<Tab.Screen name="SearchTab" getComponent={() => SearchTabNavigator} /> <Tab.Screen name="SearchTab" getComponent={() => SearchTabNavigator} />
<Tab.Screen name="FeedsTab" getComponent={() => FeedsTabNavigator} />
<Tab.Screen <Tab.Screen
name="NotificationsTab" name="NotificationsTab"
getComponent={() => NotificationsTabNavigator} getComponent={() => NotificationsTabNavigator}
@ -384,24 +382,6 @@ function SearchTabNavigator() {
) )
} }
function FeedsTabNavigator() {
const pal = usePalette('default')
return (
<FeedsTab.Navigator
screenOptions={{
animation: isAndroid ? 'ios' : undefined,
animationDuration: 285,
gestureEnabled: true,
fullScreenGestureEnabled: true,
headerShown: false,
contentStyle: pal.view,
}}>
<FeedsTab.Screen name="Feeds" getComponent={() => FeedsScreen} />
{commonScreens(FeedsTab as typeof HomeTab)}
</FeedsTab.Navigator>
)
}
function NotificationsTabNavigator() { function NotificationsTabNavigator() {
const pal = usePalette('default') const pal = usePalette('default')
return ( return (
@ -505,11 +485,6 @@ const FlatNavigator = () => {
getComponent={() => SearchScreen} getComponent={() => SearchScreen}
options={{title: title(msg`Search`)}} options={{title: title(msg`Search`)}}
/> />
<Flat.Screen
name="Feeds"
getComponent={() => FeedsScreen}
options={{title: title(msg`Feeds`)}}
/>
<Flat.Screen <Flat.Screen
name="Notifications" name="Notifications"
getComponent={() => NotificationsScreen} getComponent={() => NotificationsScreen}

View File

@ -0,0 +1,9 @@
import {createSinglePathSVG} from './TEMPLATE'
/*
* This icon is off-menu, not part of the icon set
*/
export const ListPlus_Stroke2_Corner0_Rounded = createSinglePathSVG({
path: 'M4 5a1 1 0 0 0 0 2h16a1 1 0 1 0 0-2H4Zm0 12a1 1 0 1 0 0 2h3a1 1 0 1 0 0-2H4Zm-1-5a1 1 0 0 1 1-1h5a1 1 0 1 1 0 2H4a1 1 0 0 1-1-1Zm14-3c.552 0 1 .41 1 .917V13.5h3.583c.507 0 .917.448.917 1s-.41 1-.917 1H18v3.583c0 .507-.448.917-1 .917s-1-.41-1-.917V15.5h-3.583c-.507 0-.917-.448-.917-1s.41-1 .917-1H16V9.917C16 9.41 16.448 9 17 9Z',
})

View File

@ -0,0 +1,5 @@
import {createSinglePathSVG} from './TEMPLATE'
export const Menu_Stroke2_Corner0_Rounded = createSinglePathSVG({
path: 'M2 6a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm0 6a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm0 6a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Z',
})

View File

@ -0,0 +1,5 @@
import {createSinglePathSVG} from './TEMPLATE'
export const Pin_Stroke2_Corner0_Rounded = createSinglePathSVG({
path: 'M6.5 3a1 1 0 0 1 1-1h9a1 1 0 0 1 1 1v3.997a6.25 6.25 0 0 0 1.83 4.42l.377.376A1 1 0 0 1 20 12.5V15a1 1 0 0 1-1 1h-6v5a1 1 0 1 1-2 0v-5H5a1 1 0 0 1-1-1v-2.5a1 1 0 0 1 .293-.707l.376-.377A6.25 6.25 0 0 0 6.5 6.996V3.001Zm2 1v2.997a8.25 8.25 0 0 1-2.416 5.834L6 12.914V14h12v-1.086l-.084-.083A8.25 8.25 0 0 1 15.5 6.997V4h-7Z',
})

View File

@ -0,0 +1,5 @@
import {createSinglePathSVG} from './TEMPLATE'
export const Shapes_Stroke2_Corner0_Rounded = createSinglePathSVG({
path: 'M7 3a1 1 0 0 1 1 1v2h2a1 1 0 1 1 0 2H8v2a1 1 0 1 1-2 0V8H4a1 1 0 0 1 0-2h2V4a1 1 0 0 1 1-1Zm6 4a4 4 0 1 1 8 0 4 4 0 0 1-8 0Zm4-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4ZM3 14a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-6Zm2 1v4h4v-4H5Zm9.171-.829a1 1 0 0 1 1.415 0L17 15.585l1.414-1.414a1 1 0 1 1 1.414 1.414L18.414 17l1.414 1.414a1 1 0 0 1-1.414 1.414L17 18.414l-1.415 1.414a1 1 0 0 1-1.414-1.414l1.415-1.415-1.415-1.414a1 1 0 0 1 0-1.414Z',
})

View File

@ -0,0 +1,9 @@
import {createSinglePathSVG} from './TEMPLATE'
export const Star_Stroke2_Corner0_Rounded = createSinglePathSVG({
path: 'M12 1a1 1 0 0 1 .902.568l2.643 5.517 6.085.799a1 1 0 0 1 .557 1.718l-4.45 4.207 1.118 6.008a1 1 0 0 1-1.46 1.063L12 17.962 6.604 20.88a1 1 0 0 1-1.459-1.063l1.117-6.008-4.45-4.207a1 1 0 0 1 .558-1.718l6.085-.8 2.643-5.516A1 1 0 0 1 12 1Zm0 3.315-1.975 4.123a1 1 0 0 1-.772.56l-4.538.595 3.317 3.137a1 1 0 0 1 .296.91l-.834 4.485 4.03-2.179a1 1 0 0 1 .952 0l4.03 2.179-.834-4.485a1 1 0 0 1 .296-.91l3.317-3.137-4.538-.596a1 1 0 0 1-.772-.56L12 4.316Z',
})
export const Star_Filled_Corner0_Rounded = createSinglePathSVG({
path: 'M12.902 1.568a1 1 0 0 0-1.804 0L8.455 7.085l-6.085.799a1 1 0 0 0-.557 1.718l4.45 4.207-1.117 6.008a1 1 0 0 0 1.458 1.063L12 17.962l5.396 2.918a1 1 0 0 0 1.459-1.063l-1.117-6.008 4.45-4.207a1 1 0 0 0-.558-1.718l-6.085-.8-2.643-5.516Z',
})

View File

@ -7,6 +7,7 @@ export function useNavigationTabState() {
const res = { const res = {
isAtHome: getTabState(state, 'Home') !== TabState.Outside, isAtHome: getTabState(state, 'Home') !== TabState.Outside,
isAtSearch: getTabState(state, 'Search') !== TabState.Outside, isAtSearch: getTabState(state, 'Search') !== TabState.Outside,
// FeedsTab no longer exists, but this check works for `Feeds` screen as well
isAtFeeds: getTabState(state, 'Feeds') !== TabState.Outside, isAtFeeds: getTabState(state, 'Feeds') !== TabState.Outside,
isAtNotifications: isAtNotifications:
getTabState(state, 'Notifications') !== TabState.Outside, getTabState(state, 'Notifications') !== TabState.Outside,

View File

@ -35,7 +35,7 @@ export function isStateAtTabRoot(state: State | undefined) {
return ( return (
isTab(currentRoute.name, 'Home') || isTab(currentRoute.name, 'Home') ||
isTab(currentRoute.name, 'Search') || isTab(currentRoute.name, 'Search') ||
isTab(currentRoute.name, 'Feeds') || isTab(currentRoute.name, 'Messages') ||
isTab(currentRoute.name, 'Notifications') || isTab(currentRoute.name, 'Notifications') ||
isTab(currentRoute.name, 'MyProfile') isTab(currentRoute.name, 'MyProfile')
) )

View File

@ -40,12 +40,12 @@ export type CommonNavigatorParams = {
Hashtag: {tag: string; author?: string} Hashtag: {tag: string; author?: string}
MessagesConversation: {conversation: string; embed?: string} MessagesConversation: {conversation: string; embed?: string}
MessagesSettings: undefined MessagesSettings: undefined
Feeds: undefined
} }
export type BottomTabNavigatorParams = CommonNavigatorParams & { export type BottomTabNavigatorParams = CommonNavigatorParams & {
HomeTab: undefined HomeTab: undefined
SearchTab: undefined SearchTab: undefined
FeedsTab: undefined
NotificationsTab: undefined NotificationsTab: undefined
MyProfileTab: undefined MyProfileTab: undefined
MessagesTab: undefined MessagesTab: undefined
@ -59,10 +59,6 @@ export type SearchTabNavigatorParams = CommonNavigatorParams & {
Search: {q?: string} Search: {q?: string}
} }
export type FeedsTabNavigatorParams = CommonNavigatorParams & {
Feeds: undefined
}
export type NotificationsTabNavigatorParams = CommonNavigatorParams & { export type NotificationsTabNavigatorParams = CommonNavigatorParams & {
Notifications: undefined Notifications: undefined
} }
@ -89,7 +85,6 @@ export type AllNavigatorParams = CommonNavigatorParams & {
Home: undefined Home: undefined
SearchTab: undefined SearchTab: undefined
Search: {q?: string} Search: {q?: string}
FeedsTab: undefined
Feeds: undefined Feeds: undefined
NotificationsTab: undefined NotificationsTab: undefined
Notifications: undefined Notifications: undefined

View File

@ -3,13 +3,10 @@ import {View} from 'react-native'
import {TID} from '@atproto/common-web' import {TID} from '@atproto/common-web'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native'
import {DISCOVER_SAVED_FEED, TIMELINE_SAVED_FEED} from '#/lib/constants' import {DISCOVER_SAVED_FEED, TIMELINE_SAVED_FEED} from '#/lib/constants'
import {isNative} from '#/platform/detection'
import {useOverwriteSavedFeedsMutation} from '#/state/queries/preferences' import {useOverwriteSavedFeedsMutation} from '#/state/queries/preferences'
import {UsePreferencesQueryResponse} from '#/state/queries/preferences' import {UsePreferencesQueryResponse} from '#/state/queries/preferences'
import {NavigationProp} from 'lib/routes/types'
import {CenteredView} from '#/view/com/util/Views' import {CenteredView} from '#/view/com/util/Views'
import {atoms as a} from '#/alf' import {atoms as a} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {Button, ButtonIcon, ButtonText} from '#/components/Button'
@ -26,7 +23,6 @@ export function NoFeedsPinned({
}) { }) {
const {_} = useLingui() const {_} = useLingui()
const headerOffset = useHeaderOffset() const headerOffset = useHeaderOffset()
const navigation = useNavigation<NavigationProp>()
const {isPending, mutateAsync: overwriteSavedFeeds} = const {isPending, mutateAsync: overwriteSavedFeeds} =
useOverwriteSavedFeedsMutation() useOverwriteSavedFeedsMutation()
@ -66,15 +62,6 @@ export function NoFeedsPinned({
await overwriteSavedFeeds(toSave) await overwriteSavedFeeds(toSave)
}, [overwriteSavedFeeds, preferences.savedFeeds]) }, [overwriteSavedFeeds, preferences.savedFeeds])
const onPressFeedsLink = React.useCallback(() => {
if (isNative) {
// Hack that's necessary due to how our navigators are set up.
navigation.navigate('FeedsTab')
navigation.popToTop()
return false
}
}, [navigation])
return ( return (
<CenteredView sideBorders style={[a.h_full_vh]}> <CenteredView sideBorders style={[a.h_full_vh]}>
<View <View
@ -115,7 +102,6 @@ export function NoFeedsPinned({
<Link <Link
label={_(msg`Browse other feeds`)} label={_(msg`Browse other feeds`)}
to="/feeds" to="/feeds"
onPress={onPressFeedsLink}
size="medium" size="medium"
variant="solid" variant="solid"
color="secondary"> color="secondary">

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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