diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 42eb648443..cf324e96f2 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -545,6 +545,7 @@ export const Button = React.forwardRef( a.flex_row, a.align_center, a.justify_center, + a.curve_continuous, flattenedBaseStyles, ...(state.hovered || state.pressed ? [hoverStyles, flatten(hoverStyleProp)] diff --git a/src/components/ProfileCard.tsx b/src/components/ProfileCard.tsx index 4aec74880a..1e1e32abc6 100644 --- a/src/components/ProfileCard.tsx +++ b/src/components/ProfileCard.tsx @@ -1,5 +1,10 @@ -import React from 'react' -import {type GestureResponderEvent, View} from 'react-native' +import {useMemo} from 'react' +import { + type GestureResponderEvent, + type StyleProp, + type TextStyle, + View, +} from 'react-native' import { moderateProfile, type ModerationOpts, @@ -136,12 +141,14 @@ export function Avatar({ onPress, disabledPreview, liveOverride, + size = 40, }: { profile: bsky.profile.AnyProfileView moderationOpts: ModerationOpts onPress?: () => void disabledPreview?: boolean liveOverride?: boolean + size?: number }) { const moderation = moderateProfile(profile, moderationOpts) @@ -149,7 +156,7 @@ export function Avatar({ return disabledPreview ? ( ) : ( @@ -340,12 +347,14 @@ export function NameAndHandlePlaceholder() { export function Description({ profile: profileUnshadowed, numberOfLines = 3, + style, }: { profile: bsky.profile.AnyProfileView numberOfLines?: number + style?: StyleProp }) { const profile = useProfileShadow(profileUnshadowed) - const rt = React.useMemo(() => { + const rt = useMemo(() => { if (!('description' in profile)) return const rt = new RichTextApi({text: profile.description || ''}) rt.detectFacetsWithoutResolution() @@ -363,7 +372,7 @@ export function Description({ diff --git a/src/components/Skeleton.tsx b/src/components/Skeleton.tsx index 14c3177c54..54770737b9 100644 --- a/src/components/Skeleton.tsx +++ b/src/components/Skeleton.tsx @@ -1,4 +1,3 @@ -import {type ReactNode} from 'react' import {View} from 'react-native' import { @@ -15,7 +14,7 @@ type SkeletonProps = { blend?: boolean } -export function Text({blend, style}: TextStyleProp & SkeletonProps) { +export function Text({blend, style}: Required & SkeletonProps) { const {fonts, flags, theme: t} = useAlf() const {width, ...flattened} = flatten(style) const {lineHeight = 14, ...rest} = normalizeTextStyles( @@ -28,7 +27,11 @@ export function Text({blend, style}: TextStyleProp & SkeletonProps) { ) return ( + style={[ + a.flex_1, + a.w_full, + {maxWidth: width, paddingVertical: lineHeight * 0.15}, + ]}> { + const unblockAccount = useCallback(async () => { try { await queueUnblock() Toast.show(_(msg({message: 'Account unblocked', context: 'toast'}))) @@ -308,6 +310,9 @@ let ProfileHeaderStandard = ({ )} + {showSuggestedFollows && ( + + )} + {children} + + ) +} + +export function SuggestedFollowPlaceholder() { + return ( + + + + + + + + + + ) +} + +export function ProfileHeaderSuggestedFollows({actorDid}: {actorDid: string}) { + const t = useTheme() + const {_} = useLingui() + const {isPending: isSuggestionsPending, data} = + useSuggestedFollowsByActorQuery({did: actorDid}) + const moderationOpts = useModerationOpts() + const isPending = isSuggestionsPending || !moderationOpts + + const followAll = () => {} + + return ( + <> + + + Suggested for you + + + + + + + + {isPending ? ( + <> + + + + + + + ) : data ? ( + data.suggestions + .filter(s => (s.associated?.labeler ? false : true)) + .map(profile => ( + { + logger.metric( + 'profile:header:suggestedFollowsCard:press', + {}, + ) + }} + style={[a.flex_1]}> + {({hovered, pressed}) => ( + + + + + + + + + + + + + )} + + )) + ) : null} + + + + + ) +}