Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

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

feat: render bold/italic/underline facets in feed and reply-to

Winter d5791fd9 b39e0799

+49 -8
+25 -3
src/components/RichText.tsx
··· 113 113 const link = segment.link 114 114 const mention = segment.mention 115 115 const tag = segment.tag 116 + const features = segment.facet?.features 117 + const hasFeature = (kind: string) => 118 + features?.some( 119 + f => (f as {$type: string}).$type === `app.bsky.richtext.facet#${kind}`, 120 + ) 121 + const formatStyles = [ 122 + hasFeature('bold') && a.font_bold, 123 + hasFeature('italic') && ({fontStyle: 'italic'} as const), 124 + hasFeature('underline') && ({textDecorationLine: 'underline'} as const), 125 + ] 116 126 117 127 if ( 118 128 mention && ··· 125 135 <InlineLinkText 126 136 selectable={selectable} 127 137 to={`/profile/${mention.did}`} 128 - style={interactiveStyles} 138 + style={[interactiveStyles, ...formatStyles]} 129 139 // @ts-ignore TODO 130 140 dataSet={WORD_WRAP} 131 141 shouldProxy={shouldProxyLinks} ··· 144 154 selectable={selectable} 145 155 key={key} 146 156 to={link.uri} 147 - style={interactiveStyles} 157 + style={[interactiveStyles, ...formatStyles]} 148 158 // @ts-ignore TODO 149 159 dataSet={WORD_WRAP} 150 160 shareOnLongPress ··· 166 176 key={key} 167 177 display={segment.text} 168 178 tag={tag.tag} 169 - textStyle={interactiveStyles} 179 + textStyle={ 180 + [interactiveStyles, ...formatStyles] as StyleProp<TextStyle> 181 + } 170 182 authorHandle={authorHandle} 171 183 />, 184 + ) 185 + } else if (formatStyles.some(Boolean)) { 186 + els.push( 187 + <Text 188 + key={key} 189 + emoji 190 + selectable={selectable} 191 + style={[plainStyles, ...formatStyles]}> 192 + {segment.text} 193 + </Text>, 172 194 ) 173 195 } else { 174 196 els.push(segment.text)
+1
src/screens/PostThread/components/ThreadItemAnchor.tsx
··· 263 263 uri: post.uri, 264 264 cid: post.cid, 265 265 text: record.text, 266 + facets: record.facets, 266 267 author: post.author, 267 268 embed: post.embed, 268 269 moderation,
+1
src/screens/PostThread/components/ThreadItemPost.tsx
··· 232 232 uri: post.uri, 233 233 cid: post.cid, 234 234 text: record.text, 235 + facets: record.facets, 235 236 author: post.author, 236 237 embed: post.embed, 237 238 moderation,
+1
src/screens/PostThread/components/ThreadItemTreePost.tsx
··· 297 297 uri: post.uri, 298 298 cid: post.cid, 299 299 text: record.text, 300 + facets: record.facets, 300 301 author: post.author, 301 302 embed: post.embed, 302 303 moderation,
+1
src/screens/PostThread/index.tsx
··· 119 119 uri: anchor.uri, 120 120 cid: post.cid, 121 121 text: post.record.text, 122 + facets: post.record.facets, 122 123 author: post.author, 123 124 embed: post.embed, 124 125 moderation: anchor.moderation,
+1
src/screens/VideoFeed/index.tsx
··· 774 774 uri: post.uri, 775 775 cid: post.cid, 776 776 text: record?.text || '', 777 + facets: record?.facets, 777 778 author: post.author, 778 779 embed: post.embed, 779 780 langs: record?.langs,
+2
src/state/shell/composer/index.tsx
··· 2 2 import { 3 3 type AppBskyActorDefs, 4 4 type AppBskyFeedDefs, 5 + type AppBskyRichtextFacet, 5 6 type AppBskyUnspeccedGetPostThreadV2, 6 7 type BlobRef, 7 8 type ModerationDecision, ··· 25 26 uri: string 26 27 cid: string 27 28 text: string 29 + facets?: AppBskyRichtextFacet.Main[] 28 30 langs?: string[] 29 31 // remove this after updating atproto api package 30 32 author: AppBskyActorDefs.ProfileViewBasic & {
+16 -5
src/view/com/composer/ComposerReplyTo.tsx
··· 6 6 AppBskyEmbedRecord, 7 7 AppBskyEmbedRecordWithMedia, 8 8 AppBskyFeedPost, 9 + RichText as RichTextAPI, 9 10 } from '@atproto/api' 10 11 import {msg} from '@lingui/core/macro' 11 12 import {useLingui} from '@lingui/react' ··· 18 19 import {atoms as a, useTheme, web} from '#/alf' 19 20 import {PdsBadge} from '#/components/PdsBadge' 20 21 import {QuoteEmbed} from '#/components/Post/Embed' 22 + import {RichText} from '#/components/RichText' 21 23 import {Text} from '#/components/Typography' 22 24 import {useSimpleVerificationState} from '#/components/verification' 23 25 import {VerificationCheck} from '#/components/verification/VerificationCheck' ··· 145 147 </View> 146 148 <View style={[a.flex_row, a.gap_md]}> 147 149 <View style={[a.flex_1, a.flex_grow]}> 148 - <Text 150 + <RichText 151 + value={ 152 + new RichTextAPI({ 153 + text: replyTo.text, 154 + facets: replyTo.facets, 155 + }) 156 + } 149 157 style={[a.text_md, a.leading_snug, t.atoms.text_contrast_high]} 150 158 numberOfLines={!showFull ? 6 : undefined} 151 - emoji> 152 - {replyTo.text} 153 - </Text> 159 + disableLinks 160 + /> 154 161 </View> 155 162 {images && !replyTo.moderation?.ui('contentMedia').blur && ( 156 163 <ComposerReplyToImages images={images} showFull={showFull} /> 157 164 )} 158 165 </View> 159 166 {showFull && parsedQuoteEmbed && parsedQuoteEmbed.type === 'post' && ( 160 - <QuoteEmbed embed={parsedQuoteEmbed} showPronouns={true} linkDisabled /> 167 + <QuoteEmbed 168 + embed={parsedQuoteEmbed} 169 + showPronouns={true} 170 + linkDisabled 171 + /> 161 172 )} 162 173 </View> 163 174 </Pressable>
+1
src/view/com/posts/PostFeedItem.tsx
··· 189 189 uri: post.uri, 190 190 cid: post.cid, 191 191 text: record.text || '', 192 + facets: record.facets, 192 193 author: post.author, 193 194 embed: post.embed, 194 195 moderation,