Skip to content

Commit

Permalink
feat: show picture of current profile
Browse files Browse the repository at this point in the history
  • Loading branch information
maui-r committed Nov 6, 2022
1 parent 8d6c738 commit 4d7da75
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 31 deletions.
52 changes: 46 additions & 6 deletions src/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import Typography from '@mui/material/Typography'
import IconButton from '@mui/material/IconButton'
import HelpIcon from '@mui/icons-material/Help'
import SettingsIcon from '@mui/icons-material/Settings'
import { Box, Menu, MenuItem, Avatar as MuiAvatar, Stack, Tooltip } from '@mui/material'
import { Box, Button, Menu, MenuItem, Stack, Tooltip } from '@mui/material'
import LoadingButton from '@mui/lab/LoadingButton'
import { useAppStore } from '../../stores'
import { signOut } from '../../lens/auth'
import { JWT_ADDRESS_KEY } from '../../constants'
import { useAccount } from 'wagmi'
import { ProfilePicture } from '../Shared/ProfilePicture'
import { useQuery } from 'urql'
import { graphql } from '../../lens/schema'

const SettingsButton = () => {
const showSettings = useAppStore((state) => state.showSettings)
Expand Down Expand Up @@ -56,7 +59,40 @@ const SignInButton = () => {
)
}

