diff --git a/src/types/atproto/index.ts b/src/types/atproto/index.ts new file mode 100644 index 0000000000..58e2a5eb23 --- /dev/null +++ b/src/types/atproto/index.ts @@ -0,0 +1 @@ +export * as profile from '#/types/atproto/profile' diff --git a/src/types/atproto/profile.ts b/src/types/atproto/profile.ts new file mode 100644 index 0000000000..884f10295d --- /dev/null +++ b/src/types/atproto/profile.ts @@ -0,0 +1,67 @@ +import {AppBskyActorDefs} from '@atproto/api' + +export { + /** + * Renamed to clarify source of this util, but directly aliases the original. + * {@link AppBskyActorDefs.isProfileViewBasic} + */ + isProfileViewBasic as isBasicView, + /** + * Renamed to clarify source of this util, but directly aliases the original. + * {@link AppBskyActorDefs.isProfileViewDetailed} + */ + isProfileViewDetailed as isDetailedView, + /** + * Renamed to clarify source of this util, but directly aliases the original. + * {@link AppBskyActorDefs.isProfileView} + */ + isProfileView as isView, +} from '@atproto/api/dist/client/types/app/bsky/actor/defs' + +/** + * Matches any profile view exported by our SDK + */ +export type AnyProfileView = + | AppBskyActorDefs.ProfileViewBasic + | AppBskyActorDefs.ProfileView + | AppBskyActorDefs.ProfileViewDetailed + +/** + * Maps any profile view type to `ProfileViewBasic`. + */ +export function anyToBasic( + view: AnyProfileView, +): AppBskyActorDefs.ProfileViewBasic { + return { + $type: 'app.bsky.actor.defs#profileViewBasic', + did: view.did, + handle: view.handle, + displayName: view.displayName, + avatar: view.avatar, + associated: view.associated, + viewer: view.viewer, + labels: view.labels, + createdAt: view.createdAt, + } +} + +/** + * Maps `ProfileViewDetailed` to `ProfileView`. + */ +export function detailedToView( + view: AppBskyActorDefs.ProfileViewDetailed, +): AppBskyActorDefs.ProfileView { + return { + $type: 'app.bsky.actor.defs#profileView', + did: view.did, + handle: view.handle, + displayName: view.displayName, + avatar: view.avatar, + associated: view.associated, + viewer: view.viewer, + labels: view.labels, + createdAt: view.createdAt, + description: view.description, + indexedAt: view.indexedAt, + } +} diff --git a/src/view/com/lists/ListMembers.tsx b/src/view/com/lists/ListMembers.tsx index 0caae67011..c8ecfc057a 100644 --- a/src/view/com/lists/ListMembers.tsx +++ b/src/view/com/lists/ListMembers.tsx @@ -1,6 +1,6 @@ import React, {useCallback} from 'react' import {Dimensions, StyleProp, View, ViewStyle} from 'react-native' -import {AppBskyActorDefs, AppBskyGraphDefs} from '@atproto/api' +import {AppBskyGraphDefs} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -11,6 +11,7 @@ import {useModalControls} from '#/state/modals' import {useListMembersQuery} from '#/state/queries/list-members' import {useSession} from '#/state/session' import {ListFooter} from '#/components/Lists' +import * as atp from '#/types/atproto' import {ProfileCard} from '../profile/ProfileCard' import {ErrorMessage} from '../util/error/ErrorMessage' import {Button} from '../util/forms/Button' @@ -116,7 +117,7 @@ export function ListMembers({ }, [fetchNextPage]) const onPressEditMembership = React.useCallback( - (profile: AppBskyActorDefs.ProfileViewBasic) => { + (profile: atp.profile.AnyProfileView) => { openModal({ name: 'user-add-remove-lists', subject: profile.did, @@ -131,7 +132,7 @@ export function ListMembers({ // = const renderMemberButton = React.useCallback( - (profile: AppBskyActorDefs.ProfileViewBasic) => { + (profile: atp.profile.AnyProfileView) => { if (!isOwner) { return null } diff --git a/src/view/com/profile/FollowButton.tsx b/src/view/com/profile/FollowButton.tsx index c2d76316e6..6446b7b878 100644 --- a/src/view/com/profile/FollowButton.tsx +++ b/src/view/com/profile/FollowButton.tsx @@ -1,10 +1,10 @@ import {StyleProp, TextStyle, View} from 'react-native' -import {AppBskyActorDefs} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {Shadow} from '#/state/cache/types' import {useProfileFollowMutationQueue} from '#/state/queries/profile' +import * as atp from '#/types/atproto' import {Button, ButtonType} from '../util/forms/Button' import * as Toast from '../util/Toast' @@ -17,7 +17,7 @@ export function FollowButton({ }: { unfollowedType?: ButtonType followedType?: ButtonType - profile: Shadow + profile: Shadow labelStyle?: StyleProp logContext: 'ProfileCard' | 'StarterPackProfilesList' }) { diff --git a/src/view/com/profile/ProfileCard.tsx b/src/view/com/profile/ProfileCard.tsx index f6e59fc69d..8a258498fb 100644 --- a/src/view/com/profile/ProfileCard.tsx +++ b/src/view/com/profile/ProfileCard.tsx @@ -24,6 +24,7 @@ import { shouldShowKnownFollowers, } from '#/components/KnownFollowers' import * as Pills from '#/components/Pills' +import * as atp from '#/types/atproto' import {Link} from '../util/Link' import {Text} from '../util/text/Text' import {PreviewableUserAvatar} from '../util/UserAvatar' @@ -41,12 +42,12 @@ export function ProfileCard({ showKnownFollowers, }: { testID?: string - profile: Omit + profile: atp.profile.AnyProfileView noModFilter?: boolean noBg?: boolean noBorder?: boolean renderButton?: ( - profile: Shadow, + profile: Shadow, ) => React.ReactNode onPress?: () => void style?: StyleProp @@ -60,7 +61,7 @@ export function ProfileCard({ const onBeforePress = React.useCallback(() => { onPress?.() - precacheProfile(queryClient, profile) + precacheProfile(queryClient, atp.profile.anyToBasic(profile)) }, [onPress, profile, queryClient]) if (!moderationOpts) { @@ -126,29 +127,35 @@ export function ProfileCard({ {renderButton(profile)} ) : undefined} - {profile.description || knownFollowersVisible ? ( - - {profile.description ? ( - - {profile.description as string} - - ) : null} - {knownFollowersVisible ? ( - - + {atp.profile.isView(profile) || atp.profile.isDetailedView(profile) ? ( + <> + {profile.description || knownFollowersVisible ? ( + + {profile.description ? ( + + {profile.description as string} + + ) : null} + {knownFollowersVisible ? ( + + {atp.profile.isDetailedView(profile) && ( + + )} + + ) : null} ) : null} - + ) : null} )