diff --git a/src/lib/strings/rich-text-helpers.ts b/src/lib/strings/rich-text-helpers.ts
new file mode 100644
index 00000000..08971ca0
--- /dev/null
+++ b/src/lib/strings/rich-text-helpers.ts
@@ -0,0 +1,29 @@
+import {AppBskyRichtextFacet, RichText} from '@atproto/api'
+import {linkRequiresWarning} from './url-helpers'
+
+export function richTextToString(rt: RichText): string {
+ const {text, facets} = rt
+
+ if (!facets?.length) {
+ return text
+ }
+
+ let result = ''
+
+ for (const segment of rt.segments()) {
+ const link = segment.link
+
+ if (link && AppBskyRichtextFacet.validateLink(link).success) {
+ const href = link.uri
+ const text = segment.text
+
+ const requiresWarning = linkRequiresWarning(href, text)
+
+ result += !requiresWarning ? href : `[${text}](${href})`
+ } else {
+ result += segment.text
+ }
+ }
+
+ return result
+}
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index bb3c7e2c..cd218a06 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -336,6 +336,7 @@ let PostThreadItemLoaded = ({
postCid={post.cid}
postUri={post.uri}
record={record}
+ richText={richText}
showAppealLabelItem={
post.author.did === currentAccount?.did && isModeratedPost
}
@@ -439,6 +440,7 @@ let PostThreadItemLoaded = ({
big
post={post}
record={record}
+ richText={richText}
onPressReply={onPressReply}
/>
@@ -587,6 +589,7 @@ let PostThreadItemLoaded = ({
diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx
index 0e5a459f..f035c32a 100644
--- a/src/view/com/post/Post.tsx
+++ b/src/view/com/post/Post.tsx
@@ -213,7 +213,12 @@ function PostInner({
) : null}
-
+
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index f2b5605d..8dee4ed4 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -304,6 +304,7 @@ let FeedItemInner = ({
showAppealLabelItem?: boolean
}): React.ReactNode => {
@@ -96,9 +104,11 @@ let PostDropdownBtn = ({
}, [rootUri, toggleThreadMute, _])
const onCopyPostText = React.useCallback(() => {
- Clipboard.setString(record?.text || '')
+ const str = richTextToString(richText)
+
+ Clipboard.setString(str)
Toast.show(_(msg`Copied to clipboard`))
- }, [record, _])
+ }, [_, richText])
const onOpenTranslate = React.useCallback(() => {
Linking.openURL(translatorUrl)
diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx
index 575f19bf..50ef8a87 100644
--- a/src/view/com/util/post-ctrls/PostCtrls.tsx
+++ b/src/view/com/util/post-ctrls/PostCtrls.tsx
@@ -6,7 +6,11 @@ import {
View,
ViewStyle,
} from 'react-native'
-import {AppBskyFeedDefs, AppBskyFeedPost} from '@atproto/api'
+import {
+ AppBskyFeedDefs,
+ AppBskyFeedPost,
+ RichText as RichTextAPI,
+} from '@atproto/api'
import {Text} from '../text/Text'
import {PostDropdownBtn} from '../forms/PostDropdownBtn'
import {HeartIcon, HeartIconSolid, CommentBottomArrow} from 'lib/icons'
@@ -33,6 +37,7 @@ let PostCtrls = ({
big,
post,
record,
+ richText,
showAppealLabelItem,
style,
onPressReply,
@@ -40,6 +45,7 @@ let PostCtrls = ({
big?: boolean
post: Shadow
record: AppBskyFeedPost.Record
+ richText: RichTextAPI
showAppealLabelItem?: boolean
style?: StyleProp
onPressReply: () => void
@@ -212,6 +218,7 @@ let PostCtrls = ({
postCid={post.cid}
postUri={post.uri}
record={record}
+ richText={richText}
showAppealLabelItem={showAppealLabelItem}
style={styles.ctrlPad}
/>