diff --git a/src/lib/components/layout/Navbar/Menu.svelte b/src/lib/components/layout/Navbar/Menu.svelte index 85e7b037b..079976dcf 100644 --- a/src/lib/components/layout/Navbar/Menu.svelte +++ b/src/lib/components/layout/Navbar/Menu.svelte @@ -103,7 +103,7 @@
{/if} + {#if !$temporaryChatEnabled} + { + shareHandler(); + }} + > + + + +
{$i18n.t('Share')}
+
+ {/if} + {$i18n.t('Artifacts')}
- { - const res = await copyToClipboard(await getChatAsText()).catch((e) => { - console.error(e); - }); - - if (res) { - toast.success($i18n.t('Copied to clipboard')); - } - }} - > - -
{$i18n.t('Copy')}
-
- - {#if !$temporaryChatEnabled} - { - shareHandler(); - }} - > - - - -
{$i18n.t('Share')}
-
- {/if} - {$i18n.t('Download')} @@ -273,8 +256,25 @@ + { + const res = await copyToClipboard(await getChatAsText()).catch((e) => { + console.error(e); + }); + + if (res) { + toast.success($i18n.t('Copied to clipboard')); + } + }} + > + +
{$i18n.t('Copy')}
+
+ {#if !$temporaryChatEnabled} -
+
diff --git a/src/lib/components/layout/Sidebar/ChatMenu.svelte b/src/lib/components/layout/Sidebar/ChatMenu.svelte index 28d5c5a42..458e1c895 100644 --- a/src/lib/components/layout/Sidebar/ChatMenu.svelte +++ b/src/lib/components/layout/Sidebar/ChatMenu.svelte @@ -3,6 +3,9 @@ import { flyAndScale } from '$lib/utils/transitions'; import { getContext, createEventDispatcher } from 'svelte'; + import fileSaver from 'file-saver'; + const { saveAs } = fileSaver; + const dispatch = createEventDispatcher(); import Dropdown from '$lib/components/common/Dropdown.svelte'; @@ -15,8 +18,14 @@ import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte'; import Bookmark from '$lib/components/icons/Bookmark.svelte'; import BookmarkSlash from '$lib/components/icons/BookmarkSlash.svelte'; - import { getChatPinnedStatusById, toggleChatPinnedStatusById } from '$lib/apis/chats'; + import { + getChatById, + getChatPinnedStatusById, + toggleChatPinnedStatusById + } from '$lib/apis/chats'; import { chats } from '$lib/stores'; + import { createMessagesList } from '$lib/utils'; + import { downloadChatAsPDF } from '$lib/apis/utils'; const i18n = getContext('i18n'); @@ -41,6 +50,71 @@ pinned = await getChatPinnedStatusById(localStorage.token, chatId); }; + const getChatAsText = async () => { + const chat = await getChatById(localStorage.token, chatId); + if (!chat) { + return; + } + + const history = chat.chat.history; + const messages = createMessagesList(history, history.currentId); + const chatText = messages.reduce((a, message, i, arr) => { + return `${a}### ${message.role.toUpperCase()}\n${message.content}\n\n`; + }, ''); + + return chatText.trim(); + }; + + const downloadTxt = async () => { + const chatText = await getChatAsText(); + + let blob = new Blob([chatText], { + type: 'text/plain' + }); + + saveAs(blob, `chat-${chat.chat.title}.txt`); + }; + + const downloadPdf = async () => { + const chat = await getChatById(localStorage.token, chatId); + if (!chat) { + return; + } + + const history = chat.chat.history; + const messages = createMessagesList(history, history.currentId); + const blob = await downloadChatAsPDF(chat.chat.title, messages); + + // Create a URL for the blob + const url = window.URL.createObjectURL(blob); + + // Create a link element to trigger the download + const a = document.createElement('a'); + a.href = url; + a.download = `chat-${chat.chat.title}.pdf`; + + // Append the link to the body and click it programmatically + document.body.appendChild(a); + a.click(); + + // Remove the link from the body + document.body.removeChild(a); + + // Revoke the URL to release memory + window.URL.revokeObjectURL(url); + }; + + const downloadJSONExport = async () => { + const chat = await getChatById(localStorage.token, chatId); + + if (chat) { + let blob = new Blob([JSON.stringify([chat])], { + type: 'application/json' + }); + saveAs(blob, `chat-export-${Date.now()}.json`); + } + }; + $: if (show) { checkPinned(); } @@ -60,7 +134,7 @@
{$i18n.t('Share')}
+ + + + + + +
{$i18n.t('Download')}
+
+ + { + downloadJSONExport(); + }} + > +
{$i18n.t('Export chat (.json)')}
+
+ { + downloadTxt(); + }} + > +
{$i18n.t('Plain text (.txt)')}
+
+ + { + downloadPdf(); + }} + > +
{$i18n.t('PDF document (.pdf)')}
+
+
+
{