Skip to content

Commit

Permalink
Merge pull request #1276 from matiasbenary/native-profile
Browse files Browse the repository at this point in the history
Native profile
  • Loading branch information
calebjacob authored Aug 8, 2024
2 parents dd831b5 + f685249 commit 4f06d9d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 24 deletions.
3 changes: 3 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ const nextConfig = {
poweredByHeader: false,
compiler: { styledComponents: true },
reactStrictMode: true,
images: {
domains: ['ipfs.near.social'],
},
experimental: {
optimizePackageImports: ['@phosphor-icons/react'],
},
Expand Down
57 changes: 57 additions & 0 deletions src/components/NTFImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Image from 'next/image';
import { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';

import { useVmStore } from '@/stores/vm';

const RoundedImage = styled(Image)`
border-radius: 50%;
`;

interface Nft {
contractId: string;
tokenId: string;
}

interface NftImageProps {
nft: Nft;
ipfs_cid?: string;
alt: string;
}

const DEFAULT_IMAGE = 'https://ipfs.near.social/ipfs/bafkreidoxgv2w7kmzurdnmflegkthgzaclgwpiccgztpkfdkfzb4265zuu';

export const NftImage: React.FC<NftImageProps> = ({ nft, ipfs_cid, alt }) => {
const near = useVmStore((store) => store.near);
const [imageUrl, setImageUrl] = useState<string>(DEFAULT_IMAGE);

const fetchNftData = useCallback(async () => {
if (!near || !nft || !nft.contractId || !nft.tokenId || ipfs_cid) return;

const [nftMetadata, tokenData] = await Promise.all([
near.viewCall(nft.contractId, 'nft_metadata'),
near.viewCall(nft.contractId, 'nft_token', { token_id: nft.tokenId }),
]);

const tokenMetadata = tokenData.metadata;
const tokenMedia = tokenMetadata?.media || '';

if (tokenMedia.startsWith('https://') || tokenMedia.startsWith('http://') || tokenMedia.startsWith('data:image')) {
setImageUrl(tokenMedia);
} else if (nftMetadata?.base_uri) {
setImageUrl(`${nftMetadata.base_uri}/${tokenMedia}`);
} else if (tokenMedia.startsWith('Qm') || tokenMedia.startsWith('ba')) {
setImageUrl(`https://ipfs.near.social/ipfs/${tokenMedia}`);
}
}, [near, nft, ipfs_cid]);

useEffect(() => {
if (ipfs_cid) {
setImageUrl(`https://ipfs.near.social/ipfs/${ipfs_cid}`);
} else {
fetchNftData();
}
}, [ipfs_cid, fetchNftData]);

return <RoundedImage width={43} height={43} src={imageUrl} alt={alt} />;
};
42 changes: 18 additions & 24 deletions src/components/marketing-navigation/UserDropdownMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Dropdown, SvgIcon } from '@near-pagoda/ui';
import { Bank, Gear, SignOut, User, Wallet } from '@phosphor-icons/react';
import { useRouter } from 'next/router';
import { useCallback } from 'react';
import { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';

import { VmComponent } from '@/components/vm/VmComponent';
import { useBosComponents } from '@/hooks/useBosComponents';
import { useAuthStore } from '@/stores/auth';
import { useVmStore } from '@/stores/vm';

import { NftImage } from '../NTFImage';

const Wrapper = styled.div`
flex-grow: 1;
Expand Down Expand Up @@ -45,11 +46,6 @@ const Wrapper = styled.div`
.d-inline-block {
width: unset !important;
height: unset !important;
img {
border-radius: 50% !important;
width: 38px !important;
height: 38px !important;
}
}
i {
Expand Down Expand Up @@ -88,13 +84,6 @@ const Wrapper = styled.div`
background: var(--sand6);
padding: 1px;
}
.d-inline-block {
img {
width: 43px !important;
height: 43px !important;
}
}
}
`;

Expand All @@ -115,6 +104,19 @@ export const UserDropdownMenu = ({ collapsed }: Props) => {
await near.contract.storage_withdraw({}, undefined, '1');
}, [near]);

const [profile, setProfile] = useState<any>({});

useEffect(() => {
async function getProfile() {
const profile = await near.viewCall('social.near', 'get', { keys: [`${accountId}/profile/**`] });
setProfile(profile[accountId].profile);
}

if (!near || !accountId) return;

getProfile();
}, [near, accountId]);

return (
<Wrapper>
<Dropdown.Root>
Expand All @@ -124,17 +126,9 @@ export const UserDropdownMenu = ({ collapsed }: Props) => {
</Dropdown.Trigger>
) : (
<Dropdown.Trigger>
<VmComponent
src={components.profileImage}
props={{
accountId,
className: 'd-inline-block',
}}
/>
<NftImage nft={profile.image?.nft} ipfs_cid={profile.image?.ipfs_cid} alt={profile.name || accountId} />
<div className="profile-info">
<div className="profile-name">
<VmComponent src={components.profileName} />
</div>
<div className="profile-name">{profile.name}</div>
<div className="profile-username">{accountId}</div>
</div>
<i className="ph ph-caret-right"></i>
Expand Down

0 comments on commit 4f06d9d

Please sign in to comment.