Bluesky app fork with some witchin' additions 馃挮
at post-text-option 134 lines 4.0 kB view raw
1import {StyleSheet, View} from 'react-native' 2import {AppBskyFeedDefs, type ModerationDecision} from '@atproto/api' 3import {msg, Trans} from '@lingui/macro' 4import {useLingui} from '@lingui/react' 5 6import {isReasonFeedSource, type ReasonFeedSource} from '#/lib/api/feed/types' 7import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name' 8import {makeProfileLink} from '#/lib/routes/links' 9import {getTerminology, TERMINOLOGY} from '#/lib/strings/terminology' 10import {useTerminologyPreference} from '#/state/preferences' 11import {useSession} from '#/state/session' 12import {atoms as a, useTheme} from '#/alf' 13import {Pin_Stroke2_Corner0_Rounded as PinIcon} from '#/components/icons/Pin' 14import {Repost_Stroke2_Corner3_Rounded as RepostIcon} from '#/components/icons/Repost' 15import {Link} from '#/components/Link' 16import {ProfileHoverCard} from '#/components/ProfileHoverCard' 17import {Text} from '#/components/Typography' 18import {FeedNameText} from '../util/FeedInfoText' 19 20export function PostFeedReason({ 21 reason, 22 moderation, 23 onOpenReposter, 24}: { 25 reason: 26 | ReasonFeedSource 27 | AppBskyFeedDefs.ReasonRepost 28 | AppBskyFeedDefs.ReasonPin 29 | {[k: string]: unknown; $type: string} 30 moderation?: ModerationDecision 31 onOpenReposter?: () => void 32}) { 33 const t = useTheme() 34 const {_} = useLingui() 35 const terminologyPreference = useTerminologyPreference() 36 37 const {currentAccount} = useSession() 38 39 if (isReasonFeedSource(reason)) { 40 return ( 41 <Link label={_(msg`Go to feed`)} to={reason.href}> 42 <Text 43 style={[ 44 t.atoms.text_contrast_medium, 45 a.font_medium, 46 a.leading_snug, 47 a.leading_snug, 48 ]} 49 numberOfLines={1}> 50 <Trans context="from-feed"> 51 From{' '} 52 <FeedNameText 53 uri={reason.uri} 54 href={reason.href} 55 style={[ 56 t.atoms.text_contrast_medium, 57 a.font_medium, 58 a.leading_snug, 59 ]} 60 numberOfLines={1} 61 /> 62 </Trans> 63 </Text> 64 </Link> 65 ) 66 } 67 68 if (AppBskyFeedDefs.isReasonRepost(reason)) { 69 const isOwner = reason.by.did === currentAccount?.did 70 const reposter = createSanitizedDisplayName( 71 reason.by, 72 false, 73 moderation?.ui('displayName'), 74 ) 75 return ( 76 <Link 77 style={styles.includeReason} 78 to={makeProfileLink(reason.by)} 79 label={ 80 isOwner 81 ? _(getTerminology(terminologyPreference, TERMINOLOGY.repost.byLine)) 82 : `${_(getTerminology(terminologyPreference, TERMINOLOGY.repost.byLine))} ${reposter}` 83 } 84 onPress={onOpenReposter}> 85 <RepostIcon 86 style={[t.atoms.text_contrast_medium, {marginRight: 3}]} 87 width={13} 88 height={13} 89 /> 90 <ProfileHoverCard did={reason.by.did}> 91 <Text 92 style={[ 93 t.atoms.text_contrast_medium, 94 a.font_medium, 95 a.leading_snug, 96 ]} 97 numberOfLines={1}> 98 {isOwner ? ( 99 <Trans>{_(getTerminology(terminologyPreference, TERMINOLOGY.repost.byLine))}</Trans> 100 ) : ( 101 <Trans>{_(getTerminology(terminologyPreference, TERMINOLOGY.repost.byLine))} {reposter}</Trans> 102 )} 103 </Text> 104 </ProfileHoverCard> 105 </Link> 106 ) 107 } 108 109 if (AppBskyFeedDefs.isReasonPin(reason)) { 110 return ( 111 <View style={styles.includeReason}> 112 <PinIcon 113 style={[t.atoms.text_contrast_medium, {marginRight: 3}]} 114 width={13} 115 height={13} 116 /> 117 <Text 118 style={[t.atoms.text_contrast_medium, a.font_medium, a.leading_snug]} 119 numberOfLines={1}> 120 <Trans>Pinned</Trans> 121 </Text> 122 </View> 123 ) 124 } 125} 126 127const styles = StyleSheet.create({ 128 includeReason: { 129 flexDirection: 'row', 130 alignItems: 'center', 131 marginBottom: 2, 132 marginLeft: -16, 133 }, 134})