Spaces:
Running on Zero
Running on Zero
File size: 3,494 Bytes
38bd54a 78cc96f 38bd54a 78cc96f 38bd54a d6ca3a2 38bd54a 78cc96f 38bd54a 78cc96f 38bd54a 78cc96f 38bd54a 78cc96f 38bd54a 78cc96f 38bd54a 78cc96f 38bd54a 78cc96f 38bd54a 3f78ea8 38bd54a 78cc96f 38bd54a 78cc96f 38bd54a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | """
HearthNet PWA Enhancement
Adds Progressive Web App support to the Gradio UI:
- Service worker for offline caching
- Web app manifest for installability
- Push notifications support
"""
from pathlib import Path
from fastapi import FastAPI
from fastapi.responses import FileResponse
def setup_pwa(app: FastAPI, static_dir: Path) -> None:
"""
Set up PWA support for HearthNet Gradio UI.
Args:
app: FastAPI application instance
static_dir: Directory where PWA files are served from
"""
# Serve manifest.json
@app.get("/manifest.json")
async def get_manifest():
manifest_path = Path(__file__).parent / "manifest.json"
if manifest_path.exists():
return FileResponse(manifest_path, media_type="application/manifest+json")
# Fallback manifest
return {
"name": "HearthNet",
"short_name": "HearthNet",
"description": "Local-first community AI mesh",
"start_url": "/",
"display": "standalone",
"theme_color": "#1e40af",
"background_color": "#ffffff",
"icons": [
{
"src": "/static/icon-192.png",
"sizes": "192x192",
"type": "image/png",
}
],
}
# Serve service worker
@app.get("/sw.js")
async def get_service_worker():
sw_path = Path(__file__).parent / "sw.js"
if sw_path.exists():
return FileResponse(sw_path, media_type="application/javascript")
return {"error": "Service worker not found"}
# Inject PWA meta tags into HTML
@app.middleware("http")
async def inject_pwa_headers(request, call_next):
response = await call_next(request)
# Only modify HTML responses
if "text/html" in response.headers.get("content-type", ""):
# Read body
body = b""
async for chunk in response.body_iterator:
body += chunk
# Inject PWA tags
pwa_tags = """
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#1e40af">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="HearthNet">
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then(reg => {
console.log('[PWA] Service Worker registered', reg);
}).catch(err => {
console.warn('[PWA] Service Worker registration failed:', err);
});
}
</script>
"""
# Insert before </head>
if b"</head>" in body:
body = body.replace(b"</head>", pwa_tags.encode() + b"</head>", 1)
# Create new response with modified content
from starlette.responses import Response as StarletteResponse
response = StarletteResponse(
content=body,
status_code=response.status_code,
headers=dict(response.headers),
media_type=response.media_type,
)
return response
print("✅ PWA support enabled")
print(" - Manifest: /manifest.json")
print(" - Service Worker: /sw.js")
print(" - Installable from mobile browsers")
__all__ = ["setup_pwa"]
|