const Avatar = () => {
const ProfilePictureQuery = graphql(`
query ProfilePicture($profileId: ProfileId!) {
profile(request: { profileId: $profileId }) {
picture {
... on NftImage {
uri
}
... on MediaSet {
original {
url
mimeType
}
}
__typename
}
}
}
`)

const CurrentProfilePicture = ({ profileId }: { profileId: string }) => {
const [{ data, fetching, error }] = useQuery({
query: ProfilePictureQuery,
variables: { profileId },
requestPolicy: 'cache-and-network',
})
if (error) console.log(error.message)
const profile = data?.profile

if (fetching || error || !profile) return null
return <ProfilePicture profile={profile} sx={{ width: 36, height: 36 }} />
}

const CurrentProfileMenu = () => {
const currentProfileId = useAppStore((state) => state.currentProfileId)
const [anchor, setAnchor] = useState<null | HTMLElement>(null)

const handleOpenMenu = (event: React.MouseEvent<HTMLElement>) => {
Expand All @@ -75,9 +111,13 @@ const Avatar = () => {
return (
<Box>
<Tooltip title='Show user menu'>
<IconButton onClick={handleOpenMenu}>
<MuiAvatar alt='' src='' sx={{ width: 36, height: 36 }} />
</IconButton>
{currentProfileId ?
<IconButton onClick={handleOpenMenu}>
<CurrentProfilePicture profileId={currentProfileId} />
</IconButton>
:
<Button onClick={handleOpenMenu}>No Profile</Button>
}
</Tooltip>
<Menu
sx={{ mt: '45px' }}
Expand Down Expand Up @@ -129,7 +169,7 @@ const Header = () => {
<Stack direction='row' spacing={1.3}>
<SettingsButton />
<HelpButton />
{currentAddress ? <Avatar /> : <SignInButton />}
{currentAddress ? <CurrentProfileMenu /> : <SignInButton />}
</Stack>

</Toolbar>
Expand Down
9 changes: 5 additions & 4 deletions src/components/NodeDetails/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { utils } from 'ethers'
import { useQuery } from 'urql'
import { useSnackbar } from 'notistack'
import { useAccount, useContractWrite, useNetwork, useSignTypedData } from 'wagmi'
import { Avatar, Box, Button, Card, Stack, styled, Tooltip, Typography } from '@mui/material'
import { Box, Button, Card, Stack, styled, Tooltip, Typography } from '@mui/material'
import { LoadingButton } from '@mui/lab'
import PersonAddIcon from '@mui/icons-material/PersonAdd'
import PersonRemoveIcon from '@mui/icons-material/PersonRemove'
import { useAppStore, useNodeStore, useOptimisticCache } from '../../stores'
import { getProfilePictureUrl, sleep } from '../../helpers'
import { sleep } from '../../helpers'
import { graphql } from '../../lens/schema'
import { FollowModule, FollowModuleRedeemParams, Profile } from '../../lens/schema/graphql'
import { APP_CHAIN_ID, REQUEST_DELAY, REQUEST_LIMIT } from '../../constants'
Expand All @@ -22,6 +22,7 @@ import { OptimisticAction, OptimisticTransactionStatus } from '../../types'
import { getOptimisticTransactionStatus } from '../../lens/optimisticTransaction'
import { broadcastTypedData } from '../../lens/broadcast'
import { createUnfollowTypedData } from '../../lens/unfollow'
import { ProfilePicture } from '../Shared/ProfilePicture'

const ProfileStatCard = styled(Card)(({ theme }) => ({
display: 'flex',
Expand Down Expand Up @@ -470,7 +471,7 @@ const ProfileDetails = ({ profileId }: { profileId: string }) => {
const currentProfileId = useAppStore((state) => state.currentProfileId)
const currentAddress = useAppStore((state) => state.currentAddress)
useEffect(() => {
console.debug('refetch profile')
console.debug('refetch selected profile')
refetchProfile()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentAddress, currentProfileId])
Expand All @@ -481,7 +482,7 @@ const ProfileDetails = ({ profileId }: { profileId: string }) => {
return (
<Box sx={{ p: 1 }}>
<Box sx={{ textAlign: 'center' }}>
<Avatar src={getProfilePictureUrl(profile)} sx={{ margin: 'auto', width: 80, height: 80 }} />
<ProfilePicture profile={profile} sx={{ margin: 'auto', width: 80, height: 80 }} />
<Typography variant='h5' component='h3' sx={{ mt: 1 }}>{profile.name ?? profile.handle}</Typography>
{isFollowing ? <UnfollowButton profile={profile} refetchProfile={refetchProfile} /> : <FollowButton profile={profile} refetchProfile={refetchProfile} />}
<Typography sx={{ m: 1 }}>{profile.bio}</Typography>
Expand Down
29 changes: 29 additions & 0 deletions src/components/Shared/ProfilePicture.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Avatar, AvatarProps } from '@mui/material'
import { parseIpfs } from '../../helpers'
import { MediaSet, NftImage } from '../../lens/schema/graphql'

interface ProfileWithPictureInfo {
picture?: MediaSet | Pick<NftImage, '__typename' | 'uri'> | null
}

const getProfilePictureUrl = (profile: ProfileWithPictureInfo) => {
if (!profile.picture) return

if (profile.picture?.__typename === 'MediaSet') {
return parseIpfs(profile.picture.original.url)
}

if (profile.picture.__typename === 'NftImage') {
return parseIpfs(profile.picture.uri)
}
}

type ProfilePictureProps = AvatarProps & {
profile: ProfileWithPictureInfo
}

export const ProfilePicture = (props: ProfilePictureProps) => {
const { profile, ...avatarProps } = props
const url = getProfilePictureUrl(profile)
return <Avatar {...avatarProps} src={url} />
}
13 changes: 0 additions & 13 deletions src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { MediaSet, NftImage } from './lens/schema/graphql'
import { Node } from './types'

export const sleep = (milliseconds: number): Promise<void> => {
Expand All @@ -11,18 +10,6 @@ export const parseIpfs = (url: string | undefined): string | undefined => {
return url.replace('ipfs://', 'https://ipfs.io/ipfs/')
}

export const getProfilePictureUrl = (profile: { picture?: MediaSet | Pick<NftImage, '__typename' | 'uri'> | null }) => {
if (!profile.picture) return

if (profile.picture?.__typename === 'MediaSet') {
return parseIpfs(profile.picture.original.url)
}

if (profile.picture.__typename === 'NftImage') {
return parseIpfs(profile.picture.uri)
}
}

export const parseOffset = (offsetJson: string): number => {
return JSON.parse(offsetJson).offset
}
Expand Down
Loading

0 comments on commit 4d7da75

Please sign in to comment.