From d1aa541a53a63aa78333034d97b37d4e2fd5ebb8 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Mon, 11 Dec 2023 23:18:19 +0100 Subject: [PATCH] [backend/web-api] Add pagination to timeline and user note endpoints --- .../server/api/common/make-pagination-query.ts | 18 +++++++++--------- .../src/server/api/web/controllers/timeline.ts | 6 ++++-- .../src/server/api/web/controllers/user.ts | 6 ++++-- .../src/server/api/web/handlers/timeline.ts | 8 ++++++-- .../src/server/api/web/handlers/user.ts | 8 ++++++-- 5 files changed, 29 insertions(+), 17 deletions(-) diff --git a/packages/backend/src/server/api/common/make-pagination-query.ts b/packages/backend/src/server/api/common/make-pagination-query.ts index a2c327569..5a19c08d5 100644 --- a/packages/backend/src/server/api/common/make-pagination-query.ts +++ b/packages/backend/src/server/api/common/make-pagination-query.ts @@ -2,20 +2,20 @@ import type { SelectQueryBuilder } from "typeorm"; export function makePaginationQuery( q: SelectQueryBuilder, - sinceId?: string, - untilId?: string, + minId?: string, + maxId?: string, sinceDate?: number, untilDate?: number, ) { - if (sinceId && untilId) { - q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: sinceId }); - q.andWhere(`${q.alias}.id < :untilId`, { untilId: untilId }); + if (minId && maxId) { + q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: minId }); + q.andWhere(`${q.alias}.id < :untilId`, { untilId: maxId }); q.orderBy(`${q.alias}.id`, "DESC"); - } else if (sinceId) { - q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: sinceId }); + } else if (minId) { + q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: minId }); q.orderBy(`${q.alias}.id`, "ASC"); - } else if (untilId) { - q.andWhere(`${q.alias}.id < :untilId`, { untilId: untilId }); + } else if (maxId) { + q.andWhere(`${q.alias}.id < :untilId`, { untilId: maxId }); q.orderBy(`${q.alias}.id`, "DESC"); } else if (sinceDate && untilDate) { q.andWhere(`${q.alias}.createdAt > :sinceDate`, { diff --git a/packages/backend/src/server/api/web/controllers/timeline.ts b/packages/backend/src/server/api/web/controllers/timeline.ts index 3e1e24df6..3f83f739d 100644 --- a/packages/backend/src/server/api/web/controllers/timeline.ts +++ b/packages/backend/src/server/api/web/controllers/timeline.ts @@ -12,9 +12,11 @@ export class TimelineController { @Flow([AuthorizationMiddleware()]) async getHomeTimeline( @CurrentUser() me: ILocalUser, - @Query('limit') limit: number = 20, @Query('replies') replies: boolean = true, + @Query('limit') limit: number = 20, + @Query('max_id') maxId?: string, + @Query('min_id') minId?: string, ): Promise { - return TimelineHandler.getHomeTimeline(me, limit, replies); + return TimelineHandler.getHomeTimeline(me, replies, limit, maxId, minId); } } diff --git a/packages/backend/src/server/api/web/controllers/user.ts b/packages/backend/src/server/api/web/controllers/user.ts index bf5e4c2a4..0e167e5da 100644 --- a/packages/backend/src/server/api/web/controllers/user.ts +++ b/packages/backend/src/server/api/web/controllers/user.ts @@ -19,9 +19,11 @@ export class UserController { async getUserNotes( @CurrentUser() me: ILocalUser | null, @Params('id') id: string, - @Query('limit') limit: number = 20, @Query('replies') replies: boolean = false, + @Query('limit') limit: number = 20, + @Query('max_id') maxId?: string, + @Query('min_id') minId?: string, ): Promise { - return UserHandler.getUserNotes(me, id, limit, replies); + return UserHandler.getUserNotes(id, replies, me, limit, maxId, minId); } } diff --git a/packages/backend/src/server/api/web/handlers/timeline.ts b/packages/backend/src/server/api/web/handlers/timeline.ts index 02693cf92..502f5a67a 100644 --- a/packages/backend/src/server/api/web/handlers/timeline.ts +++ b/packages/backend/src/server/api/web/handlers/timeline.ts @@ -15,8 +15,12 @@ import { generateRepliesQuery } from "@/server/api/common/generate-replies-query import { generateMutedUserRenotesQueryForNotes } from "@/server/api/common/generated-muted-renote-query.js"; export class TimelineHandler { - public static async getHomeTimeline(me: ILocalUser, limit: number, replies: boolean): Promise { - const query = makePaginationQuery(Notes.createQueryBuilder('note')) + public static async getHomeTimeline(me: ILocalUser, replies: boolean, limit: number, maxId: string | undefined, minId: string | undefined): Promise { + const query = makePaginationQuery( + Notes.createQueryBuilder('note'), + minId, + maxId + ) .innerJoinAndSelect("note.user", "user") .leftJoinAndSelect("note.reply", "reply") .leftJoinAndSelect("note.renote", "renote") diff --git a/packages/backend/src/server/api/web/handlers/user.ts b/packages/backend/src/server/api/web/handlers/user.ts index fdbdfbd85..0e8feb7f5 100644 --- a/packages/backend/src/server/api/web/handlers/user.ts +++ b/packages/backend/src/server/api/web/handlers/user.ts @@ -10,11 +10,15 @@ import { notFound } from "@hapi/boom"; import { NoteHandler } from "@/server/api/web/handlers/note.js"; export class UserHandler { - public static async getUserNotes(me: ILocalUser | null, id: string, limit: number, replies: boolean): Promise { + public static async getUserNotes(id: string, replies: boolean, me: ILocalUser | null, limit: number, maxId: string | undefined, minId: string | undefined): Promise { const user = await Users.findOneBy({ id }); if (!user) throw notFound('No such user'); - const query = makePaginationQuery(Notes.createQueryBuilder('note')) + const query = makePaginationQuery( + Notes.createQueryBuilder('note'), + minId, + maxId + ) .andWhere("note.userId = :userId", { userId: id }) .innerJoinAndSelect("note.user", "user") .leftJoinAndSelect("note.reply", "reply")