Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 121 lines 3.4 kB view raw
1import { CheckBadgeIcon } from "@heroicons/react/24/solid"; 2import getAccount from "@hey/helpers/getAccount"; 3import getAvatar from "@hey/helpers/getAvatar"; 4import type { AccountFragment } from "@hey/indexer"; 5import { memo } from "react"; 6import Markup from "@/components/Shared/Markup"; 7import Slug from "@/components/Shared/Slug"; 8import { Image } from "@/components/Shared/UI"; 9import cn from "@/helpers/cn"; 10import getMentions from "@/helpers/getMentions"; 11import AccountLink from "./AccountLink"; 12import AccountPreview from "./AccountPreview"; 13import FollowUnfollowButton from "./FollowUnfollowButton"; 14 15interface SingleAccountProps { 16 hideFollowButton?: boolean; 17 hideUnfollowButton?: boolean; 18 isBig?: boolean; 19 isVerified?: boolean; 20 linkToAccount?: boolean; 21 account: AccountFragment; 22 showBio?: boolean; 23 showUserPreview?: boolean; 24} 25 26const SingleAccount = ({ 27 hideFollowButton = false, 28 hideUnfollowButton = false, 29 isBig = false, 30 isVerified = false, 31 linkToAccount = true, 32 account, 33 showBio = false, 34 showUserPreview = true 35}: SingleAccountProps) => { 36 const UserAvatar = () => ( 37 <Image 38 alt={account.address} 39 className={cn( 40 isBig ? "size-14" : "size-11", 41 "rounded-full border border-gray-200 bg-gray-200 dark:border-gray-700" 42 )} 43 height={isBig ? 56 : 44} 44 loading="lazy" 45 src={getAvatar(account)} 46 width={isBig ? 56 : 44} 47 /> 48 ); 49 50 const UserName = () => ( 51 <div> 52 <div 53 className={cn( 54 { "font-bold": isBig }, 55 "flex max-w-sm items-center gap-x-1.5" 56 )} 57 > 58 <div className="truncate font-semibold">{getAccount(account).name}</div> 59 {(isVerified || account.hasSubscribed) && ( 60 <CheckBadgeIcon className="size-4 text-brand-500" /> 61 )} 62 {account.heyEns?.localName && ( 63 <Image 64 className="size-4" 65 src="https://ens.domains/assets/brand/mark/ens-mark-Blue.svg" 66 /> 67 )} 68 </div> 69 <Slug className="text-sm" slug={getAccount(account).username} /> 70 </div> 71 ); 72 73 const AccountInfo = () => ( 74 <AccountPreview 75 address={account.address} 76 showUserPreview={showUserPreview} 77 username={account.username?.localName} 78 > 79 <div className="mr-8 flex items-center gap-x-3"> 80 <UserAvatar /> 81 <UserName /> 82 </div> 83 </AccountPreview> 84 ); 85 86 return ( 87 <div className="flex flex-col gap-y-2"> 88 <div className="flex items-center justify-between"> 89 {linkToAccount && account.address ? ( 90 <AccountLink account={account}> 91 <AccountInfo /> 92 </AccountLink> 93 ) : ( 94 <AccountInfo /> 95 )} 96 <FollowUnfollowButton 97 account={account} 98 hideFollowButton={hideFollowButton} 99 hideUnfollowButton={hideUnfollowButton} 100 small 101 /> 102 </div> 103 {showBio && account?.metadata?.bio && ( 104 <div 105 className={cn( 106 isBig ? "text-base" : "text-sm", 107 "mt-2", 108 "linkify leading-6" 109 )} 110 style={{ wordBreak: "break-word" }} 111 > 112 <Markup mentions={getMentions(account.metadata.bio)}> 113 {account?.metadata.bio} 114 </Markup> 115 </div> 116 )} 117 </div> 118 ); 119}; 120 121export default memo(SingleAccount);