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