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) => (
+
)}