From 4a7ef5cc29eb8120864137c5e9ae2d5de1a1bb09 Mon Sep 17 00:00:00 2001 From: shinalok Date: Mon, 20 Jul 2026 15:34:19 +0900 Subject: [PATCH] improve PWA feel on iOS: offline fallback, overscroll, tap feedback, dark status bar, apple touch icon Add offline.html served by the service worker when a never-visited route is requested without network. Disable rubber-band overscroll bounce and gray tap highlights so standalone mode feels less like a webview. Split theme-color by prefers-color-scheme so the iOS status bar matches dark mode, and add a proper 180x180 apple-touch-icon instead of downscaling the 192px icon. --- app/static/css/style.css | 5 +++++ app/static/icons/icon-apple-180.png | Bin 0 -> 857 bytes app/static/offline.html | 23 +++++++++++++++++++++++ app/static/service-worker.js | 6 ++++-- app/templates/base.html | 5 ++++- scripts/generate_icons.py | 2 ++ 6 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 app/static/icons/icon-apple-180.png create mode 100644 app/static/offline.html diff --git a/app/static/css/style.css b/app/static/css/style.css index 1b0e993..30fd1f8 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -46,6 +46,7 @@ * { box-sizing: border-box; + -webkit-tap-highlight-color: transparent; } [x-cloak] { @@ -56,6 +57,7 @@ html, body { margin: 0; padding: 0; + overscroll-behavior-y: none; } body { @@ -239,6 +241,7 @@ p { text-decoration: none; color: var(--color-text-muted); font-size: 11px; + touch-action: manipulation; } .bottom-tab-bar .tab-item svg { @@ -277,6 +280,7 @@ p { cursor: pointer; font-family: inherit; transition: background-color 0.15s ease, opacity 0.15s ease; + touch-action: manipulation; } .btn-primary { @@ -452,6 +456,7 @@ label { gap: 8px var(--space-2); padding: 12px 4px; border-bottom: 1px solid var(--color-border); + touch-action: manipulation; } .habit-item:last-child { diff --git a/app/static/icons/icon-apple-180.png b/app/static/icons/icon-apple-180.png new file mode 100644 index 0000000000000000000000000000000000000000..f85dc10a46582417a888fe6a373a70fb544af24b GIT binary patch literal 857 zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD4M^IaWiw)6U{>&SaSW-L^Y+fg+}j2s4i}fa z(23K$t0KE_ammt(nIeC6CaG=o?fi1pa{ey^j>k;`E-!8O+1T&3b2zg7CU?U`7T>M~ zo`NQtO=_+emT=4xah$A_5j4<(r@r6hPLN(6zyE%W_5VK;|L=Z#fxYwR;@7H8eU`OC zxwcu3?Q`}?WLsuAy2nVp)Rfw~fO%D6ob!cpzcc@ZzQ_uHj&9l)oK!b|0l(B|%c>Jf zFRYcH^>hB}>-bsRv`;wcpOn73tirS6FLgg{%U&Gq{Att_H)Dpr`U}_2pH@wA6K1Se ze{r93?b3D` zFyq@M$Mt3fu4jIGu%9=PzP&ZDt8!n=h0Tk^K1)q{Yb&1%o8@2j#xVacU$G#aUG>>pS-lsLiJg`5?L1ZQ z4;(hU=X#n73&?+sg5)O@G7DJ@bxFf4=Q~od>P`b)1 TsiNQm%rXp~u6{1-oD!M + + + + + 오프라인 - 습관 트래커 + + + + +
+
+

+ 오프라인 상태예요. 이 화면은 아직 캐시에 저장되지 않았어요. +

+

+ 네트워크 연결을 확인한 뒤 다시 시도해주세요. +

+ +
+
+ + diff --git a/app/static/service-worker.js b/app/static/service-worker.js index 1da5d7e..7f4c777 100644 --- a/app/static/service-worker.js +++ b/app/static/service-worker.js @@ -1,4 +1,4 @@ -const CACHE_NAME = "habit-tracker-v3"; +const CACHE_NAME = "habit-tracker-v4"; const APP_SHELL = [ "/static/css/style.css", "/static/js/app.js", @@ -9,7 +9,9 @@ const APP_SHELL = [ "/static/js/vendor/sortable.min.js", "/static/icons/icon-192.png", "/static/icons/icon-512.png", + "/static/icons/icon-apple-180.png", "/static/manifest.json", + "/static/offline.html", ]; self.addEventListener("install", (event) => { @@ -50,7 +52,7 @@ self.addEventListener("fetch", (event) => { } return response; }) - .catch(() => caches.match(request)) + .catch(() => caches.match(request).then((cached) => cached || caches.match("/static/offline.html"))) ); return; } diff --git a/app/templates/base.html b/app/templates/base.html index 2e0d1d3..d3019d1 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -6,10 +6,12 @@ {% block title %}습관 트래커{% endblock %} - + + + @@ -37,6 +39,7 @@ {% if current_user %}