Skip to content

Commit

Permalink
[Experiment] Remove "Load Latest" button (#7120)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
gaearon authored Dec 15, 2024
1 parent 80c0125 commit 1ac307b
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 37 deletions.
31 changes: 17 additions & 14 deletions src/App.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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>
Expand Down
27 changes: 15 additions & 12 deletions src/App.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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>
Expand Down
1 change: 1 addition & 0 deletions src/lib/statsig/gates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
24 changes: 24 additions & 0 deletions src/state/home-badge.tsx
Original file line number Diff line number Diff line change
@@ -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)
}
8 changes: 8 additions & 0 deletions src/view/com/feeds/FeedPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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({
Expand Down
6 changes: 6 additions & 0 deletions src/view/com/util/load-latest/LoadLatestBtn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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
Expand Down
11 changes: 10 additions & 1 deletion src/view/shell/bottom-bar/BottomBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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(() => {
Expand Down Expand Up @@ -153,6 +157,7 @@ export function BottomBar({navigation}: BottomTabBarProps) {
/>
)
}
hasNew={hasHomeBadge && gate('remove_show_latest_button')}
onPress={onPressHome}
accessibilityRole="tab"
accessibilityLabel={_(msg`Home`)}
Expand Down Expand Up @@ -334,13 +339,15 @@ interface BtnProps
testID?: string
icon: JSX.Element
notificationCount?: string
hasNew?: boolean
onPress?: (event: GestureResponderEvent) => void
onLongPress?: (event: GestureResponderEvent) => void
}

function Btn({
testID,
icon,
hasNew,
notificationCount,
onPress,
onLongPress,
Expand All @@ -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>
)
}
11 changes: 11 additions & 0 deletions src/view/shell/bottom-bar/BottomBarStyles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
28 changes: 19 additions & 9 deletions src/view/shell/bottom-bar/BottomBarWeb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -51,6 +53,8 @@ export function BottomBarWeb() {

const unreadMessageCount = useUnreadMessageCount()
const notificationCountStr = useUnreadNotifications()
const hasHomeBadge = useHomeBadge()
const gate = useGate()

const showSignIn = React.useCallback(() => {
closeAllActiveElements()
Expand All @@ -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 (
Expand Down Expand Up @@ -105,7 +112,7 @@ export function BottomBarWeb() {
<NavItem
routeName="Messages"
href="/messages"
badge={
notificationCount={
unreadMessageCount.count > 0
? unreadMessageCount.numUnread
: undefined
Expand All @@ -128,7 +135,7 @@ export function BottomBarWeb() {
<NavItem
routeName="Notifications"
href="/notifications"
badge={notificationCountStr}>
notificationCount={notificationCountStr}>
{({isActive}) => {
const Icon = isActive ? BellFilled : Bell
return (
Expand Down Expand Up @@ -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 => {
Expand All @@ -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>
)
}
26 changes: 25 additions & 1 deletion src/view/shell/desktop/LeftNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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 && (
Expand Down Expand Up @@ -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
Expand All @@ -348,6 +371,7 @@ export function DesktopLeftNav() {
<>
<NavItem
href="/"
hasNew={hasHomeBadge && gate('remove_show_latest_button')}
icon={
<Home
aria-hidden={true}
Expand Down

0 comments on commit 1ac307b

Please sign in to comment.