From 564b47c21ac278141584e1d5d13174509e7aebad Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Sun, 7 Apr 2024 12:29:31 -1000 Subject: [PATCH] Fix Link header on account statuses --- server/api/api/v1/accounts/[id]/statuses.ts | 105 +++++++++++++++++--- 1 file changed, 93 insertions(+), 12 deletions(-) diff --git a/server/api/api/v1/accounts/[id]/statuses.ts b/server/api/api/v1/accounts/[id]/statuses.ts index 46269f97..e92e4c08 100644 --- a/server/api/api/v1/accounts/[id]/statuses.ts +++ b/server/api/api/v1/accounts/[id]/statuses.ts @@ -78,14 +78,61 @@ export default apiRoute<{ }, }); - // Constuct HTTP Link header (next and prev) + // Constuct HTTP Link header (next and prev) only if there are more statuses const linkHeader = []; + if (objects.length > 0) { - const urlWithoutQuery = req.url.split("?")[0]; - linkHeader.push( - `<${urlWithoutQuery}?max_id=${objects.at(-1)?.id}>; rel="next"`, - `<${urlWithoutQuery}?min_id=${objects[0].id}>; rel="prev"`, - ); + // Check if there are statuses before the first one + const objectsBefore = await client.status.findMany({ + where: { + authorId: id, + isReblog: false, + pinnedBy: { + some: { + id: user.id, + }, + }, + id: { + lt: objects[0].id, + }, + }, + take: 1, + }); + + if (objectsBefore.length > 0) { + const urlWithoutQuery = req.url.split("?")[0]; + // Add prev link + linkHeader.push( + `<${urlWithoutQuery}?max_id=${objects[0].id}>; rel="prev"`, + ); + } + + // Check if there are statuses after the last one + const objectsAfter = await client.status.findMany({ + where: { + authorId: id, + isReblog: false, + pinnedBy: { + some: { + id: user.id, + }, + }, + id: { + gt: objects.at(-1)?.id, + }, + }, + take: 1, + }); + + if (objectsAfter.length > 0) { + const urlWithoutQuery = req.url.split("?")[0]; + // Add next link + linkHeader.push( + `<${urlWithoutQuery}?min_id=${ + objects.at(-1)?.id + }>; rel="next"`, + ); + } } return jsonResponse( @@ -116,14 +163,48 @@ export default apiRoute<{ }, }); - // Constuct HTTP Link header (next and prev) + // Constuct HTTP Link header (next and prev) only if there are more statuses const linkHeader = []; if (objects.length > 0) { - const urlWithoutQuery = req.url.split("?")[0]; - linkHeader.push( - `<${urlWithoutQuery}?max_id=${objects.at(-1)?.id}>; rel="next"`, - `<${urlWithoutQuery}?min_id=${objects[0].id}>; rel="prev"`, - ); + // Check if there are statuses before the first one + const objectsBefore = await client.status.findMany({ + where: { + authorId: id, + isReblog: exclude_reblogs ? true : undefined, + id: { + lt: objects[0].id, + }, + }, + take: 1, + }); + + if (objectsBefore.length > 0) { + const urlWithoutQuery = req.url.split("?")[0]; + // Add prev link + linkHeader.push( + `<${urlWithoutQuery}?max_id=${objects[0].id}>; rel="prev"`, + ); + } + + // Check if there are statuses after the last one + const objectsAfter = await client.status.findMany({ + where: { + authorId: id, + isReblog: exclude_reblogs ? true : undefined, + id: { + gt: objects.at(-1)?.id, + }, + }, + take: 1, + }); + + if (objectsAfter.length > 0) { + const urlWithoutQuery = req.url.split("?")[0]; + // Add next link + linkHeader.push( + `<${urlWithoutQuery}?min_id=${objects.at(-1)?.id}>; rel="next"`, + ); + } } return jsonResponse(