mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-12 04:15:25 +00:00
feat: save temporary chats
This commit is contained in:
parent
47ec443728
commit
575db66295
4 changed files with 110 additions and 33 deletions
|
|
@ -129,13 +129,16 @@ def upload_file(
|
||||||
id = str(uuid.uuid4())
|
id = str(uuid.uuid4())
|
||||||
name = filename
|
name = filename
|
||||||
filename = f"{id}_{filename}"
|
filename = f"{id}_{filename}"
|
||||||
tags = {
|
contents, file_path = Storage.upload_file(
|
||||||
"OpenWebUI-User-Email": user.email,
|
file.file,
|
||||||
"OpenWebUI-User-Id": user.id,
|
filename,
|
||||||
"OpenWebUI-User-Name": user.name,
|
{
|
||||||
"OpenWebUI-File-Id": id,
|
"OpenWebUI-User-Email": user.email,
|
||||||
}
|
"OpenWebUI-User-Id": user.id,
|
||||||
contents, file_path = Storage.upload_file(file.file, filename, tags)
|
"OpenWebUI-User-Name": user.name,
|
||||||
|
"OpenWebUI-File-Id": id,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
file_item = Files.insert_new_file(
|
file_item = Files.insert_new_file(
|
||||||
user.id,
|
user.id,
|
||||||
|
|
|
||||||
|
|
@ -2196,6 +2196,42 @@
|
||||||
shareEnabled={!!history.currentId}
|
shareEnabled={!!history.currentId}
|
||||||
{initNewChat}
|
{initNewChat}
|
||||||
showBanners={!showCommands}
|
showBanners={!showCommands}
|
||||||
|
onSaveTempChat={async () => {
|
||||||
|
try {
|
||||||
|
if (!history?.currentId || !Object.keys(history.messages).length) {
|
||||||
|
toast.error($i18n.t('No conversation to save'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const messages = createMessagesList(history, history.currentId);
|
||||||
|
const title =
|
||||||
|
messages.find((m) => m.role === 'user')?.content ?? $i18n.t('New Chat');
|
||||||
|
|
||||||
|
const savedChat = await createNewChat(
|
||||||
|
localStorage.token,
|
||||||
|
{
|
||||||
|
id: uuidv4(),
|
||||||
|
title: title.length > 50 ? `${title.slice(0, 50)}...` : title,
|
||||||
|
models: selectedModels,
|
||||||
|
history: history,
|
||||||
|
messages: messages,
|
||||||
|
timestamp: Date.now()
|
||||||
|
},
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
if (savedChat) {
|
||||||
|
temporaryChatEnabled.set(false);
|
||||||
|
chatId.set(savedChat.id);
|
||||||
|
chats.set(await getChatList(localStorage.token, $currentChatPage));
|
||||||
|
|
||||||
|
await goto(`/c/${savedChat.id}`);
|
||||||
|
toast.success($i18n.t('Conversation saved successfully'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error saving conversation:', error);
|
||||||
|
toast.error($i18n.t('Failed to save conversation'));
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="flex flex-col flex-auto z-10 w-full @container overflow-auto">
|
<div class="flex flex-col flex-auto z-10 w-full @container overflow-auto">
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
import ShareChatModal from '../chat/ShareChatModal.svelte';
|
import ShareChatModal from '../chat/ShareChatModal.svelte';
|
||||||
import ModelSelector from '../chat/ModelSelector.svelte';
|
import ModelSelector from '../chat/ModelSelector.svelte';
|
||||||
|
|
@ -34,7 +35,7 @@
|
||||||
import ChatBubbleDottedChecked from '../icons/ChatBubbleDottedChecked.svelte';
|
import ChatBubbleDottedChecked from '../icons/ChatBubbleDottedChecked.svelte';
|
||||||
|
|
||||||
import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
|
import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
|
||||||
import { goto } from '$app/navigation';
|
import ChatPlus from '../icons/ChatPlus.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
|
|
@ -48,6 +49,8 @@
|
||||||
export let showModelSelector = true;
|
export let showModelSelector = true;
|
||||||
export let showBanners = true;
|
export let showBanners = true;
|
||||||
|
|
||||||
|
export let onSaveTempChat: () => {};
|
||||||
|
|
||||||
let closedBannerIds = [];
|
let closedBannerIds = [];
|
||||||
|
|
||||||
let showShareChatModal = false;
|
let showShareChatModal = false;
|
||||||
|
|
@ -105,31 +108,47 @@
|
||||||
<div class="self-start flex flex-none items-center text-gray-600 dark:text-gray-400">
|
<div class="self-start flex flex-none items-center text-gray-600 dark:text-gray-400">
|
||||||
<!-- <div class="md:hidden flex self-center w-[1px] h-5 mx-2 bg-gray-300 dark:bg-stone-700" /> -->
|
<!-- <div class="md:hidden flex self-center w-[1px] h-5 mx-2 bg-gray-300 dark:bg-stone-700" /> -->
|
||||||
|
|
||||||
{#if !chat?.id && ($user?.role === 'user' ? ($user?.permissions?.chat?.temporary ?? true) && !($user?.permissions?.chat?.temporary_enforced ?? false) : true)}
|
{#if $user?.role === 'user' ? ($user?.permissions?.chat?.temporary ?? true) && !($user?.permissions?.chat?.temporary_enforced ?? false) : true}
|
||||||
<Tooltip content={$i18n.t(`Temporary Chat`)}>
|
{#if !chat?.id}
|
||||||
<button
|
<Tooltip content={$i18n.t(`Temporary Chat`)}>
|
||||||
class="flex cursor-pointer px-2 py-2 rounded-xl hover:bg-gray-50 dark:hover:bg-gray-850 transition"
|
<button
|
||||||
id="temporary-chat-button"
|
class="flex cursor-pointer px-2 py-2 rounded-xl hover:bg-gray-50 dark:hover:bg-gray-850 transition"
|
||||||
on:click={async () => {
|
id="temporary-chat-button"
|
||||||
temporaryChatEnabled.set(!$temporaryChatEnabled);
|
on:click={async () => {
|
||||||
await goto('/');
|
temporaryChatEnabled.set(!$temporaryChatEnabled);
|
||||||
// add 'temporary-chat=true' to the URL
|
await goto('/');
|
||||||
if ($temporaryChatEnabled) {
|
// add 'temporary-chat=true' to the URL
|
||||||
window.history.replaceState(null, '', '?temporary-chat=true');
|
if ($temporaryChatEnabled) {
|
||||||
} else {
|
window.history.replaceState(null, '', '?temporary-chat=true');
|
||||||
window.history.replaceState(null, '', location.pathname);
|
} else {
|
||||||
}
|
window.history.replaceState(null, '', location.pathname);
|
||||||
}}
|
}
|
||||||
>
|
}}
|
||||||
<div class=" m-auto self-center">
|
>
|
||||||
{#if $temporaryChatEnabled}
|
<div class=" m-auto self-center">
|
||||||
<ChatBubbleDottedChecked className=" size-4.5" strokeWidth="1.5" />
|
{#if $temporaryChatEnabled}
|
||||||
{:else}
|
<ChatBubbleDottedChecked className=" size-4.5" strokeWidth="1.5" />
|
||||||
<ChatBubbleDotted className=" size-4.5" strokeWidth="1.5" />
|
{:else}
|
||||||
{/if}
|
<ChatBubbleDotted className=" size-4.5" strokeWidth="1.5" />
|
||||||
</div>
|
{/if}
|
||||||
</button>
|
</div>
|
||||||
</Tooltip>
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
{:else if $temporaryChatEnabled}
|
||||||
|
<Tooltip content={$i18n.t(`Save Chat`)}>
|
||||||
|
<button
|
||||||
|
class="flex cursor-pointer px-2 py-2 rounded-xl hover:bg-gray-50 dark:hover:bg-gray-850 transition"
|
||||||
|
id="save-temporary-chat-button"
|
||||||
|
on:click={async () => {
|
||||||
|
onSaveTempChat();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div class=" m-auto self-center">
|
||||||
|
<ChatPlus className=" size-4.5" strokeWidth="1.5" />
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if shareEnabled && chat && (chat.id || $temporaryChatEnabled)}
|
{#if shareEnabled && chat && (chat.id || $temporaryChatEnabled)}
|
||||||
|
|
|
||||||
19
src/lib/components/icons/ChatPlus.svelte
Normal file
19
src/lib/components/icons/ChatPlus.svelte
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let className = 'w-4 h-4';
|
||||||
|
export let strokeWidth = '1.5';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width={strokeWidth}
|
||||||
|
stroke="currentColor"
|
||||||
|
class={className}
|
||||||
|
><path d="M9 12H12M15 12H12M12 12V9M12 12V15" stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
></path><path
|
||||||
|
d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 13.8214 2.48697 15.5291 3.33782 17L2.5 21.5L7 20.6622C8.47087 21.513 10.1786 22 12 22Z"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
></path></svg
|
||||||
|
>
|
||||||
Loading…
Reference in a new issue