mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-04 14:57:42 +00:00
📉 refactor: Reduce Frontend Build Warning Noise (#13463)
This commit is contained in:
parent
e0c346c0a4
commit
88e5a2f23b
4 changed files with 67 additions and 29 deletions
|
|
@ -1,5 +1,4 @@
|
|||
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
||||
import mermaid from 'mermaid';
|
||||
import { Button } from '@librechat/client';
|
||||
import { ZoomIn, ZoomOut, RotateCcw } from 'lucide-react';
|
||||
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch';
|
||||
|
|
@ -11,6 +10,16 @@ interface MermaidDiagramProps {
|
|||
isDarkMode?: boolean;
|
||||
}
|
||||
|
||||
let mermaidPromise: Promise<typeof import('mermaid').default> | null = null;
|
||||
|
||||
const loadMermaid = () => {
|
||||
if (!mermaidPromise) {
|
||||
mermaidPromise = import('mermaid').then((mod) => mod.default);
|
||||
}
|
||||
|
||||
return mermaidPromise;
|
||||
};
|
||||
|
||||
const MermaidDiagram: React.FC<MermaidDiagramProps> = ({ content, isDarkMode = true }) => {
|
||||
const mermaidRef = useRef<HTMLDivElement>(null);
|
||||
const transformRef = useRef<ReactZoomPanPinchRef>(null);
|
||||
|
|
@ -19,19 +28,23 @@ const MermaidDiagram: React.FC<MermaidDiagramProps> = ({ content, isDarkMode = t
|
|||
const bgColor = isDarkMode ? '#212121' : '#FFFFFF';
|
||||
|
||||
useEffect(() => {
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
theme,
|
||||
securityLevel: 'sandbox',
|
||||
flowchart: artifactFlowchartConfig,
|
||||
});
|
||||
let isMounted = true;
|
||||
|
||||
const renderDiagram = async () => {
|
||||
if (!mermaidRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const mermaid = await loadMermaid();
|
||||
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
theme,
|
||||
securityLevel: 'sandbox',
|
||||
flowchart: artifactFlowchartConfig,
|
||||
});
|
||||
|
||||
if (!mermaidRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { svg } = await mermaid.render('mermaid-diagram', content);
|
||||
mermaidRef.current.innerHTML = svg;
|
||||
|
||||
|
|
@ -40,7 +53,9 @@ const MermaidDiagram: React.FC<MermaidDiagramProps> = ({ content, isDarkMode = t
|
|||
svgElement.style.width = '100%';
|
||||
svgElement.style.height = '100%';
|
||||
}
|
||||
setIsRendered(true);
|
||||
if (isMounted) {
|
||||
setIsRendered(true);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Mermaid rendering error:', error);
|
||||
if (mermaidRef.current) {
|
||||
|
|
@ -50,6 +65,10 @@ const MermaidDiagram: React.FC<MermaidDiagramProps> = ({ content, isDarkMode = t
|
|||
};
|
||||
|
||||
renderDiagram();
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, [content, theme]);
|
||||
|
||||
const centerAndFitDiagram = useCallback(() => {
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ jest.mock('~/utils', () => ({
|
|||
}));
|
||||
|
||||
const mockValidateFiles = jest.requireMock('~/utils').validateFiles;
|
||||
const mockProcessFileForUpload = jest.requireMock('~/utils/heicConverter')
|
||||
.processFileForUpload as jest.Mock;
|
||||
|
||||
describe('useFileHandling', () => {
|
||||
beforeEach(() => {
|
||||
|
|
@ -109,6 +111,20 @@ describe('useFileHandling', () => {
|
|||
const loadHook = async () => (await import('../useFileHandling')).default;
|
||||
|
||||
describe('endpointOverride', () => {
|
||||
it('checks possible image uploads for HEIC conversion without HEIC metadata', async () => {
|
||||
const useFileHandling = await loadHook();
|
||||
const { result } = renderHook(() => useFileHandling());
|
||||
|
||||
const imageFile = new File(['maybe-heic'], 'photo.jpg', { type: 'image/jpeg' });
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleFiles([imageFile]);
|
||||
});
|
||||
|
||||
expect(mockProcessFileForUpload).toHaveBeenCalledTimes(1);
|
||||
expect(mockProcessFileForUpload).toHaveBeenCalledWith(imageFile, 0.9, expect.any(Function));
|
||||
});
|
||||
|
||||
it('uses conversation endpoint when no override is provided', async () => {
|
||||
mockConversation = {
|
||||
conversationId: 'convo-1',
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import { logger, validateFiles, cachePreview, getCachedPreview, removePreviewEnt
|
|||
import { useGetFileConfig, useUploadFileMutation } from '~/data-provider';
|
||||
import useLocalize, { TranslationKeys } from '~/hooks/useLocalize';
|
||||
import { useDelayedUploadToast } from './useDelayedUploadToast';
|
||||
import { processFileForUpload } from '~/utils/heicConverter';
|
||||
import { useChatContext } from '~/Providers/ChatContext';
|
||||
import store, { ephemeralAgentByConvoId } from '~/store';
|
||||
import useClientResize from './useClientResize';
|
||||
|
|
@ -339,11 +338,16 @@ const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: Fil
|
|||
// Add file immediately to show in UI
|
||||
addFile(initialExtendedFile);
|
||||
|
||||
const originalFileName = originalFile.name.toLowerCase();
|
||||
|
||||
// Check if HEIC conversion is needed and show toast
|
||||
const isHEIC =
|
||||
originalFile.type === 'image/heic' ||
|
||||
originalFile.type === 'image/heif' ||
|
||||
originalFile.name.toLowerCase().match(/\.(heic|heif)$/);
|
||||
/\.(heic|heif)$/.test(originalFileName);
|
||||
const isPossibleImage =
|
||||
originalFile.type.startsWith('image/') ||
|
||||
/\.(avif|bmp|gif|heic|heif|jpe?g|png|svg|tiff?|webp)$/.test(originalFileName);
|
||||
|
||||
if (isHEIC) {
|
||||
showToast({
|
||||
|
|
@ -353,19 +357,17 @@ const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: Fil
|
|||
});
|
||||
}
|
||||
|
||||
// Process file for HEIC conversion if needed
|
||||
const heicProcessedFile = await processFileForUpload(
|
||||
originalFile,
|
||||
0.9,
|
||||
(conversionProgress) => {
|
||||
// Update progress during HEIC conversion (0.1 to 0.5 range for conversion)
|
||||
const adjustedProgress = 0.1 + conversionProgress * 0.4;
|
||||
replaceFile({
|
||||
...initialExtendedFile,
|
||||
progress: adjustedProgress,
|
||||
});
|
||||
},
|
||||
);
|
||||
const heicProcessedFile = isPossibleImage
|
||||
? await import('~/utils/heicConverter').then(({ processFileForUpload }) =>
|
||||
processFileForUpload(originalFile, 0.9, (conversionProgress) => {
|
||||
const adjustedProgress = 0.1 + conversionProgress * 0.4;
|
||||
replaceFile({
|
||||
...initialExtendedFile,
|
||||
progress: adjustedProgress,
|
||||
});
|
||||
}),
|
||||
)
|
||||
: originalFile;
|
||||
|
||||
let finalProcessedFile = heicProcessedFile;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ const backendPort = (process.env.BACKEND_PORT && Number(process.env.BACKEND_PORT
|
|||
const backendURL = process.env.HOST
|
||||
? `http://${process.env.HOST}:${backendPort}`
|
||||
: `http://localhost:${backendPort}`;
|
||||
const buildSourceMap = process.env.NODE_ENV === 'development';
|
||||
|
||||
export default defineConfig(({ command }) => ({
|
||||
base: '',
|
||||
|
|
@ -124,14 +125,14 @@ export default defineConfig(({ command }) => ({
|
|||
],
|
||||
},
|
||||
}),
|
||||
sourcemapExclude({ excludeNodeModules: true }),
|
||||
...(buildSourceMap ? [sourcemapExclude({ excludeNodeModules: true })] : []),
|
||||
compression({
|
||||
threshold: 10240,
|
||||
}),
|
||||
],
|
||||
publicDir: command === 'serve' ? './public' : false,
|
||||
build: {
|
||||
sourcemap: process.env.NODE_ENV === 'development',
|
||||
sourcemap: buildSourceMap,
|
||||
outDir: './dist',
|
||||
minify: 'terser',
|
||||
rolldownOptions: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue