diff options
Diffstat (limited to 'src/view/com/profile')
-rw-r--r-- | src/view/com/profile/ProfileCard.tsx | 12 | ||||
-rw-r--r-- | src/view/com/profile/ProfileHeader.tsx | 43 |
2 files changed, 43 insertions, 12 deletions
diff --git a/src/view/com/profile/ProfileCard.tsx b/src/view/com/profile/ProfileCard.tsx index 2dfc7ad30..946e0f2ab 100644 --- a/src/view/com/profile/ProfileCard.tsx +++ b/src/view/com/profile/ProfileCard.tsx @@ -10,11 +10,13 @@ import {usePalette} from 'lib/hooks/usePalette' import {useStores} from 'state/index' import {FollowButton} from './FollowButton' import {sanitizeDisplayName} from 'lib/strings/display-names' +import {sanitizeHandle} from 'lib/strings/handles' import { getProfileViewBasicLabelInfo, getProfileModeration, } from 'lib/labeling/helpers' import {ModerationBehaviorCode} from 'lib/labeling/types' +import {makeProfileLink} from 'lib/routes/links' export const ProfileCard = observer( ({ @@ -60,7 +62,7 @@ export const ProfileCard = observer( noBorder && styles.outerNoBorder, !noBg && pal.view, ]} - href={`/profile/${profile.handle}`} + href={makeProfileLink(profile)} title={profile.handle} asAnchor anchorNoUnderline> @@ -78,10 +80,12 @@ export const ProfileCard = observer( style={[s.bold, pal.text]} numberOfLines={1} lineHeight={1.2}> - {sanitizeDisplayName(profile.displayName || profile.handle)} + {sanitizeDisplayName( + profile.displayName || sanitizeHandle(profile.handle), + )} </Text> <Text type="md" style={[pal.textLight]} numberOfLines={1}> - @{profile.handle} + {sanitizeHandle(profile.handle, '@')} </Text> {!!profile.viewer?.followedBy && ( <View style={s.flexRow}> @@ -160,7 +164,7 @@ export const ProfileCardWithFollowBtn = observer( followers?: AppBskyActorDefs.ProfileView[] | undefined }) => { const store = useStores() - const isMe = store.me.handle === profile.handle + const isMe = store.me.did === profile.did return ( <ProfileCard diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx index 320d8a778..11e9e74c3 100644 --- a/src/view/com/profile/ProfileHeader.tsx +++ b/src/view/com/profile/ProfileHeader.tsx @@ -15,11 +15,13 @@ import {ProfileImageLightbox} from 'state/models/ui/shell' import {pluralize} from 'lib/strings/helpers' import {toShareUrl} from 'lib/strings/url-helpers' import {sanitizeDisplayName} from 'lib/strings/display-names' +import {sanitizeHandle} from 'lib/strings/handles' import {s, colors} from 'lib/styles' import {DropdownButton, DropdownItem} from '../util/forms/DropdownButton' import * as Toast from '../util/Toast' import {LoadingPlaceholder} from '../util/LoadingPlaceholder' import {Text} from '../util/text/Text' +import {ThemedText} from '../util/text/ThemedText' import {TextLink} from '../util/Link' import {RichText} from '../util/text/RichText' import {UserAvatar} from '../util/UserAvatar' @@ -34,6 +36,8 @@ import {FollowState} from 'state/models/cache/my-follows' import {shareUrl} from 'lib/sharing' import {formatCount} from '../util/numeric/format' import {navigate} from '../../../Navigation' +import {isInvalidHandle} from 'lib/strings/handles' +import {makeProfileLink} from 'lib/routes/links' const BACK_HITSLOP = {left: 30, top: 30, right: 30, bottom: 30} @@ -67,7 +71,9 @@ export const ProfileHeader = observer( </View> <View> <Text type="title-2xl" style={[pal.text, styles.title]}> - {sanitizeDisplayName(view.displayName || view.handle)} + {sanitizeDisplayName( + view.displayName || sanitizeHandle(view.handle), + )} </Text> </View> </View> @@ -104,6 +110,7 @@ const ProfileHeaderLoaded = observer( const store = useStores() const navigation = useNavigation<NavigationProp>() const {track} = useAnalytics() + const invalidHandle = isInvalidHandle(view.handle) const onPressBack = React.useCallback(() => { navigation.goBack() @@ -144,19 +151,23 @@ const ProfileHeaderLoaded = observer( const onPressFollowers = React.useCallback(() => { track('ProfileHeader:FollowersButtonClicked') - navigate('ProfileFollowers', {name: view.handle}) + navigate('ProfileFollowers', { + name: isInvalidHandle(view.handle) ? view.did : view.handle, + }) store.shell.closeAllActiveElements() // for when used in the profile preview modal }, [track, view, store.shell]) const onPressFollows = React.useCallback(() => { track('ProfileHeader:FollowsButtonClicked') - navigate('ProfileFollows', {name: view.handle}) + navigate('ProfileFollows', { + name: isInvalidHandle(view.handle) ? view.did : view.handle, + }) store.shell.closeAllActiveElements() // for when used in the profile preview modal }, [track, view, store.shell]) const onPressShare = React.useCallback(() => { track('ProfileHeader:ShareButtonClicked') - const url = toShareUrl(`/profile/${view.handle}`) + const url = toShareUrl(makeProfileLink(view)) shareUrl(url) }, [track, view]) @@ -338,7 +349,7 @@ const ProfileHeaderLoaded = observer( style={[styles.btn, styles.mainBtn, pal.btn]} accessibilityRole="button" accessibilityLabel={`Unfollow ${view.handle}`} - accessibilityHint={`Hides direct posts from ${view.handle} in your feed`}> + accessibilityHint={`Hides posts from ${view.handle} in your feed`}> <FontAwesomeIcon icon="check" style={[pal.text, s.mr5]} @@ -355,7 +366,7 @@ const ProfileHeaderLoaded = observer( style={[styles.btn, styles.mainBtn, palInverted.view]} accessibilityRole="button" accessibilityLabel={`Follow ${view.handle}`} - accessibilityHint={`Shows direct posts from ${view.handle} in your feed`}> + accessibilityHint={`Shows posts from ${view.handle} in your feed`}> <FontAwesomeIcon icon="plus" style={[palInverted.text, s.mr5]} @@ -382,7 +393,9 @@ const ProfileHeaderLoaded = observer( testID="profileHeaderDisplayName" type="title-2xl" style={[pal.text, styles.title]}> - {sanitizeDisplayName(view.displayName || view.handle)} + {sanitizeDisplayName( + view.displayName || sanitizeHandle(view.handle), + )} </Text> </View> <View style={styles.handleLine}> @@ -393,7 +406,16 @@ const ProfileHeaderLoaded = observer( </Text> </View> ) : undefined} - <Text style={[pal.textLight, styles.handle]}>@{view.handle}</Text> + <ThemedText + type={invalidHandle ? 'xs' : 'md'} + fg={invalidHandle ? 'error' : 'light'} + border={invalidHandle ? 'error' : undefined} + style={[ + invalidHandle ? styles.invalidHandle : undefined, + styles.handle, + ]}> + {invalidHandle ? 'ā Invalid Handle' : `@${view.handle}`} + </ThemedText> </View> {!blockHide && ( <> @@ -600,6 +622,11 @@ const styles = StyleSheet.create({ // @ts-ignore web only -prf wordBreak: 'break-all', }, + invalidHandle: { + borderWidth: 1, + borderRadius: 4, + paddingHorizontal: 4, + }, handleLine: { flexDirection: 'row', |