[backend/web-api] Add pagination to timeline and user note endpoints

This commit is contained in:
Laura Hausmann 2023-12-11 23:18:19 +01:00
parent a168e4ec03
commit d1aa541a53
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
5 changed files with 29 additions and 17 deletions

View file

@ -2,20 +2,20 @@ import type { SelectQueryBuilder } from "typeorm";
export function makePaginationQuery<T>( export function makePaginationQuery<T>(
q: SelectQueryBuilder<T>, q: SelectQueryBuilder<T>,
sinceId?: string, minId?: string,
untilId?: string, maxId?: string,
sinceDate?: number, sinceDate?: number,
untilDate?: number, untilDate?: number,
) { ) {
if (sinceId && untilId) { if (minId && maxId) {
q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: sinceId }); q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: minId });
q.andWhere(`${q.alias}.id < :untilId`, { untilId: untilId }); q.andWhere(`${q.alias}.id < :untilId`, { untilId: maxId });
q.orderBy(`${q.alias}.id`, "DESC"); q.orderBy(`${q.alias}.id`, "DESC");
} else if (sinceId) { } else if (minId) {
q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: sinceId }); q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: minId });
q.orderBy(`${q.alias}.id`, "ASC"); q.orderBy(`${q.alias}.id`, "ASC");
} else if (untilId) { } else if (maxId) {
q.andWhere(`${q.alias}.id < :untilId`, { untilId: untilId }); q.andWhere(`${q.alias}.id < :untilId`, { untilId: maxId });
q.orderBy(`${q.alias}.id`, "DESC"); q.orderBy(`${q.alias}.id`, "DESC");
} else if (sinceDate && untilDate) { } else if (sinceDate && untilDate) {
q.andWhere(`${q.alias}.createdAt > :sinceDate`, { q.andWhere(`${q.alias}.createdAt > :sinceDate`, {

View file

@ -12,9 +12,11 @@ export class TimelineController {
@Flow([AuthorizationMiddleware()]) @Flow([AuthorizationMiddleware()])
async getHomeTimeline( async getHomeTimeline(
@CurrentUser() me: ILocalUser, @CurrentUser() me: ILocalUser,
@Query('limit') limit: number = 20,
@Query('replies') replies: boolean = true, @Query('replies') replies: boolean = true,
@Query('limit') limit: number = 20,
@Query('max_id') maxId?: string,
@Query('min_id') minId?: string,
): Promise<TimelineResponse> { ): Promise<TimelineResponse> {
return TimelineHandler.getHomeTimeline(me, limit, replies); return TimelineHandler.getHomeTimeline(me, replies, limit, maxId, minId);
} }
} }

View file

@ -19,9 +19,11 @@ export class UserController {
async getUserNotes( async getUserNotes(
@CurrentUser() me: ILocalUser | null, @CurrentUser() me: ILocalUser | null,
@Params('id') id: string, @Params('id') id: string,
@Query('limit') limit: number = 20,
@Query('replies') replies: boolean = false, @Query('replies') replies: boolean = false,
@Query('limit') limit: number = 20,
@Query('max_id') maxId?: string,
@Query('min_id') minId?: string,
): Promise<TimelineResponse> { ): Promise<TimelineResponse> {
return UserHandler.getUserNotes(me, id, limit, replies); return UserHandler.getUserNotes(id, replies, me, limit, maxId, minId);
} }
} }

View file

@ -15,8 +15,12 @@ import { generateRepliesQuery } from "@/server/api/common/generate-replies-query
import { generateMutedUserRenotesQueryForNotes } from "@/server/api/common/generated-muted-renote-query.js"; import { generateMutedUserRenotesQueryForNotes } from "@/server/api/common/generated-muted-renote-query.js";
export class TimelineHandler { export class TimelineHandler {
public static async getHomeTimeline(me: ILocalUser, limit: number, replies: boolean): Promise<TimelineResponse> { public static async getHomeTimeline(me: ILocalUser, replies: boolean, limit: number, maxId: string | undefined, minId: string | undefined): Promise<TimelineResponse> {
const query = makePaginationQuery(Notes.createQueryBuilder('note')) const query = makePaginationQuery(
Notes.createQueryBuilder('note'),
minId,
maxId
)
.innerJoinAndSelect("note.user", "user") .innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("note.reply", "reply") .leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote") .leftJoinAndSelect("note.renote", "renote")

View file

@ -10,11 +10,15 @@ import { notFound } from "@hapi/boom";
import { NoteHandler } from "@/server/api/web/handlers/note.js"; import { NoteHandler } from "@/server/api/web/handlers/note.js";
export class UserHandler { export class UserHandler {
public static async getUserNotes(me: ILocalUser | null, id: string, limit: number, replies: boolean): Promise<TimelineResponse> { public static async getUserNotes(id: string, replies: boolean, me: ILocalUser | null, limit: number, maxId: string | undefined, minId: string | undefined): Promise<TimelineResponse> {
const user = await Users.findOneBy({ id }); const user = await Users.findOneBy({ id });
if (!user) throw notFound('No such user'); 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 }) .andWhere("note.userId = :userId", { userId: id })
.innerJoinAndSelect("note.user", "user") .innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("note.reply", "reply") .leftJoinAndSelect("note.reply", "reply")