mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
fix(frontend): handle avatar missing images better (#10903)
## Changes 🏗️ I think this helps `next/image` being more tolerant when optimising images from certain origins according to Claude. ## Checklist 📋 ### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Deploy preview to dev - [x] Verify avatar images load better ### For configuration changes: None
This commit is contained in:
@@ -12,6 +12,23 @@ const nextConfig = {
|
||||
"ideogram.ai", // for generated images
|
||||
"picsum.photos", // for placeholder images
|
||||
],
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "storage.googleapis.com",
|
||||
pathname: "/**",
|
||||
},
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "storage.cloud.google.com",
|
||||
pathname: "/**",
|
||||
},
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "lh3.googleusercontent.com",
|
||||
pathname: "/**",
|
||||
},
|
||||
],
|
||||
},
|
||||
output: "standalone",
|
||||
transpilePackages: ["geist"],
|
||||
|
||||
@@ -8,6 +8,7 @@ import React, {
|
||||
useState,
|
||||
} from "react";
|
||||
import Image, { ImageProps } from "next/image";
|
||||
import BoringAvatarWrapper from "@/components/ui/BoringAvatarWrapper";
|
||||
|
||||
type AvatarContextValue = {
|
||||
isLoaded: boolean;
|
||||
@@ -91,16 +92,18 @@ export function AvatarImage({
|
||||
unoptimized,
|
||||
...rest
|
||||
}: AvatarImageProps): JSX.Element | null {
|
||||
const { setIsLoaded, setHasImage } = useAvatarContext();
|
||||
const { setIsLoaded, setHasImage, hasImage } = useAvatarContext();
|
||||
|
||||
const normalizedSrc = typeof src === "string" ? src.trim() : src;
|
||||
|
||||
useEffect(
|
||||
function setHasImageOnSrcChange() {
|
||||
setHasImage(Boolean(src));
|
||||
setHasImage(Boolean(normalizedSrc));
|
||||
},
|
||||
[src, setHasImage],
|
||||
[normalizedSrc, setHasImage],
|
||||
);
|
||||
|
||||
if (!src) return null;
|
||||
if (!normalizedSrc || !hasImage) return null;
|
||||
|
||||
const sizeFromClass = getAvatarSizeFromClassName(className);
|
||||
const computedWidth = width || sizeFromClass || 40;
|
||||
@@ -120,7 +123,7 @@ export function AvatarImage({
|
||||
return (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={src}
|
||||
src={normalizedSrc}
|
||||
alt={alt || "Avatar image"}
|
||||
className={["h-full w-full object-cover", className || ""].join(" ")}
|
||||
width={computedWidth}
|
||||
@@ -142,7 +145,7 @@ export function AvatarImage({
|
||||
|
||||
return (
|
||||
<Image
|
||||
src={src}
|
||||
src={normalizedSrc}
|
||||
alt={alt || "Avatar image"}
|
||||
className={["h-full w-full object-cover", className || ""].join(" ")}
|
||||
width={fill ? undefined : computedWidth}
|
||||
@@ -170,15 +173,23 @@ export function AvatarFallback({
|
||||
const { isLoaded, hasImage } = useAvatarContext();
|
||||
const show = !isLoaded || !hasImage;
|
||||
if (!show) return null;
|
||||
const computedSize = _size || getAvatarSizeFromClassName(className) || 40;
|
||||
const name =
|
||||
typeof children === "string" && children.trim() ? children : "User";
|
||||
return (
|
||||
<span
|
||||
className={[
|
||||
"flex h-full w-full items-center justify-center rounded-full bg-neutral-200 text-neutral-600",
|
||||
"flex h-full w-full items-center justify-center rounded-full bg-neutral-200 text-lg text-neutral-600",
|
||||
className || "",
|
||||
].join(" ")}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<BoringAvatarWrapper
|
||||
size={computedSize}
|
||||
name={name}
|
||||
variant="marble"
|
||||
colors={["#92A1C6", "#146A7C", "#F0AB3D", "#C271B4", "#C20D90"]}
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user