refactor: extract user avatar color and initials logic into a new utility module, update related components to use the new functions

This commit is contained in:
Anish Sarkar 2026-05-18 21:40:23 +05:30
parent 87caa4b6d0
commit e0ecea61f8
6 changed files with 65 additions and 63 deletions

View file

@ -316,7 +316,7 @@ const MessageInfoDropdown: FC<{ chatTurnId: string | null | undefined }> = ({ ch
)}
{hasUsage && (
<>
<ActionBarMorePrimitive.Separator className="bg-popover-border mx-2 my-1 h-px" />
<ActionBarMorePrimitive.Separator className="bg-popover-border mx-1 my-1 h-px" />
{models.length > 0 ? (
models.map(([model, counts]) => {
const { name, icon } = resolveModel(model);
@ -586,7 +586,7 @@ const AssistantActionBar: FC = () => {
className="aui-assistant-action-bar-root -ml-1 col-start-3 row-start-2 flex gap-1 text-muted-foreground md:data-floating:absolute md:data-floating:rounded-md md:data-floating:p-1 [&>button]:opacity-100 md:[&>button]:opacity-[var(--aui-button-opacity,1)]"
>
<ActionBarPrimitive.Copy asChild>
<TooltipIconButton tooltip="Copy to clipboard">
<TooltipIconButton tooltip="Copy">
<AuiIf condition={({ message }) => message.isCopied}>
<CheckIcon />
</AuiIf>

View file

@ -38,6 +38,7 @@ import { usePlatform } from "@/hooks/use-platform";
import { GITHUB_RELEASES_URL, usePrimaryDownload } from "@/lib/desktop-download-utils";
import { APP_VERSION } from "@/lib/env-config";
import { trackDesktopDownloadClicked } from "@/lib/posthog/events";
import { getUserAvatarColor, getUserInitials } from "@/lib/user-avatar";
import { cn } from "@/lib/utils";
import type { User } from "../../types/layout.types";
@ -81,46 +82,6 @@ function formatAnnouncementCount(count: number): string {
return `${thousands}k+`;
}
/**
* Generates a consistent color based on email
*/
function stringToColor(str: string): string {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash);
}
const colors = [
"#6366f1",
"#8b5cf6",
"#a855f7",
"#d946ef",
"#ec4899",
"#f43f5e",
"#ef4444",
"#f97316",
"#eab308",
"#84cc16",
"#22c55e",
"#14b8a6",
"#06b6d4",
"#0ea5e9",
"#3b82f6",
];
return colors[Math.abs(hash) % colors.length];
}
/**
* Gets initials from email
*/
function getInitials(email: string): string {
const name = email.split("@")[0];
const parts = name.split(/[._-]/);
if (parts.length >= 2) {
return (parts[0][0] + parts[1][0]).toUpperCase();
}
return name.slice(0, 2).toUpperCase();
}
/**
* User avatar component - shows image if available, otherwise falls back to initials
*/
@ -180,8 +141,8 @@ export function SidebarUserProfile({
const isDesktopViewport = useMediaQuery("(min-width: 768px)");
const { os, primary } = usePrimaryDownload();
const [isLoggingOut, setIsLoggingOut] = useState(false);
const bgColor = stringToColor(user.email);
const initials = getInitials(user.email);
const bgColor = getUserAvatarColor(user.email);
const initials = getUserInitials(user.email);
const displayName = user.name || user.email.split("@")[0];
const downloadUrl = primary?.url ?? GITHUB_RELEASES_URL;
const downloadLabel = t("download_for_os", { os });

View file

@ -251,7 +251,7 @@ export function UserSettingsPanel({
<div className="min-w-0 flex-1">
<div className="hidden md:block">
<h2 className="text-lg font-semibold">{selectedLabel}</h2>
<Separator className="mt-4" />
<Separator className="mt-4 bg-border" />
</div>
<div className="min-w-0 pt-4 md:max-w-3xl">
{selectedTab === "profile" && <ProfileContent />}