Update trending topics UI (#11304)

This commit is contained in:
DS Boyce
2026-07-27 16:34:15 -07:00
committed by GitHub
parent d9eacc3d98
commit a5f0e8839a
10 changed files with 281 additions and 203 deletions
@@ -9,6 +9,7 @@ import {atoms as a, native, useTheme, type ViewStyleProp} from '#/alf'
import {Button, ButtonIcon} from '#/components/Button'
import * as FeedCard from '#/components/FeedCard'
import {sizes as iconSizes} from '#/components/icons/common'
import {DotGrid3x1_Stroke2_Corner0_Rounded as EllipsisIcon} from '#/components/icons/DotGrid'
import {MagnifyingGlass_Stroke2_Corner0_Rounded as SearchIcon} from '#/components/icons/MagnifyingGlass'
import {Link} from '#/components/Link'
import {Text, type TextProps} from '#/components/Typography'
@@ -151,6 +152,32 @@ export function SearchButton({
)
}
export function EllipsisButton({
label,
onPress,
}: {
label: string
onPress?: () => void
}) {
return (
<Button
label={label}
size="small"
variant="ghost"
color="secondary"
shape="round"
PressableComponent={native(PressableScale)}
onPress={onPress}
style={[
{
right: -4,
},
]}>
<ButtonIcon icon={EllipsisIcon} size="md" />
</Button>
)
}
export function PinButton({feed}: {feed: AppBskyFeedDefs.GeneratorView}) {
return (
<View style={[a.z_20, {marginRight: -6}]}>
@@ -9,7 +9,10 @@ import {
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useTrendingSettings} from '#/state/preferences/trending'
import {
useTrendingSettings,
useTrendingSettingsApi,
} from '#/state/preferences/trending'
import {useGetTrendsQuery} from '#/state/queries/trending/useGetTrendsQuery'
import {useTrendingConfig} from '#/state/service-config'
import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
@@ -18,6 +21,7 @@ import {atoms as a, useGutters, useTheme, type ViewStyleProp} from '#/alf'
import {AvatarStack} from '#/components/AvatarStack'
import {Trending3_Stroke2_Corner1_Rounded as TrendingIcon} from '#/components/icons/Trending'
import {Link} from '#/components/Link'
import * as Prompt from '#/components/Prompt'
import {RichText} from '#/components/RichText'
import {SubtleHover} from '#/components/SubtleHover'
import {Text} from '#/components/Typography'
@@ -36,6 +40,9 @@ export function ExploreTrendingTopics() {
function Inner() {
const ax = useAnalytics()
const {t: l} = useLingui()
const trendingPrompt = Prompt.usePromptControl()
const {setTrendingDisabled} = useTrendingSettingsApi()
const {data: trending, error, isLoading, isRefetching} = useGetTrendsQuery()
const noTopics = !isLoading && !error && !trending?.trends?.length
const showLoading = isLoading || isRefetching
@@ -43,31 +50,48 @@ function Inner() {
if (!showLoading && (error || !trending?.trends || noTopics)) return null
return (
<View style={[a.pb_md]}>
<ModuleHeader.Container bottomBorder>
<ModuleHeader.Icon icon={TrendingIcon} size="md" />
<ModuleHeader.TitleText>
<Trans>Trending</Trans>
</ModuleHeader.TitleText>
</ModuleHeader.Container>
{showLoading
? Array.from({length: TOPIC_COUNT}).map((__, i) => (
<TrendingTopicRowSkeleton key={i} />
))
: trending?.trends.map((trend, index) => (
<TrendRow
key={trend.link}
trend={trend}
rank={index + 1}
onPress={() => {
ax.metric('trendingTopic:click', {
context: 'explore',
recId: trending.recId,
})
}}
/>
))}
</View>
<>
<View style={[a.pb_md]}>
<ModuleHeader.Container bottomBorder>
<ModuleHeader.Icon icon={TrendingIcon} size="md" />
<ModuleHeader.TitleText>
<Trans>Trending</Trans>
</ModuleHeader.TitleText>
<ModuleHeader.EllipsisButton
label={l`Trending options`}
onPress={() => trendingPrompt.open()}
/>
</ModuleHeader.Container>
{showLoading
? Array.from({length: TOPIC_COUNT}).map((__, i) => (
<TrendingTopicRowSkeleton key={i} />
))
: trending?.trends.map((trend, index) => (
<TrendRow
key={trend.link}
trend={trend}
rank={index + 1}
onPress={() => {
ax.metric('trendingTopic:click', {
context: 'explore',
recId: trending.recId,
})
}}
/>
))}
</View>
<Prompt.Basic
control={trendingPrompt}
title={l`Hide trending topics?`}
description={l`You can update this later from your settings.`}
confirmButtonCta={l`Hide`}
onConfirm={() => {
ax.metric('trendingTopics:hide', {context: 'explore:trending'})
setTrendingDisabled(true)
}}
/>
</>
)
}
@@ -112,7 +136,7 @@ export function TrendRow({
<View style={[gutters, a.w_full, a.flex_row, a.py_md, a.gap_sm]}>
<Text
style={[
a.text_sm,
a.text_md,
a.font_medium,
t.atoms.text_contrast_low,
@@ -126,7 +150,7 @@ export function TrendRow({
</Text>
<View style={[a.flex_1, a.gap_2xs]}>
<Text
style={[a.text_sm, a.font_semi_bold, a.leading_snug]}
style={[a.text_md, a.font_semi_bold, a.leading_snug]}
numberOfLines={1}>
{trend.displayName}
</Text>