2024-11-25 07:43:34 +00:00
|
|
|
import type { Message } from 'ai';
|
|
|
|
import { toast } from 'react-toastify';
|
2024-11-25 17:57:53 +00:00
|
|
|
import { ImportFolderButton } from '~/components/chat/ImportFolderButton';
|
2025-01-28 10:39:12 +00:00
|
|
|
import { Button } from '~/components/ui/Button';
|
2025-01-30 16:17:36 +00:00
|
|
|
import { classNames } from '~/utils/classNames';
|
2024-11-25 07:43:34 +00:00
|
|
|
|
2025-01-07 14:46:42 +00:00
|
|
|
type ChatData = {
|
|
|
|
messages?: Message[]; // Standard Bolt format
|
|
|
|
description?: string; // Optional description
|
|
|
|
};
|
|
|
|
|
2024-11-25 17:57:53 +00:00
|
|
|
export function ImportButtons(importChat: ((description: string, messages: Message[]) => Promise<void>) | undefined) {
|
2024-11-25 07:43:34 +00:00
|
|
|
return (
|
2024-12-03 05:39:37 +00:00
|
|
|
<div className="flex flex-col items-center justify-center w-auto">
|
2024-11-25 07:43:34 +00:00
|
|
|
<input
|
|
|
|
type="file"
|
|
|
|
id="chat-import"
|
|
|
|
className="hidden"
|
|
|
|
accept=".json"
|
|
|
|
onChange={async (e) => {
|
|
|
|
const file = e.target.files?.[0];
|
|
|
|
|
|
|
|
if (file && importChat) {
|
|
|
|
try {
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
|
|
|
reader.onload = async (e) => {
|
|
|
|
try {
|
|
|
|
const content = e.target?.result as string;
|
2025-01-07 14:46:42 +00:00
|
|
|
const data = JSON.parse(content) as ChatData;
|
2024-11-25 07:43:34 +00:00
|
|
|
|
2025-01-07 14:46:42 +00:00
|
|
|
// Standard format
|
|
|
|
if (Array.isArray(data.messages)) {
|
|
|
|
await importChat(data.description || 'Imported Chat', data.messages);
|
|
|
|
toast.success('Chat imported successfully');
|
2025-01-10 15:47:32 +00:00
|
|
|
|
2025-01-07 14:46:42 +00:00
|
|
|
return;
|
2024-11-25 07:43:34 +00:00
|
|
|
}
|
|
|
|
|
2025-01-07 14:46:42 +00:00
|
|
|
toast.error('Invalid chat file format');
|
2024-11-25 07:43:34 +00:00
|
|
|
} catch (error: unknown) {
|
|
|
|
if (error instanceof Error) {
|
|
|
|
toast.error('Failed to parse chat file: ' + error.message);
|
|
|
|
} else {
|
|
|
|
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');
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
<div className="flex flex-col items-center gap-4 max-w-2xl text-center">
|
|
|
|
<div className="flex gap-2">
|
2025-01-28 10:39:12 +00:00
|
|
|
<Button
|
2024-11-25 07:43:34 +00:00
|
|
|
onClick={() => {
|
|
|
|
const input = document.getElementById('chat-import');
|
|
|
|
input?.click();
|
|
|
|
}}
|
2025-01-28 10:39:12 +00:00
|
|
|
variant="outline"
|
|
|
|
size="lg"
|
2025-01-30 16:17:36 +00:00
|
|
|
className={classNames(
|
2025-01-28 10:39:12 +00:00
|
|
|
'gap-2 bg-[#F5F5F5] dark:bg-[#252525]',
|
|
|
|
'text-bolt-elements-textPrimary dark:text-white',
|
|
|
|
'hover:bg-[#E5E5E5] dark:hover:bg-[#333333]',
|
|
|
|
'border-[#E5E5E5] dark:border-[#333333]',
|
|
|
|
'h-10 px-4 py-2 min-w-[120px] justify-center',
|
|
|
|
'transition-all duration-200 ease-in-out',
|
|
|
|
)}
|
2024-11-25 07:43:34 +00:00
|
|
|
>
|
2025-01-28 10:39:12 +00:00
|
|
|
<span className="i-ph:upload-simple w-4 h-4" />
|
2024-11-25 07:43:34 +00:00
|
|
|
Import Chat
|
2025-01-28 10:39:12 +00:00
|
|
|
</Button>
|
2024-11-25 17:57:53 +00:00
|
|
|
<ImportFolderButton
|
|
|
|
importChat={importChat}
|
2025-01-30 16:17:36 +00:00
|
|
|
className={classNames(
|
2025-01-28 10:39:12 +00:00
|
|
|
'gap-2 bg-[#F5F5F5] dark:bg-[#252525]',
|
|
|
|
'text-bolt-elements-textPrimary dark:text-white',
|
|
|
|
'hover:bg-[#E5E5E5] dark:hover:bg-[#333333]',
|
|
|
|
'border border-[#E5E5E5] dark:border-[#333333]',
|
|
|
|
'h-10 px-4 py-2 min-w-[120px] justify-center',
|
|
|
|
'transition-all duration-200 ease-in-out rounded-lg',
|
|
|
|
)}
|
2024-11-25 17:57:53 +00:00
|
|
|
/>
|
2024-11-25 07:43:34 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|