feat(reader): chapter comments + readers-this-week count
Some checks failed
CI / Backend (push) Successful in 48s
CI / UI (push) Failing after 22s
Release / Check ui (push) Failing after 33s
Release / Docker / ui (push) Has been skipped
Release / Test backend (push) Successful in 53s
Release / Docker / caddy (push) Successful in 48s
CI / Backend (pull_request) Successful in 44s
CI / UI (pull_request) Failing after 44s
Release / Docker / runner (push) Failing after 46s
Release / Docker / backend (push) Successful in 1m54s
Release / Gitea Release (push) Has been skipped
Some checks failed
CI / Backend (push) Successful in 48s
CI / UI (push) Failing after 22s
Release / Check ui (push) Failing after 33s
Release / Docker / ui (push) Has been skipped
Release / Test backend (push) Successful in 53s
Release / Docker / caddy (push) Successful in 48s
CI / Backend (pull_request) Successful in 44s
CI / UI (pull_request) Failing after 44s
Release / Docker / runner (push) Failing after 46s
Release / Docker / backend (push) Successful in 1m54s
Release / Gitea Release (push) Has been skipped
- CommentsSection now accepts a chapter prop and scopes comments to that chapter - Chapter reader page mounts CommentsSection with current chapter number - Book detail page shows rolling 7-day unique reader count badge - API GET/POST pass chapter param; pocketbase listComments filters by chapter Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,9 +21,10 @@ export const GET: RequestHandler = async ({ params, url, locals }) => {
|
||||
const { slug } = params;
|
||||
const sortParam = url.searchParams.get('sort') ?? 'new';
|
||||
const sort: CommentSort = sortParam === 'top' ? 'top' : 'new';
|
||||
const chapter = parseInt(url.searchParams.get('chapter') ?? '0', 10) || 0;
|
||||
|
||||
try {
|
||||
const topLevel = await listComments(slug, sort);
|
||||
const topLevel = await listComments(slug, sort, chapter);
|
||||
|
||||
// Fetch replies for all top-level comments in parallel
|
||||
const repliesPerComment = await Promise.all(topLevel.map((c) => listReplies(c.id)));
|
||||
@@ -75,7 +76,7 @@ export const POST: RequestHandler = async ({ params, request, locals }) => {
|
||||
if (!locals.user) error(401, 'Login required to comment');
|
||||
|
||||
const { slug } = params;
|
||||
let body: { body?: string; parent_id?: string };
|
||||
let body: { body?: string; parent_id?: string; chapter?: number };
|
||||
try {
|
||||
body = await request.json();
|
||||
} catch {
|
||||
@@ -86,8 +87,8 @@ export const POST: RequestHandler = async ({ params, request, locals }) => {
|
||||
if (!text) error(400, 'Comment body is required');
|
||||
if (text.length > 2000) error(400, 'Comment is too long (max 2000 characters)');
|
||||
|
||||
// Enforce 1-level depth: parent_id must be a top-level comment
|
||||
const parentId = body.parent_id?.trim() || undefined;
|
||||
const chapter = typeof body.chapter === 'number' ? body.chapter : 0;
|
||||
|
||||
try {
|
||||
const comment = await createComment(
|
||||
@@ -95,7 +96,8 @@ export const POST: RequestHandler = async ({ params, request, locals }) => {
|
||||
text,
|
||||
locals.user.id,
|
||||
locals.user.username,
|
||||
parentId
|
||||
parentId,
|
||||
chapter
|
||||
);
|
||||
return json(comment, { status: 201 });
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user