feat: Refactor image caching logic and integrate getAgentAvatarUrl for improved avatar handling

This commit is contained in:
Marco Beretta 2025-12-14 03:11:10 +01:00
parent 96ea589881
commit 0cf71b9e18
No known key found for this signature in database
GPG key ID: D918033D8E74CC11
3 changed files with 25 additions and 35 deletions

View file

@ -8,7 +8,7 @@ import type {
} from 'librechat-data-provider';
import ConvoIconURL from '~/components/Endpoints/ConvoIconURL';
import MinimalIcon from '~/components/Endpoints/MinimalIcon';
import { getIconEndpoint } from '~/utils';
import { getIconEndpoint, getAgentAvatarUrl } from '~/utils';
export default function EndpointIcon({
conversation,
@ -42,7 +42,7 @@ export default function EndpointIcon({
const agent =
endpoint === EModelEndpoint.agents ? agentsMap?.[conversation?.agent_id ?? ''] : null;
const agentAvatar = agent?.avatar?.filepath ?? '';
const agentAvatar = getAgentAvatarUrl(agent) ?? '';
const iconURL = assistantAvatar || agentAvatar || convoIconURL;

View file

@ -2,6 +2,7 @@ import React, { memo, useState, useEffect } from 'react';
import { AlertCircle } from 'lucide-react';
import { Skeleton } from '@librechat/client';
import { icons } from '~/hooks/Endpoint/Icons';
import { isImageCached } from '~/utils';
export const URLIcon = memo(
({
@ -20,28 +21,15 @@ export const URLIcon = memo(
endpoint?: string;
}) => {
const [imageError, setImageError] = useState(false);
const [isLoaded, setIsLoaded] = useState(() => {
// Check if image is already cached
if (typeof window !== 'undefined' && iconURL) {
const img = new Image();
img.src = iconURL;
return img.complete && img.naturalWidth > 0;
}
return false;
});
const [isLoaded, setIsLoaded] = useState(() => isImageCached(iconURL));
useEffect(() => {
// When URL changes, check if new image is cached
if (iconURL) {
const img = new Image();
img.src = iconURL;
if (img.complete && img.naturalWidth > 0) {
setIsLoaded(true);
setImageError(false);
} else {
setIsLoaded(false);
setImageError(false);
}
if (isImageCached(iconURL)) {
setIsLoaded(true);
setImageError(false);
} else {
setIsLoaded(false);
setImageError(false);
}
}, [iconURL]);

View file

@ -3,6 +3,19 @@ import { Feather } from 'lucide-react';
import { Skeleton } from '@librechat/client';
import type t from 'librechat-data-provider';
/**
* Checks if an image is already cached in the browser
* Returns true if image is complete and has valid dimensions
*/
export const isImageCached = (url: string | null | undefined): boolean => {
if (typeof window === 'undefined' || !url) {
return false;
}
const img = new Image();
img.src = url;
return img.complete && img.naturalWidth > 0;
};
/**
* Extracts the avatar URL from an agent's avatar property
* Handles both string and object formats
@ -32,22 +45,11 @@ const LazyAgentAvatar = ({
alt: string;
imgClass: string;
}) => {
const [isLoaded, setIsLoaded] = useState(() => {
// Check if image is already cached by creating a test image
if (typeof window !== 'undefined') {
const img = new Image();
img.src = url;
return img.complete && img.naturalWidth > 0;
}
return false;
});
const [isLoaded, setIsLoaded] = useState(() => isImageCached(url));
const [hasError, setHasError] = useState(false);
useEffect(() => {
// When URL changes, check if new image is cached
const img = new Image();
img.src = url;
if (img.complete && img.naturalWidth > 0) {
if (isImageCached(url)) {
setIsLoaded(true);
setHasError(false);
} else {