forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {View} from 'react-native'
2import {msg, Trans} from '@lingui/macro'
3import {useLingui} from '@lingui/react'
4
5import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
6import {
7 useTrendingSettings,
8 useTrendingSettingsApi,
9} from '#/state/preferences/trending'
10import {useTrendingTopics} from '#/state/queries/trending/useTrendingTopics'
11import {useTrendingConfig} from '#/state/service-config'
12import {atoms as a, useTheme} from '#/alf'
13import {Button, ButtonIcon} from '#/components/Button'
14import {DotGrid_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/DotGrid'
15import {Trending3_Stroke2_Corner1_Rounded as TrendingIcon} from '#/components/icons/Trending'
16import * as Prompt from '#/components/Prompt'
17import {TrendingTopicLink} from '#/components/TrendingTopics'
18import {Text} from '#/components/Typography'
19import {useAnalytics} from '#/analytics'
20
21const TRENDING_LIMIT = 5
22
23export function SidebarTrendingTopics() {
24 const {enabled} = useTrendingConfig()
25 const {trendingDisabled} = useTrendingSettings()
26 return !enabled ? null : trendingDisabled ? null : <Inner />
27}
28
29function Inner() {
30 const t = useTheme()
31 const {_} = useLingui()
32 const ax = useAnalytics()
33 const trendingPrompt = Prompt.usePromptControl()
34 const {setTrendingDisabled} = useTrendingSettingsApi()
35 const {data: trending, error, isLoading} = useTrendingTopics()
36 const noTopics = !isLoading && !error && !trending?.topics?.length
37
38 const enableSquareButtons = useEnableSquareButtons()
39
40 const onConfirmHide = () => {
41 ax.metric('trendingTopics:hide', {context: 'sidebar'})
42 setTrendingDisabled(true)
43 }
44
45 return error || noTopics ? null : (
46 <>
47 <View
48 style={[a.p_lg, a.rounded_md, a.border, t.atoms.border_contrast_low]}>
49 <View style={[a.flex_row, a.align_center, a.gap_xs, a.pb_md]}>
50 <TrendingIcon width={16} height={16} fill={t.atoms.text.color} />
51 <Text style={[a.flex_1, a.text_md, a.font_semi_bold, t.atoms.text]}>
52 <Trans>Trending</Trans>
53 </Text>
54 <Button
55 variant="ghost"
56 size="tiny"
57 color="secondary"
58 shape={enableSquareButtons ? 'square' : 'round'}
59 label={_(msg`Trending options`)}
60 onPress={() => trendingPrompt.open()}
61 style={[a.bg_transparent, {marginTop: -6, marginRight: -6}]}>
62 <ButtonIcon icon={Ellipsis} size="xs" />
63 </Button>
64 </View>
65
66 <View style={[a.gap_xs]}>
67 {isLoading ? (
68 Array(TRENDING_LIMIT)
69 .fill(0)
70 .map((_n, i) => (
71 <View key={i} style={[a.flex_row, a.align_center, a.gap_sm]}>
72 <Text
73 style={[
74 a.text_sm,
75 t.atoms.text_contrast_low,
76 {minWidth: 16},
77 ]}>
78 {i + 1}.
79 </Text>
80 <View
81 style={[
82 a.rounded_xs,
83 t.atoms.bg_contrast_50,
84 {height: 14, width: i % 2 === 0 ? 80 : 100},
85 ]}
86 />
87 </View>
88 ))
89 ) : !trending?.topics ? null : (
90 <>
91 {trending.topics.slice(0, TRENDING_LIMIT).map((topic, i) => (
92 <TrendingTopicLink
93 key={topic.link}
94 topic={topic}
95 style={[a.self_start]}
96 onPress={() => {
97 ax.metric('trendingTopic:click', {context: 'sidebar'})
98 }}>
99 {({hovered}) => (
100 <View style={[a.flex_row, a.align_center, a.gap_xs]}>
101 <Text
102 style={[
103 a.text_sm,
104 a.leading_snug,
105 t.atoms.text_contrast_low,
106 {minWidth: 16},
107 ]}>
108 {i + 1}.
109 </Text>
110 <Text
111 style={[
112 a.text_sm,
113 a.leading_snug,
114 hovered
115 ? [t.atoms.text, a.underline]
116 : t.atoms.text_contrast_medium,
117 ]}
118 numberOfLines={1}>
119 {topic.displayName ?? topic.topic}
120 </Text>
121 </View>
122 )}
123 </TrendingTopicLink>
124 ))}
125 </>
126 )}
127 </View>
128 </View>
129 <Prompt.Basic
130 control={trendingPrompt}
131 title={_(msg`Hide trending topics?`)}
132 description={_(msg`You can update this later from your settings.`)}
133 confirmButtonCta={_(msg`Hide`)}
134 onConfirm={onConfirmHide}
135 />
136 </>
137 )
138}