deer social fork for personal usage. but you might see a use idk. github mirror
4
fork

Configure Feed

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

make profile headers more similar to each other

ayla 7673dc64 876f62b6

+50 -32
+43 -1
src/screens/Profile/Header/ProfileHeaderLabeler.tsx
··· 14 14 import {MAX_LABELERS} from '#/lib/constants' 15 15 import {useHaptics} from '#/lib/haptics' 16 16 import {isAppLabeler} from '#/lib/moderation' 17 + import {formatJoinDate} from '#/lib/strings/time' 18 + import { 19 + sanitizeWebsiteForDisplay, 20 + sanitizeWebsiteForLink, 21 + } from '#/lib/strings/website' 17 22 import {logger} from '#/logger' 18 23 import {isIOS} from '#/platform/detection' 19 24 import {useProfileShadow} from '#/state/cache/profile-shadow' ··· 27 32 import {atoms as a, tokens, useTheme} from '#/alf' 28 33 import {Button, ButtonText} from '#/components/Button' 29 34 import {type DialogOuterProps, useDialogControl} from '#/components/Dialog' 35 + import {CalendarDays_Stroke2_Corner0_Rounded as CalendarDays} from '#/components/icons/CalendarDays' 36 + import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe' 30 37 import { 31 38 Heart2_Filled_Stroke2_Corner0_Rounded as HeartFilled, 32 39 Heart2_Stroke2_Corner0_Rounded as Heart, ··· 68 75 const cantSubscribePrompt = Prompt.usePromptControl() 69 76 const isSelf = currentAccount?.did === profile.did 70 77 78 + const website = profile.website 79 + const websiteFormatted = sanitizeWebsiteForDisplay(website ?? '') 80 + 81 + const dateJoined = useMemo(() => { 82 + if (!profile.createdAt) return '' 83 + return formatJoinDate(profile.createdAt) 84 + }, [profile.createdAt]) 85 + 71 86 const moderation = useMemo( 72 87 () => moderateProfile(profile, moderationOpts), 73 88 [profile, moderationOpts], ··· 170 185 style={[a.px_lg, a.pt_md, a.pb_sm]} 171 186 pointerEvents={isIOS ? 'auto' : 'box-none'}> 172 187 <View 173 - style={[a.flex_row, a.justify_end, a.align_center, a.gap_xs, a.pb_lg]} 188 + style={[a.flex_row, a.justify_end, a.align_center, a.gap_xs, a.pb_sm]} 174 189 pointerEvents={isIOS ? 'auto' : 'box-none'}> 175 190 {isMe ? ( 176 191 <> ··· 261 276 /> 262 277 </View> 263 278 ) : undefined} 279 + { 280 + <View style={[a.flex_row, a.flex_wrap, {gap: 10}, a.pt_md]}> 281 + {websiteFormatted && ( 282 + <Link 283 + to={sanitizeWebsiteForLink(websiteFormatted)} 284 + label={_(msg({message: `Visit ${websiteFormatted}`}))} 285 + style={[a.flex_row, a.align_center, a.gap_xs]}> 286 + <Globe 287 + width={tokens.space.lg} 288 + style={{color: t.palette.primary_500}} 289 + /> 290 + <Text style={[{color: t.palette.primary_500}]}> 291 + {websiteFormatted} 292 + </Text> 293 + </Link> 294 + )} 295 + <View style={[a.flex_row, a.align_center, a.gap_xs]}> 296 + <CalendarDays 297 + width={tokens.space.lg} 298 + style={{color: t.atoms.text_contrast_medium.color}} 299 + /> 300 + <Text style={[t.atoms.text_contrast_medium]}> 301 + <Trans>Joined {dateJoined}</Trans> 302 + </Text> 303 + </View> 304 + </View> 305 + } 264 306 {!isAppLabeler(profile.did) && ( 265 307 <View style={[a.flex_row, a.gap_xs, a.align_center, a.pt_lg]}> 266 308 <Button
+7 -31
src/screens/Profile/Header/ProfileHeaderStandard.tsx
··· 11 11 12 12 import {useActorStatus} from '#/lib/actor-status' 13 13 import {sanitizeDisplayName} from '#/lib/strings/display-names' 14 - import {sanitizeHandle} from '#/lib/strings/handles' 15 14 import {formatJoinDate} from '#/lib/strings/time' 16 15 import { 17 16 sanitizeWebsiteForDisplay, ··· 27 26 import {useRequireAuth, useSession} from '#/state/session' 28 27 import {ProfileMenu} from '#/view/com/profile/ProfileMenu' 29 28 import * as Toast from '#/view/com/util/Toast' 30 - import {atoms as a, platform, tokens, useBreakpoints, useTheme} from '#/alf' 29 + import {atoms as a, tokens, useTheme} from '#/alf' 31 30 import {SubscribeProfileButton} from '#/components/activity-notifications/SubscribeProfileButton' 32 31 import {Button, ButtonIcon, ButtonText} from '#/components/Button' 33 32 import {useDialogControl} from '#/components/Dialog' ··· 43 42 import * as Prompt from '#/components/Prompt' 44 43 import {RichText} from '#/components/RichText' 45 44 import {Text} from '#/components/Typography' 46 - import {VerificationCheckButton} from '#/components/verification/VerificationCheckButton' 45 + import {ProfileHeaderDisplayName} from './DisplayName' 47 46 import {EditProfileDialog} from './EditProfileDialog' 48 47 import {ProfileHeaderHandle} from './Handle' 49 48 import {ProfileHeaderMetrics} from './Metrics' ··· 66 65 isPlaceholderProfile, 67 66 }: Props): React.ReactNode => { 68 67 const t = useTheme() 69 - const {gtMobile} = useBreakpoints() 70 68 const profile = 71 69 useProfileShadow<AppBskyActorDefs.ProfileViewDetailed>(profileUnshadowed) 72 70 const {currentAccount, hasSession} = useSession() ··· 278 276 <ProfileMenu profile={profile} /> 279 277 </View> 280 278 <View 281 - style={[a.flex_col, a.gap_xs, a.pb_sm, live ? a.pt_sm : a.pt_2xs]}> 282 - <View style={[a.flex_row, a.align_center, a.gap_xs, a.flex_1]}> 283 - <Text 284 - emoji 285 - testID="profileHeaderDisplayName" 286 - style={[ 287 - t.atoms.text, 288 - gtMobile ? a.text_4xl : a.text_3xl, 289 - a.self_start, 290 - a.font_bold, 291 - a.leading_tight, 292 - ]}> 293 - {sanitizeDisplayName( 294 - profile.displayName || sanitizeHandle(profile.handle), 295 - moderation.ui('displayName'), 296 - )} 297 - <View 298 - style={[ 299 - a.pl_xs, 300 - { 301 - marginTop: platform({ios: 2}), 302 - }, 303 - ]}> 304 - <VerificationCheckButton profile={profile} size="lg" /> 305 - </View> 306 - </Text> 307 - </View> 279 + style={[a.flex_col, a.gap_2xs, a.pb_md, live ? a.pt_sm : a.pt_2xs]}> 280 + <ProfileHeaderDisplayName 281 + profile={profile} 282 + moderation={moderation} 283 + /> 308 284 <ProfileHeaderHandle profile={profile} /> 309 285 </View> 310 286 {!isPlaceholderProfile && !isBlockedUser && (