@@ -85,12 +85,25 @@ type AgentIconProps = {
85
85
export function AgentIcon ( { icons, onChange, name } : AgentIconProps ) {
86
86
const { theme } = useTheme ( ) ;
87
87
const [ imageUrlDialogOpen , setImageUrlDialogOpen ] = useState ( false ) ;
88
+ const [ showFallback , setShowFallback ] = useState ( false ) ;
88
89
89
90
const { icon = "" , iconDark = "" } = icons ?? { } ;
90
91
const isDarkMode = theme === AppTheme . Dark ;
91
92
const obotIconIndex = iconOptions . findIndex ( ( option ) =>
92
93
icon . includes ( option )
93
94
) ;
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
+ } ;
94
107
return (
95
108
< >
96
109
< DropdownMenu >
@@ -99,10 +112,15 @@ export function AgentIcon({ icons, onChange, name }: AgentIconProps) {
99
112
< DropdownMenuTrigger asChild >
100
113
< Button variant = "ghost" size = "icon-xl" className = "group relative" >
101
114
< 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
+ ) }
106
124
</ Avatar >
107
125
< 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" >
108
126
< PencilIcon className = "!size-4" />
0 commit comments