mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import React from 'react'
2import {TextStyle, StyleProp} from 'react-native'
3import {RichText as RichTextObj, AppBskyRichtextFacet} from '@atproto/api'
4import {TextLink} from '../Link'
5import {Text} from './Text'
6import {lh} from 'lib/styles'
7import {toShortUrl} from 'lib/strings/url-helpers'
8import {useTheme, TypographyVariant} from 'lib/ThemeContext'
9import {usePalette} from 'lib/hooks/usePalette'
10import {makeTagLink} from 'lib/routes/links'
11import {TagMenu, useTagMenuControl} from '#/components/TagMenu'
12import {isNative} from '#/platform/detection'
13
14const WORD_WRAP = {wordWrap: 1}
15
16/**
17 * @deprecated use `#/components/RichText`
18 */
19export function RichText({
20 testID,
21 type = 'md',
22 richText,
23 lineHeight = 1.2,
24 style,
25 numberOfLines,
26 selectable,
27 noLinks,
28}: {
29 testID?: string
30 type?: TypographyVariant
31 richText?: RichTextObj
32 lineHeight?: number
33 style?: StyleProp<TextStyle>
34 numberOfLines?: number
35 selectable?: boolean
36 noLinks?: boolean
37}) {
38 const theme = useTheme()
39 const pal = usePalette('default')
40 const lineHeightStyle = lh(theme, type, lineHeight)
41
42 if (!richText) {
43 return null
44 }
45
46 const {text, facets} = richText
47 if (!facets?.length) {
48 if (/^\p{Extended_Pictographic}+$/u.test(text) && text.length <= 5) {
49 style = {
50 fontSize: 26,
51 lineHeight: 30,
52 }
53 return (
54 // @ts-ignore web only -prf
55 <Text
56 testID={testID}
57 style={[style, pal.text]}
58 dataSet={WORD_WRAP}
59 selectable={selectable}>
60 {text}
61 </Text>
62 )
63 }
64 return (
65 <Text
66 testID={testID}
67 type={type}
68 style={[style, pal.text, lineHeightStyle]}
69 numberOfLines={numberOfLines}
70 // @ts-ignore web only -prf
71 dataSet={WORD_WRAP}
72 selectable={selectable}>
73 {text}
74 </Text>
75 )
76 }
77 if (!style) {
78 style = []
79 } else if (!Array.isArray(style)) {
80 style = [style]
81 }
82
83 const els = []
84 let key = 0
85 for (const segment of richText.segments()) {
86 const link = segment.link
87 const mention = segment.mention
88 const tag = segment.tag
89 if (
90 !noLinks &&
91 mention &&
92 AppBskyRichtextFacet.validateMention(mention).success
93 ) {
94 els.push(
95 <TextLink
96 key={key}
97 type={type}
98 text={segment.text}
99 href={`/profile/${mention.did}`}
100 style={[style, lineHeightStyle, pal.link, {pointerEvents: 'auto'}]}
101 dataSet={WORD_WRAP}
102 selectable={selectable}
103 />,
104 )
105 } else if (link && AppBskyRichtextFacet.validateLink(link).success) {
106 if (noLinks) {
107 els.push(toShortUrl(segment.text))
108 } else {
109 els.push(
110 <TextLink
111 key={key}
112 type={type}
113 text={toShortUrl(segment.text)}
114 href={link.uri}
115 style={[style, lineHeightStyle, pal.link, {pointerEvents: 'auto'}]}
116 dataSet={WORD_WRAP}
117 selectable={selectable}
118 />,
119 )
120 }
121 } else if (
122 !noLinks &&
123 tag &&
124 AppBskyRichtextFacet.validateTag(tag).success
125 ) {
126 els.push(
127 <RichTextTag
128 key={key}
129 text={segment.text}
130 type={type}
131 style={style}
132 lineHeightStyle={lineHeightStyle}
133 selectable={selectable}
134 />,
135 )
136 } else {
137 els.push(segment.text)
138 }
139 key++
140 }
141 return (
142 <Text
143 testID={testID}
144 type={type}
145 style={[style, pal.text, lineHeightStyle]}
146 numberOfLines={numberOfLines}
147 // @ts-ignore web only -prf
148 dataSet={WORD_WRAP}
149 selectable={selectable}>
150 {els}
151 </Text>
152 )
153}
154
155function RichTextTag({
156 text: tag,
157 type,
158 style,
159 lineHeightStyle,
160 selectable,
161}: {
162 text: string
163 type?: TypographyVariant
164 style?: StyleProp<TextStyle>
165 lineHeightStyle?: TextStyle
166 selectable?: boolean
167}) {
168 const pal = usePalette('default')
169 const control = useTagMenuControl()
170
171 const open = React.useCallback(() => {
172 control.open()
173 }, [control])
174
175 return (
176 <React.Fragment>
177 <TagMenu control={control} tag={tag}>
178 {isNative ? (
179 <TextLink
180 type={type}
181 text={tag}
182 // segment.text has the leading "#" while tag.tag does not
183 href={makeTagLink(tag)}
184 style={[style, lineHeightStyle, pal.link, {pointerEvents: 'auto'}]}
185 dataSet={WORD_WRAP}
186 selectable={selectable}
187 onPress={open}
188 />
189 ) : (
190 <Text
191 selectable={selectable}
192 type={type}
193 style={[style, lineHeightStyle, pal.link, {pointerEvents: 'auto'}]}>
194 {tag}
195 </Text>
196 )}
197 </TagMenu>
198 </React.Fragment>
199 )
200}