Bluesky app fork with some witchin' additions 💫 witchsky.app
bluesky fork client

Fix RTL text rendering for display names (#4747)

* header display name rtl support

* highlighted post rtl

* move `NON_BREAKING_SPACE` to an external constant

* rtl support in search dropdown

* profile card rtl

* old profile card rtl

* hover card

* wizard list card

* new chat

* account card

* chat header

* clean up notifications

* just force LTR on meta display name

authored by hailey.at and committed by

GitHub f8a59e10 d5503d17

+41 -23
+3 -1
src/components/ProfileCard.tsx
··· 166 166 167 167 return ( 168 168 <View style={[a.flex_1]}> 169 - <Text style={[a.text_md, a.font_bold, a.leading_snug]} numberOfLines={1}> 169 + <Text 170 + style={[a.text_md, a.font_bold, a.leading_snug, a.self_start]} 171 + numberOfLines={1}> 170 172 {name} 171 173 </Text> 172 174 <Text
+2 -1
src/components/ProfileHoverCard/index.web.tsx
··· 462 462 463 463 <Link to={profileURL} label={_(msg`View profile`)} onPress={hide}> 464 464 <View style={[a.pb_sm, a.flex_1]}> 465 - <Text style={[a.pt_md, a.pb_xs, a.text_lg, a.font_bold]}> 465 + <Text 466 + style={[a.pt_md, a.pb_xs, a.text_lg, a.font_bold, a.self_start]}> 466 467 {sanitizeDisplayName( 467 468 profile.displayName || sanitizeHandle(profile.handle), 468 469 moderation.ui('displayName'),
+7 -1
src/components/StarterPack/Wizard/WizardListCard.tsx
··· 78 78 /> 79 79 <View style={[a.flex_1, a.gap_2xs]}> 80 80 <Text 81 - style={[a.flex_1, a.font_bold, a.text_md, a.leading_tight]} 81 + style={[ 82 + a.flex_1, 83 + a.font_bold, 84 + a.text_md, 85 + a.leading_tight, 86 + a.self_start, 87 + ]} 82 88 numberOfLines={1}> 83 89 {displayName} 84 90 </Text>
+6 -1
src/components/dms/MessagesListHeader.tsx
··· 168 168 </View> 169 169 <View style={a.flex_1}> 170 170 <Text 171 - style={[a.text_md, a.font_bold, web(a.leading_normal)]} 171 + style={[ 172 + a.text_md, 173 + a.font_bold, 174 + a.self_start, 175 + web(a.leading_normal), 176 + ]} 172 177 numberOfLines={1}> 173 178 {displayName} 174 179 </Text>
+1 -1
src/components/dms/dialogs/SearchablePeopleList.tsx
··· 395 395 /> 396 396 <View style={[a.flex_1, a.gap_2xs]}> 397 397 <Text 398 - style={[t.atoms.text, a.font_bold, a.leading_tight]} 398 + style={[t.atoms.text, a.font_bold, a.leading_tight, a.self_start]} 399 399 numberOfLines={1}> 400 400 {displayName} 401 401 </Text>
+1
src/lib/strings/constants.ts
··· 1 + export const NON_BREAKING_SPACE = '\u00A0'
+1 -1
src/screens/Profile/Header/DisplayName.tsx
··· 20 20 <View pointerEvents="none"> 21 21 <Text 22 22 testID="profileHeaderDisplayName" 23 - style={[t.atoms.text, a.text_4xl, {fontWeight: '500'}]}> 23 + style={[t.atoms.text, a.text_4xl, a.self_start, {fontWeight: '500'}]}> 24 24 {sanitizeDisplayName( 25 25 profile.displayName || sanitizeHandle(profile.handle), 26 26 moderation.ui('displayName'),
+6 -3
src/view/com/notifications/FeedItem.tsx
··· 58 58 import {parseTenorGif} from '#/lib/strings/embed-player' 59 59 import {logger} from '#/logger' 60 60 import {NavigationProp} from 'lib/routes/types' 61 + import {forceLTR} from 'lib/strings/bidi' 61 62 import {DM_SERVICE_HEADERS} from 'state/queries/messages/const' 62 63 import {useAgent} from 'state/session' 63 64 import {Button, ButtonText} from '#/components/Button' ··· 274 275 showDmButton={item.type === 'starterpack-joined' || isFollowBack} 275 276 /> 276 277 <ExpandedAuthorsList visible={isAuthorsExpanded} authors={authors} /> 277 - <Text style={styles.meta}> 278 + <Text style={[styles.meta, a.self_start]}> 278 279 <TextLink 279 280 key={authors[0].href} 280 281 style={[pal.text, s.bold]} 281 282 href={authors[0].href} 282 - text={sanitizeDisplayName( 283 - authors[0].profile.displayName || authors[0].profile.handle, 283 + text={forceLTR( 284 + sanitizeDisplayName( 285 + authors[0].profile.displayName || authors[0].profile.handle, 286 + ), 284 287 )} 285 288 disableMismatchWarning 286 289 />
+1 -1
src/view/com/post-thread/PostThreadItem.tsx
··· 281 281 <Link style={s.flex1} href={authorHref} title={authorTitle}> 282 282 <Text 283 283 type="xl-bold" 284 - style={[pal.text]} 284 + style={[pal.text, a.self_start]} 285 285 numberOfLines={1} 286 286 lineHeight={1.2}> 287 287 {sanitizeDisplayName(
+1 -1
src/view/com/profile/ProfileCard.tsx
··· 97 97 <View style={styles.layoutContent}> 98 98 <Text 99 99 type="lg" 100 - style={[s.bold, pal.text]} 100 + style={[s.bold, pal.text, a.self_start]} 101 101 numberOfLines={1} 102 102 lineHeight={1.2}> 103 103 {sanitizeDisplayName(
+8 -10
src/view/com/util/PostMeta.tsx
··· 6 6 import {precacheProfile} from '#/state/queries/profile' 7 7 import {usePalette} from 'lib/hooks/usePalette' 8 8 import {makeProfileLink} from 'lib/routes/links' 9 + import {forceLTR} from 'lib/strings/bidi' 10 + import {NON_BREAKING_SPACE} from 'lib/strings/constants' 9 11 import {sanitizeDisplayName} from 'lib/strings/display-names' 10 12 import {sanitizeHandle} from 'lib/strings/handles' 11 13 import {niceDate} from 'lib/strings/time' ··· 31 33 onOpenAuthor?: () => void 32 34 style?: StyleProp<ViewStyle> 33 35 } 34 - 35 - const NON_BREAKING_SPACE = '\u00A0' 36 36 37 37 let PostMeta = (opts: PostMetaOpts): React.ReactNode => { 38 38 const pal = usePalette('default') ··· 70 70 style={[pal.text]} 71 71 lineHeight={1.2} 72 72 disableMismatchWarning 73 - text={ 74 - <> 75 - {sanitizeDisplayName( 76 - displayName, 77 - opts.moderation?.ui('displayName'), 78 - )} 79 - </> 80 - } 73 + text={forceLTR( 74 + sanitizeDisplayName( 75 + displayName, 76 + opts.moderation?.ui('displayName'), 77 + ), 78 + )} 81 79 href={profileLink} 82 80 onBeforePress={onBeforePressAuthor} 83 81 />
+2 -1
src/view/screens/Settings/index.tsx
··· 68 68 import {Email2FAToggle} from './Email2FAToggle' 69 69 import {ExportCarDialog} from './ExportCarDialog' 70 70 import hairlineWidth = StyleSheet.hairlineWidth 71 + import {atoms as a} from '#/alf' 71 72 72 73 function SettingsAccountCard({ 73 74 account, ··· 104 105 /> 105 106 </View> 106 107 <View style={[s.flex1]}> 107 - <Text type="md-bold" style={pal.text} numberOfLines={1}> 108 + <Text type="md-bold" style={[pal.text, a.self_start]} numberOfLines={1}> 108 109 {profile?.displayName || account.handle} 109 110 </Text> 110 111 <Text type="sm" style={pal.textLight} numberOfLines={1}>
+2 -1
src/view/shell/desktop/Search.tsx
··· 30 30 import {Link} from '#/view/com/util/Link' 31 31 import {UserAvatar} from '#/view/com/util/UserAvatar' 32 32 import {Text} from 'view/com/util/text/Text' 33 + import {atoms as a} from '#/alf' 33 34 34 35 let SearchLinkCard = ({ 35 36 label, ··· 127 128 <View style={{flex: 1}}> 128 129 <Text 129 130 type="lg" 130 - style={[s.bold, pal.text]} 131 + style={[s.bold, pal.text, a.self_start]} 131 132 numberOfLines={1} 132 133 lineHeight={1.2}> 133 134 {sanitizeDisplayName(