mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import React, {memo} from 'react'
2import {StyleProp, StyleSheet, TextStyle, View, ViewStyle} from 'react-native'
3import {Text} from './text/Text'
4import {TextLinkOnWebOnly} from './Link'
5import {niceDate} from 'lib/strings/time'
6import {usePalette} from 'lib/hooks/usePalette'
7import {TypographyVariant} from 'lib/ThemeContext'
8import {UserAvatar} from './UserAvatar'
9import {sanitizeDisplayName} from 'lib/strings/display-names'
10import {sanitizeHandle} from 'lib/strings/handles'
11import {isAndroid, isWeb} from 'platform/detection'
12import {TimeElapsed} from './TimeElapsed'
13import {makeProfileLink} from 'lib/routes/links'
14import {ModerationUI} from '@atproto/api'
15import {usePrefetchProfileQuery} from '#/state/queries/profile'
16
17interface PostMetaOpts {
18 author: {
19 avatar?: string
20 did: string
21 handle: string
22 displayName?: string | undefined
23 }
24 authorHasWarning: boolean
25 postHref: string
26 timestamp: string
27 showAvatar?: boolean
28 avatarModeration?: ModerationUI
29 avatarSize?: number
30 displayNameType?: TypographyVariant
31 displayNameStyle?: StyleProp<TextStyle>
32 style?: StyleProp<ViewStyle>
33}
34
35let PostMeta = (opts: PostMetaOpts): React.ReactNode => {
36 const pal = usePalette('default')
37 const displayName = opts.author.displayName || opts.author.handle
38 const handle = opts.author.handle
39 const prefetchProfileQuery = usePrefetchProfileQuery()
40
41 return (
42 <View style={[styles.container, opts.style]}>
43 {opts.showAvatar && (
44 <View style={styles.avatar}>
45 <UserAvatar
46 avatar={opts.author.avatar}
47 size={opts.avatarSize || 16}
48 moderation={opts.avatarModeration}
49 />
50 </View>
51 )}
52 <View style={styles.maxWidth}>
53 <TextLinkOnWebOnly
54 type={opts.displayNameType || 'lg-bold'}
55 style={[pal.text, opts.displayNameStyle]}
56 numberOfLines={1}
57 lineHeight={1.2}
58 text={
59 <>
60 {sanitizeDisplayName(displayName)}
61 <Text
62 type="md"
63 numberOfLines={1}
64 lineHeight={1.2}
65 style={pal.textLight}>
66 {sanitizeHandle(handle, '@')}
67 </Text>
68 </>
69 }
70 href={makeProfileLink(opts.author)}
71 onPointerEnter={
72 isWeb ? () => prefetchProfileQuery(opts.author.did) : undefined
73 }
74 />
75 </View>
76 {!isAndroid && (
77 <Text
78 type="md"
79 style={pal.textLight}
80 lineHeight={1.2}
81 accessible={false}>
82 ·
83 </Text>
84 )}
85 <TimeElapsed timestamp={opts.timestamp}>
86 {({timeElapsed}) => (
87 <TextLinkOnWebOnly
88 type="md"
89 style={pal.textLight}
90 lineHeight={1.2}
91 text={timeElapsed}
92 accessibilityLabel={niceDate(opts.timestamp)}
93 title={niceDate(opts.timestamp)}
94 accessibilityHint=""
95 href={opts.postHref}
96 />
97 )}
98 </TimeElapsed>
99 </View>
100 )
101}
102PostMeta = memo(PostMeta)
103export {PostMeta}
104
105const styles = StyleSheet.create({
106 container: {
107 flexDirection: 'row',
108 alignItems: 'center',
109 paddingBottom: 2,
110 gap: 4,
111 zIndex: 1,
112 flex: 1,
113 },
114 avatar: {
115 alignSelf: 'center',
116 },
117 maxWidth: {
118 flex: isAndroid ? 1 : undefined,
119 maxWidth: !isAndroid ? '80%' : undefined,
120 },
121})