From 17e7c92ece3861e36233dccc384335a2dc5fa790 Mon Sep 17 00:00:00 2001 From: Nathan Schneider Date: Thu, 22 Oct 2026 13:32:05 -0600 Subject: [PATCH] =?UTF-8?q?manifest=20icons:=20per-build=20version=20query?= =?UTF-8?q?=20=E2=80=94=20PWA=20icon=20URLs=20are=20cached=2048h=20by=20th?= =?UTF-8?q?e=20phone=20and=20remove/re-add=20does=20not=20clear=20that=20c?= =?UTF-8?q?ache,=20so=20launchers=20kept=20rendering=20the=20previous=20bu?= =?UTF-8?q?ild's=20icon=20bytes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- patch_index.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/patch_index.py b/patch_index.py index 49fc35a..18292ae 100644 --- a/patch_index.py +++ b/patch_index.py @@ -69,14 +69,21 @@ try: mf["description"] = "Member-governed AI inference — private and renewable model choices." # Deterministic icon list: explicit any/maskable entries (no dual-purpose # values — some Firefox Android versions mishandle "any maskable"), and - # the launcher-suitable sizes first. + # the launcher-suitable sizes first. Each src carries a per-build version + # query: PWA icon URLs are served with max-age=172800, and removing/re-adding + # the PWA does NOT clear the phone's HTTP cache — without the query, launchers + # keep rendering the PREVIOUS build's icon bytes ("my icon never changes"). + ver = str(int(time.time())) + def _v(src: str) -> str: + return f"{src}?v={ver}" + mf["icons"] = [ - {"src": "assets/icon-192x192.png", "sizes": "192x192", "type": "image/png", "purpose": "any"}, - {"src": "assets/maskable-icon.png", "sizes": "512x512", "type": "image/png", "purpose": "any"}, - {"src": "assets/maskable-icon.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable"}, - {"src": "assets/apple-touch-icon-180x180.png", "sizes": "180x180", "type": "image/png"}, - {"src": "assets/favicon-32x32.png", "sizes": "32x32", "type": "image/png"}, - {"src": "assets/favicon-16x16.png", "sizes": "16x16", "type": "image/png"}, + {"src": _v("assets/icon-192x192.png"), "sizes": "192x192", "type": "image/png", "purpose": "any"}, + {"src": _v("assets/maskable-icon.png"), "sizes": "512x512", "type": "image/png", "purpose": "any"}, + {"src": _v("assets/maskable-icon.png"), "sizes": "512x512", "type": "image/png", "purpose": "maskable"}, + {"src": _v("assets/apple-touch-icon-180x180.png"), "sizes": "180x180", "type": "image/png"}, + {"src": _v("assets/favicon-32x32.png"), "sizes": "32x32", "type": "image/png"}, + {"src": _v("assets/favicon-16x16.png"), "sizes": "16x16", "type": "image/png"}, ] open(MPATH, "w", encoding="utf-8").write(_json.dumps(mf, indent=2)) print("manifest: co-op identity set")