Skip to content

Commit

Permalink
Fix communities without a name (#1995)
Browse files Browse the repository at this point in the history
* enable hover cards on nft detail page

* fixxxx

* fix types
  • Loading branch information
Robinnnnn authored Oct 5, 2023
1 parent 9744cc1 commit 151892f
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 58 deletions.
8 changes: 7 additions & 1 deletion apps/mobile/src/components/Community/CommunityHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { View } from 'react-native';
import { graphql, useFragment } from 'react-relay';

import { CommunityHeaderFragment$key } from '~/generated/CommunityHeaderFragment.graphql';
import { truncateAddress } from '~/shared/utils/wallet';

import { GalleryBottomSheetModalType } from '../GalleryBottomSheet/GalleryBottomSheetModal';
import { GalleryTouchableOpacity } from '../GalleryTouchableOpacity';
Expand All @@ -19,6 +20,9 @@ export function CommunityHeader({ communityRef }: Props) {
graphql`
fragment CommunityHeaderFragment on Community {
name
contractAddress {
address
}
description
...CommunityProfilePictureFragment
...CommunityBottomSheetFragment
Expand All @@ -40,6 +44,8 @@ export function CommunityHeader({ communityRef }: Props) {
const cleanedSentences = community.description?.trim().replace(/\s+/g, ' ');
const formattedDescription = cleanedSentences?.split(/[.!?]\s+/).join(' ');

const displayName = community.name || truncateAddress(community.contractAddress?.address ?? '');

return (
<View className="mb-2">
<View className="flex flex-row space-x-2 items-center">
Expand All @@ -56,7 +62,7 @@ export function CommunityHeader({ communityRef }: Props) {
font={{ family: 'ABCDiatype', weight: 'Bold' }}
className="text-lg leading-5 mb-1"
>
{community.name}
{displayName}
</Typography>

{formattedDescription && <Markdown numberOfLines={3}>{formattedDescription}</Markdown>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export function CommunityProfilePicture({ communityRef, style, ...rest }: Profil
graphql`
fragment CommunityProfilePictureFragment on Community {
name
contractAddress {
address
}
profileImageURL
}
`,
Expand All @@ -25,7 +28,8 @@ export function CommunityProfilePicture({ communityRef, style, ...rest }: Profil

const imageUrl = community?.profileImageURL;

const letter = community?.name?.[0]?.toUpperCase();
const letter =
community?.name?.[0]?.toUpperCase() || community?.contractAddress?.address?.[0]?.toUpperCase();

const fallbackProfilePicture = (
<RawProfilePicture
Expand Down
7 changes: 3 additions & 4 deletions apps/mobile/src/screens/NftDetailScreen/NftDetailSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import TokenViewEmitter from '~/shared/components/TokenViewEmitter';
import { useTrack } from '~/shared/contexts/AnalyticsContext';
import { useLoggedInUserId } from '~/shared/relay/useLoggedInUserId';
import colors from '~/shared/theme/colors';
import { isFxHashContractAddress } from '~/shared/utils/getTezosExternalUrl';
import { extractRelevantMetadataFromToken } from '~/shared/utils/extractRelevantMetadataFromToken';

import { NftAdditionalDetails } from './NftAdditionalDetails';
import { NftDetailAsset } from './NftDetailAsset/NftDetailAsset';
Expand Down Expand Up @@ -83,6 +83,7 @@ export function NftDetailSection({ onShare, queryRef }: Props) {
...NftAdditionalDetailsFragment
...NftDetailAssetFragment
...TokenFailureBoundaryFragment
...extractRelevantMetadataFromTokenFragment
}
}
...useLoggedInUserIdFragment
Expand Down Expand Up @@ -153,9 +154,7 @@ export function NftDetailSection({ onShare, queryRef }: Props) {
// }
// }, [navigation, track, token.creator?.username]);

const contractName = isFxHashContractAddress(token.contract?.contractAddress?.address)
? 'fx(hash)'
: token.contract?.name ?? 'Untitled Contract';
const { contractName } = extractRelevantMetadataFromToken(token);

return (
<ScrollView>
Expand Down
6 changes: 5 additions & 1 deletion apps/web/src/components/Feed/Posts/PostCommunityPill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ export default function PostCommunityPill({ postRef }: Props) {
}

return (
<CommunityHoverCard communityRef={token.community} onClick={handleClick}>
<CommunityHoverCard
communityRef={token.community}
communityName={contractName}
onClick={handleClick}
>
<StyledPill>
<StyledCommunityName>{contractName}</StyledCommunityName>
</StyledPill>
Expand Down
37 changes: 15 additions & 22 deletions apps/web/src/components/HoverCard/CommunityHoverCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import { ErrorWithSentryMetadata } from '~/shared/errors/ErrorWithSentryMetadata
import { removeNullValues } from '~/shared/relay/removeNullValues';
import { useLoggedInUserId } from '~/shared/relay/useLoggedInUserId';
import colors from '~/shared/theme/colors';
import { isValidEthereumAddress, truncateAddress } from '~/shared/utils/wallet';
import handleCustomDisplayName from '~/utils/handleCustomDisplayName';

import InteractiveLink from '../core/InteractiveLink/InteractiveLink';
import Markdown from '../core/Markdown/Markdown';
Expand All @@ -27,7 +25,6 @@ const CommunityHoverCardQueryNode = graphql`
communityByAddress(communityAddress: $communityAddress) {
__typename
... on Community {
name
description
contractAddress {
address
Expand Down Expand Up @@ -59,14 +56,19 @@ const CommunityHoverCardQueryNode = graphql`

type Props = PropsWithChildren<{
communityRef: CommunityHoverCardFragment$key;
communityName: string;
onClick?: HoverCardProps<CommunityHoverCardQuery>['onHoverableElementClick'];
}>;

export default function CommunityHoverCard({ children, communityRef, onClick }: Props) {
export default function CommunityHoverCard({
children,
communityName,
communityRef,
onClick,
}: Props) {
const community = useFragment(
graphql`
fragment CommunityHoverCardFragment on Community {
name
contractAddress {
address
chain
Expand Down Expand Up @@ -99,20 +101,17 @@ export default function CommunityHoverCard({ children, communityRef, onClick }:
});
}, [community.contractAddress?.address, community.contractAddress?.chain, preloadHoverCardQuery]);

if (!community.name) {
return null;
}

const displayName = handleCustomDisplayName(community.name);

return (
<HoverCard
HoverableElement={children ?? <BaseS color={colors.shadow}>{displayName}</BaseS>}
HoverableElement={children ?? <BaseS color={colors.shadow}>{communityName}</BaseS>}
onHoverableElementClick={onClick}
hoverableElementHref={communityProfileLink}
HoveringContent={
preloadedHoverCardQuery ? (
<CommunityHoverCardContent preloadedQuery={preloadedHoverCardQuery} />
<CommunityHoverCardContent
preloadedQuery={preloadedHoverCardQuery}
communityName={communityName}
/>
) : null
}
preloadQuery={handlePreloadQuery}
Expand All @@ -123,8 +122,10 @@ export default function CommunityHoverCard({ children, communityRef, onClick }:

function CommunityHoverCardContent({
preloadedQuery,
communityName,
}: {
preloadedQuery: PreloadedQuery<CommunityHoverCardQuery>;
communityName: string;
}) {
const communityQuery = usePreloadedQuery(CommunityHoverCardQueryNode, preloadedQuery);

Expand Down Expand Up @@ -197,10 +198,6 @@ function CommunityHoverCardContent({
};
}, [community]);

if (!community.name) {
return null;
}

const hasDescription = Boolean(community.description);
return (
<VStack gap={6}>
Expand All @@ -210,11 +207,7 @@ function CommunityHoverCardContent({
</StyledLink>
<Section gap={2}>
<StyledLink href={communityProfileLink}>
<StyledCardTitle>
{isValidEthereumAddress(community.name)
? truncateAddress(community.name)
: community.name}
</StyledCardTitle>
<StyledCardTitle>{communityName}</StyledCardTitle>
</StyledLink>
{community.description && (
<StyledCardDescription>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export default function CommunityProfilePicture({ communityRef, ...rest }: Props
graphql`
fragment CommunityProfilePictureFragment on Community {
name
contractAddress {
address
}
profileImageURL
}
`,
Expand All @@ -24,6 +27,7 @@ export default function CommunityProfilePicture({ communityRef, ...rest }: Props
return <RawProfilePicture imageUrl={imageUrl} {...rest} />;
}

const firstLetter = community?.name?.[0]?.toUpperCase();
const firstLetter =
community?.name?.[0]?.toUpperCase() || community?.contractAddress?.address?.[0]?.toUpperCase();
return <RawProfilePicture letter={firstLetter ?? ''} {...rest} />;
}
9 changes: 6 additions & 3 deletions apps/web/src/scenes/CommunityPage/CommunityPageViewHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import GlobeIcon from '~/icons/GlobeIcon';
import ShareIcon from '~/icons/ShareIcon';
import { useTrack } from '~/shared/contexts/AnalyticsContext';
import { replaceUrlsWithMarkdownFormat } from '~/shared/utils/replaceUrlsWithMarkdownFormat';
import { getExternalAddressLink } from '~/shared/utils/wallet';
import { getExternalAddressLink, truncateAddress } from '~/shared/utils/wallet';
import { getBaseUrl } from '~/utils/getBaseUrl';

import CommunityPageMetadata from './CommunityPageMetadata';
Expand All @@ -37,6 +37,7 @@ export default function CommunityPageViewHeader({ communityRef, queryRef }: Prop
description
badgeURL
contractAddress {
address
...walletGetExternalAddressLinkFragment
}
...CommunityPageMetadataFragment
Expand Down Expand Up @@ -152,14 +153,16 @@ export default function CommunityPageViewHeader({ communityRef, queryRef }: Prop
showExpandedDescription,
]);

const displayName = name || truncateAddress(contractAddress?.address ?? '');

if (isMobile) {
return (
<VStack justify="space-between" gap={16}>
{ExternalLinks}
<HStack gap={12} align="center">
<CommunityProfilePicture communityRef={community} size="xxl" />
<VStack>
<TitleDiatypeL>{name}</TitleDiatypeL>
<TitleDiatypeL>{displayName}</TitleDiatypeL>
{DescriptionContainer}
</VStack>
</HStack>
Expand All @@ -175,7 +178,7 @@ export default function CommunityPageViewHeader({ communityRef, queryRef }: Prop
<StyledContainer>
<HStack gap={12} align="center">
<CommunityProfilePicture communityRef={community} size="lg" />
<TitleL>{name}</TitleL>
<TitleL>{displayName}</TitleL>
{badgeURL && <StyledBadge src={badgeURL} />}
</HStack>
<HStack gap={48}>
Expand Down
9 changes: 9 additions & 0 deletions apps/web/src/scenes/NftDetailPage/NftDetailAsset.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const UnknownMediaResponse: NftDetailAssetTestQueryQuery = {
lastUpdated: '2023-07-25T11:47:41.83653Z',
ownerIsCreator: false,
owner: {
dbid: 'testOwnerId',
id: 'GalleryUser:TestOwnerId',
username: 'Test Username',
profileImage: {
Expand Down Expand Up @@ -102,6 +103,14 @@ const UnknownMediaResponse: NftDetailAssetTestQueryQuery = {
},
badgeURL: 'http://someurl.com',
},
community: {
__typename: 'Community',
id: 'Contract:someCommunityId',
contractAddress: {
chain: Chain.Ethereum,
address: '0x0Ff979fB365e20c09bE06676D569EF581a46621D',
},
},
},
},
};
Expand Down
50 changes: 30 additions & 20 deletions apps/web/src/scenes/NftDetailPage/NftDetailText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import InteractiveLink from '~/components/core/InteractiveLink/InteractiveLink';
import Markdown from '~/components/core/Markdown/Markdown';
import { HStack, VStack } from '~/components/core/Spacer/Stack';
import { BaseM, TitleDiatypeM, TitleM, TitleXS } from '~/components/core/Text/Text';
import CommunityHoverCard from '~/components/HoverCard/CommunityHoverCard';
import UserHoverCard from '~/components/HoverCard/UserHoverCard';
import { ClickablePill, NonclickablePill } from '~/components/Pill';
import { PostComposerModal } from '~/components/Posts/PostComposerModal';
import { ProfilePicture } from '~/components/ProfilePicture/ProfilePicture';
Expand Down Expand Up @@ -49,6 +51,7 @@ function NftDetailText({ tokenRef, authenticatedUserOwnsAsset }: Props) {
owner {
username
...ProfilePictureFragment
...UserHoverCardFragment
}
ownerIsCreator
contract {
Expand All @@ -59,6 +62,9 @@ function NftDetailText({ tokenRef, authenticatedUserOwnsAsset }: Props) {
}
badgeURL
}
community {
...CommunityHoverCardFragment
}
...NftAdditionalDetailsFragment
...getCommunityUrlForTokenFragment
Expand Down Expand Up @@ -159,14 +165,16 @@ function NftDetailText({ tokenRef, authenticatedUserOwnsAsset }: Props) {
<VStack gap={8}>
{token.name && <TitleM>{decodedTokenName}</TitleM>}
<HStack align="center" gap={4}>
{communityUrl ? (
<ClickablePill to={communityUrl}>
<StyledPillContent gap={4} align="center" justify="flex-end">
{token.chain === 'POAP' && <PoapLogo />}
{token.contract?.badgeURL && <StyledBadge src={token.contract.badgeURL} />}
<StyledContractName>{contractName}</StyledContractName>
</StyledPillContent>
</ClickablePill>
{communityUrl && token.community ? (
<CommunityHoverCard communityRef={token.community} communityName={contractName}>
<ClickablePill to={communityUrl}>
<StyledPillContent gap={4} align="center" justify="flex-end">
{token.chain === 'POAP' && <PoapLogo />}
{token.contract?.badgeURL && <StyledBadge src={token.contract.badgeURL} />}
<StyledContractName>{contractName}</StyledContractName>
</StyledPillContent>
</ClickablePill>
</CommunityHoverCard>
) : (
<NonclickablePill>
<StyledContractName>{contractName}</StyledContractName>
Expand All @@ -177,18 +185,20 @@ function NftDetailText({ tokenRef, authenticatedUserOwnsAsset }: Props) {

<HStack justify="space-between">
{token.owner?.username && (
<VStack gap={2}>
<TitleXS>{token.ownerIsCreator ? 'CREATOR' : 'OWNER'}</TitleXS>
<StyledInteractiveLink
to={{ pathname: '/[username]', query: { username: token.owner.username } }}
onClick={handleCollectorNameClick}
>
<HStack align="center" gap={4}>
<ProfilePicture size="sm" userRef={token.owner} />
<TitleDiatypeM>{token.owner.username}</TitleDiatypeM>
</HStack>
</StyledInteractiveLink>
</VStack>
<UserHoverCard userRef={token.owner}>
<VStack gap={2}>
<TitleXS>{token.ownerIsCreator ? 'CREATOR' : 'OWNER'}</TitleXS>
<StyledInteractiveLink
to={{ pathname: '/[username]', query: { username: token.owner.username } }}
onClick={handleCollectorNameClick}
>
<HStack align="center" gap={4}>
<ProfilePicture size="sm" userRef={token.owner} />
<TitleDiatypeM>{token.owner.username}</TitleDiatypeM>
</HStack>
</StyledInteractiveLink>
</VStack>
</UserHoverCard>
)}
{ENABLED_CREATOR && (
// TODO: Update this to use the creator's username
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,16 @@ export default function SharedCommunitiesList({ userRef }: Props) {
)
: null;

if (!community.name && !descriptionFirstLine) {
const displayName =
community.name || community.contractAddress?.address || 'Untitled Contract';

if (!displayName && !descriptionFirstLine) {
return null;
}

return (
<div style={style} key={key}>
<CommunityHoverCard communityRef={community}>
<CommunityHoverCard communityRef={community} communityName={displayName}>
<PaginatedListRow
title={community.name ?? ''}
subTitle={descriptionFirstLine}
Expand Down
Loading

1 comment on commit 151892f

@vercel
Copy link

@vercel vercel bot commented on 151892f Oct 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.