Als App installierbar (Web-Manifest, Vollbild) und Vollbild-Rückholung im Lesemodus

- Manifest mit Icons, display fullscreen; Backend liefert statische Dateien
  des Frontends direkt aus.
- Nach dem Sperren des Handys holt das nächste Umblättern das Vollbild zurück.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
team3
2026-10-09 18:29:38 +02:00
parent 48cf53db9c
commit 2067f0615f
6 changed files with 32 additions and 2 deletions

View File

@@ -190,4 +190,8 @@ if config.FRONTEND_DIST.exists():
async def spa(pfad: str):
if pfad.startswith("api/"):
raise HTTPException(404, "Unbekannter API-Pfad")
# Statische Dateien des Frontends (Manifest, Icons) direkt ausliefern, alles andere ist die App
datei = (config.FRONTEND_DIST / pfad).resolve()
if pfad and datei.is_file() and config.FRONTEND_DIST.resolve() in datei.parents:
return FileResponse(datei)
return FileResponse(config.FRONTEND_DIST / "index.html")

View File

@@ -4,6 +4,10 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>buchwerk</title>
<link rel="manifest" href="/manifest.webmanifest" />
<meta name="theme-color" content="#000000" />
<meta name="mobile-web-app-capable" content="yes" />
<link rel="apple-touch-icon" href="/icons/icon-192.png" />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' rx='7' fill='%237a5b2c'/><path d='M8 8h7a3 3 0 0 1 3 3v13a2 2 0 0 0-2-2H8zM24 8h-7a3 3 0 0 0-3 3v13a2 2 0 0 1 2-2h8z' fill='%23f8f1de'/></svg>" />
</head>
<body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,16 @@
{
"name": "buchwerk",
"short_name": "buchwerk",
"description": "Sachbücher lesen",
"lang": "de",
"start_url": "/",
"scope": "/",
"display": "fullscreen",
"orientation": "portrait",
"background_color": "#000000",
"theme_color": "#000000",
"icons": [
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any maskable" },
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
]
}

View File

@@ -46,13 +46,19 @@ function html(s) {
return cache.get(key)
}
function vor() { if (pos.value < screens.value.length - 1) pos.value++ }
// Nach dem Sperren des Handys ist das Vollbild weg; ein Tippen darf es wieder anfordern. Als installierte App unnötig.
function vollbildHolen() {
if (document.fullscreenElement || !document.documentElement.requestFullscreen) return
if (matchMedia('(display-mode: fullscreen), (display-mode: standalone)').matches) return
document.documentElement.requestFullscreen().catch(() => {})
}
function vor() { vollbildHolen(); if (pos.value < screens.value.length - 1) pos.value++ }
// Von vorn: auch die Buchansicht zurücksetzen, sonst zöge sie den Lesemodus wieder nach hinten
async function vonVorn() {
await api.positionSetzen(props.slug, props.version, { abschnitt: 'vorwort', lesemodus: 'vorwort', zuletzt: 'lesen' }).catch(() => {})
pos.value = 0
}
function zurueck() { if (pos.value > 0) pos.value-- }
function zurueck() { vollbildHolen(); if (pos.value > 0) pos.value-- }
let merkTimer = null
watch(pos, (p) => {
buehne.value?.scrollTo({ top: 0 })