Merge branch 'feature/export-chat-to-pdf' into 'wip/h3132'
Added functionallity to export chat to PDF See merge request schihei/chatbot-ui!2
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { IconClearAll, IconSettings } from '@tabler/icons-react';
|
import { IconClearAll, IconSettings, IconPdf } from '@tabler/icons-react';
|
||||||
import {
|
import {
|
||||||
MutableRefObject,
|
MutableRefObject,
|
||||||
memo,
|
memo,
|
||||||
@@ -34,6 +34,9 @@ import { SystemPrompt } from './SystemPrompt';
|
|||||||
import { TemperatureSlider } from './Temperature';
|
import { TemperatureSlider } from './Temperature';
|
||||||
import { MemoizedChatMessage } from './MemoizedChatMessage';
|
import { MemoizedChatMessage } from './MemoizedChatMessage';
|
||||||
|
|
||||||
|
import {jsPDF} from "jspdf";
|
||||||
|
import html2canvas from "html2canvas";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
stopConversationRef: MutableRefObject<boolean>;
|
stopConversationRef: MutableRefObject<boolean>;
|
||||||
}
|
}
|
||||||
@@ -300,6 +303,34 @@ export const Chat = memo(({ stopConversationRef }: Props) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onPdf = () => {
|
||||||
|
if (chatContainerRef.current === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
chatContainerRef.current.classList.remove('max-h-full')
|
||||||
|
html2canvas(chatContainerRef.current).then((canvas) => {
|
||||||
|
if (chatContainerRef.current) {
|
||||||
|
chatContainerRef.current.classList.add('max-h-full')
|
||||||
|
}
|
||||||
|
const imgData = canvas.toDataURL('image/png');
|
||||||
|
const orientation = canvas.width > canvas.height ? "l" : "p";
|
||||||
|
const pixelRatio = window.devicePixelRatio > 2 ? window.devicePixelRatio : 2
|
||||||
|
const pdf = new jsPDF(
|
||||||
|
orientation,
|
||||||
|
"pt",
|
||||||
|
[canvas.width / pixelRatio, canvas.height / pixelRatio],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
var pdfWidth = pdf.internal.pageSize.getWidth();
|
||||||
|
var pdfHeight = pdf.internal.pageSize.getHeight();
|
||||||
|
pdf.addImage(imgData, "PNG", 0, 0, pdfWidth, pdfHeight, "", "FAST");
|
||||||
|
const title = `${selectedConversation?.name || 'conversation'}.pdf`
|
||||||
|
pdf.save(title)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const scrollDown = () => {
|
const scrollDown = () => {
|
||||||
if (autoScrollEnabled) {
|
if (autoScrollEnabled) {
|
||||||
messagesEndRef.current?.scrollIntoView(true);
|
messagesEndRef.current?.scrollIntoView(true);
|
||||||
@@ -454,6 +485,12 @@ export const Chat = memo(({ stopConversationRef }: Props) => {
|
|||||||
>
|
>
|
||||||
<IconClearAll size={18} />
|
<IconClearAll size={18} />
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
className="ml-2 cursor-pointer hover:opacity-50"
|
||||||
|
onClick={onPdf}
|
||||||
|
>
|
||||||
|
<IconPdf size={18} />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{showSettings && (
|
{showSettings && (
|
||||||
<div className="flex flex-col space-y-10 md:mx-auto md:max-w-xl md:gap-6 md:py-3 md:pt-6 lg:max-w-2xl lg:px-0 xl:max-w-3xl">
|
<div className="flex flex-col space-y-10 md:mx-auto md:max-w-xl md:gap-6 md:py-3 md:pt-6 lg:max-w-2xl lg:px-0 xl:max-w-3xl">
|
||||||
|
|||||||
@@ -15,7 +15,9 @@
|
|||||||
"@dqbd/tiktoken": "^1.0.2",
|
"@dqbd/tiktoken": "^1.0.2",
|
||||||
"@tabler/icons-react": "^2.9.0",
|
"@tabler/icons-react": "^2.9.0",
|
||||||
"eventsource-parser": "^0.1.0",
|
"eventsource-parser": "^0.1.0",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
"i18next": "^22.4.13",
|
"i18next": "^22.4.13",
|
||||||
|
"jspdf": "^2.5.1",
|
||||||
"next": "13.2.4",
|
"next": "13.2.4",
|
||||||
"next-i18next": "^13.2.2",
|
"next-i18next": "^13.2.2",
|
||||||
"openai": "^3.2.1",
|
"openai": "^3.2.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user