Add import, fix export
This commit is contained in:
@@ -12,7 +12,6 @@ import { Messages } from './Messages.client';
|
||||
import { SendButton } from './SendButton.client';
|
||||
import { APIKeyManager } from './APIKeyManager';
|
||||
import Cookies from 'js-cookie';
|
||||
import { exportChat, importChat } from '~/utils/chatExport';
|
||||
import { toast } from 'react-toastify';
|
||||
import * as Tooltip from '@radix-ui/react-tooltip';
|
||||
|
||||
@@ -90,6 +89,8 @@ interface BaseChatProps {
|
||||
sendMessage?: (event: React.UIEvent, messageInput?: string) => void;
|
||||
handleInputChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
||||
enhancePrompt?: () => void;
|
||||
importChat?: (description: string, messages: Message[]) => Promise<void>;
|
||||
exportChat?: () => void;
|
||||
}
|
||||
|
||||
export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
@@ -113,7 +114,9 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
sendMessage,
|
||||
handleInputChange,
|
||||
enhancePrompt,
|
||||
handleStop
|
||||
handleStop,
|
||||
importChat,
|
||||
exportChat
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
@@ -292,7 +295,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
</>
|
||||
)}
|
||||
</IconButton>
|
||||
<ClientOnly>{() => <ExportChatButton description={description} messages={messages}/>}</ClientOnly>
|
||||
<ClientOnly>{() => <ExportChatButton exportChat={exportChat}/>}</ClientOnly>
|
||||
</div>
|
||||
{input.length > 3 ? (
|
||||
<div className="text-xs text-bolt-elements-textTertiary">
|
||||
@@ -317,18 +320,31 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
accept=".json"
|
||||
onChange={async (e) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (file) {
|
||||
if (file && importChat) {
|
||||
try {
|
||||
const { messages: importedMessages } = await importChat(file);
|
||||
// Import each message
|
||||
for (const msg of importedMessages) {
|
||||
await sendMessage(new Event('import') as unknown as React.UIEvent, msg.content);
|
||||
}
|
||||
toast.success('Chat imported successfully');
|
||||
const reader = new FileReader();
|
||||
reader.onload = async (e) => {
|
||||
try {
|
||||
const content = e.target?.result as string;
|
||||
const data = JSON.parse(content);
|
||||
if (!Array.isArray(data.messages)) {
|
||||
toast.error('Invalid chat file format');
|
||||
}
|
||||
await importChat(data.description, data.messages);
|
||||
toast.success('Chat imported successfully');
|
||||
} catch (error) {
|
||||
toast.error('Failed to parse chat file');
|
||||
}
|
||||
};
|
||||
reader.onerror = () => toast.error('Failed to read chat file');
|
||||
reader.readAsText(file);
|
||||
|
||||
} catch (error) {
|
||||
toast.error(error instanceof Error ? error.message : 'Failed to import chat');
|
||||
}
|
||||
e.target.value = ''; // Reset file input
|
||||
} else {
|
||||
toast.error('Something went wrong');
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -28,12 +28,12 @@ const logger = createScopedLogger('Chat');
|
||||
export function Chat() {
|
||||
renderLogger.trace('Chat');
|
||||
|
||||
const { ready, initialMessages, storeMessageHistory } = useChatHistory();
|
||||
const { ready, initialMessages, storeMessageHistory, importChat, exportChat } = useChatHistory();
|
||||
const title = useStore(description);
|
||||
|
||||
return (
|
||||
<>
|
||||
{ready && <ChatImpl description={title} initialMessages={initialMessages} storeMessageHistory={storeMessageHistory} />}
|
||||
{ready && <ChatImpl description={title} initialMessages={initialMessages} exportChat={exportChat} storeMessageHistory={storeMessageHistory} importChat={importChat} />}
|
||||
<ToastContainer
|
||||
closeButton={({ closeToast }) => {
|
||||
return (
|
||||
@@ -68,9 +68,11 @@ export function Chat() {
|
||||
interface ChatProps {
|
||||
initialMessages: Message[];
|
||||
storeMessageHistory: (messages: Message[]) => Promise<void>;
|
||||
importChat: (description: string, messages: Message[]) => Promise<void>;
|
||||
exportChat: () => void;
|
||||
}
|
||||
|
||||
export const ChatImpl = memo(({ description, initialMessages, storeMessageHistory }: ChatProps) => {
|
||||
export const ChatImpl = memo(({ description, initialMessages, storeMessageHistory, importChat, exportChat }: ChatProps) => {
|
||||
useShortcuts();
|
||||
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
@@ -254,6 +256,8 @@ export const ChatImpl = memo(({ description, initialMessages, storeMessageHistor
|
||||
handleInputChange={handleInputChange}
|
||||
handleStop={abort}
|
||||
description={description}
|
||||
importChat={importChat}
|
||||
exportChat={exportChat}
|
||||
messages={messages.map((message, i) => {
|
||||
if (message.role === 'user') {
|
||||
return message;
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import WithTooltip from '~/components/ui/Tooltip';
|
||||
import { IconButton } from '~/components/ui/IconButton';
|
||||
import { exportChat } from '~/utils/chatExport';
|
||||
import React from 'react';
|
||||
import type { Message } from 'ai';
|
||||
|
||||
export const ExportChatButton = ({description, messages}: {description: string, messages: Message[]}) => {
|
||||
export const ExportChatButton = ({exportChat}: {exportChat: () => void}) => {
|
||||
return (<WithTooltip tooltip="Export Chat">
|
||||
<IconButton
|
||||
title="Export Chat"
|
||||
onClick={() => exportChat(messages || [], description)}
|
||||
onClick={exportChat}
|
||||
>
|
||||
<div className="i-ph:download-simple text-xl"></div>
|
||||
</IconButton>
|
||||
|
||||
@@ -33,7 +33,6 @@ export const Messages = React.forwardRef<HTMLDivElement, MessagesProps>((props:
|
||||
toast.error('Chat persistence is not available');
|
||||
return;
|
||||
}
|
||||
|
||||
const urlId = await forkChat(db, chatId.get()!, messageId);
|
||||
window.location.href = `/chat/${urlId}`;
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user