nsfwapp/backend/preview_status_svg.go
2026-02-06 10:28:46 +01:00

87 lines
2.9 KiB
Go

package main
import (
"html"
"net/http"
"strings"
)
func servePreviewStatusSVG(w http.ResponseWriter, label string, status int) {
w.Header().Set("Content-Type", "image/svg+xml; charset=utf-8")
w.Header().Set("Cache-Control", "no-store")
w.Header().Set("X-Content-Type-Options", "nosniff")
if status <= 0 {
status = http.StatusOK
}
title := html.EscapeString(strings.TrimSpace(label))
if title == "" {
title = "Preview"
}
// 16:9 (passt zu deinen Cards)
svg := `<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" preserveAspectRatio="xMidYMid slice">
<defs>
<!-- Subtle gradient background -->
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="rgba(99,102,241,0.10)"/>
<stop offset="1" stop-color="rgba(14,165,233,0.08)"/>
</linearGradient>
<!-- Soft vignette -->
<radialGradient id="vig" cx="50%" cy="45%" r="75%">
<stop offset="0" stop-color="rgba(0,0,0,0)"/>
<stop offset="1" stop-color="rgba(0,0,0,0.18)"/>
</radialGradient>
<!-- Card shadow -->
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="0" dy="6" stdDeviation="8" flood-color="rgba(0,0,0,0.18)"/>
</filter>
</defs>
<!-- base -->
<rect x="0" y="0" width="320" height="180" rx="18" fill="rgba(17,24,39,0.06)"/>
<rect x="0" y="0" width="320" height="180" rx="18" fill="url(#bg)"/>
<rect x="0" y="0" width="320" height="180" rx="18" fill="url(#vig)"/>
<!-- inner card -->
<g filter="url(#shadow)">
<rect x="18" y="18" width="284" height="144" rx="16"
fill="rgba(255,255,255,0.72)"
stroke="rgba(0,0,0,0.08)"/>
<rect x="18" y="18" width="284" height="144" rx="16"
fill="rgba(255,255,255,0)"
stroke="rgba(99,102,241,0.18)"
stroke-width="2"
stroke-dasharray="6 6"/>
</g>
<!-- icon -->
<g transform="translate(160 70)">
<circle r="20" fill="rgba(17,24,39,0.08)" stroke="rgba(0,0,0,0.08)"/>
<!-- simple "image-off" icon -->
<path d="M-10 6 L-4 0 L2 6 L10 -2" fill="none" stroke="rgba(17,24,39,0.55)" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M-10 -6 H10" fill="none" stroke="rgba(17,24,39,0.35)" stroke-width="2.4" stroke-linecap="round"/>
<path d="M-12 12 L12 -12" fill="none" stroke="rgba(239,68,68,0.55)" stroke-width="2.6" stroke-linecap="round"/>
</g>
<!-- text -->
<text x="160" y="118" text-anchor="middle"
font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto"
font-size="16" font-weight="750"
fill="rgba(17,24,39,0.88)">` + title + `</text>
<text x="160" y="140" text-anchor="middle"
font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto"
font-size="11.5" font-weight="650"
fill="rgba(75,85,99,0.82)">Preview nicht verfügbar</text>
</svg>
`
w.WriteHeader(status)
_, _ = w.Write([]byte(svg))
}