Added export button

This commit is contained in:
eduardruzga 2024-11-22 11:51:52 +02:00
parent 60411550a5
commit 9f49c25f96
4 changed files with 38 additions and 5 deletions

View File

@ -12,12 +12,14 @@ import { Messages } from './Messages.client';
import { SendButton } from './SendButton.client';
import { APIKeyManager } from './APIKeyManager';
import Cookies from 'js-cookie';
import { importChat } from '~/utils/chatExport';
import { exportChat, importChat } from '~/utils/chatExport';
import { toast } from 'react-toastify';
import * as Tooltip from '@radix-ui/react-tooltip';
import styles from './BaseChat.module.scss';
import type { ProviderInfo } from '~/utils/types';
import WithTooltip from '~/components/ui/Tooltip';
import { ExportChatButton } from '~/components/chat/ExportChatButton';
const EXAMPLE_PROMPTS = [
{ text: 'Build a todo app in React using Tailwind' },
@ -76,6 +78,7 @@ interface BaseChatProps {
chatStarted?: boolean;
isStreaming?: boolean;
messages?: Message[];
description?: string;
enhancingPrompt?: boolean;
promptEnhanced?: boolean;
input?: string;
@ -101,6 +104,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
enhancingPrompt = false,
promptEnhanced = false,
messages,
description,
input = '',
model,
setModel,
@ -288,6 +292,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
</>
)}
</IconButton>
<ClientOnly>{() => <ExportChatButton description={description} messages={messages}/>}</ClientOnly>
</div>
{input.length > 3 ? (
<div className="text-xs text-bolt-elements-textTertiary">

View File

@ -7,7 +7,7 @@ import { useAnimate } from 'framer-motion';
import { memo, useEffect, useRef, useState } from 'react';
import { cssTransition, toast, ToastContainer } from 'react-toastify';
import { useMessageParser, usePromptEnhancer, useShortcuts, useSnapScroll } from '~/lib/hooks';
import { useChatHistory } from '~/lib/persistence';
import { description, useChatHistory } from '~/lib/persistence';
import { chatStore } from '~/lib/stores/chat';
import { workbenchStore } from '~/lib/stores/workbench';
import { fileModificationsToHTML } from '~/utils/diff';
@ -29,10 +29,11 @@ export function Chat() {
renderLogger.trace('Chat');
const { ready, initialMessages, storeMessageHistory } = useChatHistory();
const title = useStore(description);
return (
<>
{ready && <ChatImpl initialMessages={initialMessages} storeMessageHistory={storeMessageHistory} />}
{ready && <ChatImpl description={title} initialMessages={initialMessages} storeMessageHistory={storeMessageHistory} />}
<ToastContainer
closeButton={({ closeToast }) => {
return (
@ -69,7 +70,7 @@ interface ChatProps {
storeMessageHistory: (messages: Message[]) => Promise<void>;
}
export const ChatImpl = memo(({ initialMessages, storeMessageHistory }: ChatProps) => {
export const ChatImpl = memo(({ description, initialMessages, storeMessageHistory }: ChatProps) => {
useShortcuts();
const textareaRef = useRef<HTMLTextAreaElement>(null);
@ -252,6 +253,7 @@ export const ChatImpl = memo(({ initialMessages, storeMessageHistory }: ChatProp
scrollRef={scrollRef}
handleInputChange={handleInputChange}
handleStop={abort}
description={description}
messages={messages.map((message, i) => {
if (message.role === 'user') {
return message;

View File

@ -0,0 +1,16 @@
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[]}) => {
return (<WithTooltip tooltip="Export Chat">
<IconButton
title="Export Chat"
onClick={() => exportChat(messages || [], description)}
>
<div className="i-ph:download-simple text-xl"></div>
</IconButton>
</WithTooltip>);
}

View File

@ -1,7 +1,17 @@
import React from 'react';
import * as Tooltip from '@radix-ui/react-tooltip';
import type {ReactNode} from 'react';
const WithTooltip = ({ tooltip, children, sideOffset = 5, className = '', arrowClassName = '', tooltipStyle = {} }) => {
interface ToolTipProps {
tooltip: string,
children: ReactNode | ReactNode[];
sideOffset?: number,
className?: string,
arrowClassName?: string,
tooltipStyle?: any, //TODO better type
}
const WithTooltip = ({ tooltip, children, sideOffset = 5, className = '', arrowClassName = '', tooltipStyle = {} }: ToolTipProps) => {
return (
<Tooltip.Root>
<Tooltip.Trigger asChild>