From ba60448d05def078e3e5e648e29c93ac9eee1595 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Sun, 16 Aug 2026 16:06:25 +0700 Subject: [PATCH] feat(frontend): load older messages in Messages view (cursor pagination) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wire the existing useLoadMore + useMessagesHasMore pagination hooks into the Messages view: add a "↑ Load older messages" button at the top of the list and auto-load the next (older) page when the user scrolls to the top. Backend messages.list already returns a created_at-based nextCursor (DESC order), so older pages are just subsequent cursors. Newest-first live feed is preserved; the load-older control is hidden during search. --- .../src/app/(dashboard)/messages/view.tsx | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/services/frontend/src/app/(dashboard)/messages/view.tsx b/services/frontend/src/app/(dashboard)/messages/view.tsx index 0cd1af6..0215e92 100644 --- a/services/frontend/src/app/(dashboard)/messages/view.tsx +++ b/services/frontend/src/app/(dashboard)/messages/view.tsx @@ -27,9 +27,11 @@ import { } from "@/components/shared"; import { GuildChannelPicker } from "@/components/shared/guild-picker"; import { + useLoadMore, useMessageDetail, useMessageSearch, useMessages, + useMessagesHasMore, useMessagesWsSync, } from "@/hooks"; import { @@ -82,6 +84,11 @@ export function MessagesView({ isLoading, error, } = useMessages(guildId ?? "", channelId ?? undefined); + // Cursor to the next (older) page + whether more history exists. + const { data: pageInfo } = useMessagesHasMore(guildId ?? "", channelId ?? undefined); + const nextCursor = pageInfo?.cursor ?? null; + const hasMore = pageInfo?.hasMore ?? false; + const loadMore = useLoadMore(); useMessagesWsSync(ws, guildId ?? ""); const search = useMessageSearch(query, query.trim().length >= 2); const detail = useMessageDetail(selected); @@ -141,8 +148,49 @@ export function MessagesView({ description="Pick a guild to begin, or run a search." /> ) : ( -
- {list.map((m) => ( +
+ {!searching && ( +
+ {hasMore ? ( + + ) : ( + messages && + messages.length > 0 && ( + + beginning of history + + ) + )} +
+ )} +
{ + // Auto-load older messages when the user scrolls to the top. + if (searching || !hasMore || loadMore.isPending) return; + if (e.currentTarget.scrollTop <= 8) { + loadMore.mutate({ + guildId: guildId ?? "", + channelId: channelId ?? undefined, + cursor: nextCursor ?? "", + }); + } + }} + > + {list.map((m) => (
+
)}