Bluesky app fork with some witchin' additions 馃挮
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 182 lines 4.4 kB view raw
1import {useMemo} from 'react' 2import {View} from 'react-native' 3import {BSKY_LABELER_DID, type ModerationCause} from '@atproto/api' 4import {Trans} from '@lingui/react/macro' 5 6import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' 7import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons' 8import {UserAvatar} from '#/view/com/util/UserAvatar' 9import {atoms as a, useTheme, type ViewStyleProp} from '#/alf' 10import {Button} from '#/components/Button' 11import { 12 ModerationDetailsDialog, 13 useModerationDetailsDialogControl, 14} from '#/components/moderation/ModerationDetailsDialog' 15import {Text} from '#/components/Typography' 16 17export type AppModerationCause = 18 | ModerationCause 19 | { 20 type: 'reply-hidden' 21 source: {type: 'user'; did: string} 22 priority: 6 23 downgraded?: boolean 24 } 25 26export type CommonProps = { 27 size?: 'sm' | 'lg' 28} 29 30export function Row({ 31 children, 32 style, 33 size = 'sm', 34}: {children: React.ReactNode | React.ReactNode[]} & CommonProps & 35 ViewStyleProp) { 36 const styles = useMemo(() => { 37 switch (size) { 38 case 'lg': 39 return [{gap: 5}] 40 case 'sm': 41 default: 42 return [{gap: 3}] 43 } 44 }, [size]) 45 return ( 46 <View style={[a.flex_row, a.flex_wrap, a.gap_xs, styles, style]}> 47 {children} 48 </View> 49 ) 50} 51 52export type LabelProps = { 53 cause: AppModerationCause 54 disableDetailsDialog?: boolean 55 noBg?: boolean 56} & CommonProps 57 58export function Label({ 59 cause, 60 size = 'sm', 61 disableDetailsDialog, 62 noBg, 63}: LabelProps) { 64 const t = useTheme() 65 const control = useModerationDetailsDialogControl() 66 const desc = useModerationCauseDescription(cause) 67 const isLabeler = Boolean(desc.sourceType && desc.sourceDid) 68 const isBlueskyLabel = 69 desc.sourceType === 'labeler' && desc.sourceDid === BSKY_LABELER_DID 70 71 const enableSquareButtons = useEnableSquareButtons() 72 73 const {outer, avi, text} = useMemo(() => { 74 switch (size) { 75 case 'lg': { 76 return { 77 outer: [ 78 t.atoms.bg_contrast_25, 79 { 80 gap: 5, 81 paddingHorizontal: 5, 82 paddingVertical: 5, 83 }, 84 ], 85 avi: 16, 86 text: [a.text_sm], 87 } 88 } 89 case 'sm': 90 default: { 91 return { 92 outer: [ 93 !noBg && t.atoms.bg_contrast_25, 94 { 95 gap: 3, 96 paddingHorizontal: 3, 97 paddingVertical: 3, 98 }, 99 ], 100 avi: 12, 101 text: [a.text_xs], 102 } 103 } 104 } 105 }, [t, size, noBg]) 106 107 return ( 108 <> 109 <Button 110 disabled={disableDetailsDialog} 111 label={desc.name} 112 onPress={e => { 113 e.preventDefault() 114 e.stopPropagation() 115 control.open() 116 }}> 117 {({hovered, pressed}) => ( 118 <View 119 style={[ 120 a.flex_row, 121 a.align_center, 122 enableSquareButtons ? a.rounded_sm : a.rounded_full, 123 outer, 124 (hovered || pressed) && t.atoms.bg_contrast_50, 125 ]}> 126 {isBlueskyLabel || !isLabeler ? ( 127 <desc.icon 128 width={avi} 129 fill={t.atoms.text_contrast_medium.color} 130 /> 131 ) : ( 132 <UserAvatar avatar={desc.sourceAvi} type="user" size={avi} /> 133 )} 134 135 <Text 136 emoji 137 style={[ 138 text, 139 a.font_semi_bold, 140 a.leading_tight, 141 t.atoms.text_contrast_medium, 142 {paddingRight: 3}, 143 ]}> 144 {desc.name} 145 </Text> 146 </View> 147 )} 148 </Button> 149 150 {!disableDetailsDialog && ( 151 <ModerationDetailsDialog control={control} modcause={cause} /> 152 )} 153 </> 154 ) 155} 156 157export function FollowsYou({size = 'sm'}: CommonProps) { 158 const t = useTheme() 159 160 const variantStyles = useMemo(() => { 161 switch (size) { 162 case 'sm': 163 case 'lg': 164 default: 165 return [ 166 { 167 paddingHorizontal: 6, 168 paddingVertical: 3, 169 borderRadius: 4, 170 }, 171 ] 172 } 173 }, [size]) 174 175 return ( 176 <View style={[variantStyles, a.justify_center, t.atoms.bg_contrast_50]}> 177 <Text style={[a.text_xs, a.leading_tight]}> 178 <Trans>Follows You</Trans> 179 </Text> 180 </View> 181 ) 182}