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