feat: implement UserAvatar component with dynamic color assignment and memoization
This commit is contained in:
parent
d18aee8a95
commit
1e3a1e390b
1 changed files with 82 additions and 28 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import React from "react";
|
||||
import { isColorDark } from "~/lib/color";
|
||||
import { cn, getHexColorFromString, getInitials } from "~/lib/utils";
|
||||
import type { UsersId } from "~/schemas/public/Users";
|
||||
import { Facehash, type FacehashProps } from "./facehash/facehash";
|
||||
|
||||
const colorOptions = new Map<string, string>();
|
||||
|
||||
|
|
@ -39,7 +40,8 @@ export const UserAvatarOld = ({
|
|||
);
|
||||
};
|
||||
*/
|
||||
export const UserAvatar = (
|
||||
/*
|
||||
export const UserAvatar2 = (
|
||||
props: {
|
||||
userId: UsersId;
|
||||
username?: string;
|
||||
|
|
@ -59,32 +61,7 @@ export const UserAvatar = (
|
|||
<Facehash
|
||||
{...rest}
|
||||
className={cn("size-20 rounded-full", rest.className)}
|
||||
colors={[
|
||||
"#2D3436",
|
||||
"#535C68",
|
||||
"#636E72",
|
||||
"#FAB1A0",
|
||||
"#FF7675",
|
||||
"#FF4757",
|
||||
"#EE5253",
|
||||
"#D63031",
|
||||
"#FF9F43",
|
||||
"#FDCB6E",
|
||||
"#F1C40F",
|
||||
"#55E6C1",
|
||||
"#00B894",
|
||||
"#26DE81",
|
||||
"#2ECC71",
|
||||
"#00CEC9",
|
||||
"#81ECEC",
|
||||
"#74B9FF",
|
||||
"#0984E3",
|
||||
"#4834D4",
|
||||
"#6C5CE7",
|
||||
"#A29BFE",
|
||||
"#A55EEA",
|
||||
"#6D214F",
|
||||
]}
|
||||
colors={user_colors}
|
||||
initialsCount={2}
|
||||
intensity3d="none"
|
||||
name={value}
|
||||
|
|
@ -93,3 +70,80 @@ export const UserAvatar = (
|
|||
/>
|
||||
);
|
||||
};
|
||||
*/
|
||||
const user_colors = [
|
||||
"#2D3436",
|
||||
"#535C68",
|
||||
"#636E72",
|
||||
"#FAB1A0",
|
||||
"#FF7675",
|
||||
"#FF4757",
|
||||
"#EE5253",
|
||||
"#D63031",
|
||||
"#FF9F43",
|
||||
"#FDCB6E",
|
||||
"#F1C40F",
|
||||
"#55E6C1",
|
||||
"#00B894",
|
||||
"#26DE81",
|
||||
"#2ECC71",
|
||||
"#00CEC9",
|
||||
"#81ECEC",
|
||||
"#74B9FF",
|
||||
"#0984E3",
|
||||
"#4834D4",
|
||||
"#6C5CE7",
|
||||
"#A29BFE",
|
||||
"#A55EEA",
|
||||
"#6D214F",
|
||||
];
|
||||
|
||||
function stringHash(str: string): number {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
const char = str.charCodeAt(i);
|
||||
hash = (hash << 5) - hash + char;
|
||||
hash &= hash; // Convert to 32bit integer
|
||||
}
|
||||
return Math.abs(hash);
|
||||
}
|
||||
|
||||
export const UserAvatar = (
|
||||
props: {
|
||||
userId: UsersId;
|
||||
username?: string;
|
||||
} & React.HTMLAttributes<HTMLDivElement>,
|
||||
) => {
|
||||
const { userId, username, className, ...rest } = props;
|
||||
const value = `${username && getInitials(username)}${userId}`;
|
||||
|
||||
const colorIndex = React.useMemo(() => {
|
||||
const hash = stringHash(value);
|
||||
const colorsLength = user_colors.length ?? 1;
|
||||
const _colorIndex = hash % colorsLength;
|
||||
|
||||
return _colorIndex;
|
||||
}, [value]);
|
||||
const userColor = user_colors[colorIndex];
|
||||
return (
|
||||
<div
|
||||
{...rest}
|
||||
className={cn(
|
||||
"@container flex size-20 items-center justify-center rounded-full",
|
||||
className,
|
||||
)}
|
||||
style={{
|
||||
backgroundColor: userColor,
|
||||
color: userColor
|
||||
? isColorDark(userColor, 180)
|
||||
? "#FFFFFF"
|
||||
: "#oklch(0.24 0 0)"
|
||||
: "#oklch(0.24 0 0)",
|
||||
}}
|
||||
>
|
||||
<span className="text-[40cqw] tracking-wide">
|
||||
{username && getInitials(username)}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue