From 929bfbc88259ddf08f2ad0bc13c6c63b8ab1c37b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 7 Oct 2024 22:18:06 +0300 Subject: [PATCH] web/roomview: add history pagination button --- go.mod | 2 +- go.sum | 4 ++-- web/src/api/client.ts | 19 ++++++++++++++++--- web/src/api/statestore.ts | 11 +++++++++++ web/src/api/types/hitypes.ts | 5 +++++ web/src/ui/RoomView.tsx | 1 + 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index fb82b31..fed43bd 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( go.mau.fi/util v0.8.1-0.20241003092848-3b49d3e0b9ee go.mau.fi/zeroconfig v0.1.3 maunium.net/go/mauflag v1.0.0 - maunium.net/go/mautrix v0.21.1-0.20241006181705-64692eb06e11 + maunium.net/go/mautrix v0.21.1-0.20241007191346-1d8891fdb40e ) require ( diff --git a/go.sum b/go.sum index 2b1713b..545d4b2 100644 --- a/go.sum +++ b/go.sum @@ -58,5 +58,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.21.1-0.20241006181705-64692eb06e11 h1:XhBqRfWg75OCsXxmb4uFJtHs6feq4MG9xaBWZKcMhFg= -maunium.net/go/mautrix v0.21.1-0.20241006181705-64692eb06e11/go.mod h1:+fF5qsmXRCEXQZgW5ececC0PI3c7gISHTLcyftP4Bh0= +maunium.net/go/mautrix v0.21.1-0.20241007191346-1d8891fdb40e h1:/R+hxB3+o+6iWxhBP/ibzooMF3OU0r3WRCu5m7FeKNs= +maunium.net/go/mautrix v0.21.1-0.20241007191346-1d8891fdb40e/go.mod h1:+fF5qsmXRCEXQZgW5ececC0PI3c7gISHTLcyftP4Bh0= diff --git a/web/src/api/client.ts b/web/src/api/client.ts index 649bdc8..4a77cb1 100644 --- a/web/src/api/client.ts +++ b/web/src/api/client.ts @@ -15,7 +15,7 @@ // along with this program. If not, see . import { CachedEventDispatcher } from "../util/eventdispatcher.ts" import type { - ClientWellKnown, DBEvent, EventID, EventRowID, EventType, RoomID, TimelineRowID, UserID, + ClientWellKnown, DBEvent, EventID, EventRowID, EventType, PaginationResponse, RoomID, TimelineRowID, UserID, } from "./types/hitypes.ts" import { ClientState, RPCEvent } from "./types/hievents.ts" import { RPCClient } from "./rpc.ts" @@ -59,11 +59,24 @@ export default class Client { return this.request("get_events_by_row_ids", { row_ids }) } - paginate(room_id: RoomID, max_timeline_id: TimelineRowID, limit: number): Promise { + async loadMoreHistory(roomID: RoomID): Promise { + const room = this.store.rooms.get(roomID) + if (!room) { + throw new Error("Room not found") + } + const oldestRowID = room.timeline.current[0]?.timeline_rowid + const resp = await this.paginate(roomID, oldestRowID ?? 0, 100) + if (room.timeline.current[0]?.timeline_rowid !== oldestRowID) { + throw new Error("Timeline changed while loading history") + } + room.applyPagination(resp.events) + } + + paginate(room_id: RoomID, max_timeline_id: TimelineRowID, limit: number): Promise { return this.request("paginate", { room_id, max_timeline_id, limit }) } - paginateServer(room_id: RoomID, limit: number): Promise { + paginateServer(room_id: RoomID, limit: number): Promise { return this.request("paginate_server", { room_id, limit }) } diff --git a/web/src/api/statestore.ts b/web/src/api/statestore.ts index 2dccac9..a637312 100644 --- a/web/src/api/statestore.ts +++ b/web/src/api/statestore.ts @@ -67,6 +67,17 @@ export class RoomStateStore { this.meta = new NonNullCachedEventDispatcher(meta) } + applyPagination(history: DBEvent[]) { + // Pagination comes in newest to oldest, timeline is in the opposite order + history.reverse() + const newTimeline = history.map(evt => { + this.eventsByRowID.set(evt.rowid, evt) + this.eventsByID.set(evt.event_id, evt) + return { timeline_rowid: evt.timeline_rowid, event_rowid: evt.rowid } + }) + this.timeline.emit([...newTimeline, ...this.timeline.current]) + } + applySync(sync: SyncRoom) { if (visibleMetaIsEqual(this.meta.current, sync.meta)) { this.meta.current = sync.meta diff --git a/web/src/api/types/hitypes.ts b/web/src/api/types/hitypes.ts index 190aebe..38e3a86 100644 --- a/web/src/api/types/hitypes.ts +++ b/web/src/api/types/hitypes.ts @@ -110,6 +110,11 @@ export interface DBEvent { last_edit_rowid?: EventRowID } +export interface PaginationResponse { + events: DBEvent[] + has_more: boolean +} + export interface EventUnsigned { prev_content?: unknown prev_sender?: UserID diff --git a/web/src/ui/RoomView.tsx b/web/src/ui/RoomView.tsx index eabf1d7..e00b7a7 100644 --- a/web/src/ui/RoomView.tsx +++ b/web/src/ui/RoomView.tsx @@ -29,6 +29,7 @@ const RoomView = ({ client, room }: RoomViewProps) => { const timeline = useNonNullEventAsState(room.timeline) return
{roomMeta.room_id} + {timeline.map(entry => )}