From bb3dd5ee578f480acc6837f41c521108d0a31dbc Mon Sep 17 00:00:00 2001 From: Jaime Idolpx Date: Tue, 14 Apr 2026 14:04:23 -0400 Subject: [PATCH] feat: add PWA support with service worker, manifest, and icons --- index.html | 7 +++++++ public/icon.192.png | Bin 0 -> 2185 bytes public/icon.512.png | Bin 0 -> 6136 bytes public/manifest.webmanifest | 21 +++++++++++++++++++++ public/service-worker.js | 15 +++++++++++++++ src/main.tsx | 8 ++++++++ 6 files changed, 51 insertions(+) create mode 100644 public/icon.192.png create mode 100644 public/icon.512.png create mode 100644 public/manifest.webmanifest create mode 100644 public/service-worker.js diff --git a/index.html b/index.html index 302e473..c6800a8 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,13 @@ Meatloaf Config + + + + + + + diff --git a/public/icon.192.png b/public/icon.192.png new file mode 100644 index 0000000000000000000000000000000000000000..c6b232b00c831602cc912161f9848d30c3ab6acf GIT binary patch literal 2185 zcmbtW{Xf&~7ylS@Z;PfGc_>y=RuoyqO`gIqk|9*?5u2pYkcZ0FkcZv3r|+V>7K-up zO!`KshF7DgiIAFDl&2W7MwWd)y8nak_lI+xbFS-L=XD;g*ZW-QCywKl5n2cU0F<4b z?1>=fZV*fnT#14Uzkv)M>Ess$vY`!Mo^+-1F2*nHa2#DXn0su zP+%l^e*`t;&b*}-0Kn9p?QOl{*mEP@%rj&i-r^*?!o}xE^g)dz*B-~OuZ&yrE`8?x zmF{%RCURLiy?@hsKD(+AUzDcub6}DIJ)QB-rYBEkT?$v+=t2bz9>RlfC{Pyn@ z^zy@j0g-vk$AkmVL?Ity%)R3aB*e0rlBNW4MaF$I>$}HgJEx(}A0SI&PyZoZLPGJV zXjFt$Oo~cPO(i+~aGTPT9}K88$k@ufA6H@6z2}OBg#|5l`RY_LWbo?+Z|{)q<{F8e zE?mXV1AT>4vgsaD0X88#xV#0BQ$qu#9>6U}xd1IFJ@kK91|z8Bb8{Du#w~D%>M^F> zOVs&B_j19z3({K-<|jPfR_qRXwY!)kePZbHQ}UtKi@&$5Gt7$~HdHe`Sbe(riX{AB zEp0_3BmVx6seVJXvUuSrUpAj{SSP;f+hld6i?#Gy#B1oehYB+i!jsi6v+sw8Lt`TA z0%K!+YFn2&dsBra9&#D?dpU%y;`d>-M2H~{DNEUeOtnJqsXpAs0+=Q0iJ>X(*A3({ zT}-4zrhcyn3+Q_xv@XcksJ^O0N4?9N>9QVrk#6h~&>t#v4}eU~yBh1)>5Fq{HT|`A zCm`BX__GONiwz4CVV*)-S|*#hWS0rr4^*$1OdVul4$QUd%J#pT9lD3L)uC=%ootnX zUQ3K77YI7}Hh2#Pu39TmHH6{s!FV`fwZyL$@5y0dlux!FfUdY1>!;n}ED)|IqTS)2 zf{mm^Zl&D`M$-z62Dvg;m+x>-;ZmL168}*1-elxAl%Q$RXHFzawb~XXy&;>xj;%#l z`G|T(TWBx;;IC$=5IZ0%KhET%lDAMNWb3o;gX?UjeH7U&@7OFkemKet2hBEUYp&WS zWy8a-qgI}G$z+TO#@0ahF}$mgCY{bvJYC6GAwN5LD2L)%UZA!Y5h`mit=KMU^SHp+ zdQV{_11rsqPAuyiCh>o#37T`Cu3asvpmv{+CKMI>ZjRA=w9vV02I9mD@ZQl;$kj1h z2jwCo$Mt@F4q}MC%7ebe223Pnjld8JpnCvv-S8CEDw_ z;G^^Wch3aR&CIcr1R`Lg@|3VLl|cU3Y?)^9p+*0u(GQb@tFCB3!-wkH}+ zRi^Fz-F3OB)&)Io;>r|5WN)xn?C1G*EuEN=8bK;e^LuE}i>X zr_%#`9Nvy2+JNXlz}(^~jcF!13JmCa4E7!b5JA+y833-uKqg9~rxyaH9~m~fPK>jy z7aB3OP3fk&Y(2!-_UGxEJ}EXT4Hdm@wh|JWedwwaf{yw46nm3XIQ&MOYk565&P}L2mvJr9%5_3wsmS=|*WD`3rA5 ziJ3*o>PB^K`N>z^a5*VwIew9;O~8cgGRI#r(*o|N0>mpFHkvrtg4 zzz8+GzU__d%gkY!a?foOc`leO-!MxXt91Jxi05?{8UN*0XF6L8mf&Cq3bru>c&M%% z@lfGD(AMDiMw_XEGl94Q+#w5S&3QMPRa#FQ=muJp1N)@sO(FBOStp>UAEEcMhj@ zv|l6{&0fxJa^1P~UDRA-{azqwwffsNQL20XtLiC!(cBU68v!^w9JjBr3t;>g$C~+; literal 0 HcmV?d00001 diff --git a/public/icon.512.png b/public/icon.512.png new file mode 100644 index 0000000000000000000000000000000000000000..b7158415d9424b56e20b21d0cb97cac91899efe8 GIT binary patch literal 6136 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 literal 0 HcmV?d00001 diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest new file mode 100644 index 0000000..a1be9fa --- /dev/null +++ b/public/manifest.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "Meatloaf Config", + "short_name": "Meatloaf", + "start_url": ".", + "display": "standalone", + "background_color": "#4d4d4d", + "theme_color": "#4d4d4d", + "description": "Configuration app for Meatloaf device.", + "icons": [ + { + "src": "/icon.192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/icon.512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/public/service-worker.js b/public/service-worker.js new file mode 100644 index 0000000..51d723d --- /dev/null +++ b/public/service-worker.js @@ -0,0 +1,15 @@ +self.addEventListener('install', event => { + self.skipWaiting(); +}); + +self.addEventListener('activate', event => { + event.waitUntil(self.clients.claim()); +}); + +self.addEventListener('fetch', event => { + event.respondWith( + caches.match(event.request).then(response => { + return response || fetch(event.request); + }) + ); +}); diff --git a/src/main.tsx b/src/main.tsx index eb07ffb..2a9ee59 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,7 +1,15 @@ + import { createRoot } from "react-dom/client"; import App from "./app/App.tsx"; import "./styles/index.css"; + // Register service worker for PWA installability + if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('/service-worker.js'); + }); + } + createRoot(document.getElementById("root")!).render(); \ No newline at end of file