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.tsx66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/view/com/util/text/RichText.tsx b/src/view/com/util/text/RichText.tsx
index b6d461224..0ec3f3181 100644
--- a/src/view/com/util/text/RichText.tsx
+++ b/src/view/com/util/text/RichText.tsx
@@ -7,6 +7,9 @@ import {lh} from 'lib/styles'
 import {toShortUrl} from 'lib/strings/url-helpers'
 import {useTheme, TypographyVariant} from 'lib/ThemeContext'
 import {usePalette} from 'lib/hooks/usePalette'
+import {makeTagLink} from 'lib/routes/links'
+import {TagMenu, useTagMenuControl} from '#/components/TagMenu'
+import {isNative} from '#/platform/detection'
 
 const WORD_WRAP = {wordWrap: 1}
 
@@ -82,6 +85,7 @@ export function RichText({
   for (const segment of richText.segments()) {
     const link = segment.link
     const mention = segment.mention
+    const tag = segment.tag
     if (
       !noLinks &&
       mention &&
@@ -115,6 +119,21 @@ export function RichText({
           />,
         )
       }
+    } else if (
+      !noLinks &&
+      tag &&
+      AppBskyRichtextFacet.validateTag(tag).success
+    ) {
+      els.push(
+        <RichTextTag
+          key={key}
+          text={segment.text}
+          type={type}
+          style={style}
+          lineHeightStyle={lineHeightStyle}
+          selectable={selectable}
+        />,
+      )
     } else {
       els.push(segment.text)
     }
@@ -133,3 +152,50 @@ export function RichText({
     </Text>
   )
 }
+
+function RichTextTag({
+  text: tag,
+  type,
+  style,
+  lineHeightStyle,
+  selectable,
+}: {
+  text: string
+  type?: TypographyVariant
+  style?: StyleProp<TextStyle>
+  lineHeightStyle?: TextStyle
+  selectable?: boolean
+}) {
+  const pal = usePalette('default')
+  const control = useTagMenuControl()
+
+  const open = React.useCallback(() => {
+    control.open()
+  }, [control])
+
+  return (
+    <React.Fragment>
+      <TagMenu control={control} tag={tag}>
+        {isNative ? (
+          <TextLink
+            type={type}
+            text={tag}
+            // segment.text has the leading "#" while tag.tag does not
+            href={makeTagLink(tag)}
+            style={[style, lineHeightStyle, pal.link, {pointerEvents: 'auto'}]}
+            dataSet={WORD_WRAP}
+            selectable={selectable}
+            onPress={open}
+          />
+        ) : (
+          <Text
+            selectable={selectable}
+            type={type}
+            style={[style, lineHeightStyle, pal.link, {pointerEvents: 'auto'}]}>
+            {tag}
+          </Text>
+        )}
+      </TagMenu>
+    </React.Fragment>
+  )
+}