-
-
Notifications
You must be signed in to change notification settings - Fork 488
💄 Update avatar colors #1351
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
💄 Update avatar colors #1351
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { useTranslation } from "@/app/i18n/client"; | ||
|
|
||
| export function YouAvatar() { | ||
| const { t } = useTranslation(); | ||
|
|
||
| return ( | ||
| <div className="inline-flex size-5 items-center justify-center rounded-full bg-gray-200 text-xs font-medium"> | ||
| {t("you")[0]} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential localization issue when extracting the first character Using Consider the following alternatives:
Ensure that the chosen solution provides a consistent and understandable experience for all users regardless of their language settings.
|
||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,24 +2,9 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import * as React from "react"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import * as AvatarPrimitive from "@radix-ui/react-avatar"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { cva, type VariantProps } from "class-variance-authority"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { cn } from "@rallly/ui"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const avatarColors = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "indigo", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "green", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "blue", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "purple", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "emerald", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "violet", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "sky", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "cyan", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "pink", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ] as const; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export type AvatarColor = (typeof avatarColors)[number]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const Avatar = React.forwardRef< | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| React.ElementRef<typeof AvatarPrimitive.Root>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> & { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -50,47 +35,54 @@ const AvatarImage = React.forwardRef< | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AvatarImage.displayName = AvatarPrimitive.Image.displayName; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const avatarFallbackVariants = cva( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "flex h-full w-full items-center justify-center rounded-full font-medium", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| variants: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| color: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| indigo: "bg-indigo-50 text-indigo-600", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| green: "bg-green-50 text-green-600", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| blue: "bg-blue-50 text-blue-600", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| purple: "bg-purple-50 text-purple-600", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emerald: "bg-emerald-50 text-emerald-600", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| violet: "bg-violet-50 text-violet-600", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sky: "bg-sky-50 text-sky-600", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cyan: "bg-cyan-50 text-cyan-600", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pink: "bg-pink-50 text-pink-600", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| defaultVariants: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| color: "indigo", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const colorPairs = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { bg: "#E6F4FF", text: "#0065BD" }, // Light blue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { bg: "#DCFCE7", text: "#15803D" }, // Light green | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { bg: "#FFE6F4", text: "#BD007A" }, // Light pink | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { bg: "#F4E6FF", text: "#6200BD" }, // Light purple | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { bg: "#FFE6E6", text: "#BD0000" }, // Light red | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { bg: "#FFE6FF", text: "#A300A3" }, // Bright pink | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { bg: "#F0E6FF", text: "#5700BD" }, // Lavender | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { bg: "#FFE6F9", text: "#BD0066" }, // Rose | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { bg: "#E6E6FF", text: "#0000BD" }, // Periwinkle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { bg: "#FFE6EC", text: "#BD001F" }, // Salmon pink | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { bg: "#EBE6FF", text: "#4800BD" }, // Light indigo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function getColor(seed: string): AvatarColor { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function getColor(seed?: string): { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bgColor: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| textColor: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!seed) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { bgColor: "#E6F4FF", textColor: "#0065BD" }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let hash = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (let i = 0; i < seed.length; i++) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hash = seed.charCodeAt(i) + ((hash << 5) - hash); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return avatarColors[Math.abs(hash) % avatarColors.length]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const colorPair = colorPairs[Math.abs(hash) % colorPairs.length]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { bgColor: colorPair.bg, textColor: colorPair.text }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+52
to
+64
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider using a more robust hash function for better color distribution The current hash function may lead to uneven color distribution for similar seed strings, resulting in less variation than expected. Utilizing a more robust hashing algorithm could improve the randomness and ensure a more uniform assignment of colors. Apply this diff to update the hash function: +import crypto from 'crypto';
export function getColor(seed?: string): {
bgColor: string;
textColor: string;
} {
if (!seed) {
return { bgColor: "#E6F4FF", textColor: "#0065BD" };
}
- let hash = 0;
- for (let i = 0; i < seed.length; i++) {
- hash = seed.charCodeAt(i) + ((hash << 5) - hash);
- }
- const colorPair = colorPairs[Math.abs(hash) % colorPairs.length];
+ const hash = crypto.createHash('sha256').update(seed).digest('hex');
+ const hashInt = parseInt(hash.substring(0, 8), 16);
+ const colorPair = colorPairs[hashInt % colorPairs.length];
return { bgColor: colorPair.bg, textColor: colorPair.text };
}Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const AvatarFallback = React.forwardRef< | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| React.ElementRef<typeof AvatarPrimitive.Fallback>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback> & | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| VariantProps<typeof avatarFallbackVariants> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| >(({ className, color, ...props }, ref) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <AvatarPrimitive.Fallback | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ref={ref} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={cn(avatarFallbackVariants({ color }), className)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {...props} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback> & { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| seed: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| >(({ className, seed, ...props }, ref) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { bgColor, textColor } = getColor(seed); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <AvatarPrimitive.Fallback | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ref={ref} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={cn( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "flex h-full w-full items-center justify-center rounded-full font-medium", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| style={{ backgroundColor: bgColor, color: textColor }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {...props} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+69
to
+85
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make the Since the Apply this diff to update the prop type: React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback> & {
- seed: string;
+ seed?: string;
}Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export { Avatar, AvatarImage, AvatarFallback }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.