Files
indiekit-endpoint-activitypub/lib/controllers/following.js
Ricardo 25513c7ea5 feat: add breadcrumb navigation across all ActivityPub UI pages
Document.njk pages (followers, following, activities, featured, tags,
profile, migrate) get parent breadcrumbs via the upstream heading
component. Reader pages (explore, notifications, compose, moderation,
tag timeline, post detail, remote profile, my profile) get a new
breadcrumb nav bar in ap-reader.njk layout.
2026-02-27 12:10:31 +01:00

61 lines
1.7 KiB
JavaScript

/**
* Following list controller — paginated list of accounts this actor follows.
*/
const PAGE_SIZE = 20;
export function followingController(mountPath) {
return async (request, response, next) => {
try {
const { application } = request.app.locals;
const collection = application?.collections?.get("ap_following");
if (!collection) {
return response.render("activitypub-following", {
title: response.locals.__("activitypub.following"),
parent: { href: mountPath, text: response.locals.__("activitypub.title") },
following: [],
followingCount: 0,
mountPath,
});
}
const page = Math.max(1, Number.parseInt(request.query.page, 10) || 1);
const totalCount = await collection.countDocuments();
const totalPages = Math.ceil(totalCount / PAGE_SIZE);
const following = await collection
.find()
.sort({ followedAt: -1 })
.skip((page - 1) * PAGE_SIZE)
.limit(PAGE_SIZE)
.toArray();
const cursor = buildCursor(page, totalPages, mountPath + "/admin/following");
response.render("activitypub-following", {
title: `${totalCount} ${response.locals.__("activitypub.following")}`,
parent: { href: mountPath, text: response.locals.__("activitypub.title") },
following,
followingCount: totalCount,
mountPath,
cursor,
});
} catch (error) {
next(error);
}
};
}
function buildCursor(page, totalPages, basePath) {
if (totalPages <= 1) return null;
return {
previous: page > 1
? { href: `${basePath}?page=${page - 1}` }
: undefined,
next: page < totalPages
? { href: `${basePath}?page=${page + 1}` }
: undefined,
};
}