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