diff --git a/src/lib/components/chat/Settings/Chats.svelte b/src/lib/components/chat/Settings/Chats.svelte
index 2c032d4df..f62e3926e 100644
--- a/src/lib/components/chat/Settings/Chats.svelte
+++ b/src/lib/components/chat/Settings/Chats.svelte
@@ -12,7 +12,12 @@
getAllUserChats,
getChatList
} from '$lib/apis/chats';
- import { getImportOrigin, convertOpenAIChats, disablePagination } from '$lib/utils';
+ import {
+ getImportOrigin,
+ convertOpenAIChats,
+ disablePagination,
+ enablePagination
+ } from '$lib/utils';
import { onMount, getContext } from 'svelte';
import { goto } from '$app/navigation';
import { toast } from 'svelte-sonner';
@@ -61,8 +66,7 @@
await createNewChat(localStorage.token, chat);
}
}
- disablePagination();
- await chats.set(await getChatList(localStorage.token));
+ enablePagination();
};
const exportChats = async () => {
@@ -77,8 +81,7 @@
await archiveAllChats(localStorage.token).catch((error) => {
toast.error(error);
});
- disablePagination();
- await chats.set(await getChatList(localStorage.token));
+ enablePagination();
};
const deleteAllChatsHandler = async () => {
@@ -86,8 +89,8 @@
await deleteAllChats(localStorage.token).catch((error) => {
toast.error(error);
});
- disablePagination();
- await chats.set(await getChatList(localStorage.token));
+
+ enablePagination();
};
const toggleSaveChatHistory = async () => {
diff --git a/src/lib/components/chat/Tags.svelte b/src/lib/components/chat/Tags.svelte
index 19efa2662..a806f2aaa 100644
--- a/src/lib/components/chat/Tags.svelte
+++ b/src/lib/components/chat/Tags.svelte
@@ -8,12 +8,13 @@
getTagsById,
updateChatById
} from '$lib/apis/chats';
- import { tags as _tags, chats, pinnedChats, pageSkip, pageLimit, tagView } from '$lib/stores';
+ import { tags as _tags, chats, pinnedChats, pageSkip, pageLimit } from '$lib/stores';
import { createEventDispatcher, onMount } from 'svelte';
const dispatch = createEventDispatcher();
import Tags from '../common/Tags.svelte';
+ import { enablePagination } from '$lib/utils';
export let chatId = '';
let tags = [];
@@ -59,7 +60,7 @@
}
} else {
// if the tag we deleted is no longer a valid tag, return to main chat list view
- tagView.set(false);
+ enablePagination();
await chats.set(
await getChatList(localStorage.token, 0, $pageSkip * $pageLimit || $pageLimit)
);
diff --git a/src/lib/components/common/Loader.svelte b/src/lib/components/common/Loader.svelte
new file mode 100644
index 000000000..dbe84fd60
--- /dev/null
+++ b/src/lib/components/common/Loader.svelte
@@ -0,0 +1,30 @@
+
+
+
+
+
diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte
index 07dac20f0..70360a46d 100644
--- a/src/lib/components/layout/Sidebar.svelte
+++ b/src/lib/components/layout/Sidebar.svelte
@@ -14,13 +14,12 @@
pinnedChats,
pageSkip,
pageLimit,
- scrollPaginationEnabled,
- tagView
+ scrollPaginationEnabled
} from '$lib/stores';
import { onMount, getContext, tick } from 'svelte';
const i18n = getContext('i18n');
- import { disablePagination } from '$lib/utils';
+ import { disablePagination, enablePagination } from '$lib/utils';
import { updateUserSettings } from '$lib/apis/users';
import {
@@ -40,6 +39,7 @@
import ChatItem from './Sidebar/ChatItem.svelte';
import DeleteConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import Spinner from '../common/Spinner.svelte';
+ import Loader from '../common/Loader.svelte';
const BREAKPOINT = 768;
@@ -55,9 +55,10 @@
let showDropdown = false;
let filteredChatList = [];
- let paginationScrollThreashold = 0.6;
- let nextPageLoading = false;
- let chatPagniationComplete = false;
+
+ // Pagination variables
+ let chatListLoading = false;
+ let allChatsLoaded = false;
pageLimit.set(20);
@@ -81,6 +82,18 @@
}
});
+ const loadMoreChats = async () => {
+ chatListLoading = true;
+ pageSkip.set($pageSkip + 1);
+ const newChatList = await getChatList(localStorage.token, $pageSkip * $pageLimit, $pageLimit);
+
+ // once the bottom of the list has been reached (no results) there is no need to continue querying
+ allChatsLoaded = newChatList.length === 0;
+ await chats.set([...$chats, ...newChatList]);
+
+ chatListLoading = false;
+ };
+
onMount(async () => {
mobile.subscribe((e) => {
if ($showSidebar && e) {
@@ -151,48 +164,6 @@
window.addEventListener('focus', onFocus);
window.addEventListener('blur', onBlur);
- // Infinite scroll
- const loader = document.getElementById('loader');
-
- const observer = new IntersectionObserver(
- (entries, observer) => {
- entries.forEach((entry) => {
- if (entry.isIntersecting) {
- loadMoreContent();
- observer.unobserve(loader); // Stop observing until content is loaded
- }
- });
- },
- {
- root: null, // viewport
- rootMargin: '0px',
- threshold: 1.0 // When 100% of the loader is visible
- }
- );
-
- observer.observe(loader);
- const loadMoreContent = async () => {
- if (!$scrollPaginationEnabled) return;
- if ($tagView) return;
- if (nextPageLoading) return;
- if (chatPagniationComplete) return;
-
- nextPageLoading = true;
- pageSkip.set($pageSkip + 1);
- // extend existing chats
- const nextPageChats = await getChatList(
- localStorage.token,
- $pageSkip * $pageLimit,
- $pageLimit
- );
- // once the bottom of the list has been reached (no results) there is no need to continue querying
- chatPagniationComplete = nextPageChats.length === 0;
- await chats.set([...$chats, ...nextPageChats]);
- nextPageLoading = false;
-
- observer.observe(loader); // Start observing again after content is loaded
- };
-
return () => {
window.removeEventListener('keydown', onKeyDown);
window.removeEventListener('keyup', onKeyUp);
@@ -466,8 +437,8 @@
placeholder={$i18n.t('Search')}
bind:value={search}
on:focus={async () => {
- disablePagination();
// TODO: migrate backend for more scalable search mechanism
+ disablePagination();
await chats.set(await getChatList(localStorage.token)); // when searching, load all chats
enrichChatsWithContent($chats);
}}
@@ -480,8 +451,8 @@