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

This commit is contained in:
Paul Frazee 2023-04-07 11:09:25 -05:00 committed by GitHub
parent 4b98992257
commit ab11f206d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 58 additions and 23 deletions

View file

@ -3,6 +3,7 @@ import {AppBskyEmbedImages} from '@atproto/api'
import {RootStoreModel} from 'state/models/root-store' import {RootStoreModel} from 'state/models/root-store'
import {NotificationsFeedItemModel} from 'state/models/feeds/notifications' import {NotificationsFeedItemModel} from 'state/models/feeds/notifications'
import {enforceLen} from 'lib/strings/helpers' import {enforceLen} from 'lib/strings/helpers'
import {sanitizeDisplayName} from './strings/display-names'
import {resetToTab} from '../Navigation' import {resetToTab} from '../Navigation'
export function init(store: RootStoreModel) { export function init(store: RootStoreModel) {
@ -42,7 +43,9 @@ export function displayNotification(
export function displayNotificationFromModel( export function displayNotificationFromModel(
notif: NotificationsFeedItemModel, notif: NotificationsFeedItemModel,
) { ) {
let author = notif.author.displayName || notif.author.handle let author = sanitizeDisplayName(
notif.author.displayName || notif.author.handle,
)
let title: string let title: string
let body: string = '' let body: string = ''
if (notif.isLike) { if (notif.isLike) {

View file

@ -0,0 +1,12 @@
// \u2705 = ✅
// \u2713 = ✓
// \u2714 = ✔
// \u2611 = ☑
const CHECK_MARKS_RE = /[\u2705\u2713\u2714\u2611]/gu
export function sanitizeDisplayName(str: string): string {
if (typeof str === 'string') {
return str.replace(CHECK_MARKS_RE, '')
}
return ''
}

View file

@ -26,6 +26,7 @@ import {useStores} from 'state/index'
import * as apilib from 'lib/api/index' import * as apilib from 'lib/api/index'
import {ComposerOpts} from 'state/models/ui/shell' import {ComposerOpts} from 'state/models/ui/shell'
import {s, colors, gradients} from 'lib/styles' import {s, colors, gradients} from 'lib/styles'
import {sanitizeDisplayName} from 'lib/strings/display-names'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {SelectPhotoBtn} from './photos/SelectPhotoBtn' import {SelectPhotoBtn} from './photos/SelectPhotoBtn'
import {OpenCameraBtn} from './photos/OpenCameraBtn' import {OpenCameraBtn} from './photos/OpenCameraBtn'
@ -265,7 +266,9 @@ export const ComposePost = observer(function ComposePost({
<UserAvatar avatar={replyTo.author.avatar} size={50} /> <UserAvatar avatar={replyTo.author.avatar} size={50} />
<View style={styles.replyToPost}> <View style={styles.replyToPost}>
<Text type="xl-medium" style={[pal.text]}> <Text type="xl-medium" style={[pal.text]}>
{replyTo.author.displayName || replyTo.author.handle} {sanitizeDisplayName(
replyTo.author.displayName || replyTo.author.handle,
)}
</Text> </Text>
<Text type="post-text" style={pal.text} numberOfLines={6}> <Text type="post-text" style={pal.text} numberOfLines={6}>
{replyTo.text} {replyTo.text}

View file

@ -18,6 +18,7 @@ import {NotificationsFeedItemModel} from 'state/models/feeds/notifications'
import {PostThreadModel} from 'state/models/content/post-thread' import {PostThreadModel} from 'state/models/content/post-thread'
import {s, colors} from 'lib/styles' import {s, colors} from 'lib/styles'
import {ago} from 'lib/strings/time' import {ago} from 'lib/strings/time'
import {sanitizeDisplayName} from 'lib/strings/display-names'
import {pluralize} from 'lib/strings/helpers' import {pluralize} from 'lib/strings/helpers'
import {HeartIconSolid} from 'lib/icons' import {HeartIconSolid} from 'lib/icons'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
@ -187,7 +188,9 @@ export const FeedItem = observer(function FeedItem({
key={authors[0].href} key={authors[0].href}
style={[pal.text, s.bold, styles.metaItem]} style={[pal.text, s.bold, styles.metaItem]}
href={authors[0].href} href={authors[0].href}
text={authors[0].displayName || authors[0].handle} text={sanitizeDisplayName(
authors[0].displayName || authors[0].handle,
)}
/> />
{authors.length > 1 ? ( {authors.length > 1 ? (
<> <>
@ -310,7 +313,7 @@ function ExpandedAuthorsList({
<Link <Link
key={author.href} key={author.href}
href={author.href} href={author.href}
title={author.displayName || author.handle} title={sanitizeDisplayName(author.displayName || author.handle)}
style={styles.expandedAuthor} style={styles.expandedAuthor}
asAnchor> asAnchor>
<View style={styles.expandedAuthorAvi}> <View style={styles.expandedAuthorAvi}>
@ -322,7 +325,7 @@ function ExpandedAuthorsList({
numberOfLines={1} numberOfLines={1}
style={pal.text} style={pal.text}
lineHeight={1.2}> lineHeight={1.2}>
{author.displayName || author.handle} {sanitizeDisplayName(author.displayName || author.handle)}
&nbsp; &nbsp;
<Text style={[pal.textLight]} lineHeight={1.2}> <Text style={[pal.textLight]} lineHeight={1.2}>
{author.handle} {author.handle}

View file

@ -15,6 +15,7 @@ import {CenteredView} from '../util/Views.web'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {s} from 'lib/styles' import {s} from 'lib/styles'
import {sanitizeDisplayName} from 'lib/strings/display-names'
export const InvitedUsers = observer(() => { export const InvitedUsers = observer(() => {
const store = useStores() const store = useStores()
@ -65,7 +66,7 @@ function InvitedUser({
type="md-bold" type="md-bold"
style={pal.text} style={pal.text}
href={`/profile/${profile.handle}`} href={`/profile/${profile.handle}`}
text={profile.displayName || profile.handle} text={sanitizeDisplayName(profile.displayName || profile.handle)}
/>{' '} />{' '}
joined using your invite code! joined using your invite code!
</Text> </Text>

View file

@ -16,6 +16,7 @@ import * as Toast from '../util/Toast'
import {UserAvatar} from '../util/UserAvatar' import {UserAvatar} from '../util/UserAvatar'
import {s} from 'lib/styles' import {s} from 'lib/styles'
import {ago} from 'lib/strings/time' import {ago} from 'lib/strings/time'
import {sanitizeDisplayName} from 'lib/strings/display-names'
import {pluralize} from 'lib/strings/helpers' import {pluralize} from 'lib/strings/helpers'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {PostMeta} from '../util/PostMeta' import {PostMeta} from '../util/PostMeta'
@ -151,7 +152,9 @@ export const PostThreadItem = observer(function PostThreadItem({
style={[pal.text]} style={[pal.text]}
numberOfLines={1} numberOfLines={1}
lineHeight={1.2}> lineHeight={1.2}>
{item.post.author.displayName || item.post.author.handle} {sanitizeDisplayName(
item.post.author.displayName || item.post.author.handle,
)}
</Text> </Text>
</Link> </Link>
<Text type="md" style={[styles.metaItem, pal.textLight]}> <Text type="md" style={[styles.metaItem, pal.textLight]}>

View file

@ -22,6 +22,7 @@ import {s} from 'lib/styles'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {useAnalytics} from 'lib/analytics' import {useAnalytics} from 'lib/analytics'
import {sanitizeDisplayName} from 'lib/strings/display-names'
export const FeedItem = observer(function ({ export const FeedItem = observer(function ({
item, item,
@ -151,9 +152,9 @@ export const FeedItem = observer(function ({
<Link <Link
style={styles.includeReason} style={styles.includeReason}
href={`/profile/${item.reasonRepost.by.handle}`} href={`/profile/${item.reasonRepost.by.handle}`}
title={ title={sanitizeDisplayName(
item.reasonRepost.by.displayName || item.reasonRepost.by.handle item.reasonRepost.by.displayName || item.reasonRepost.by.handle,
}> )}>
<FontAwesomeIcon <FontAwesomeIcon
icon="retweet" icon="retweet"
style={[ style={[
@ -172,10 +173,10 @@ export const FeedItem = observer(function ({
style={pal.textLight} style={pal.textLight}
lineHeight={1.2} lineHeight={1.2}
numberOfLines={1} numberOfLines={1}
text={ text={sanitizeDisplayName(
item.reasonRepost.by.displayName || item.reasonRepost.by.displayName ||
item.reasonRepost.by.handle item.reasonRepost.by.handle,
} )}
href={`/profile/${item.reasonRepost.by.handle}`} href={`/profile/${item.reasonRepost.by.handle}`}
/> />
</Text> </Text>

View file

@ -9,6 +9,7 @@ import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {FollowButton} from './FollowButton' import {FollowButton} from './FollowButton'
import {sanitizeDisplayName} from 'lib/strings/display-names'
export function ProfileCard({ export function ProfileCard({
testID, testID,
@ -57,7 +58,7 @@ export function ProfileCard({
style={[s.bold, pal.text]} style={[s.bold, pal.text]}
numberOfLines={1} numberOfLines={1}
lineHeight={1.2}> lineHeight={1.2}>
{displayName || handle} {sanitizeDisplayName(displayName || handle)}
</Text> </Text>
<Text type="md" style={[pal.textLight]} numberOfLines={1}> <Text type="md" style={[pal.textLight]} numberOfLines={1}>
@{handle} @{handle}

View file

@ -18,6 +18,7 @@ import {useStores} from 'state/index'
import {ProfileImageLightbox} from 'state/models/ui/shell' import {ProfileImageLightbox} from 'state/models/ui/shell'
import {pluralize} from 'lib/strings/helpers' import {pluralize} from 'lib/strings/helpers'
import {toShareUrl} from 'lib/strings/url-helpers' import {toShareUrl} from 'lib/strings/url-helpers'
import {sanitizeDisplayName} from 'lib/strings/display-names'
import {s, colors} from 'lib/styles' import {s, colors} from 'lib/styles'
import {DropdownButton, DropdownItem} from '../util/forms/DropdownButton' import {DropdownButton, DropdownItem} from '../util/forms/DropdownButton'
import * as Toast from '../util/Toast' import * as Toast from '../util/Toast'
@ -58,7 +59,7 @@ export const ProfileHeader = observer(
</View> </View>
<View style={styles.displayNameLine}> <View style={styles.displayNameLine}>
<Text type="title-2xl" style={[pal.text, styles.title]}> <Text type="title-2xl" style={[pal.text, styles.title]}>
{view.displayName || view.handle} {sanitizeDisplayName(view.displayName || view.handle)}
</Text> </Text>
</View> </View>
</View> </View>
@ -108,9 +109,9 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoaded({
view?.toggleFollowing().then( view?.toggleFollowing().then(
() => { () => {
Toast.show( Toast.show(
`${view.viewer.following ? 'Following' : 'No longer following'} ${ `${
view.displayName || view.handle view.viewer.following ? 'Following' : 'No longer following'
}`, } ${sanitizeDisplayName(view.displayName || view.handle)}`,
) )
}, },
err => store.log.error('Failed to toggle follow', err), err => store.log.error('Failed to toggle follow', err),
@ -266,7 +267,7 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoaded({
testID="profileHeaderDisplayName" testID="profileHeaderDisplayName"
type="title-2xl" type="title-2xl"
style={[pal.text, styles.title]}> style={[pal.text, styles.title]}>
{view.displayName || view.handle} {sanitizeDisplayName(view.displayName || view.handle)}
</Text> </Text>
</View> </View>
<View style={styles.handleLine}> <View style={styles.handleLine}>

View file

@ -5,6 +5,7 @@ import {FoafsModel} from 'state/models/discovery/foafs'
import {SuggestedActorsModel} from 'state/models/discovery/suggested-actors' import {SuggestedActorsModel} from 'state/models/discovery/suggested-actors'
import {SuggestedFollows} from 'view/com/discover/SuggestedFollows' import {SuggestedFollows} from 'view/com/discover/SuggestedFollows'
import {ProfileCardFeedLoadingPlaceholder} from 'view/com/util/LoadingPlaceholder' import {ProfileCardFeedLoadingPlaceholder} from 'view/com/util/LoadingPlaceholder'
import {sanitizeDisplayName} from 'lib/strings/display-names'
export const Suggestions = observer( export const Suggestions = observer(
({ ({
@ -43,7 +44,9 @@ export const Suggestions = observer(
return ( return (
<View key={`sf-${item.did}`} style={styles.suggestions}> <View key={`sf-${item.did}`} style={styles.suggestions}>
<SuggestedFollows <SuggestedFollows
title={`Followed by ${item.displayName || item.handle}`} title={`Followed by ${sanitizeDisplayName(
item.displayName || item.handle,
)}`}
suggestions={item.follows.slice(0, 10)} suggestions={item.follows.slice(0, 10)}
/> />
</View> </View>

View file

@ -9,6 +9,7 @@ import {UserAvatar} from './UserAvatar'
import {observer} from 'mobx-react-lite' import {observer} from 'mobx-react-lite'
import {FollowButton} from '../profile/FollowButton' import {FollowButton} from '../profile/FollowButton'
import {FollowState} from 'state/models/cache/my-follows' import {FollowState} from 'state/models/cache/my-follows'
import {sanitizeDisplayName} from 'lib/strings/display-names'
interface PostMetaOpts { interface PostMetaOpts {
authorAvatar?: string authorAvatar?: string
@ -52,7 +53,7 @@ export const PostMeta = observer(function (opts: PostMetaOpts) {
style={pal.text} style={pal.text}
numberOfLines={1} numberOfLines={1}
lineHeight={1.2} lineHeight={1.2}
text={displayName} text={sanitizeDisplayName(displayName)}
href={`/profile/${opts.authorHandle}`} href={`/profile/${opts.authorHandle}`}
/> />
<Text type="md" style={pal.textLight} lineHeight={1.2}> <Text type="md" style={pal.textLight} lineHeight={1.2}>
@ -103,7 +104,7 @@ export const PostMeta = observer(function (opts: PostMetaOpts) {
lineHeight={1.2} lineHeight={1.2}
text={ text={
<> <>
{displayName} {sanitizeDisplayName(displayName)}
<Text type="md" style={[pal.textLight]}> <Text type="md" style={[pal.textLight]}>
&nbsp;{handle} &nbsp;{handle}
</Text> </Text>

View file

@ -6,6 +6,7 @@ import {Text} from './text/Text'
import {LoadingPlaceholder} from './LoadingPlaceholder' import {LoadingPlaceholder} from './LoadingPlaceholder'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {TypographyVariant} from 'lib/ThemeContext' import {TypographyVariant} from 'lib/ThemeContext'
import {sanitizeDisplayName} from 'lib/strings/display-names'
export function UserInfoText({ export function UserInfoText({
type = 'md', type = 'md',
@ -68,7 +69,9 @@ export function UserInfoText({
lineHeight={1.2} lineHeight={1.2}
numberOfLines={1} numberOfLines={1}
href={`/profile/${profile.handle}`} href={`/profile/${profile.handle}`}
text={`${prefix || ''}${profile[attr] || profile.handle}`} text={`${prefix || ''}${sanitizeDisplayName(
profile[attr] || profile.handle,
)}`}
/> />
) )
} else { } else {