forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {View} from 'react-native'
2import {type AppBskyActorDefs} from '@atproto/api'
3import {msg} from '@lingui/core/macro'
4import {useLingui} from '@lingui/react'
5import {Trans} from '@lingui/react/macro'
6
7import {isInvalidHandle, sanitizeHandle} from '#/lib/strings/handles'
8import {sanitizePronouns} from '#/lib/strings/pronouns'
9import {type Shadow} from '#/state/cache/types'
10import {useShowFollowsYouBadge} from '#/state/preferences/show-follows-you-badge'
11import {useShowLinkInHandle} from '#/state/preferences/show-link-in-handle.tsx'
12import {atoms as a, useTheme, web} from '#/alf'
13import {InlineLinkText} from '#/components/Link.tsx'
14import {NewskieDialog} from '#/components/NewskieDialog'
15import {Text} from '#/components/Typography'
16import {IS_IOS, IS_NATIVE} from '#/env'
17
18export function ProfileHeaderHandle({
19 profile,
20 disableTaps,
21}: {
22 profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>
23 disableTaps?: boolean
24}) {
25 const t = useTheme()
26 const {_} = useLingui()
27 const invalidHandle = isInvalidHandle(profile.handle)
28 const pronouns = profile.pronouns
29 const blockHide = profile.viewer?.blocking || profile.viewer?.blockedBy
30 const isBskySocialHandle = profile.handle.endsWith('.bsky.social')
31 const showFollowsYouBadge = useShowFollowsYouBadge()
32 const showProfileInHandle = useShowLinkInHandle()
33 const sanitized = sanitizeHandle(
34 profile.handle,
35 '@',
36 // forceLTR handled by CSS above on web
37 IS_NATIVE,
38 )
39 return (
40 <View
41 style={[a.flex_row, a.gap_sm, a.align_center, {maxWidth: '100%'}]}
42 pointerEvents={disableTaps ? 'none' : IS_IOS ? 'auto' : 'box-none'}>
43 <NewskieDialog profile={profile} disabled={disableTaps} />
44 {showFollowsYouBadge && profile.viewer?.followedBy && !blockHide ? (
45 <View style={[t.atoms.bg_contrast_50, a.rounded_xs, a.px_sm, a.py_xs]}>
46 <Text style={[t.atoms.text, a.text_sm]}>
47 <Trans>Follows you</Trans>
48 </Text>
49 </View>
50 ) : undefined}
51 <View style={[a.flex_row, a.flex_wrap, {gap: 6}]}>
52 <Text
53 emoji
54 numberOfLines={1}
55 style={[
56 invalidHandle
57 ? [
58 a.border,
59 a.text_xs,
60 a.px_sm,
61 a.py_xs,
62 a.rounded_xs,
63 {borderColor: t.palette.contrast_200},
64 ]
65 : [a.text_md, a.leading_tight, t.atoms.text_contrast_medium],
66 web({
67 wordBreak: 'break-all',
68 direction: 'ltr',
69 unicodeBidi: 'isolate',
70 }),
71 ]}>
72 {invalidHandle ? (
73 _(msg`鈿營nvalid Handle`)
74 ) : showProfileInHandle && !isBskySocialHandle ? (
75 <InlineLinkText
76 to={`https://${profile.handle}`}
77 label={profile.handle}>
78 <Text style={[a.text_md, {color: t.palette.primary_500}]}>
79 {sanitized}
80 </Text>
81 </InlineLinkText>
82 ) : (
83 sanitized
84 )}
85 </Text>
86 {pronouns && (
87 <Text style={[t.atoms.text_contrast_low, a.text_md, a.leading_tight]}>
88 {sanitizePronouns(pronouns, IS_NATIVE)}
89 </Text>
90 )}
91 </View>
92 </View>
93 )
94}