mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-22 02:14:10 +01:00
🤝 feat: View Artifacts in Shared Conversations (#10477)
* feat: Integrate logger for MessageIcon component * feat: Enhance artifact sharing functionality with updated path checks and read-only state management * feat: Refactor Thinking and Reasoning components for improved structure and styling * feat: Enhance artifact sharing with context value management and responsive layout * feat: Enhance ShareView with theme and language management features * feat: Improve ThinkingButton accessibility and styling for better user interaction * feat: Introduce isArtifactRoute utility for route validation in Artifact components * feat: Add latest message text extraction in SharedView for improved message display * feat: Update locale handling in SharedView for dynamic date formatting * feat: Refactor ArtifactsContext and SharedView for improved context handling and styling adjustments * feat: Enhance artifact panel size management with local storage integration * chore: imports * refactor: move ShareArtifactsContainer out of ShareView --------- Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
cabc8afeac
commit
c2505d2bc9
15 changed files with 443 additions and 73 deletions
|
|
@ -6,8 +6,8 @@ import { useLocation } from 'react-router-dom';
|
|||
import type { Pluggable } from 'unified';
|
||||
import type { Artifact } from '~/common';
|
||||
import { useMessageContext, useArtifactContext } from '~/Providers';
|
||||
import { logger, extractContent, isArtifactRoute } from '~/utils';
|
||||
import { artifactsState } from '~/store/artifacts';
|
||||
import { logger, extractContent } from '~/utils';
|
||||
import ArtifactButton from './ArtifactButton';
|
||||
|
||||
export const artifactPlugin: Pluggable = () => {
|
||||
|
|
@ -88,7 +88,7 @@ export function Artifact({
|
|||
lastUpdateTime: now,
|
||||
};
|
||||
|
||||
if (!location.pathname.includes('/c/')) {
|
||||
if (!isArtifactRoute(location.pathname)) {
|
||||
return setArtifact(currentArtifact);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { useLocation } from 'react-router-dom';
|
|||
import { useRecoilState, useSetRecoilState, useResetRecoilState } from 'recoil';
|
||||
import type { Artifact } from '~/common';
|
||||
import FilePreview from '~/components/Chat/Input/Files/FilePreview';
|
||||
import { cn, getFileType, logger } from '~/utils';
|
||||
import { cn, getFileType, logger, isArtifactRoute } from '~/utils';
|
||||
import { useLocalize } from '~/hooks';
|
||||
import store from '~/store';
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ const ArtifactButton = ({ artifact }: { artifact: Artifact | null }) => {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!location.pathname.includes('/c/')) {
|
||||
if (!isArtifactRoute(location.pathname)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -57,8 +57,6 @@ const ArtifactButton = ({ artifact }: { artifact: Artifact | null }) => {
|
|||
<div className="group relative my-4 rounded-xl text-sm text-text-primary">
|
||||
{(() => {
|
||||
const handleClick = () => {
|
||||
if (!location.pathname.includes('/c/')) return;
|
||||
|
||||
if (isSelected) {
|
||||
resetCurrentArtifactId();
|
||||
setVisible(false);
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ export const ArtifactCodeEditor = function ({
|
|||
artifact,
|
||||
editorRef,
|
||||
sharedProps,
|
||||
readOnly: externalReadOnly,
|
||||
}: {
|
||||
fileKey: string;
|
||||
artifact: Artifact;
|
||||
|
|
@ -164,6 +165,7 @@ export const ArtifactCodeEditor = function ({
|
|||
template: SandpackProviderProps['template'];
|
||||
sharedProps: Partial<SandpackProviderProps>;
|
||||
editorRef: React.MutableRefObject<CodeEditorRef>;
|
||||
readOnly?: boolean;
|
||||
}) {
|
||||
const { data: config } = useGetStartupConfig();
|
||||
const { isSubmitting } = useArtifactsContext();
|
||||
|
|
@ -177,10 +179,10 @@ export const ArtifactCodeEditor = function ({
|
|||
bundlerURL: template === 'static' ? config.staticBundlerURL : config.bundlerURL,
|
||||
};
|
||||
}, [config, template, fileKey]);
|
||||
const [readOnly, setReadOnly] = useState(isSubmitting ?? false);
|
||||
const [readOnly, setReadOnly] = useState(externalReadOnly ?? isSubmitting ?? false);
|
||||
useEffect(() => {
|
||||
setReadOnly(isSubmitting ?? false);
|
||||
}, [isSubmitting]);
|
||||
setReadOnly(externalReadOnly ?? isSubmitting ?? false);
|
||||
}, [isSubmitting, externalReadOnly]);
|
||||
|
||||
if (Object.keys(files).length === 0) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -15,10 +15,12 @@ export default function ArtifactTabs({
|
|||
artifact,
|
||||
editorRef,
|
||||
previewRef,
|
||||
isSharedConvo,
|
||||
}: {
|
||||
artifact: Artifact;
|
||||
editorRef: React.MutableRefObject<CodeEditorRef>;
|
||||
previewRef: React.MutableRefObject<SandpackPreviewRef>;
|
||||
isSharedConvo?: boolean;
|
||||
}) {
|
||||
const { isSubmitting } = useArtifactsContext();
|
||||
const { currentCode, setCurrentCode } = useCodeState();
|
||||
|
|
@ -54,6 +56,7 @@ export default function ArtifactTabs({
|
|||
artifact={artifact}
|
||||
editorRef={editorRef}
|
||||
sharedProps={sharedProps}
|
||||
readOnly={isSharedConvo}
|
||||
/>
|
||||
</Tabs.Content>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ import { Code, Play, RefreshCw, X } from 'lucide-react';
|
|||
import { useSetRecoilState, useResetRecoilState } from 'recoil';
|
||||
import { Button, Spinner, useMediaQuery, Radio } from '@librechat/client';
|
||||
import type { SandpackPreviewRef, CodeEditorRef } from '@codesandbox/sandpack-react';
|
||||
import { useShareContext, useMutationState } from '~/Providers';
|
||||
import useArtifacts from '~/hooks/Artifacts/useArtifacts';
|
||||
import DownloadArtifact from './DownloadArtifact';
|
||||
import ArtifactVersion from './ArtifactVersion';
|
||||
import { useMutationState } from '~/Providers/EditorContext';
|
||||
import ArtifactTabs from './ArtifactTabs';
|
||||
import { CopyCodeButton } from './Code';
|
||||
import { useLocalize } from '~/hooks';
|
||||
|
|
@ -20,6 +20,7 @@ const MAX_BACKDROP_OPACITY = 0.3;
|
|||
export default function Artifacts() {
|
||||
const localize = useLocalize();
|
||||
const { isMutating } = useMutationState();
|
||||
const { isSharedConvo } = useShareContext();
|
||||
const isMobile = useMediaQuery('(max-width: 868px)');
|
||||
const editorRef = useRef<CodeEditorRef>();
|
||||
const previewRef = useRef<SandpackPreviewRef>();
|
||||
|
|
@ -294,6 +295,7 @@ export default function Artifacts() {
|
|||
artifact={currentArtifact}
|
||||
editorRef={editorRef as React.MutableRefObject<CodeEditorRef>}
|
||||
previewRef={previewRef as React.MutableRefObject<SandpackPreviewRef>}
|
||||
isSharedConvo={isSharedConvo}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue