[Experiment] Remove "Load Latest" button (#7120)
* Remove "show latest" behind the gate * Add HomeBadgeProvider * Update provider state from home feed tabs * Add Home badge to native * Add Home badge to mobile web * Add Home badge to desktop web
This commit is contained in:
+17
-14
@@ -32,6 +32,7 @@ import {
|
||||
ensureGeolocationResolved,
|
||||
Provider as GeolocationProvider,
|
||||
} from '#/state/geolocation'
|
||||
import {Provider as HomeBadgeProvider} from '#/state/home-badge'
|
||||
import {Provider as InvitesStateProvider} from '#/state/invites'
|
||||
import {Provider as LightboxStateProvider} from '#/state/lightbox'
|
||||
import {MessagesProvider} from '#/state/messages'
|
||||
@@ -137,20 +138,22 @@ function InnerApp() {
|
||||
<LoggedOutViewProvider>
|
||||
<SelectedFeedProvider>
|
||||
<HiddenRepliesProvider>
|
||||
<UnreadNotifsProvider>
|
||||
<BackgroundNotificationPreferencesProvider>
|
||||
<MutedThreadsProvider>
|
||||
<ProgressGuideProvider>
|
||||
<GestureHandlerRootView
|
||||
style={s.h100pct}>
|
||||
<TestCtrls />
|
||||
<Shell />
|
||||
<NuxDialogs />
|
||||
</GestureHandlerRootView>
|
||||
</ProgressGuideProvider>
|
||||
</MutedThreadsProvider>
|
||||
</BackgroundNotificationPreferencesProvider>
|
||||
</UnreadNotifsProvider>
|
||||
<HomeBadgeProvider>
|
||||
<UnreadNotifsProvider>
|
||||
<BackgroundNotificationPreferencesProvider>
|
||||
<MutedThreadsProvider>
|
||||
<ProgressGuideProvider>
|
||||
<GestureHandlerRootView
|
||||
style={s.h100pct}>
|
||||
<TestCtrls />
|
||||
<Shell />
|
||||
<NuxDialogs />
|
||||
</GestureHandlerRootView>
|
||||
</ProgressGuideProvider>
|
||||
</MutedThreadsProvider>
|
||||
</BackgroundNotificationPreferencesProvider>
|
||||
</UnreadNotifsProvider>
|
||||
</HomeBadgeProvider>
|
||||
</HiddenRepliesProvider>
|
||||
</SelectedFeedProvider>
|
||||
</LoggedOutViewProvider>
|
||||
|
||||
+15
-12
@@ -22,6 +22,7 @@ import {
|
||||
ensureGeolocationResolved,
|
||||
Provider as GeolocationProvider,
|
||||
} from '#/state/geolocation'
|
||||
import {Provider as HomeBadgeProvider} from '#/state/home-badge'
|
||||
import {Provider as InvitesStateProvider} from '#/state/invites'
|
||||
import {Provider as LightboxStateProvider} from '#/state/lightbox'
|
||||
import {MessagesProvider} from '#/state/messages'
|
||||
@@ -120,18 +121,20 @@ function InnerApp() {
|
||||
<LoggedOutViewProvider>
|
||||
<SelectedFeedProvider>
|
||||
<HiddenRepliesProvider>
|
||||
<UnreadNotifsProvider>
|
||||
<BackgroundNotificationPreferencesProvider>
|
||||
<MutedThreadsProvider>
|
||||
<SafeAreaProvider>
|
||||
<ProgressGuideProvider>
|
||||
<Shell />
|
||||
<NuxDialogs />
|
||||
</ProgressGuideProvider>
|
||||
</SafeAreaProvider>
|
||||
</MutedThreadsProvider>
|
||||
</BackgroundNotificationPreferencesProvider>
|
||||
</UnreadNotifsProvider>
|
||||
<HomeBadgeProvider>
|
||||
<UnreadNotifsProvider>
|
||||
<BackgroundNotificationPreferencesProvider>
|
||||
<MutedThreadsProvider>
|
||||
<SafeAreaProvider>
|
||||
<ProgressGuideProvider>
|
||||
<Shell />
|
||||
<NuxDialogs />
|
||||
</ProgressGuideProvider>
|
||||
</SafeAreaProvider>
|
||||
</MutedThreadsProvider>
|
||||
</BackgroundNotificationPreferencesProvider>
|
||||
</UnreadNotifsProvider>
|
||||
</HomeBadgeProvider>
|
||||
</HiddenRepliesProvider>
|
||||
</SelectedFeedProvider>
|
||||
</LoggedOutViewProvider>
|
||||
|
||||
@@ -2,3 +2,4 @@ export type Gate =
|
||||
// Keep this alphabetic please.
|
||||
| 'debug_show_feedcontext' // DISABLED DUE TO EME
|
||||
| 'post_feed_lang_window' // DISABLED DUE TO EME
|
||||
| 'remove_show_latest_button'
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react'
|
||||
|
||||
type StateContext = boolean
|
||||
type ApiContext = (hasNew: boolean) => void
|
||||
|
||||
const stateContext = React.createContext<StateContext>(false)
|
||||
const apiContext = React.createContext<ApiContext>((_: boolean) => {})
|
||||
|
||||
export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||
const [state, setState] = React.useState(false)
|
||||
return (
|
||||
<stateContext.Provider value={state}>
|
||||
<apiContext.Provider value={setState}>{children}</apiContext.Provider>
|
||||
</stateContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useHomeBadge() {
|
||||
return React.useContext(stateContext)
|
||||
}
|
||||
|
||||
export function useSetHomeBadge() {
|
||||
return React.useContext(apiContext)
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import {s} from '#/lib/styles'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {listenSoftReset} from '#/state/events'
|
||||
import {FeedFeedbackProvider, useFeedFeedback} from '#/state/feed-feedback'
|
||||
import {useSetHomeBadge} from '#/state/home-badge'
|
||||
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
|
||||
import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed'
|
||||
import {truncateAndInvalidate} from '#/state/queries/util'
|
||||
@@ -59,6 +60,13 @@ export function FeedPage({
|
||||
const feedFeedback = useFeedFeedback(feed, hasSession)
|
||||
const scrollElRef = React.useRef<ListMethods>(null)
|
||||
const [hasNew, setHasNew] = React.useState(false)
|
||||
const setHomeBadge = useSetHomeBadge()
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isPageFocused) {
|
||||
setHomeBadge(hasNew)
|
||||
}
|
||||
}, [isPageFocused, hasNew, setHomeBadge])
|
||||
|
||||
const scrollToTop = React.useCallback(() => {
|
||||
scrollElRef.current?.scrollToOffset({
|
||||
|
||||
@@ -9,6 +9,7 @@ import {useMinimalShellFabTransform} from '#/lib/hooks/useMinimalShellTransform'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {useGate} from '#/lib/statsig/statsig'
|
||||
import {colors} from '#/lib/styles'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useSession} from '#/state/session'
|
||||
@@ -34,6 +35,11 @@ export function LoadLatestBtn({
|
||||
// move button inline if it starts overlapping the left nav
|
||||
const isTallViewport = useMediaQuery({minHeight: 700})
|
||||
|
||||
const gate = useGate()
|
||||
if (gate('remove_show_latest_button')) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Adjust height of the fab if we have a session only on mobile web. If we don't have a session, we want to adjust
|
||||
// it on both tablet and mobile since we are showing the bottom bar (see createNativeStackNavigatorWithAuth)
|
||||
const showBottomBar = hasSession ? isMobile : isTabletOrMobile
|
||||
|
||||
@@ -15,8 +15,10 @@ import {useNavigationTabState} from '#/lib/hooks/useNavigationTabState'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {getTabState, TabState} from '#/lib/routes/helpers'
|
||||
import {useGate} from '#/lib/statsig/statsig'
|
||||
import {s} from '#/lib/styles'
|
||||
import {emitSoftReset} from '#/state/events'
|
||||
import {useHomeBadge} from '#/state/home-badge'
|
||||
import {useUnreadMessageCount} from '#/state/queries/messages/list-conversations'
|
||||
import {useUnreadNotifications} from '#/state/queries/notifications/unread'
|
||||
import {useProfileQuery} from '#/state/queries/profile'
|
||||
@@ -73,6 +75,8 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
||||
const dedupe = useDedupe()
|
||||
const accountSwitchControl = useDialogControl()
|
||||
const playHaptic = useHaptics()
|
||||
const hasHomeBadge = useHomeBadge()
|
||||
const gate = useGate()
|
||||
const iconWidth = 28
|
||||
|
||||
const showSignIn = React.useCallback(() => {
|
||||
@@ -153,6 +157,7 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
||||
/>
|
||||
)
|
||||
}
|
||||
hasNew={hasHomeBadge && gate('remove_show_latest_button')}
|
||||
onPress={onPressHome}
|
||||
accessibilityRole="tab"
|
||||
accessibilityLabel={_(msg`Home`)}
|
||||
@@ -334,6 +339,7 @@ interface BtnProps
|
||||
testID?: string
|
||||
icon: JSX.Element
|
||||
notificationCount?: string
|
||||
hasNew?: boolean
|
||||
onPress?: (event: GestureResponderEvent) => void
|
||||
onLongPress?: (event: GestureResponderEvent) => void
|
||||
}
|
||||
@@ -341,6 +347,7 @@ interface BtnProps
|
||||
function Btn({
|
||||
testID,
|
||||
icon,
|
||||
hasNew,
|
||||
notificationCount,
|
||||
onPress,
|
||||
onLongPress,
|
||||
@@ -363,7 +370,9 @@ function Btn({
|
||||
<View style={[styles.notificationCount, a.rounded_full]}>
|
||||
<Text style={styles.notificationCountLabel}>{notificationCount}</Text>
|
||||
</View>
|
||||
) : undefined}
|
||||
) : hasNew ? (
|
||||
<View style={[styles.hasNewBadge, a.rounded_full]} />
|
||||
) : null}
|
||||
</PressableScale>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -44,6 +44,17 @@ export const styles = StyleSheet.create({
|
||||
color: colors.white,
|
||||
fontVariant: ['tabular-nums'],
|
||||
},
|
||||
hasNewBadge: {
|
||||
position: 'absolute',
|
||||
left: '52%',
|
||||
marginLeft: 4,
|
||||
top: 10,
|
||||
width: 8,
|
||||
height: 8,
|
||||
backgroundColor: colors.blue3,
|
||||
borderRadius: 6,
|
||||
zIndex: 1,
|
||||
},
|
||||
ctrlIcon: {
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
|
||||
@@ -9,6 +9,8 @@ import {useMinimalShellFooterTransform} from '#/lib/hooks/useMinimalShellTransfo
|
||||
import {getCurrentRoute, isTab} from '#/lib/routes/helpers'
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {CommonNavigatorParams} from '#/lib/routes/types'
|
||||
import {useGate} from '#/lib/statsig/statsig'
|
||||
import {useHomeBadge} from '#/state/home-badge'
|
||||
import {useUnreadMessageCount} from '#/state/queries/messages/list-conversations'
|
||||
import {useUnreadNotifications} from '#/state/queries/notifications/unread'
|
||||
import {useSession} from '#/state/session'
|
||||
@@ -51,6 +53,8 @@ export function BottomBarWeb() {
|
||||
|
||||
const unreadMessageCount = useUnreadMessageCount()
|
||||
const notificationCountStr = useUnreadNotifications()
|
||||
const hasHomeBadge = useHomeBadge()
|
||||
const gate = useGate()
|
||||
|
||||
const showSignIn = React.useCallback(() => {
|
||||
closeAllActiveElements()
|
||||
@@ -75,7 +79,10 @@ export function BottomBarWeb() {
|
||||
]}>
|
||||
{hasSession ? (
|
||||
<>
|
||||
<NavItem routeName="Home" href="/">
|
||||
<NavItem
|
||||
routeName="Home"
|
||||
href="/"
|
||||
hasNew={hasHomeBadge && gate('remove_show_latest_button')}>
|
||||
{({isActive}) => {
|
||||
const Icon = isActive ? HomeFilled : Home
|
||||
return (
|
||||
@@ -105,7 +112,7 @@ export function BottomBarWeb() {
|
||||
<NavItem
|
||||
routeName="Messages"
|
||||
href="/messages"
|
||||
badge={
|
||||
notificationCount={
|
||||
unreadMessageCount.count > 0
|
||||
? unreadMessageCount.numUnread
|
||||
: undefined
|
||||
@@ -128,7 +135,7 @@ export function BottomBarWeb() {
|
||||
<NavItem
|
||||
routeName="Notifications"
|
||||
href="/notifications"
|
||||
badge={notificationCountStr}>
|
||||
notificationCount={notificationCountStr}>
|
||||
{({isActive}) => {
|
||||
const Icon = isActive ? BellFilled : Bell
|
||||
return (
|
||||
@@ -220,8 +227,9 @@ const NavItem: React.FC<{
|
||||
children: (props: {isActive: boolean}) => React.ReactChild
|
||||
href: string
|
||||
routeName: string
|
||||
badge?: string
|
||||
}> = ({children, href, routeName, badge}) => {
|
||||
hasNew?: boolean
|
||||
notificationCount?: string
|
||||
}> = ({children, href, routeName, hasNew, notificationCount}) => {
|
||||
const {_} = useLingui()
|
||||
const {currentAccount} = useSession()
|
||||
const currentRoute = useNavigationState(state => {
|
||||
@@ -246,13 +254,15 @@ const NavItem: React.FC<{
|
||||
aria-label={routeName}
|
||||
accessible={true}>
|
||||
{children({isActive})}
|
||||
{!!badge && (
|
||||
{notificationCount ? (
|
||||
<View
|
||||
style={styles.notificationCount}
|
||||
aria-label={_(msg`${badge} unread items`)}>
|
||||
<Text style={styles.notificationCountLabel}>{badge}</Text>
|
||||
aria-label={_(msg`${notificationCount} unread items`)}>
|
||||
<Text style={styles.notificationCountLabel}>{notificationCount}</Text>
|
||||
</View>
|
||||
)}
|
||||
) : hasNew ? (
|
||||
<View style={styles.hasNewBadge} />
|
||||
) : null}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,8 +14,10 @@ import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {getCurrentRoute, isTab} from '#/lib/routes/helpers'
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {CommonNavigatorParams} from '#/lib/routes/types'
|
||||
import {useGate} from '#/lib/statsig/statsig'
|
||||
import {isInvalidHandle} from '#/lib/strings/handles'
|
||||
import {emitSoftReset} from '#/state/events'
|
||||
import {useHomeBadge} from '#/state/home-badge'
|
||||
import {useFetchHandle} from '#/state/queries/handle'
|
||||
import {useUnreadMessageCount} from '#/state/queries/messages/list-conversations'
|
||||
import {useUnreadNotifications} from '#/state/queries/notifications/unread'
|
||||
@@ -100,12 +102,13 @@ function ProfileCard() {
|
||||
|
||||
interface NavItemProps {
|
||||
count?: string
|
||||
hasNew?: boolean
|
||||
href: string
|
||||
icon: JSX.Element
|
||||
iconFilled: JSX.Element
|
||||
label: string
|
||||
}
|
||||
function NavItem({count, href, icon, iconFilled, label}: NavItemProps) {
|
||||
function NavItem({count, hasNew, href, icon, iconFilled, label}: NavItemProps) {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const {currentAccount} = useSession()
|
||||
@@ -214,6 +217,24 @@ function NavItem({count, href, icon, iconFilled, label}: NavItemProps) {
|
||||
{count}
|
||||
</Text>
|
||||
</View>
|
||||
) : hasNew ? (
|
||||
<View
|
||||
style={[
|
||||
a.absolute,
|
||||
a.rounded_full,
|
||||
{
|
||||
backgroundColor: t.palette.primary_500,
|
||||
width: 8,
|
||||
height: 8,
|
||||
right: -1,
|
||||
top: -3,
|
||||
},
|
||||
isTablet && {
|
||||
right: 6,
|
||||
top: 4,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
{gtTablet && (
|
||||
@@ -322,6 +343,8 @@ export function DesktopLeftNav() {
|
||||
const {_} = useLingui()
|
||||
const {isDesktop, isTablet} = useWebMediaQueries()
|
||||
const numUnreadNotifications = useUnreadNotifications()
|
||||
const hasHomeBadge = useHomeBadge()
|
||||
const gate = useGate()
|
||||
|
||||
if (!hasSession && !isDesktop) {
|
||||
return null
|
||||
@@ -348,6 +371,7 @@ export function DesktopLeftNav() {
|
||||
<>
|
||||
<NavItem
|
||||
href="/"
|
||||
hasNew={hasHomeBadge && gate('remove_show_latest_button')}
|
||||
icon={
|
||||
<Home
|
||||
aria-hidden={true}
|
||||
|
||||
Reference in New Issue
Block a user