Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

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

Stripe checkmark emojis from display names (close #396) (#419)

authored by

Paul Frazee and committed by
GitHub
ab11f206 4b989922

+58 -23
+4 -1
src/lib/notifee.ts
··· 3 3 import {RootStoreModel} from 'state/models/root-store' 4 4 import {NotificationsFeedItemModel} from 'state/models/feeds/notifications' 5 5 import {enforceLen} from 'lib/strings/helpers' 6 + import {sanitizeDisplayName} from './strings/display-names' 6 7 import {resetToTab} from '../Navigation' 7 8 8 9 export function init(store: RootStoreModel) { ··· 42 43 export function displayNotificationFromModel( 43 44 notif: NotificationsFeedItemModel, 44 45 ) { 45 - let author = notif.author.displayName || notif.author.handle 46 + let author = sanitizeDisplayName( 47 + notif.author.displayName || notif.author.handle, 48 + ) 46 49 let title: string 47 50 let body: string = '' 48 51 if (notif.isLike) {
+12
src/lib/strings/display-names.ts
··· 1 + // \u2705 = ✅ 2 + // \u2713 = ✓ 3 + // \u2714 = ✔ 4 + // \u2611 = ☑ 5 + const CHECK_MARKS_RE = /[\u2705\u2713\u2714\u2611]/gu 6 + 7 + export function sanitizeDisplayName(str: string): string { 8 + if (typeof str === 'string') { 9 + return str.replace(CHECK_MARKS_RE, '') 10 + } 11 + return '' 12 + }
+4 -1
src/view/com/composer/Composer.tsx
··· 26 26 import * as apilib from 'lib/api/index' 27 27 import {ComposerOpts} from 'state/models/ui/shell' 28 28 import {s, colors, gradients} from 'lib/styles' 29 + import {sanitizeDisplayName} from 'lib/strings/display-names' 29 30 import {cleanError} from 'lib/strings/errors' 30 31 import {SelectPhotoBtn} from './photos/SelectPhotoBtn' 31 32 import {OpenCameraBtn} from './photos/OpenCameraBtn' ··· 265 266 <UserAvatar avatar={replyTo.author.avatar} size={50} /> 266 267 <View style={styles.replyToPost}> 267 268 <Text type="xl-medium" style={[pal.text]}> 268 - {replyTo.author.displayName || replyTo.author.handle} 269 + {sanitizeDisplayName( 270 + replyTo.author.displayName || replyTo.author.handle, 271 + )} 269 272 </Text> 270 273 <Text type="post-text" style={pal.text} numberOfLines={6}> 271 274 {replyTo.text}
+6 -3
src/view/com/notifications/FeedItem.tsx
··· 18 18 import {PostThreadModel} from 'state/models/content/post-thread' 19 19 import {s, colors} from 'lib/styles' 20 20 import {ago} from 'lib/strings/time' 21 + import {sanitizeDisplayName} from 'lib/strings/display-names' 21 22 import {pluralize} from 'lib/strings/helpers' 22 23 import {HeartIconSolid} from 'lib/icons' 23 24 import {Text} from '../util/text/Text' ··· 187 188 key={authors[0].href} 188 189 style={[pal.text, s.bold, styles.metaItem]} 189 190 href={authors[0].href} 190 - text={authors[0].displayName || authors[0].handle} 191 + text={sanitizeDisplayName( 192 + authors[0].displayName || authors[0].handle, 193 + )} 191 194 /> 192 195 {authors.length > 1 ? ( 193 196 <> ··· 310 313 <Link 311 314 key={author.href} 312 315 href={author.href} 313 - title={author.displayName || author.handle} 316 + title={sanitizeDisplayName(author.displayName || author.handle)} 314 317 style={styles.expandedAuthor} 315 318 asAnchor> 316 319 <View style={styles.expandedAuthorAvi}> ··· 322 325 numberOfLines={1} 323 326 style={pal.text} 324 327 lineHeight={1.2}> 325 - {author.displayName || author.handle} 328 + {sanitizeDisplayName(author.displayName || author.handle)} 326 329 &nbsp; 327 330 <Text style={[pal.textLight]} lineHeight={1.2}> 328 331 {author.handle}
+2 -1
src/view/com/notifications/InvitedUsers.tsx
··· 15 15 import {useStores} from 'state/index' 16 16 import {usePalette} from 'lib/hooks/usePalette' 17 17 import {s} from 'lib/styles' 18 + import {sanitizeDisplayName} from 'lib/strings/display-names' 18 19 19 20 export const InvitedUsers = observer(() => { 20 21 const store = useStores() ··· 65 66 type="md-bold" 66 67 style={pal.text} 67 68 href={`/profile/${profile.handle}`} 68 - text={profile.displayName || profile.handle} 69 + text={sanitizeDisplayName(profile.displayName || profile.handle)} 69 70 />{' '} 70 71 joined using your invite code! 71 72 </Text>
+4 -1
src/view/com/post-thread/PostThreadItem.tsx
··· 16 16 import {UserAvatar} from '../util/UserAvatar' 17 17 import {s} from 'lib/styles' 18 18 import {ago} from 'lib/strings/time' 19 + import {sanitizeDisplayName} from 'lib/strings/display-names' 19 20 import {pluralize} from 'lib/strings/helpers' 20 21 import {useStores} from 'state/index' 21 22 import {PostMeta} from '../util/PostMeta' ··· 151 152 style={[pal.text]} 152 153 numberOfLines={1} 153 154 lineHeight={1.2}> 154 - {item.post.author.displayName || item.post.author.handle} 155 + {sanitizeDisplayName( 156 + item.post.author.displayName || item.post.author.handle, 157 + )} 155 158 </Text> 156 159 </Link> 157 160 <Text type="md" style={[styles.metaItem, pal.textLight]}>
+7 -6
src/view/com/posts/FeedItem.tsx
··· 22 22 import {useStores} from 'state/index' 23 23 import {usePalette} from 'lib/hooks/usePalette' 24 24 import {useAnalytics} from 'lib/analytics' 25 + import {sanitizeDisplayName} from 'lib/strings/display-names' 25 26 26 27 export const FeedItem = observer(function ({ 27 28 item, ··· 151 152 <Link 152 153 style={styles.includeReason} 153 154 href={`/profile/${item.reasonRepost.by.handle}`} 154 - title={ 155 - item.reasonRepost.by.displayName || item.reasonRepost.by.handle 156 - }> 155 + title={sanitizeDisplayName( 156 + item.reasonRepost.by.displayName || item.reasonRepost.by.handle, 157 + )}> 157 158 <FontAwesomeIcon 158 159 icon="retweet" 159 160 style={[ ··· 172 173 style={pal.textLight} 173 174 lineHeight={1.2} 174 175 numberOfLines={1} 175 - text={ 176 + text={sanitizeDisplayName( 176 177 item.reasonRepost.by.displayName || 177 - item.reasonRepost.by.handle 178 - } 178 + item.reasonRepost.by.handle, 179 + )} 179 180 href={`/profile/${item.reasonRepost.by.handle}`} 180 181 /> 181 182 </Text>
+2 -1
src/view/com/profile/ProfileCard.tsx
··· 9 9 import {usePalette} from 'lib/hooks/usePalette' 10 10 import {useStores} from 'state/index' 11 11 import {FollowButton} from './FollowButton' 12 + import {sanitizeDisplayName} from 'lib/strings/display-names' 12 13 13 14 export function ProfileCard({ 14 15 testID, ··· 57 58 style={[s.bold, pal.text]} 58 59 numberOfLines={1} 59 60 lineHeight={1.2}> 60 - {displayName || handle} 61 + {sanitizeDisplayName(displayName || handle)} 61 62 </Text> 62 63 <Text type="md" style={[pal.textLight]} numberOfLines={1}> 63 64 @{handle}
+6 -5
src/view/com/profile/ProfileHeader.tsx
··· 18 18 import {ProfileImageLightbox} from 'state/models/ui/shell' 19 19 import {pluralize} from 'lib/strings/helpers' 20 20 import {toShareUrl} from 'lib/strings/url-helpers' 21 + import {sanitizeDisplayName} from 'lib/strings/display-names' 21 22 import {s, colors} from 'lib/styles' 22 23 import {DropdownButton, DropdownItem} from '../util/forms/DropdownButton' 23 24 import * as Toast from '../util/Toast' ··· 58 59 </View> 59 60 <View style={styles.displayNameLine}> 60 61 <Text type="title-2xl" style={[pal.text, styles.title]}> 61 - {view.displayName || view.handle} 62 + {sanitizeDisplayName(view.displayName || view.handle)} 62 63 </Text> 63 64 </View> 64 65 </View> ··· 108 109 view?.toggleFollowing().then( 109 110 () => { 110 111 Toast.show( 111 - `${view.viewer.following ? 'Following' : 'No longer following'} ${ 112 - view.displayName || view.handle 113 - }`, 112 + `${ 113 + view.viewer.following ? 'Following' : 'No longer following' 114 + } ${sanitizeDisplayName(view.displayName || view.handle)}`, 114 115 ) 115 116 }, 116 117 err => store.log.error('Failed to toggle follow', err), ··· 266 267 testID="profileHeaderDisplayName" 267 268 type="title-2xl" 268 269 style={[pal.text, styles.title]}> 269 - {view.displayName || view.handle} 270 + {sanitizeDisplayName(view.displayName || view.handle)} 270 271 </Text> 271 272 </View> 272 273 <View style={styles.handleLine}>
+4 -1
src/view/com/search/Suggestions.tsx
··· 5 5 import {SuggestedActorsModel} from 'state/models/discovery/suggested-actors' 6 6 import {SuggestedFollows} from 'view/com/discover/SuggestedFollows' 7 7 import {ProfileCardFeedLoadingPlaceholder} from 'view/com/util/LoadingPlaceholder' 8 + import {sanitizeDisplayName} from 'lib/strings/display-names' 8 9 9 10 export const Suggestions = observer( 10 11 ({ ··· 43 44 return ( 44 45 <View key={`sf-${item.did}`} style={styles.suggestions}> 45 46 <SuggestedFollows 46 - title={`Followed by ${item.displayName || item.handle}`} 47 + title={`Followed by ${sanitizeDisplayName( 48 + item.displayName || item.handle, 49 + )}`} 47 50 suggestions={item.follows.slice(0, 10)} 48 51 /> 49 52 </View>
+3 -2
src/view/com/util/PostMeta.tsx
··· 9 9 import {observer} from 'mobx-react-lite' 10 10 import {FollowButton} from '../profile/FollowButton' 11 11 import {FollowState} from 'state/models/cache/my-follows' 12 + import {sanitizeDisplayName} from 'lib/strings/display-names' 12 13 13 14 interface PostMetaOpts { 14 15 authorAvatar?: string ··· 52 53 style={pal.text} 53 54 numberOfLines={1} 54 55 lineHeight={1.2} 55 - text={displayName} 56 + text={sanitizeDisplayName(displayName)} 56 57 href={`/profile/${opts.authorHandle}`} 57 58 /> 58 59 <Text type="md" style={pal.textLight} lineHeight={1.2}> ··· 103 104 lineHeight={1.2} 104 105 text={ 105 106 <> 106 - {displayName} 107 + {sanitizeDisplayName(displayName)} 107 108 <Text type="md" style={[pal.textLight]}> 108 109 &nbsp;{handle} 109 110 </Text>
+4 -1
src/view/com/util/UserInfoText.tsx
··· 6 6 import {LoadingPlaceholder} from './LoadingPlaceholder' 7 7 import {useStores} from 'state/index' 8 8 import {TypographyVariant} from 'lib/ThemeContext' 9 + import {sanitizeDisplayName} from 'lib/strings/display-names' 9 10 10 11 export function UserInfoText({ 11 12 type = 'md', ··· 68 69 lineHeight={1.2} 69 70 numberOfLines={1} 70 71 href={`/profile/${profile.handle}`} 71 - text={`${prefix || ''}${profile[attr] || profile.handle}`} 72 + text={`${prefix || ''}${sanitizeDisplayName( 73 + profile[attr] || profile.handle, 74 + )}`} 72 75 /> 73 76 ) 74 77 } else {