feat(ui): add audio player component, presign API route, and reading progress tracking

This commit is contained in:
Admin
2026-03-02 21:41:20 +05:00
parent 6bf79ab392
commit 4f84bd29c9
4 changed files with 252 additions and 2 deletions

View File

@@ -0,0 +1,26 @@
import { json, error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { presignAudio } from '$lib/server/minio';
/**
* GET /api/presign/audio?slug=...&n=...&voice=...&speed=...
* Returns a presigned MinIO URL for the audio file so the browser
* can stream it directly without going through the server.
*/
export const GET: RequestHandler = async ({ url }) => {
const slug = url.searchParams.get('slug');
const n = parseInt(url.searchParams.get('n') ?? '', 10);
const voice = url.searchParams.get('voice') ?? undefined;
const speed = parseFloat(url.searchParams.get('speed') ?? '1') || 1;
if (!slug || !n || n < 1) {
error(400, 'Missing slug or n');
}
try {
const presignedUrl = await presignAudio(slug, n, voice, speed);
return json({ url: presignedUrl });
} catch (e) {
error(500, `Could not get presigned URL: ${e}`);
}
};

View File

@@ -0,0 +1,19 @@
import { json, error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { setProgress } from '$lib/server/pocketbase';
/**
* POST /api/progress
* Body: { slug: string, chapter: number }
* Records the user's reading position for the current session.
*/
export const POST: RequestHandler = async ({ request, locals }) => {
const body = await request.json().catch(() => null);
if (!body || typeof body.slug !== 'string' || typeof body.chapter !== 'number') {
error(400, 'Invalid body — expected { slug, chapter }');
}
await setProgress(locals.sessionId, body.slug, body.chapter);
return json({ ok: true });
};