feat: per-source .md sidecar toggles, Picdrop folder-list diagnostic, fast JPEG fullscreen preview + thumb-first, thumbnail backfill

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNQ8ghPfzAfsyVYd6HgFb6
This commit is contained in:
tillandClaude Opus 4.8 committed 2026-07-24 07:56:57 +00:00
1 parent 5f0c33e44b
commit 32f06297a6
12 files changed
+161 -44

No files matched your search

+11 -4
View File
@@ -1,4 +1,5 @@
import type { APIRoute } from 'astro';
import sharp from 'sharp';
import { one } from '../../../../lib/db';
import { getObject } from '../../../../lib/storage';
@@ -28,13 +29,19 @@ export const GET: APIRoute = async ({ params, url, locals }) => {
: item?.result_path;
if (!path) return new Response('Nicht gefunden', { status: 404 });
try {
const buf = await getObject(path);
let buf = await getObject(path);
const download = q.get('download') === '1';
const isWebp = path.endsWith('.webp');
let contentType = path.endsWith('.webp') ? 'image/webp' : 'image/png';
// Schnelle Vollbild-Vorschau: nicht-transparente Ergebnisse als JPEG (deutlich kleiner,
// schneller auf Mobil) — reicht fürs „In Fotos sichern". Der PNG-Download bleibt unverändert.
if (q.get('preview') === '1' && !download && !item?.has_alpha) {
try { buf = await sharp(buf, { failOn: 'none' }).jpeg({ quality: 90, mozjpeg: true }).toBuffer(); contentType = 'image/jpeg'; }
catch { /* Fallback: Original */ }
}
return new Response(buf, {
headers: {
'Content-Type': isWebp ? 'image/webp' : 'image/png',
'Cache-Control': 'private, max-age=300',
'Content-Type': contentType,
'Cache-Control': 'private, max-age=600',
...(download ? { 'Content-Disposition': `attachment; filename="${item.filename || 'klarbild.png'}"` } : {}),
},
});