Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 个人主页信息与 Web3.bio Profile 数据融合改进 #178

Open
wants to merge 4 commits into
base: test
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions public/images/svg/basenames-blue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/svg/farcaster-purple.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions public/images/svg/lens-green.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions public/images/svg/web3bio-2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 46 additions & 22 deletions src/domain/profile/widgets/profile-card/ProfileCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@

import clsx from 'clsx';
import { useSession } from 'next-auth/react';
import Image from 'next/image';
import Link from 'next/link';
import { usePathname, useRouter } from 'next/navigation';
import { useState } from 'react';
import Web3BioIcon from 'public/images/svg/web3bio.svg';
import { useMemo, useState } from 'react';
import { toast } from 'react-toastify';
import useSWR from 'swr';

Expand All @@ -45,6 +47,12 @@ function ProfileCardWidget({ className, data }) {
const handle = data?.base.user_handle;
const creatorAvailable = data.base?.user_project_owner;

const userDesc = useMemo(() => {
const baseUserDesc = data?.base.user_bio;
const web3BioDesc = data?.web3Bio?.find(v => v.description)?.description;
return baseUserDesc || web3BioDesc || '--';
}, [data]);
Copy link
Member

Choose a reason for hiding this comment

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

  1. 复杂度低的纯计算不需要用 useMemo
  2. 计算过程没有强依赖组件内部状态,可以在组件外部定义函数。


const follow = async () => {
if (status !== 'authenticated') {
router.push(`/signin?from=${pathname}`);
Expand Down Expand Up @@ -78,27 +86,43 @@ function ProfileCardWidget({ className, data }) {
return (
<div className={clsx('relative md:w-[360px] md:rounded-lg md:p-6 md:bg-white', className)}>
<div className="flex flex-col gap-2 items-center">
<Avatar
className="-mt-[104px] md:mt-0"
size={110}
src={data.base.user_avatar}
defaultSrc="https://s3.us-west-1.amazonaws.com/file.openbuild.xyz/config/avatar/04.svg"
alt={data?.base.user_nick_name}
/>
<div className="relative">
<Avatar
className="-mt-[104px] md:mt-0"
Copy link
Member

Choose a reason for hiding this comment

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

class 应该挪到父层 div

size={110}
src={data.base.user_avatar}
Copy link
Member

Choose a reason for hiding this comment

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

头像没有从 Web3bio 获取。

user_avatar 返回的路径中包含 /config/avatar 是系统默认头像,代表用户自己没设置过头像,这时尝试从 Web3bio 获取,如果没有就用系统默认的。

defaultSrc="https://s3.us-west-1.amazonaws.com/file.openbuild.xyz/config/avatar/04.svg"
alt={data?.base.user_nick_name}
/>
{data.web3Bio && (
<Image
src={Web3BioIcon}
alt="web3bio"
className="size-6 rounded-full absolute right-1 bottom-1 border-1 border-white"
/>
)}
Copy link
Member

Choose a reason for hiding this comment

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

使用了 Web3bio 的头像时才显示这个

</div>

<h6 className="text-[24px] leading-none">
<a href={`/u/${handle}`}>{data?.base.user_nick_name}</a>
</h6>
{!creatorAvailable && <div className="flex items-center text-sm">
<RepositioningIcon className="mr-1" />
<p className="text-sm opacity-60">
{data.base?.user_city}, {data.base?.user_country}
</p>
</div>}
<p className="text-sm text-center">{data?.base.user_bio !== '' ? data?.base.user_bio : '--'}</p>
{!creatorAvailable && (
<div className="flex items-center text-sm">
<RepositioningIcon className="mr-1" />
<p className="text-sm opacity-60">
{data.base?.user_city}, {data.base?.user_country}
</p>
</div>
)}
<p className="text-sm text-center">{userDesc}</p>
</div>
<div className="my-6 flex gap-7 justify-center text-sm">
<Link href={`/u/${handle}/followers`}><strong>{data?.follow?.followers}</strong> <span className="opacity-60">followers</span></Link>
<Link href={`/u/${handle}/following`}><strong>{data?.follow?.following}</strong> <span className="opacity-60">following</span></Link>
<Link href={`/u/${handle}/followers`}>
<strong>{data?.follow?.followers}</strong> <span className="opacity-60">followers</span>
</Link>
<Link href={`/u/${handle}/following`}>
<strong>{data?.follow?.following}</strong> <span className="opacity-60">following</span>
</Link>
</div>
{user?.base.user_id === data?.base?.user_id ? (
<Link href="/profile">
Expand All @@ -107,11 +131,13 @@ function ProfileCardWidget({ className, data }) {
<span className="!font-bold">Edit</span>
</Button>
</Link>
) : ((status === 'authenticated' && followData?.follow) || followLoading ?
) : (status === 'authenticated' && followData?.follow) || followLoading ? (
<Button className="group" loading={followLoading} fullWidth variant="outlined" onClick={unfollow}>
<span className="!font-bold block group-hover:hidden">Following</span>
<span className="!font-bold hidden group-hover:block">Unfollow</span>
</Button> : <Button fullWidth variant="contained" loading={followLoading} onClick={follow}>
</Button>
) : (
<Button fullWidth variant="contained" loading={followLoading} onClick={follow}>
<SvgIcon name="plus" size={16} />
<span className="!font-bold">Follow</span>
</Button>
Expand All @@ -127,9 +153,7 @@ function ProfileCardWidget({ className, data }) {
<Link href="/" className="text-xs opacity-60">+ Follow</Link>
</div>
</>} */}
{creatorAvailable && (
<IdentitySwitch className="absolute top-4 right-4" userName={handle} />
)}
{creatorAvailable && <IdentitySwitch className="absolute top-4 right-4" userName={handle} />}
<SocialInfoWidget className="hidden md:block" data={data} />
</div>
);
Expand Down
28 changes: 22 additions & 6 deletions src/domain/profile/widgets/social-info/SocialInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,44 @@ import { SvgIcon } from '@/components/Image';
import SocialLink from './SocialLink';
import Web3BioProfile from './Web3BioProfile';

function socialsInfo(type, link) {
const web3BioSocialKeyMap = {
user_github: 'github',
user_discord: 'discord',
user_twitter: 'x',
Copy link
Member

Choose a reason for hiding this comment

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

应该是 user_x: 'twitter' 吧?

};

function web3BioLink(type, { web3Bio = [] }) {
const web3BioLinks = web3Bio.reduce((p, c) => (c.links ? { ...p, ...c.links } : p), {});
return web3BioLinks[web3BioSocialKeyMap[type]]?.link;
}

function socialsInfo(type, link, web3BioLink) {
const showWeb3Bio = !link && web3BioLink;

switch (type) {
case 'user_github':
return {
name: 'GitHub',
icon: 'github-black',
link: link && `https://github.com/${link}`,
link: link ? `https://github.com/${link}` : web3BioLink,
enableKey: 'user_show_github',
showWeb3Bio,
};
case 'user_x':
return {
name: 'X',
icon: 'x-black',
link: link && `https://x.com/${link}`,
link: link ? `https://x.com/${link}` : web3BioLink,
enableKey: 'user_show_x',
showWeb3Bio,
};
case 'user_discord':
return {
name: 'Discord',
icon: 'discord-black',
link: link && `https://discord.com/invite/${link}`,
link: link ? `https://discord.com/invite/${link}` : web3BioLink,
enableKey: 'user_show_discord',
showWeb3Bio,
};
default:
return null;
Expand All @@ -53,7 +69,7 @@ function SocialInfoWidget({ className, data }) {
const socials = useMemo(
() =>
Object.keys(data.social)
.map(i => socialsInfo(i, data.social[i]))
.map(i => socialsInfo(i, data.social[i], web3BioLink(i, data)))
Copy link
Member

Choose a reason for hiding this comment

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

web3BioLink 这个函数不需要:

  1. 函数里第一行的 reduce 应该拿出来在数组遍历操作(map)前计算,以避免重复计算;
  2. 函数里第二行作为 socialsInfo 的第三个参数传进去。

.filter(s => {
if (!s) {
return false;
Expand All @@ -73,7 +89,7 @@ function SocialInfoWidget({ className, data }) {
<p className="mt-6 uppercase text-xs opacity-60 font-bold">Social Profiles</p>
<div className="border border-gray-600 rounded overflow-hidden mt-2">
{socials.map(i => (
<SocialLink key={`user-social-${i.name}`} url={i.link} icon={i.icon} extra={i.extra}>
<SocialLink key={`user-social-${i.name}`} url={i.link} icon={i.icon} showWeb3Bio={i.showWeb3Bio}>
{i.name}
</SocialLink>
))}
Expand Down
22 changes: 17 additions & 5 deletions src/domain/profile/widgets/social-info/SocialLink.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,31 @@
* limitations under the License.
*/

import Image from 'next/image';
import Web3BioIcon from 'public/images/svg/web3bio-2.svg';

import { SvgIcon } from '@/components/Image';

function SocialLink({ url, icon, extra, children }) {
function SocialLink({ url, icon, showWeb3Bio, children }) {
return (
<a className="h-9 flex justify-between items-center px-4 border-b border-gray-600 last:border-0 hover:bg-gray-1000" href={url} target="_blank" rel="noreferrer">
<div className="flex justify-between items-center" style={{ flexGrow: 1, paddingRight: '8px' }}>
<a
className="h-9 flex justify-between gap-2 items-center px-4 border-b border-gray-600 last:border-0 hover:bg-gray-1000"
href={url}
target="_blank"
rel="noreferrer"
>
<div className="flex justify-between items-center flex-1">
<div className="flex items-center">
{icon && <SvgIcon name={icon} size={16} />}
<p className="pl-2 pr-1 text-sm font-semibold">{children}</p>
</div>
{extra}
{showWeb3Bio && (
<div className="border border-gray-600 rounded-md p-0.5 pt-1 shrink-0">
<Image src={Web3BioIcon} alt="web3bio" />
</div>
)}
</div>
<SvgIcon style={{ flexShrink: 0 }} name="share" size={14} />
<SvgIcon className="shrink-0" name="share" size={14} />
</a>
);
}
Expand Down
Loading
Loading