mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
Addressing eslint errors
This commit is contained in:
parent
a77ad276f1
commit
b6de2a8557
4 changed files with 47 additions and 46 deletions
|
|
@ -2,11 +2,11 @@ import { mergeFileConfig } from 'librechat-data-provider';
|
|||
import { useCallback } from 'react';
|
||||
import { useGetFileConfig } from '~/data-provider';
|
||||
import {
|
||||
resizeImage,
|
||||
shouldResizeImage,
|
||||
supportsClientSideResize,
|
||||
type ResizeOptions,
|
||||
type ResizeResult,
|
||||
resizeImage,
|
||||
shouldResizeImage,
|
||||
supportsClientSideResize,
|
||||
type ResizeOptions,
|
||||
type ResizeResult,
|
||||
} from '~/utils/imageResize';
|
||||
|
||||
/**
|
||||
|
|
@ -19,6 +19,7 @@ export const useClientSideResize = () => {
|
|||
});
|
||||
|
||||
// Safe access to clientSideImageResize config with fallbacks
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const config = (fileConfig as any)?.clientSideImageResize ?? {
|
||||
enabled: false,
|
||||
maxWidth: 1900,
|
||||
|
|
@ -66,7 +67,6 @@ export const useClientSideResize = () => {
|
|||
return { file: result.file, resized: true, result };
|
||||
} catch (error) {
|
||||
console.warn('Client-side image resizing failed:', error);
|
||||
// Return original file on error
|
||||
return { file, resized: false };
|
||||
}
|
||||
},
|
||||
|
|
@ -81,4 +81,4 @@ export const useClientSideResize = () => {
|
|||
};
|
||||
};
|
||||
|
||||
export default useClientSideResize;
|
||||
export default useClientSideResize;
|
||||
|
|
|
|||
|
|
@ -265,20 +265,20 @@ const useFileHandling = (params?: UseFileHandling) => {
|
|||
const file_id = v4();
|
||||
try {
|
||||
let processedFile = originalFile;
|
||||
|
||||
|
||||
// Apply client-side resizing if available and appropriate
|
||||
if (originalFile.type.startsWith('image/')) {
|
||||
try {
|
||||
const resizeResult = await resizeImageIfNeeded(originalFile);
|
||||
processedFile = resizeResult.file;
|
||||
|
||||
|
||||
// Show toast notification if image was resized
|
||||
if (resizeResult.resized && resizeResult.result) {
|
||||
const { originalSize, newSize, compressionRatio } = resizeResult.result;
|
||||
const originalSizeMB = (originalSize / (1024 * 1024)).toFixed(1);
|
||||
const newSizeMB = (newSize / (1024 * 1024)).toFixed(1);
|
||||
const savedPercent = Math.round((1 - compressionRatio) * 100);
|
||||
|
||||
|
||||
showToast({
|
||||
message: `Image resized: ${originalSizeMB}MB → ${newSizeMB}MB (${savedPercent}% smaller)`,
|
||||
status: 'success',
|
||||
|
|
|
|||
|
|
@ -44,10 +44,10 @@ describe('imageResize utility', () => {
|
|||
const originalCanvas = global.HTMLCanvasElement;
|
||||
// @ts-ignore
|
||||
delete global.HTMLCanvasElement;
|
||||
|
||||
|
||||
const result = supportsClientSideResize();
|
||||
expect(result).toBe(false);
|
||||
|
||||
|
||||
global.HTMLCanvasElement = originalCanvas;
|
||||
});
|
||||
});
|
||||
|
|
@ -58,7 +58,7 @@ describe('imageResize utility', () => {
|
|||
type: 'image/jpeg',
|
||||
lastModified: Date.now(),
|
||||
});
|
||||
|
||||
|
||||
// Mock large file size
|
||||
Object.defineProperty(largeImageFile, 'size', {
|
||||
value: 100 * 1024 * 1024, // 100MB
|
||||
|
|
@ -74,7 +74,7 @@ describe('imageResize utility', () => {
|
|||
type: 'image/jpeg',
|
||||
lastModified: Date.now(),
|
||||
});
|
||||
|
||||
|
||||
// Mock small file size
|
||||
Object.defineProperty(smallImageFile, 'size', {
|
||||
value: 1024, // 1KB
|
||||
|
|
@ -90,7 +90,7 @@ describe('imageResize utility', () => {
|
|||
type: 'text/plain',
|
||||
lastModified: Date.now(),
|
||||
});
|
||||
|
||||
|
||||
const result = shouldResizeImage(textFile);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
|
@ -100,9 +100,9 @@ describe('imageResize utility', () => {
|
|||
type: 'image/gif',
|
||||
lastModified: Date.now(),
|
||||
});
|
||||
|
||||
|
||||
const result = shouldResizeImage(gifFile);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ export interface ResizeResult {
|
|||
* We use slightly smaller values to ensure no backend resizing is triggered
|
||||
*/
|
||||
const DEFAULT_RESIZE_OPTIONS: ResizeOptions = {
|
||||
maxWidth: 1900, // Slightly less than backend maxLongSide=2000
|
||||
maxWidth: 1900, // Slightly less than backend maxLongSide=2000
|
||||
maxHeight: 1900, // Slightly less than backend maxLongSide=2000
|
||||
quality: 0.92, // High quality while reducing file size
|
||||
format: 'jpeg', // Most compatible format
|
||||
quality: 0.92, // High quality while reducing file size
|
||||
format: 'jpeg', // Most compatible format
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -40,11 +40,11 @@ export function supportsClientSideResize(): boolean {
|
|||
if (typeof HTMLCanvasElement === 'undefined') return false;
|
||||
if (typeof FileReader === 'undefined') return false;
|
||||
if (typeof Image === 'undefined') return false;
|
||||
|
||||
|
||||
// Test canvas creation
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
|
||||
return !!(ctx && ctx.drawImage && canvas.toBlob);
|
||||
} catch {
|
||||
return false;
|
||||
|
|
@ -60,18 +60,18 @@ function calculateDimensions(
|
|||
maxWidth: number,
|
||||
maxHeight: number,
|
||||
): { width: number; height: number } {
|
||||
let { width, height } = { width: originalWidth, height: originalHeight };
|
||||
|
||||
const { width, height } = { width: originalWidth, height: originalHeight };
|
||||
|
||||
// If image is smaller than max dimensions, don't upscale
|
||||
if (width <= maxWidth && height <= maxHeight) {
|
||||
return { width, height };
|
||||
}
|
||||
|
||||
|
||||
// Calculate scaling factor
|
||||
const widthRatio = maxWidth / width;
|
||||
const heightRatio = maxHeight / height;
|
||||
const scalingFactor = Math.min(widthRatio, heightRatio);
|
||||
|
||||
|
||||
return {
|
||||
width: Math.round(width * scalingFactor),
|
||||
height: Math.round(height * scalingFactor),
|
||||
|
|
@ -91,19 +91,19 @@ export function resizeImage(
|
|||
reject(new Error('Browser does not support client-side image resizing'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Only process image files
|
||||
if (!file.type.startsWith('image/')) {
|
||||
reject(new Error('File is not an image'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const opts = { ...DEFAULT_RESIZE_OPTIONS, ...options };
|
||||
const reader = new FileReader();
|
||||
|
||||
|
||||
reader.onload = (event) => {
|
||||
const img = new Image();
|
||||
|
||||
|
||||
img.onload = () => {
|
||||
try {
|
||||
const originalDimensions = { width: img.width, height: img.height };
|
||||
|
|
@ -113,7 +113,7 @@ export function resizeImage(
|
|||
opts.maxWidth!,
|
||||
opts.maxHeight!,
|
||||
);
|
||||
|
||||
|
||||
// If no resizing needed, return original file
|
||||
if (
|
||||
newDimensions.width === originalDimensions.width &&
|
||||
|
|
@ -129,21 +129,21 @@ export function resizeImage(
|
|||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Create canvas and resize
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
|
||||
|
||||
canvas.width = newDimensions.width;
|
||||
canvas.height = newDimensions.height;
|
||||
|
||||
|
||||
// Use high-quality image smoothing
|
||||
ctx.imageSmoothingEnabled = true;
|
||||
ctx.imageSmoothingQuality = 'high';
|
||||
|
||||
|
||||
// Draw resized image
|
||||
ctx.drawImage(img, 0, 0, newDimensions.width, newDimensions.height);
|
||||
|
||||
|
||||
// Convert to blob
|
||||
canvas.toBlob(
|
||||
(blob) => {
|
||||
|
|
@ -151,17 +151,17 @@ export function resizeImage(
|
|||
reject(new Error('Failed to create blob from canvas'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Create new file with same name but potentially different extension
|
||||
const extension = opts.format === 'jpeg' ? '.jpg' : `.${opts.format}`;
|
||||
const baseName = file.name.replace(/\.[^/.]+$/, '');
|
||||
const newFileName = `${baseName}${extension}`;
|
||||
|
||||
|
||||
const resizedFile = new File([blob], newFileName, {
|
||||
type: `image/${opts.format}`,
|
||||
lastModified: Date.now(),
|
||||
});
|
||||
|
||||
|
||||
resolve({
|
||||
file: resizedFile,
|
||||
originalSize: file.size,
|
||||
|
|
@ -178,11 +178,11 @@ export function resizeImage(
|
|||
reject(error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
img.onerror = () => reject(new Error('Failed to load image'));
|
||||
img.src = event.target?.result as string;
|
||||
};
|
||||
|
||||
|
||||
reader.onerror = () => reject(new Error('Failed to read file'));
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
|
|
@ -196,19 +196,20 @@ export function shouldResizeImage(
|
|||
fileSizeLimit: number = 512 * 1024 * 1024, // 512MB default
|
||||
): boolean {
|
||||
// Don't resize if file is already small
|
||||
if (file.size < fileSizeLimit * 0.1) { // Less than 10% of limit
|
||||
if (file.size < fileSizeLimit * 0.1) {
|
||||
// Less than 10% of limit
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Don't process non-images
|
||||
if (!file.type.startsWith('image/')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Don't process GIFs (they might be animated)
|
||||
if (file.type === 'image/gif') {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue