about summary refs log tree commit diff
path: root/src/view/com/util/text/RichText.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/util/text/RichText.tsx')
-rw-r--r--src/view/com/util/text/RichText.tsx106
1 files changed, 40 insertions, 66 deletions
diff --git a/src/view/com/util/text/RichText.tsx b/src/view/com/util/text/RichText.tsx
index d4cf19172..804db002a 100644
--- a/src/view/com/util/text/RichText.tsx
+++ b/src/view/com/util/text/RichText.tsx
@@ -1,20 +1,22 @@
 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 {RichText as RichTextObj, Entity} from 'lib/strings/rich-text'
 import {useTheme, TypographyVariant} from 'lib/ThemeContext'
 import {usePalette} from 'lib/hooks/usePalette'
 
 export function RichText({
+  testID,
   type = 'md',
   richText,
   lineHeight = 1.2,
   style,
   numberOfLines,
 }: {
+  testID?: string
   type?: TypographyVariant
   richText?: RichTextObj
   lineHeight?: number
@@ -29,17 +31,24 @@ export function RichText({
     return null
   }
 
-  const {text, entities} = richText
-  if (!entities?.length) {
+  const {text, facets} = richText
+  if (!facets?.length) {
     if (/^\p{Extended_Pictographic}+$/u.test(text) && text.length <= 5) {
       style = {
         fontSize: 26,
         lineHeight: 30,
       }
-      return <Text style={[style, pal.text]}>{text}</Text>
+      return (
+        <Text testID={testID} style={[style, pal.text]}>
+          {text}
+        </Text>
+      )
     }
     return (
-      <Text type={type} style={[style, pal.text, lineHeightStyle]}>
+      <Text
+        testID={testID}
+        type={type}
+        style={[style, pal.text, lineHeightStyle]}>
         {text}
       </Text>
     )
@@ -49,40 +58,40 @@ export function RichText({
   } else if (!Array.isArray(style)) {
     style = [style]
   }
-  entities.sort(sortByIndex)
-  const segments = Array.from(toSegments(text, entities))
+
   const els = []
   let key = 0
-  for (const segment of segments) {
-    if (typeof segment === 'string') {
-      els.push(segment)
+  for (const segment of richText.segments()) {
+    const link = segment.link
+    const mention = segment.mention
+    if (mention && AppBskyRichtextFacet.validateMention(mention).success) {
+      els.push(
+        <TextLink
+          key={key}
+          type={type}
+          text={segment.text}
+          href={`/profile/${mention.did}`}
+          style={[style, lineHeightStyle, pal.link]}
+        />,
+      )
+    } else if (link && AppBskyRichtextFacet.validateLink(link).success) {
+      els.push(
+        <TextLink
+          key={key}
+          type={type}
+          text={toShortUrl(segment.text)}
+          href={link.uri}
+          style={[style, lineHeightStyle, pal.link]}
+        />,
+      )
     } else {
-      if (segment.entity.type === 'mention') {
-        els.push(
-          <TextLink
-            key={key}
-            type={type}
-            text={segment.text}
-            href={`/profile/${segment.entity.value}`}
-            style={[style, lineHeightStyle, pal.link]}
-          />,
-        )
-      } else if (segment.entity.type === 'link') {
-        els.push(
-          <TextLink
-            key={key}
-            type={type}
-            text={toShortUrl(segment.text)}
-            href={segment.entity.value}
-            style={[style, lineHeightStyle, pal.link]}
-          />,
-        )
-      }
+      els.push(segment.text)
     }
     key++
   }
   return (
     <Text
+      testID={testID}
       type={type}
       style={[style, pal.text, lineHeightStyle]}
       numberOfLines={numberOfLines}>
@@ -90,38 +99,3 @@ export function RichText({
     </Text>
   )
 }
-
-function sortByIndex(a: Entity, b: Entity) {
-  return a.index.start - b.index.start
-}
-
-function* toSegments(text: string, entities: Entity[]) {
-  let cursor = 0
-  let i = 0
-  do {
-    let currEnt = entities[i]
-    if (cursor < currEnt.index.start) {
-      yield text.slice(cursor, currEnt.index.start)
-    } else if (cursor > currEnt.index.start) {
-      i++
-      continue
-    }
-    if (currEnt.index.start < currEnt.index.end) {
-      let subtext = text.slice(currEnt.index.start, currEnt.index.end)
-      if (!subtext.trim()) {
-        // dont yield links to empty strings
-        yield subtext
-      } else {
-        yield {
-          entity: currEnt,
-          text: subtext,
-        }
-      }
-    }
-    cursor = currEnt.index.end
-    i++
-  } while (i < entities.length)
-  if (cursor < text.length) {
-    yield text.slice(cursor, text.length)
-  }
-}