mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
* ✨ feat: Enhance Artifact Management with Version Control and UI Improvements ✨ feat: Improve mobile layout and responsiveness in Artifacts component ✨ feat: Refactor imports and remove unnecessary props in Artifact components ✨ feat: Enhance Artifacts and SidePanel components with improved mobile responsiveness and layout transitions feat: Enhance artifact panel animations and improve UI responsiveness - Updated Thinking component button styles for smoother transitions. - Implemented dynamic rendering for artifacts panel with animation effects. - Refactored localization keys for consistency across multiple languages. - Added new CSS animations for iOS-inspired smooth transitions. - Improved Tailwind CSS configuration to support enhanced animation effects. ✨ feat: Add fullWidth and icon support to Radio component for enhanced flexibility refactor: Remove unused PreviewProps import in ArtifactPreview component refactor: Improve button class handling and blur effect constants in Artifact components ✨ feat: Refactor Artifacts component structure and add mobile/desktop variants for improved UI chore: Bump @librechat/client version to 0.3.2 refactor: Update button styles and transition durations for improved UI responsiveness refactor: revert back localization key refactor: remove unused scaling and animation properties for cleaner CSS refactor: remove unused animation properties for cleaner configuration * ✨ refactor: Simplify className usage in ArtifactTabs, ArtifactsHeader, and SidePanelGroup components * refactor: Remove cycleArtifact function from useArtifacts hook * ✨ feat: Implement Chromium resize lag fix with performance optimizations and new ArtifactsPanel component * ✨ feat: Update Badge component for responsive design and improve tap scaling behavior * chore: Update react-resizable-panels dependency to version 3.0.6 * ✨ feat: Refactor Artifacts components for improved structure and performance; remove unused files and optimize styles * ✨ style: Update text color for improved visibility in Artifacts component * ✨ style: Remove text color class for improved Spinner styling in Artifacts component * refactor: Split EditorContext into MutationContext and CodeContext to optimize re-renders; update related components to use new hooks * refactor: Optimize debounced mutation handling in CodeEditor component using refs to maintain current values and reduce re-renders * fix: Correct endpoint for message artifacts by changing URL segment from 'artifacts' to 'artifact' * feat: Enhance useEditArtifact mutation with optimistic updates and rollback on error; improve type safety with context management * fix: proper switch to preview as soon as artifact becomes enclosed * refactor: Remove optimistic updates from useEditArtifact mutation to prevent errors; simplify onMutate logic * test: Add comprehensive unit tests for useArtifacts hook to validate artifact handling, tab switching, and state management * test: Enhance unit tests for useArtifacts hook to cover new conversation transitions and null message handling --------- Co-authored-by: Marco Beretta <81851188+berry-13@users.noreply.github.com>
93 lines
3.3 KiB
TypeScript
93 lines
3.3 KiB
TypeScript
import { useRecoilValue } from 'recoil';
|
|
import { useEffect, useMemo } from 'react';
|
|
import { FileSources, LocalStorageKeys } from 'librechat-data-provider';
|
|
import type { ExtendedFile } from '~/common';
|
|
import { useDeleteFilesMutation } from '~/data-provider';
|
|
import DragDropWrapper from '~/components/Chat/Input/Files/DragDropWrapper';
|
|
import { EditorProvider, SidePanelProvider, ArtifactsProvider } from '~/Providers';
|
|
import Artifacts from '~/components/Artifacts/Artifacts';
|
|
import { SidePanelGroup } from '~/components/SidePanel';
|
|
import { useSetFilesToDelete } from '~/hooks';
|
|
import store from '~/store';
|
|
|
|
export default function Presentation({ children }: { children: React.ReactNode }) {
|
|
const artifacts = useRecoilValue(store.artifactsState);
|
|
const artifactsVisibility = useRecoilValue(store.artifactsVisibility);
|
|
|
|
const setFilesToDelete = useSetFilesToDelete();
|
|
|
|
const { mutateAsync } = useDeleteFilesMutation({
|
|
onSuccess: () => {
|
|
console.log('Temporary Files deleted');
|
|
setFilesToDelete({});
|
|
},
|
|
onError: (error) => {
|
|
console.log('Error deleting temporary files:', error);
|
|
},
|
|
});
|
|
|
|
useEffect(() => {
|
|
const filesToDelete = localStorage.getItem(LocalStorageKeys.FILES_TO_DELETE);
|
|
const map = JSON.parse(filesToDelete ?? '{}') as Record<string, ExtendedFile>;
|
|
const files = Object.values(map)
|
|
.filter(
|
|
(file) =>
|
|
file.filepath != null && file.source && !(file.embedded ?? false) && file.temp_file_id,
|
|
)
|
|
.map((file) => ({
|
|
file_id: file.file_id,
|
|
filepath: file.filepath as string,
|
|
source: file.source as FileSources,
|
|
embedded: !!(file.embedded ?? false),
|
|
}));
|
|
|
|
if (files.length === 0) {
|
|
return;
|
|
}
|
|
mutateAsync({ files });
|
|
}, [mutateAsync]);
|
|
|
|
const defaultLayout = useMemo(() => {
|
|
const resizableLayout = localStorage.getItem('react-resizable-panels:layout');
|
|
return typeof resizableLayout === 'string' ? JSON.parse(resizableLayout) : undefined;
|
|
}, []);
|
|
const defaultCollapsed = useMemo(() => {
|
|
const collapsedPanels = localStorage.getItem('react-resizable-panels:collapsed');
|
|
return typeof collapsedPanels === 'string' ? JSON.parse(collapsedPanels) : true;
|
|
}, []);
|
|
const fullCollapse = useMemo(() => localStorage.getItem('fullPanelCollapse') === 'true', []);
|
|
|
|
/**
|
|
* Memoize artifacts JSX to prevent recreating it on every render
|
|
* This is critical for performance - prevents entire artifact tree from re-rendering
|
|
*/
|
|
const artifactsElement = useMemo(() => {
|
|
if (artifactsVisibility === true && Object.keys(artifacts ?? {}).length > 0) {
|
|
return (
|
|
<ArtifactsProvider>
|
|
<EditorProvider>
|
|
<Artifacts />
|
|
</EditorProvider>
|
|
</ArtifactsProvider>
|
|
);
|
|
}
|
|
return null;
|
|
}, [artifactsVisibility, artifacts]);
|
|
|
|
return (
|
|
<DragDropWrapper className="relative flex w-full grow overflow-hidden bg-presentation">
|
|
<SidePanelProvider>
|
|
<SidePanelGroup
|
|
defaultLayout={defaultLayout}
|
|
fullPanelCollapse={fullCollapse}
|
|
defaultCollapsed={defaultCollapsed}
|
|
artifacts={artifactsElement}
|
|
>
|
|
<main className="flex h-full flex-col overflow-y-auto" role="main">
|
|
{children}
|
|
</main>
|
|
</SidePanelGroup>
|
|
</SidePanelProvider>
|
|
</DragDropWrapper>
|
|
);
|
|
}
|