mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
feat: Refactor image caching logic and integrate getAgentAvatarUrl for improved avatar handling
This commit is contained in:
parent
96ea589881
commit
0cf71b9e18
3 changed files with 25 additions and 35 deletions
|
|
@ -8,7 +8,7 @@ import type {
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import ConvoIconURL from '~/components/Endpoints/ConvoIconURL';
|
import ConvoIconURL from '~/components/Endpoints/ConvoIconURL';
|
||||||
import MinimalIcon from '~/components/Endpoints/MinimalIcon';
|
import MinimalIcon from '~/components/Endpoints/MinimalIcon';
|
||||||
import { getIconEndpoint } from '~/utils';
|
import { getIconEndpoint, getAgentAvatarUrl } from '~/utils';
|
||||||
|
|
||||||
export default function EndpointIcon({
|
export default function EndpointIcon({
|
||||||
conversation,
|
conversation,
|
||||||
|
|
@ -42,7 +42,7 @@ export default function EndpointIcon({
|
||||||
|
|
||||||
const agent =
|
const agent =
|
||||||
endpoint === EModelEndpoint.agents ? agentsMap?.[conversation?.agent_id ?? ''] : null;
|
endpoint === EModelEndpoint.agents ? agentsMap?.[conversation?.agent_id ?? ''] : null;
|
||||||
const agentAvatar = agent?.avatar?.filepath ?? '';
|
const agentAvatar = getAgentAvatarUrl(agent) ?? '';
|
||||||
|
|
||||||
const iconURL = assistantAvatar || agentAvatar || convoIconURL;
|
const iconURL = assistantAvatar || agentAvatar || convoIconURL;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import React, { memo, useState, useEffect } from 'react';
|
||||||
import { AlertCircle } from 'lucide-react';
|
import { AlertCircle } from 'lucide-react';
|
||||||
import { Skeleton } from '@librechat/client';
|
import { Skeleton } from '@librechat/client';
|
||||||
import { icons } from '~/hooks/Endpoint/Icons';
|
import { icons } from '~/hooks/Endpoint/Icons';
|
||||||
|
import { isImageCached } from '~/utils';
|
||||||
|
|
||||||
export const URLIcon = memo(
|
export const URLIcon = memo(
|
||||||
({
|
({
|
||||||
|
|
@ -20,29 +21,16 @@ export const URLIcon = memo(
|
||||||
endpoint?: string;
|
endpoint?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const [imageError, setImageError] = useState(false);
|
const [imageError, setImageError] = useState(false);
|
||||||
const [isLoaded, setIsLoaded] = useState(() => {
|
const [isLoaded, setIsLoaded] = useState(() => isImageCached(iconURL));
|
||||||
// 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;
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// When URL changes, check if new image is cached
|
if (isImageCached(iconURL)) {
|
||||||
if (iconURL) {
|
|
||||||
const img = new Image();
|
|
||||||
img.src = iconURL;
|
|
||||||
if (img.complete && img.naturalWidth > 0) {
|
|
||||||
setIsLoaded(true);
|
setIsLoaded(true);
|
||||||
setImageError(false);
|
setImageError(false);
|
||||||
} else {
|
} else {
|
||||||
setIsLoaded(false);
|
setIsLoaded(false);
|
||||||
setImageError(false);
|
setImageError(false);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}, [iconURL]);
|
}, [iconURL]);
|
||||||
|
|
||||||
const handleImageError = () => {
|
const handleImageError = () => {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,19 @@ import { Feather } from 'lucide-react';
|
||||||
import { Skeleton } from '@librechat/client';
|
import { Skeleton } from '@librechat/client';
|
||||||
import type t from 'librechat-data-provider';
|
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
|
* Extracts the avatar URL from an agent's avatar property
|
||||||
* Handles both string and object formats
|
* Handles both string and object formats
|
||||||
|
|
@ -32,22 +45,11 @@ const LazyAgentAvatar = ({
|
||||||
alt: string;
|
alt: string;
|
||||||
imgClass: string;
|
imgClass: string;
|
||||||
}) => {
|
}) => {
|
||||||
const [isLoaded, setIsLoaded] = useState(() => {
|
const [isLoaded, setIsLoaded] = useState(() => isImageCached(url));
|
||||||
// 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 [hasError, setHasError] = useState(false);
|
const [hasError, setHasError] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// When URL changes, check if new image is cached
|
if (isImageCached(url)) {
|
||||||
const img = new Image();
|
|
||||||
img.src = url;
|
|
||||||
if (img.complete && img.naturalWidth > 0) {
|
|
||||||
setIsLoaded(true);
|
setIsLoaded(true);
|
||||||
setHasError(false);
|
setHasError(false);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue