Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Use the RichText facets when copying post text (#2481)

* feat: serialize rich text to string

* feat: wire richTextToString to copy post text

authored by

Mary and committed by
GitHub
0b2daa78 f7b01c35

+60 -5
+29
src/lib/strings/rich-text-helpers.ts
··· 1 + import {AppBskyRichtextFacet, RichText} from '@atproto/api' 2 + import {linkRequiresWarning} from './url-helpers' 3 + 4 + export function richTextToString(rt: RichText): string { 5 + const {text, facets} = rt 6 + 7 + if (!facets?.length) { 8 + return text 9 + } 10 + 11 + let result = '' 12 + 13 + for (const segment of rt.segments()) { 14 + const link = segment.link 15 + 16 + if (link && AppBskyRichtextFacet.validateLink(link).success) { 17 + const href = link.uri 18 + const text = segment.text 19 + 20 + const requiresWarning = linkRequiresWarning(href, text) 21 + 22 + result += !requiresWarning ? href : `[${text}](${href})` 23 + } else { 24 + result += segment.text 25 + } 26 + } 27 + 28 + return result 29 + }
+3
src/view/com/post-thread/PostThreadItem.tsx
··· 336 336 postCid={post.cid} 337 337 postUri={post.uri} 338 338 record={record} 339 + richText={richText} 339 340 showAppealLabelItem={ 340 341 post.author.did === currentAccount?.did && isModeratedPost 341 342 } ··· 439 440 big 440 441 post={post} 441 442 record={record} 443 + richText={richText} 442 444 onPressReply={onPressReply} 443 445 /> 444 446 </View> ··· 587 589 <PostCtrls 588 590 post={post} 589 591 record={record} 592 + richText={richText} 590 593 onPressReply={onPressReply} 591 594 /> 592 595 </View>
+6 -1
src/view/com/post/Post.tsx
··· 213 213 </ContentHider> 214 214 ) : null} 215 215 </ContentHider> 216 - <PostCtrls post={post} record={record} onPressReply={onPressReply} /> 216 + <PostCtrls 217 + post={post} 218 + record={record} 219 + richText={richText} 220 + onPressReply={onPressReply} 221 + /> 217 222 </View> 218 223 </View> 219 224 </Link>
+1
src/view/com/posts/FeedItem.tsx
··· 304 304 <PostCtrls 305 305 post={post} 306 306 record={record} 307 + richText={richText} 307 308 onPressReply={onPressReply} 308 309 showAppealLabelItem={ 309 310 post.author.did === currentAccount?.did && isModeratedPost
+13 -3
src/view/com/util/forms/PostDropdownBtn.tsx
··· 2 2 import {Linking, StyleProp, View, ViewStyle} from 'react-native' 3 3 import Clipboard from '@react-native-clipboard/clipboard' 4 4 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 5 - import {AppBskyActorDefs, AppBskyFeedPost, AtUri} from '@atproto/api' 5 + import { 6 + AppBskyActorDefs, 7 + AppBskyFeedPost, 8 + AtUri, 9 + RichText as RichTextAPI, 10 + } from '@atproto/api' 6 11 import {toShareUrl} from 'lib/strings/url-helpers' 7 12 import {useTheme} from 'lib/ThemeContext' 8 13 import {shareUrl} from 'lib/sharing' ··· 24 29 import {useLingui} from '@lingui/react' 25 30 import {useSession} from '#/state/session' 26 31 import {isWeb} from '#/platform/detection' 32 + import {richTextToString} from '#/lib/strings/rich-text-helpers' 27 33 28 34 let PostDropdownBtn = ({ 29 35 testID, ··· 31 37 postCid, 32 38 postUri, 33 39 record, 40 + richText, 34 41 style, 35 42 showAppealLabelItem, 36 43 }: { ··· 39 46 postCid: string 40 47 postUri: string 41 48 record: AppBskyFeedPost.Record 49 + richText: RichTextAPI 42 50 style?: StyleProp<ViewStyle> 43 51 showAppealLabelItem?: boolean 44 52 }): React.ReactNode => { ··· 96 104 }, [rootUri, toggleThreadMute, _]) 97 105 98 106 const onCopyPostText = React.useCallback(() => { 99 - Clipboard.setString(record?.text || '') 107 + const str = richTextToString(richText) 108 + 109 + Clipboard.setString(str) 100 110 Toast.show(_(msg`Copied to clipboard`)) 101 - }, [record, _]) 111 + }, [_, richText]) 102 112 103 113 const onOpenTranslate = React.useCallback(() => { 104 114 Linking.openURL(translatorUrl)
+8 -1
src/view/com/util/post-ctrls/PostCtrls.tsx
··· 6 6 View, 7 7 ViewStyle, 8 8 } from 'react-native' 9 - import {AppBskyFeedDefs, AppBskyFeedPost} from '@atproto/api' 9 + import { 10 + AppBskyFeedDefs, 11 + AppBskyFeedPost, 12 + RichText as RichTextAPI, 13 + } from '@atproto/api' 10 14 import {Text} from '../text/Text' 11 15 import {PostDropdownBtn} from '../forms/PostDropdownBtn' 12 16 import {HeartIcon, HeartIconSolid, CommentBottomArrow} from 'lib/icons' ··· 33 37 big, 34 38 post, 35 39 record, 40 + richText, 36 41 showAppealLabelItem, 37 42 style, 38 43 onPressReply, ··· 40 45 big?: boolean 41 46 post: Shadow<AppBskyFeedDefs.PostView> 42 47 record: AppBskyFeedPost.Record 48 + richText: RichTextAPI 43 49 showAppealLabelItem?: boolean 44 50 style?: StyleProp<ViewStyle> 45 51 onPressReply: () => void ··· 212 218 postCid={post.cid} 213 219 postUri={post.uri} 214 220 record={record} 221 + richText={richText} 215 222 showAppealLabelItem={showAppealLabelItem} 216 223 style={styles.ctrlPad} 217 224 />