diff --git a/src/lib/components/AddFilesPlaceholder.svelte b/src/lib/components/AddFilesPlaceholder.svelte index a3057c560..d3d700795 100644 --- a/src/lib/components/AddFilesPlaceholder.svelte +++ b/src/lib/components/AddFilesPlaceholder.svelte @@ -2,20 +2,27 @@ import { getContext } from 'svelte'; export let title = ''; + export let content = ''; const i18n = getContext('i18n'); -
📄
-
- {#if title} - {title} - {:else} - {$i18n.t('Add Files')} - {/if} -
- -
- {$i18n.t('Drop any files here to add to the conversation')} +
+
📄
+
+ {#if title} + {title} + {:else} + {$i18n.t('Add Files')} + {/if}
- + +
+ {#if content} + {content} + {:else} + {$i18n.t('Drop any files here to add to the conversation')} + {/if} +
+
+
diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte index 47af56834..3fdadf5ff 100644 --- a/src/lib/components/layout/Sidebar.svelte +++ b/src/lib/components/layout/Sidebar.svelte @@ -19,7 +19,7 @@ showOverview, showControls } from '$lib/stores'; - import { onMount, getContext, tick } from 'svelte'; + import { onMount, getContext, tick, onDestroy } from 'svelte'; const i18n = getContext('i18n'); @@ -33,7 +33,8 @@ getAllChatTags, archiveChatById, cloneChatById, - getChatListBySearchText + getChatListBySearchText, + createNewChat } from '$lib/apis/chats'; import { WEBUI_BASE_URL } from '$lib/constants'; @@ -43,6 +44,8 @@ import DeleteConfirmDialog from '$lib/components/common/ConfirmDialog.svelte'; import Spinner from '../common/Spinner.svelte'; import Loader from '../common/Loader.svelte'; + import FilesOverlay from '../chat/MessageInput/FilesOverlay.svelte'; + import AddFilesPlaceholder from '../AddFilesPlaceholder.svelte'; const BREAKPOINT = 768; @@ -115,91 +118,6 @@ } }; - onMount(async () => { - mobile.subscribe((e) => { - if ($showSidebar && e) { - showSidebar.set(false); - } - - if (!$showSidebar && !e) { - showSidebar.set(true); - } - }); - - showSidebar.set(!$mobile ? localStorage.sidebar === 'true' : false); - showSidebar.subscribe((value) => { - localStorage.sidebar = value; - }); - - await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); - await initChatList(); - - let touchstart; - let touchend; - - function checkDirection() { - const screenWidth = window.innerWidth; - const swipeDistance = Math.abs(touchend.screenX - touchstart.screenX); - if (touchstart.clientX < 40 && swipeDistance >= screenWidth / 8) { - if (touchend.screenX < touchstart.screenX) { - showSidebar.set(false); - } - if (touchend.screenX > touchstart.screenX) { - showSidebar.set(true); - } - } - } - - const onTouchStart = (e) => { - touchstart = e.changedTouches[0]; - console.log(touchstart.clientX); - }; - - const onTouchEnd = (e) => { - touchend = e.changedTouches[0]; - checkDirection(); - }; - - const onKeyDown = (e) => { - if (e.key === 'Shift') { - shiftKey = true; - } - }; - - const onKeyUp = (e) => { - if (e.key === 'Shift') { - shiftKey = false; - } - }; - - const onFocus = () => {}; - - const onBlur = () => { - shiftKey = false; - selectedChatId = null; - }; - - window.addEventListener('keydown', onKeyDown); - window.addEventListener('keyup', onKeyUp); - - window.addEventListener('touchstart', onTouchStart); - window.addEventListener('touchend', onTouchEnd); - - window.addEventListener('focus', onFocus); - window.addEventListener('blur', onBlur); - - return () => { - window.removeEventListener('keydown', onKeyDown); - window.removeEventListener('keyup', onKeyUp); - - window.removeEventListener('touchstart', onTouchStart); - window.removeEventListener('touchend', onTouchEnd); - - window.removeEventListener('focus', onFocus); - window.removeEventListener('blur', onBlur); - }; - }); - const deleteChatHandler = async (id) => { const res = await deleteChatById(localStorage.token, id).catch((error) => { toast.error(error); @@ -220,6 +138,158 @@ await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); } }; + + const inputFilesHandler = async (files) => { + console.log(files); + + for (const file of files) { + const reader = new FileReader(); + reader.onload = async (e) => { + const content = e.target.result; + + try { + const items = JSON.parse(content); + + for (const item of items) { + if (item.chat) { + await createNewChat(localStorage.token, item.chat); + } + } + } catch { + toast.error($i18n.t(`Invalid file format.`)); + } + + initChatList(); + }; + + reader.readAsText(file); + } + }; + + let dragged = false; + + const onDragOver = (e) => { + e.preventDefault(); + dragged = true; + }; + + const onDragLeave = () => { + dragged = false; + }; + + const onDrop = async (e) => { + e.preventDefault(); + console.log(e); + + if (e.dataTransfer?.files) { + const inputFiles = Array.from(e.dataTransfer?.files); + if (inputFiles && inputFiles.length > 0) { + console.log(inputFiles); + inputFilesHandler(inputFiles); + } else { + toast.error($i18n.t(`File not found.`)); + } + } + + dragged = false; + }; + + let touchstart; + let touchend; + + function checkDirection() { + const screenWidth = window.innerWidth; + const swipeDistance = Math.abs(touchend.screenX - touchstart.screenX); + if (touchstart.clientX < 40 && swipeDistance >= screenWidth / 8) { + if (touchend.screenX < touchstart.screenX) { + showSidebar.set(false); + } + if (touchend.screenX > touchstart.screenX) { + showSidebar.set(true); + } + } + } + + const onTouchStart = (e) => { + touchstart = e.changedTouches[0]; + console.log(touchstart.clientX); + }; + + const onTouchEnd = (e) => { + touchend = e.changedTouches[0]; + checkDirection(); + }; + + const onKeyDown = (e) => { + if (e.key === 'Shift') { + shiftKey = true; + } + }; + + const onKeyUp = (e) => { + if (e.key === 'Shift') { + shiftKey = false; + } + }; + + const onFocus = () => {}; + + const onBlur = () => { + shiftKey = false; + selectedChatId = null; + }; + + onMount(async () => { + mobile.subscribe((e) => { + if ($showSidebar && e) { + showSidebar.set(false); + } + + if (!$showSidebar && !e) { + showSidebar.set(true); + } + }); + + showSidebar.set(!$mobile ? localStorage.sidebar === 'true' : false); + showSidebar.subscribe((value) => { + localStorage.sidebar = value; + }); + + await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); + await initChatList(); + + window.addEventListener('keydown', onKeyDown); + window.addEventListener('keyup', onKeyUp); + + window.addEventListener('touchstart', onTouchStart); + window.addEventListener('touchend', onTouchEnd); + + window.addEventListener('focus', onFocus); + window.addEventListener('blur', onBlur); + + const dropZone = document.getElementById('sidebar'); + + dropZone?.addEventListener('dragover', onDragOver); + dropZone?.addEventListener('drop', onDrop); + dropZone?.addEventListener('dragleave', onDragLeave); + }); + + onDestroy(() => { + window.removeEventListener('keydown', onKeyDown); + window.removeEventListener('keyup', onKeyUp); + + window.removeEventListener('touchstart', onTouchStart); + window.removeEventListener('touchend', onTouchEnd); + + window.removeEventListener('focus', onFocus); + window.removeEventListener('blur', onBlur); + + const dropZone = document.getElementById('sidebar'); + + dropZone?.removeEventListener('dragover', onDragOver); + dropZone?.removeEventListener('drop', onDrop); + dropZone?.removeEventListener('dragleave', onDragLeave); + }); + {#if dragged} +
+
+ +
+
+ {/if}