From 49199819db69837f31227cfef3674fbaf8abca72 Mon Sep 17 00:00:00 2001 From: Aryan Kothari <87589047+thearyadev@users.noreply.github.com> Date: Thu, 1 Aug 2024 12:24:05 -0400 Subject: [PATCH 01/12] add: stores for pagination state --- src/lib/stores/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts index 1b0257c4b..60a617185 100644 --- a/src/lib/stores/index.ts +++ b/src/lib/stores/index.ts @@ -41,6 +41,9 @@ export const showSettings = writable(false); export const showArchivedChats = writable(false); export const showChangelog = writable(false); export const showCallOverlay = writable(false); +export const scrollPaginationEnabled = writable(true); +export const pageSkip = writable(0); +export const pageLimit = writable(-1); export type Model = OpenAIModel | OllamaModel; From 519375b4c090d864395b6cacecc5c3b9bb3a0d93 Mon Sep 17 00:00:00 2001 From: Aryan Kothari <87589047+thearyadev@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:05:52 -0400 Subject: [PATCH 02/12] add: skip and limit use in query - limit default changed to -1 --- backend/apps/webui/models/chats.py | 9 +++++---- backend/apps/webui/routers/chats.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/apps/webui/models/chats.py b/backend/apps/webui/models/chats.py index abde4f2b3..d504b18c3 100644 --- a/backend/apps/webui/models/chats.py +++ b/backend/apps/webui/models/chats.py @@ -250,7 +250,7 @@ class ChatTable: user_id: str, include_archived: bool = False, skip: int = 0, - limit: int = 50, + limit: int = -1, ) -> List[ChatTitleIdResponse]: with get_db() as db: query = db.query(Chat).filter_by(user_id=user_id) @@ -260,9 +260,10 @@ class ChatTable: all_chats = ( query.order_by(Chat.updated_at.desc()) # limit cols - .with_entities( - Chat.id, Chat.title, Chat.updated_at, Chat.created_at - ).all() + .with_entities(Chat.id, Chat.title, Chat.updated_at, Chat.created_at) + .limit(limit) + .offset(skip) + .all() ) # result has to be destrctured from sqlalchemy `row` and mapped to a dict since the `ChatModel`is not the returned dataclass. return [ diff --git a/backend/apps/webui/routers/chats.py b/backend/apps/webui/routers/chats.py index 80308a451..47c7c4a87 100644 --- a/backend/apps/webui/routers/chats.py +++ b/backend/apps/webui/routers/chats.py @@ -43,7 +43,7 @@ router = APIRouter() @router.get("/", response_model=List[ChatTitleIdResponse]) @router.get("/list", response_model=List[ChatTitleIdResponse]) async def get_session_user_chat_list( - user=Depends(get_verified_user), skip: int = 0, limit: int = 50 + user=Depends(get_verified_user), skip: int = 0, limit: int = -1 ): return Chats.get_chat_title_id_list_by_user_id(user.id, skip=skip, limit=limit) From d11961626c56c30deb165f202e842d2ce283ccff Mon Sep 17 00:00:00 2001 From: Aryan Kothari <87589047+thearyadev@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:15:49 -0400 Subject: [PATCH 03/12] add: use skip and limit in api call --- src/lib/apis/chats/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/apis/chats/index.ts b/src/lib/apis/chats/index.ts index b046f1b10..8ff12f4b6 100644 --- a/src/lib/apis/chats/index.ts +++ b/src/lib/apis/chats/index.ts @@ -32,10 +32,10 @@ export const createNewChat = async (token: string, chat: object) => { return res; }; -export const getChatList = async (token: string = '') => { +export const getChatList = async (token: string = '', skip: number = 0, limit: number = -1) => { let error = null; - const res = await fetch(`${WEBUI_API_BASE_URL}/chats/`, { + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/?skip=${skip}&limit=${limit}`, { method: 'GET', headers: { Accept: 'application/json', From 62dc486c8577bef6d0c65fd3777b9425bd85a06d Mon Sep 17 00:00:00 2001 From: Aryan Kothari <87589047+thearyadev@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:19:14 -0400 Subject: [PATCH 04/12] add: add paginated scroll handler --- src/lib/components/layout/Sidebar.svelte | 77 +++++++++++++++++++++--- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte index 49a0e2ebb..d8434e6a2 100644 --- a/src/lib/components/layout/Sidebar.svelte +++ b/src/lib/components/layout/Sidebar.svelte @@ -11,7 +11,10 @@ showSidebar, mobile, showArchivedChats, - pinnedChats + pinnedChats, + pageSkip, + pageLimit, + scrollPaginationEnabled } from '$lib/stores'; import { onMount, getContext, tick } from 'svelte'; @@ -49,6 +52,12 @@ let showDropdown = false; let filteredChatList = []; + let paginationScrollThreashold = 0.6; + let nextPageLoading = false; + let tagView = false; + let chatPagniationComplete = false; + + pageLimit.set(20); $: filteredChatList = $chats.filter((chat) => { if (search === '') { @@ -84,7 +93,7 @@ showSidebar.set(window.innerWidth > BREAKPOINT); await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); - await chats.set(await getChatList(localStorage.token)); + await chats.set(await getChatList(localStorage.token, $pageSkip, $pageLimit)); let touchstart; let touchend; @@ -185,7 +194,9 @@ await tick(); goto('/'); } - await chats.set(await getChatList(localStorage.token)); + await chats.set( + await getChatList(localStorage.token, 0, $pageSkip * $pageLimit || $pageLimit) + ); await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); } }; @@ -235,6 +246,9 @@ ? '' : 'invisible'}" > +