feat: 公开个人主页(/u/:id 名片+统计+帖子/回复内容流,全站头像可点跳转,bio 签名+最后活跃)
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
/** 名称哈希 → 0..11 色调组(复用 style.css 的 --fi-* 12 色 MD3 变量,深浅色自适应) */
|
||||
function hashTone(name) {
|
||||
/** 名称哈希 → 0..11 色调组(复用 style.css 的 --fi-* 12 色 MD3 变量,深浅色自适应;供 Banner 渐变等复用) */
|
||||
export function hashTone(name) {
|
||||
let h = 0;
|
||||
const k = String(name || '');
|
||||
for (let i = 0; i < k.length; i += 1) h = (h * 31 + k.charCodeAt(i)) >>> 0;
|
||||
@@ -12,12 +13,40 @@ function hashTone(name) {
|
||||
* 圆形用户头像(MD3):
|
||||
* - src 非空 → 圆形 <img>(object-fit: cover)
|
||||
* - src 空 → 首字兜底(name[0] 大写 + 名称哈希底色)
|
||||
* props: { src, name, size=36, className }
|
||||
* - to 非空 → 外层包 <Link to={to}>(点击跳公开主页;内层 stopPropagation 防嵌套 Link 冒泡)
|
||||
* props: { src, name, size=36, className, to }
|
||||
*/
|
||||
export default function Avatar({ src = '', name = '', size = 36, className = '' }) {
|
||||
export default function Avatar({ src = '', name = '', size = 36, className = '', to }) {
|
||||
const style = { width: size, height: size, fontSize: Math.round(size * 0.42) };
|
||||
const base = 'avatar' + (className ? ' ' + className : '');
|
||||
const alt = name ? `${name} 的头像` : '头像';
|
||||
const letter = String(name || '?').charAt(0).toUpperCase();
|
||||
|
||||
// 跳转版本:Link 作为圆形容器(cursor 指针),fallback 底色放内层 span
|
||||
if (to) {
|
||||
return (
|
||||
<Link
|
||||
to={to}
|
||||
className={base + ' avatar-link'}
|
||||
style={style}
|
||||
aria-label={alt}
|
||||
title={name}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{src
|
||||
? <img src={src} alt={alt} />
|
||||
: (
|
||||
<span
|
||||
className={'avatar-fallback tone-' + hashTone(name)}
|
||||
style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: style.fontSize }}
|
||||
>
|
||||
{letter}
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
if (src) {
|
||||
return (
|
||||
<span className={base} style={style}>
|
||||
@@ -27,7 +56,7 @@ export default function Avatar({ src = '', name = '', size = 36, className = ''
|
||||
}
|
||||
return (
|
||||
<span className={`${base} avatar-fallback tone-${hashTone(name)}`} style={style} role="img" aria-label={alt}>
|
||||
{String(name || '?').charAt(0).toUpperCase()}
|
||||
{letter}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user