Addressing eslint errors

This commit is contained in:
Rakshit Tiwari 2025-06-16 16:42:11 +05:30
parent a77ad276f1
commit b6de2a8557
4 changed files with 47 additions and 46 deletions

View file

@ -2,11 +2,11 @@ import { mergeFileConfig } from 'librechat-data-provider';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useGetFileConfig } from '~/data-provider'; import { useGetFileConfig } from '~/data-provider';
import { import {
resizeImage, resizeImage,
shouldResizeImage, shouldResizeImage,
supportsClientSideResize, supportsClientSideResize,
type ResizeOptions, type ResizeOptions,
type ResizeResult, type ResizeResult,
} from '~/utils/imageResize'; } from '~/utils/imageResize';
/** /**
@ -19,6 +19,7 @@ export const useClientSideResize = () => {
}); });
// Safe access to clientSideImageResize config with fallbacks // Safe access to clientSideImageResize config with fallbacks
// eslint-disable-next-line react-hooks/exhaustive-deps
const config = (fileConfig as any)?.clientSideImageResize ?? { const config = (fileConfig as any)?.clientSideImageResize ?? {
enabled: false, enabled: false,
maxWidth: 1900, maxWidth: 1900,
@ -66,7 +67,6 @@ export const useClientSideResize = () => {
return { file: result.file, resized: true, result }; return { file: result.file, resized: true, result };
} catch (error) { } catch (error) {
console.warn('Client-side image resizing failed:', error); console.warn('Client-side image resizing failed:', error);
// Return original file on error
return { file, resized: false }; return { file, resized: false };
} }
}, },
@ -81,4 +81,4 @@ export const useClientSideResize = () => {
}; };
}; };
export default useClientSideResize; export default useClientSideResize;

View file

@ -265,20 +265,20 @@ const useFileHandling = (params?: UseFileHandling) => {
const file_id = v4(); const file_id = v4();
try { try {
let processedFile = originalFile; let processedFile = originalFile;
// Apply client-side resizing if available and appropriate // Apply client-side resizing if available and appropriate
if (originalFile.type.startsWith('image/')) { if (originalFile.type.startsWith('image/')) {
try { try {
const resizeResult = await resizeImageIfNeeded(originalFile); const resizeResult = await resizeImageIfNeeded(originalFile);
processedFile = resizeResult.file; processedFile = resizeResult.file;
// Show toast notification if image was resized // Show toast notification if image was resized
if (resizeResult.resized && resizeResult.result) { if (resizeResult.resized && resizeResult.result) {
const { originalSize, newSize, compressionRatio } = resizeResult.result; const { originalSize, newSize, compressionRatio } = resizeResult.result;
const originalSizeMB = (originalSize / (1024 * 1024)).toFixed(1); const originalSizeMB = (originalSize / (1024 * 1024)).toFixed(1);
const newSizeMB = (newSize / (1024 * 1024)).toFixed(1); const newSizeMB = (newSize / (1024 * 1024)).toFixed(1);
const savedPercent = Math.round((1 - compressionRatio) * 100); const savedPercent = Math.round((1 - compressionRatio) * 100);
showToast({ showToast({
message: `Image resized: ${originalSizeMB}MB → ${newSizeMB}MB (${savedPercent}% smaller)`, message: `Image resized: ${originalSizeMB}MB → ${newSizeMB}MB (${savedPercent}% smaller)`,
status: 'success', status: 'success',

View file

@ -44,10 +44,10 @@ describe('imageResize utility', () => {
const originalCanvas = global.HTMLCanvasElement; const originalCanvas = global.HTMLCanvasElement;
// @ts-ignore // @ts-ignore
delete global.HTMLCanvasElement; delete global.HTMLCanvasElement;
const result = supportsClientSideResize(); const result = supportsClientSideResize();
expect(result).toBe(false); expect(result).toBe(false);
global.HTMLCanvasElement = originalCanvas; global.HTMLCanvasElement = originalCanvas;
}); });
}); });
@ -58,7 +58,7 @@ describe('imageResize utility', () => {
type: 'image/jpeg', type: 'image/jpeg',
lastModified: Date.now(), lastModified: Date.now(),
}); });
// Mock large file size // Mock large file size
Object.defineProperty(largeImageFile, 'size', { Object.defineProperty(largeImageFile, 'size', {
value: 100 * 1024 * 1024, // 100MB value: 100 * 1024 * 1024, // 100MB
@ -74,7 +74,7 @@ describe('imageResize utility', () => {
type: 'image/jpeg', type: 'image/jpeg',
lastModified: Date.now(), lastModified: Date.now(),
}); });
// Mock small file size // Mock small file size
Object.defineProperty(smallImageFile, 'size', { Object.defineProperty(smallImageFile, 'size', {
value: 1024, // 1KB value: 1024, // 1KB
@ -90,7 +90,7 @@ describe('imageResize utility', () => {
type: 'text/plain', type: 'text/plain',
lastModified: Date.now(), lastModified: Date.now(),
}); });
const result = shouldResizeImage(textFile); const result = shouldResizeImage(textFile);
expect(result).toBe(false); expect(result).toBe(false);
}); });
@ -100,9 +100,9 @@ describe('imageResize utility', () => {
type: 'image/gif', type: 'image/gif',
lastModified: Date.now(), lastModified: Date.now(),
}); });
const result = shouldResizeImage(gifFile); const result = shouldResizeImage(gifFile);
expect(result).toBe(false); expect(result).toBe(false);
}); });
}); });
}); });

View file

@ -25,10 +25,10 @@ export interface ResizeResult {
* We use slightly smaller values to ensure no backend resizing is triggered * We use slightly smaller values to ensure no backend resizing is triggered
*/ */
const DEFAULT_RESIZE_OPTIONS: ResizeOptions = { 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 maxHeight: 1900, // Slightly less than backend maxLongSide=2000
quality: 0.92, // High quality while reducing file size quality: 0.92, // High quality while reducing file size
format: 'jpeg', // Most compatible format format: 'jpeg', // Most compatible format
}; };
/** /**
@ -40,11 +40,11 @@ export function supportsClientSideResize(): boolean {
if (typeof HTMLCanvasElement === 'undefined') return false; if (typeof HTMLCanvasElement === 'undefined') return false;
if (typeof FileReader === 'undefined') return false; if (typeof FileReader === 'undefined') return false;
if (typeof Image === 'undefined') return false; if (typeof Image === 'undefined') return false;
// Test canvas creation // Test canvas creation
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
return !!(ctx && ctx.drawImage && canvas.toBlob); return !!(ctx && ctx.drawImage && canvas.toBlob);
} catch { } catch {
return false; return false;
@ -60,18 +60,18 @@ function calculateDimensions(
maxWidth: number, maxWidth: number,
maxHeight: number, maxHeight: number,
): { width: number; height: 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 image is smaller than max dimensions, don't upscale
if (width <= maxWidth && height <= maxHeight) { if (width <= maxWidth && height <= maxHeight) {
return { width, height }; return { width, height };
} }
// Calculate scaling factor // Calculate scaling factor
const widthRatio = maxWidth / width; const widthRatio = maxWidth / width;
const heightRatio = maxHeight / height; const heightRatio = maxHeight / height;
const scalingFactor = Math.min(widthRatio, heightRatio); const scalingFactor = Math.min(widthRatio, heightRatio);
return { return {
width: Math.round(width * scalingFactor), width: Math.round(width * scalingFactor),
height: Math.round(height * scalingFactor), height: Math.round(height * scalingFactor),
@ -91,19 +91,19 @@ export function resizeImage(
reject(new Error('Browser does not support client-side image resizing')); reject(new Error('Browser does not support client-side image resizing'));
return; return;
} }
// Only process image files // Only process image files
if (!file.type.startsWith('image/')) { if (!file.type.startsWith('image/')) {
reject(new Error('File is not an image')); reject(new Error('File is not an image'));
return; return;
} }
const opts = { ...DEFAULT_RESIZE_OPTIONS, ...options }; const opts = { ...DEFAULT_RESIZE_OPTIONS, ...options };
const reader = new FileReader(); const reader = new FileReader();
reader.onload = (event) => { reader.onload = (event) => {
const img = new Image(); const img = new Image();
img.onload = () => { img.onload = () => {
try { try {
const originalDimensions = { width: img.width, height: img.height }; const originalDimensions = { width: img.width, height: img.height };
@ -113,7 +113,7 @@ export function resizeImage(
opts.maxWidth!, opts.maxWidth!,
opts.maxHeight!, opts.maxHeight!,
); );
// If no resizing needed, return original file // If no resizing needed, return original file
if ( if (
newDimensions.width === originalDimensions.width && newDimensions.width === originalDimensions.width &&
@ -129,21 +129,21 @@ export function resizeImage(
}); });
return; return;
} }
// Create canvas and resize // Create canvas and resize
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d')!; const ctx = canvas.getContext('2d')!;
canvas.width = newDimensions.width; canvas.width = newDimensions.width;
canvas.height = newDimensions.height; canvas.height = newDimensions.height;
// Use high-quality image smoothing // Use high-quality image smoothing
ctx.imageSmoothingEnabled = true; ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high'; ctx.imageSmoothingQuality = 'high';
// Draw resized image // Draw resized image
ctx.drawImage(img, 0, 0, newDimensions.width, newDimensions.height); ctx.drawImage(img, 0, 0, newDimensions.width, newDimensions.height);
// Convert to blob // Convert to blob
canvas.toBlob( canvas.toBlob(
(blob) => { (blob) => {
@ -151,17 +151,17 @@ export function resizeImage(
reject(new Error('Failed to create blob from canvas')); reject(new Error('Failed to create blob from canvas'));
return; return;
} }
// Create new file with same name but potentially different extension // Create new file with same name but potentially different extension
const extension = opts.format === 'jpeg' ? '.jpg' : `.${opts.format}`; const extension = opts.format === 'jpeg' ? '.jpg' : `.${opts.format}`;
const baseName = file.name.replace(/\.[^/.]+$/, ''); const baseName = file.name.replace(/\.[^/.]+$/, '');
const newFileName = `${baseName}${extension}`; const newFileName = `${baseName}${extension}`;
const resizedFile = new File([blob], newFileName, { const resizedFile = new File([blob], newFileName, {
type: `image/${opts.format}`, type: `image/${opts.format}`,
lastModified: Date.now(), lastModified: Date.now(),
}); });
resolve({ resolve({
file: resizedFile, file: resizedFile,
originalSize: file.size, originalSize: file.size,
@ -178,11 +178,11 @@ export function resizeImage(
reject(error); reject(error);
} }
}; };
img.onerror = () => reject(new Error('Failed to load image')); img.onerror = () => reject(new Error('Failed to load image'));
img.src = event.target?.result as string; img.src = event.target?.result as string;
}; };
reader.onerror = () => reject(new Error('Failed to read file')); reader.onerror = () => reject(new Error('Failed to read file'));
reader.readAsDataURL(file); reader.readAsDataURL(file);
}); });
@ -196,19 +196,20 @@ export function shouldResizeImage(
fileSizeLimit: number = 512 * 1024 * 1024, // 512MB default fileSizeLimit: number = 512 * 1024 * 1024, // 512MB default
): boolean { ): boolean {
// Don't resize if file is already small // 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; return false;
} }
// Don't process non-images // Don't process non-images
if (!file.type.startsWith('image/')) { if (!file.type.startsWith('image/')) {
return false; return false;
} }
// Don't process GIFs (they might be animated) // Don't process GIFs (they might be animated)
if (file.type === 'image/gif') { if (file.type === 'image/gif') {
return false; return false;
} }
return true; return true;
} }