Bluesky app fork with some witchin' additions 馃挮
at main 120 lines 3.8 kB view raw
1import {View} from 'react-native' 2import {type AppBskyUnspeccedDefs} from '@atproto/api' 3import {Trans} from '@lingui/react/macro' 4 5import { 6 DEFAULT_LIMIT as RECOMMENDATIONS_COUNT, 7 useTrendingTopics, 8} from '#/state/queries/trending/useTrendingTopics' 9import {useTrendingConfig} from '#/state/service-config' 10import {atoms as a, useGutters, useTheme} from '#/alf' 11import {Hashtag_Stroke2_Corner0_Rounded} from '#/components/icons/Hashtag' 12import { 13 TrendingTopic, 14 TrendingTopicLink, 15 TrendingTopicSkeleton, 16} from '#/components/TrendingTopics' 17import {Text} from '#/components/Typography' 18import {useAnalytics} from '#/analytics' 19import {IS_WEB} from '#/env' 20 21// Note: This module is not currently used and may be removed in the future. 22 23export function ExploreRecommendations() { 24 const {enabled} = useTrendingConfig() 25 return enabled ? <Inner /> : null 26} 27 28function Inner() { 29 const t = useTheme() 30 const ax = useAnalytics() 31 const gutters = useGutters([0, 'compact']) 32 const {data: trending, error, isLoading} = useTrendingTopics() 33 const noRecs = !isLoading && !error && !trending?.suggested?.length 34 const allFeeds = trending?.suggested && isAllFeeds(trending.suggested) 35 36 return error || noRecs ? null : ( 37 <> 38 <View 39 style={[ 40 a.flex_row, 41 IS_WEB 42 ? [a.px_lg, a.py_lg, a.pt_2xl, a.gap_md] 43 : [a.p_lg, a.pt_2xl, a.gap_md], 44 a.border_b, 45 t.atoms.border_contrast_low, 46 ]}> 47 <View style={[a.flex_1, a.gap_sm]}> 48 <View style={[a.flex_row, a.align_center, a.gap_sm]}> 49 <Hashtag_Stroke2_Corner0_Rounded 50 size="lg" 51 fill={t.palette.primary_500} 52 style={{marginLeft: -2}} 53 /> 54 <Text style={[a.text_2xl, a.font_bold, t.atoms.text]}> 55 <Trans>Recommended</Trans> 56 </Text> 57 </View> 58 {!allFeeds ? ( 59 <Text style={[t.atoms.text_contrast_high, a.leading_snug]}> 60 <Trans> 61 Content from across the network we think you might like. 62 </Trans> 63 </Text> 64 ) : ( 65 <Text style={[t.atoms.text_contrast_high, a.leading_snug]}> 66 <Trans>Feeds we think you might like.</Trans> 67 </Text> 68 )} 69 </View> 70 </View> 71 72 <View style={[a.pt_md, a.pb_lg]}> 73 <View 74 style={[ 75 a.flex_row, 76 a.justify_start, 77 a.flex_wrap, 78 {rowGap: 8, columnGap: 6}, 79 gutters, 80 ]}> 81 {isLoading ? ( 82 Array(RECOMMENDATIONS_COUNT) 83 .fill(0) 84 .map((_, i) => <TrendingTopicSkeleton key={i} index={i} />) 85 ) : !trending?.suggested ? null : ( 86 <> 87 {trending.suggested.map(topic => ( 88 <TrendingTopicLink 89 key={topic.link} 90 topic={topic} 91 onPress={() => { 92 ax.metric('recommendedTopic:click', {context: 'explore'}) 93 }}> 94 {({hovered}) => ( 95 <TrendingTopic 96 topic={topic} 97 style={[ 98 hovered && [ 99 t.atoms.border_contrast_high, 100 t.atoms.bg_contrast_25, 101 ], 102 ]} 103 /> 104 )} 105 </TrendingTopicLink> 106 ))} 107 </> 108 )} 109 </View> 110 </View> 111 </> 112 ) 113} 114 115function isAllFeeds(topics: AppBskyUnspeccedDefs.TrendingTopic[]) { 116 return topics.every(topic => { 117 const segments = topic.link.split('/').slice(1) 118 return segments[0] === 'profile' && segments[2] === 'feed' 119 }) 120}