about summary refs log tree commit diff
path: root/src/view/com/util/text/RichText.tsx
blob: b6d461224c56a4b9a2e90ccce02f86dc057c259f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import React from 'react'
import {TextStyle, StyleProp} from 'react-native'
import {RichText as RichTextObj, AppBskyRichtextFacet} from '@atproto/api'
import {TextLink} from '../Link'
import {Text} from './Text'
import {lh} from 'lib/styles'
import {toShortUrl} from 'lib/strings/url-helpers'
import {useTheme, TypographyVariant} from 'lib/ThemeContext'
import {usePalette} from 'lib/hooks/usePalette'

const WORD_WRAP = {wordWrap: 1}

/**
 * @deprecated use `#/components/RichText`
 */
export function RichText({
  testID,
  type = 'md',
  richText,
  lineHeight = 1.2,
  style,
  numberOfLines,
  selectable,
  noLinks,
}: {
  testID?: string
  type?: TypographyVariant
  richText?: RichTextObj
  lineHeight?: number
  style?: StyleProp<TextStyle>
  numberOfLines?: number
  selectable?: boolean
  noLinks?: boolean
}) {
  const theme = useTheme()
  const pal = usePalette('default')
  const lineHeightStyle = lh(theme, type, lineHeight)

  if (!richText) {
    return null
  }

  const {text, facets} = richText
  if (!facets?.length) {
    if (/^\p{Extended_Pictographic}+$/u.test(text) && text.length <= 5) {
      style = {
        fontSize: 26,
        lineHeight: 30,
      }
      return (
        // @ts-ignore web only -prf
        <Text
          testID={testID}
          style={[style, pal.text]}
          dataSet={WORD_WRAP}
          selectable={selectable}>
          {text}
        </Text>
      )
    }
    return (
      <Text
        testID={testID}
        type={type}
        style={[style, pal.text, lineHeightStyle]}
        numberOfLines={numberOfLines}
        // @ts-ignore web only -prf
        dataSet={WORD_WRAP}
        selectable={selectable}>
        {text}
      </Text>
    )
  }
  if (!style) {
    style = []
  } else if (!Array.isArray(style)) {
    style = [style]
  }

  const els = []
  let key = 0
  for (const segment of richText.segments()) {
    const link = segment.link
    const mention = segment.mention
    if (
      !noLinks &&
      mention &&
      AppBskyRichtextFacet.validateMention(mention).success
    ) {
      els.push(
        <TextLink
          key={key}
          type={type}
          text={segment.text}
          href={`/profile/${mention.did}`}
          style={[style, lineHeightStyle, pal.link, {pointerEvents: 'auto'}]}
          dataSet={WORD_WRAP}
          selectable={selectable}
        />,
      )
    } else if (link && AppBskyRichtextFacet.validateLink(link).success) {
      if (noLinks) {
        els.push(toShortUrl(segment.text))
      } else {
        els.push(
          <TextLink
            key={key}
            type={type}
            text={toShortUrl(segment.text)}
            href={link.uri}
            style={[style, lineHeightStyle, pal.link, {pointerEvents: 'auto'}]}
            dataSet={WORD_WRAP}
            warnOnMismatchingLabel
            selectable={selectable}
          />,
        )
      }
    } else {
      els.push(segment.text)
    }
    key++
  }
  return (
    <Text
      testID={testID}
      type={type}
      style={[style, pal.text, lineHeightStyle]}
      numberOfLines={numberOfLines}
      // @ts-ignore web only -prf
      dataSet={WORD_WRAP}
      selectable={selectable}>
      {els}
    </Text>
  )
}