@@ -85,12 +85,25 @@ type AgentIconProps = {
8585export function AgentIcon ( { icons, onChange, name } : AgentIconProps ) {
8686 const { theme } = useTheme ( ) ;
8787 const [ imageUrlDialogOpen , setImageUrlDialogOpen ] = useState ( false ) ;
88+ const [ showFallback , setShowFallback ] = useState ( false ) ;
8889
8990 const { icon = "" , iconDark = "" } = icons ?? { } ;
9091 const isDarkMode = theme === AppTheme . Dark ;
9192 const obotIconIndex = iconOptions . findIndex ( ( option ) =>
9293 icon . includes ( option )
9394 ) ;
95+
96+ const handleLoadingStatusChange = (
97+ status : "idle" | "loading" | "loaded" | "error"
98+ ) => {
99+ // ignore loading & idle
100+ if ( status === "error" ) {
101+ setShowFallback ( true ) ;
102+ }
103+ if ( status === "loaded" ) {
104+ setShowFallback ( false ) ;
105+ }
106+ } ;
94107 return (
95108 < >
96109 < DropdownMenu >
@@ -99,10 +112,15 @@ export function AgentIcon({ icons, onChange, name }: AgentIconProps) {
99112 < DropdownMenuTrigger asChild >
100113 < Button variant = "ghost" size = "icon-xl" className = "group relative" >
101114 < Avatar className = "size-20" >
102- < AvatarImage src = { iconDark && isDarkMode ? iconDark : icon } />
103- < AvatarFallback className = "text-[3.5rem] font-semibold" >
104- { name ?. charAt ( 0 ) ?? "" }
105- </ AvatarFallback >
115+ < AvatarImage
116+ src = { iconDark && isDarkMode ? iconDark : icon }
117+ onLoadingStatusChange = { handleLoadingStatusChange }
118+ />
119+ { showFallback && (
120+ < AvatarFallback className = "text-[3.5rem] font-semibold" >
121+ { name ?. charAt ( 0 ) ?? "" }
122+ </ AvatarFallback >
123+ ) }
106124 </ Avatar >
107125 < div className = "absolute -right-1 top-0 items-center justify-center rounded-full bg-primary-foreground p-2 opacity-0 drop-shadow-md transition group-hover:opacity-100 group-focus:opacity-100" >
108126 < PencilIcon className = "!size-4" />
0 commit comments