fix(pwa): serve Mila app icons from public /icons/ path for iOS SpringBoard and PWA manifests
This commit is contained in:
@@ -11,36 +11,36 @@
|
||||
"theme_color": "#090A0F",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/family/mila-icon-192-v3.png",
|
||||
"src": "/icons/mila-icon-192-v3.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/family/mila-icon-192-v3.png",
|
||||
"src": "/icons/mila-icon-192-v3.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/family/mila-icon-512-v3.png",
|
||||
"src": "/icons/mila-icon-512-v3.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/family/mila-icon-512-v3.png",
|
||||
"src": "/icons/mila-icon-512-v3.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/family/mila-apple-touch-icon-v3.png",
|
||||
"src": "/icons/mila-apple-touch-icon-v3.png",
|
||||
"sizes": "180x180",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/family/mila-icon.svg",
|
||||
"src": "/icons/mila-icon.svg",
|
||||
"sizes": "any",
|
||||
"type": "image/svg+xml"
|
||||
}
|
||||
|
||||
@@ -712,36 +712,36 @@ def generate_dashboard_html(engine: DatastoreEngine) -> str:
|
||||
"theme_color": "#090A0F",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/family/mila-icon-192-v3.png",
|
||||
"src": "/icons/mila-icon-192-v3.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/family/mila-icon-192-v3.png",
|
||||
"src": "/icons/mila-icon-192-v3.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/family/mila-icon-512-v3.png",
|
||||
"src": "/icons/mila-icon-512-v3.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/family/mila-icon-512-v3.png",
|
||||
"src": "/icons/mila-icon-512-v3.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/family/mila-apple-touch-icon-v3.png",
|
||||
"src": "/icons/mila-apple-touch-icon-v3.png",
|
||||
"sizes": "180x180",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/family/mila-icon.svg",
|
||||
"src": "/icons/mila-icon.svg",
|
||||
"sizes": "any",
|
||||
"type": "image/svg+xml"
|
||||
}
|
||||
@@ -767,16 +767,16 @@ def generate_dashboard_html(engine: DatastoreEngine) -> str:
|
||||
<meta name="theme-color" content="#090A0F">
|
||||
<meta name="msapplication-TileColor" content="#090A0F">
|
||||
|
||||
<link rel="manifest" href="/family/mila.webmanifest" crossorigin="use-credentials">
|
||||
<link rel="apple-touch-icon" href="/family/mila-apple-touch-icon-v3.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/family/mila-apple-touch-icon-v3.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/family/mila-icon-192-v3.png">
|
||||
<link rel="icon" type="image/png" sizes="512x512" href="/family/mila-icon-512-v3.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/family/mila-icon-32-v3.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/family/mila-icon-16-v3.png">
|
||||
<link rel="shortcut icon" href="/family/favicon.ico">
|
||||
<link rel="icon" href="/family/favicon.ico">
|
||||
<link rel="icon" type="image/svg+xml" href="/family/mila-icon.svg">
|
||||
<link rel="manifest" href="/icons/mila.webmanifest">
|
||||
<link rel="apple-touch-icon" href="/icons/mila-apple-touch-icon-v3.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/icons/mila-apple-touch-icon-v3.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/icons/mila-icon-192-v3.png">
|
||||
<link rel="icon" type="image/png" sizes="512x512" href="/icons/mila-icon-512-v3.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/icons/mila-icon-32-v3.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/icons/mila-icon-16-v3.png">
|
||||
<link rel="shortcut icon" href="/icons/favicon.ico">
|
||||
<link rel="icon" href="/icons/favicon.ico">
|
||||
<link rel="icon" type="image/svg+xml" href="/icons/mila-icon.svg">
|
||||
|
||||
<!-- Typography & Styling -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
@@ -807,7 +807,7 @@ def generate_dashboard_html(engine: DatastoreEngine) -> str:
|
||||
<div id="pwa-install-banner" class="hidden max-w-4xl mx-auto px-4 pt-3">
|
||||
<div class="flex items-center justify-between p-3 rounded-2xl bg-gradient-to-r from-purple-900/80 via-pink-900/50 to-zinc-900 border border-purple-500/40 shadow-xl backdrop-blur-md">
|
||||
<div class="flex items-center gap-3">
|
||||
<img src="/family/mila-icon-192-v3.png" alt="Mila" class="w-9 h-9 rounded-xl object-cover shadow-md border border-purple-500/40">
|
||||
<img src="/icons/mila-icon-192-v3.png" alt="Mila" class="w-9 h-9 rounded-xl object-cover shadow-md border border-purple-500/40">
|
||||
<div>
|
||||
<p class="text-xs font-bold text-white">Mila App installieren</p>
|
||||
<p class="text-[11px] text-zinc-300">Direkt auf dem Homescreen nutzen</p>
|
||||
@@ -844,7 +844,7 @@ def generate_dashboard_html(engine: DatastoreEngine) -> str:
|
||||
<div class="max-w-4xl mx-auto flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-2xl bg-gradient-to-tr from-purple-600 via-pink-500 to-teal-400 p-0.5 shadow-lg shadow-purple-500/20 overflow-hidden flex items-center justify-center">
|
||||
<img src="/family/mila-icon-192-v3.png" alt="Mila" class="w-full h-full object-cover rounded-[14px]">
|
||||
<img src="/icons/mila-icon-192-v3.png" alt="Mila" class="w-full h-full object-cover rounded-[14px]">
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -1418,12 +1418,14 @@ def publish_to_s3(html_content: str, data_dir: Optional[Path] = None) -> str:
|
||||
candidates = [assets_dir / fname]
|
||||
if data_dir:
|
||||
candidates.append(data_dir.parent / "public" / "family" / fname)
|
||||
candidates.append(data_dir.parent / "public" / "icons" / fname)
|
||||
body_bytes = None
|
||||
for candidate in candidates:
|
||||
if candidate.is_file():
|
||||
body_bytes = candidate.read_bytes()
|
||||
break
|
||||
if body_bytes:
|
||||
# 1. Upload to family/ (for backward compatibility / scoped access)
|
||||
try:
|
||||
s3.put_object(
|
||||
Bucket=DEFAULT_BUCKET,
|
||||
@@ -1435,6 +1437,19 @@ def publish_to_s3(html_content: str, data_dir: Optional[Path] = None) -> str:
|
||||
except Exception as ex:
|
||||
print(f"Warning: could not upload family/{fname}: {ex}", file=sys.stderr)
|
||||
|
||||
# 2. Upload to public icons/ prefix (unauthenticated access for iOS SpringBoard and PWA manifests)
|
||||
if fname.startswith("mila-") or fname in ("favicon.ico", "mila.webmanifest"):
|
||||
try:
|
||||
s3.put_object(
|
||||
Bucket=DEFAULT_BUCKET,
|
||||
Key=f"icons/{fname}",
|
||||
Body=body_bytes,
|
||||
ContentType=ctype,
|
||||
CacheControl=cache_ctrl,
|
||||
)
|
||||
except Exception as ex:
|
||||
print(f"Warning: could not upload icons/{fname}: {ex}", file=sys.stderr)
|
||||
|
||||
url = f"{DEFAULT_BASE_URL}/family/mila.html"
|
||||
return url
|
||||
|
||||
@@ -1459,6 +1474,21 @@ def main():
|
||||
out_file.write_text(html, encoding="utf-8")
|
||||
print(f"✅ Saved locally: {out_file}")
|
||||
|
||||
# Ensure public/icons directory exists and is populated locally too
|
||||
wiki_public_icons = data_dir.parent / "public" / "icons"
|
||||
wiki_public_icons.mkdir(parents=True, exist_ok=True)
|
||||
assets_dir = SCRIPT_DIR.parent / "assets"
|
||||
for asset in assets_dir.glob("mila-*"):
|
||||
dest = wiki_public_icons / asset.name
|
||||
if not dest.exists() or dest.stat().st_size != asset.stat().st_size:
|
||||
dest.write_bytes(asset.read_bytes())
|
||||
for extra in ["favicon.ico", "mila.webmanifest"]:
|
||||
src = assets_dir / extra
|
||||
if src.is_file():
|
||||
dest = wiki_public_icons / extra
|
||||
if not dest.exists() or dest.stat().st_size != src.stat().st_size:
|
||||
dest.write_bytes(src.read_bytes())
|
||||
|
||||
# 2. Upload to S3 hosting
|
||||
if not args.skip_upload:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user