mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
at thread-bug 165 lines 3.9 kB view raw
1import {useMemo} from 'react' 2import {View} from 'react-native' 3import {type AppBskyFeedDefs, AtUri} from '@atproto/api' 4 5import {PressableScale} from '#/lib/custom-animations/PressableScale' 6import {makeCustomFeedLink} from '#/lib/routes/links' 7import {logger} from '#/logger' 8import {UserAvatar} from '#/view/com/util/UserAvatar' 9import {atoms as a, native, useTheme, type ViewStyleProp} from '#/alf' 10import {Button, ButtonIcon} from '#/components/Button' 11import * as FeedCard from '#/components/FeedCard' 12import {sizes as iconSizes} from '#/components/icons/common' 13import {MagnifyingGlass2_Stroke2_Corner0_Rounded as SearchIcon} from '#/components/icons/MagnifyingGlass2' 14import {Link} from '#/components/Link' 15import {Text, type TextProps} from '#/components/Typography' 16 17export function Container({ 18 style, 19 children, 20 bottomBorder, 21}: { 22 children: React.ReactNode 23 bottomBorder?: boolean 24} & ViewStyleProp) { 25 const t = useTheme() 26 return ( 27 <View 28 style={[ 29 a.flex_row, 30 a.align_center, 31 a.px_lg, 32 a.pt_2xl, 33 a.pb_md, 34 a.gap_sm, 35 t.atoms.bg, 36 bottomBorder && [a.border_b, t.atoms.border_contrast_low], 37 style, 38 ]}> 39 {children} 40 </View> 41 ) 42} 43 44export function FeedLink({ 45 feed, 46 children, 47}: { 48 feed: AppBskyFeedDefs.GeneratorView 49 children?: React.ReactNode 50}) { 51 const t = useTheme() 52 const {host: did, rkey} = useMemo(() => new AtUri(feed.uri), [feed.uri]) 53 return ( 54 <Link 55 to={makeCustomFeedLink(did, rkey)} 56 label={feed.displayName} 57 style={[a.flex_1]}> 58 {({focused, hovered, pressed}) => ( 59 <View 60 style={[ 61 a.flex_1, 62 a.flex_row, 63 a.align_center, 64 {gap: 10}, 65 a.rounded_md, 66 a.p_xs, 67 {marginLeft: -6}, 68 (focused || hovered || pressed) && t.atoms.bg_contrast_25, 69 ]}> 70 {children} 71 </View> 72 )} 73 </Link> 74 ) 75} 76 77export function FeedAvatar({feed}: {feed: AppBskyFeedDefs.GeneratorView}) { 78 return <UserAvatar type="algo" size={38} avatar={feed.avatar} /> 79} 80 81export function Icon({ 82 icon: Comp, 83 size = 'lg', 84}: Pick<React.ComponentProps<typeof ButtonIcon>, 'icon' | 'size'>) { 85 const iconSize = iconSizes[size] 86 87 return ( 88 <View style={[a.z_20, {width: iconSize, height: iconSize, marginLeft: -2}]}> 89 <Comp width={iconSize} /> 90 </View> 91 ) 92} 93 94export function TitleText({style, ...props}: TextProps) { 95 return ( 96 <Text style={[a.font_bold, a.flex_1, a.text_xl, style]} emoji {...props} /> 97 ) 98} 99 100export function SubtitleText({style, ...props}: TextProps) { 101 const t = useTheme() 102 return ( 103 <Text 104 style={[ 105 t.atoms.text_contrast_medium, 106 a.leading_tight, 107 a.flex_1, 108 a.text_sm, 109 style, 110 ]} 111 {...props} 112 /> 113 ) 114} 115 116export function SearchButton({ 117 label, 118 metricsTag, 119 onPress, 120}: { 121 label: string 122 metricsTag: 'suggestedAccounts' | 'suggestedFeeds' 123 onPress?: () => void 124}) { 125 return ( 126 <Button 127 label={label} 128 size="small" 129 variant="ghost" 130 color="secondary" 131 shape="round" 132 PressableComponent={native(PressableScale)} 133 onPress={() => { 134 logger.metric( 135 'explore:module:searchButtonPress', 136 {module: metricsTag}, 137 {statsig: true}, 138 ) 139 onPress?.() 140 }} 141 style={[ 142 { 143 right: -4, 144 }, 145 ]}> 146 <ButtonIcon icon={SearchIcon} size="lg" /> 147 </Button> 148 ) 149} 150 151export function PinButton({feed}: {feed: AppBskyFeedDefs.GeneratorView}) { 152 return ( 153 <View style={[a.z_20, {marginRight: -6}]}> 154 <FeedCard.SaveButton 155 pin 156 view={feed} 157 size="large" 158 color="secondary" 159 variant="ghost" 160 shape="square" 161 text={false} 162 /> 163 </View> 164 ) 165}