[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>(
q: SelectQueryBuilder<T>,
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`, {

View file

@ -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<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(
@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<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";
export class TimelineHandler {
public static async getHomeTimeline(me: ILocalUser, limit: number, replies: boolean): Promise<TimelineResponse> {
const query = makePaginationQuery(Notes.createQueryBuilder('note'))
public static async getHomeTimeline(me: ILocalUser, replies: boolean, limit: number, maxId: string | undefined, minId: string | undefined): Promise<TimelineResponse> {
const query = makePaginationQuery(
Notes.createQueryBuilder('note'),
minId,
maxId
)
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")

View file

@ -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<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 });
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")