From f8e6c2c970712a88c8ea9f76a0c00d78b8d57c63 Mon Sep 17 00:00:00 2001 From: lobo Date: Fri, 25 Sep 2026 15:32:55 +0200 Subject: [PATCH] feat(pwa): make the app installable Manifest, gamepad icon (also the new favicon, instead of the Vite logo), iOS meta tags and the tab title ToBePlayed. No service worker, so a deploy never meets an old cached bundle. The title bar color follows light and dark mode. The README also lists adding a game by name. --- README.md | 4 ++- index.html | 9 +++++- nginx.conf | 6 ++++ public/apple-touch-icon.png | Bin 0 -> 5194 bytes public/favicon.svg | 11 +++++++- public/icon-192.png | Bin 0 -> 7175 bytes public/icon-512.png | Bin 0 -> 23341 bytes public/icon-maskable-512.png | Bin 0 -> 18630 bytes public/manifest.webmanifest | 16 +++++++++++ src/context/PreferencesContext.jsx | 4 +++ src/context/PreferencesContext.test.jsx | 35 ++++++++++++++++++++++++ src/pwa.test.js | 35 ++++++++++++++++++++++++ 12 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 public/apple-touch-icon.png create mode 100644 public/icon-192.png create mode 100644 public/icon-512.png create mode 100644 public/icon-maskable-512.png create mode 100644 public/manifest.webmanifest create mode 100644 src/context/PreferencesContext.test.jsx create mode 100644 src/pwa.test.js diff --git a/README.md b/README.md index d70e0ce..1a080ee 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ To Be Played is split into three repositories: priority first, reroll without repeats, and "Start playing" in one click. - **Library**: status filters, "short games" filter (up to 10 h), search, sorting by playtime, recently seen, newest in library, rating or priority, paging. Each row shows the unlocked achievements. +- **Add a game by name** for games outside Steam (PlayStation, Switch, Xbox, physical): search IGDB, pick a hit, + a platform and optional hours. Works without a Steam ID. - **Game detail**: status, priority, 1–5 star rating, notes, achievements, time to beat (story / extras / 100 %), a hint when Steam shows recent playtime for a game still in the backlog, and one to set the status to 100 % when every achievement is unlocked. @@ -34,6 +36,7 @@ To Be Played is split into three repositories: - **Appearance**: accent color, corner style, wide layout, page background and banner from your own game art. Saved in Auth, so it follows you to every device. - German and English, dark mode, mobile layout, session-expired message instead of a silent logout. +- **Installable** as an app on phone and desktop (web app manifest, no service worker, so no offline mode). - **Session**: the tokens are HttpOnly cookies that no script can read. `apiFetch` renews an expired access token once and sends the request again; parallel requests and other tabs share one refresh. @@ -88,7 +91,6 @@ npm run build - Mood filter for "What to play next". - A Content Security Policy in `nginx.conf`. -- Installable PWA. ## License diff --git a/index.html b/index.html index b9eb454..e56ab60 100644 --- a/index.html +++ b/index.html @@ -3,8 +3,15 @@ + + + + + + + - Game Log + ToBePlayed
diff --git a/nginx.conf b/nginx.conf index 575f511..022f911 100644 --- a/nginx.conf +++ b/nginx.conf @@ -7,6 +7,12 @@ server { add_header Cache-Control "public, max-age=31536000, immutable"; } + # Not in every nginx mime.types; browsers expect this type for the PWA manifest. + location = /manifest.webmanifest { + types { application/manifest+json webmanifest; } + add_header Cache-Control "no-cache"; + } + # index.html and /i18n/*.json keep their names across deploys. Without # no-cache the browser shows old translation keys or loads an old bundle. location / { diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..af52f7cb87c81848ef17354d35de2e91c9ce26b9 GIT binary patch literal 5194 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 NN5fFPT-7o1e*k7N{f__u literal 0 HcmV?d00001 diff --git a/public/favicon.svg b/public/favicon.svg index 6893eb1..2ffe218 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1 +1,10 @@ - \ No newline at end of file + + + + + + + + + + diff --git a/public/icon-192.png b/public/icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..ac4040bd064165dd782af15f58649ebde6241f6a GIT binary patch literal 7175 zcmZ`;cTf{fuuejN(3Gb1V(21WL$6W9N_s8AM?Csv&&V4&~`)&NwCt5U=tdsx%fJXa~y215`{;xsEu6qN# z8#w?#3(!_qH3|T3SyCVwzfE2)aK{S9YJwxycM@!{>i1t}@)l~}|DoQuw5Fwz%w)B9 zBfx61Q&_?PvU=DSkzrAcSUd7L`N_C)0FKg!BO)T}g8c1!O;O90b z%-a$7KS85_xFm!V&h52c>f{`(2?5V@U%LD19!>%LJ~n}l!1Un7)m+8dkKRhdU6$Mv zy&i=-6jD!Y-hgEFkxPKXFN^JoHuCM&S3J>x|JKplaT*8IBV2F+>TSskFB0kzN_f-- zapUY+Hg#yVuEu3fGC-iG@l+#Aw&eOmQ*#?emY^5eyvuhX$5nA_=FTg0Hn>DMVvxvc zZx^6pJN{c3i0vWg<)LJ?TI1f(?Btx95*Ie3B6 zUBr?e=;Au^Lm`GQ(#oQ8id}ANlaK?m1HR8Y;F!<(7iOcBIYerWmql2rwdBU4_2>3+_f!qpkDhTobKw>Fw`hf zJz@wum0x-DBSeFH1Tr&o;Zl*s7m>UI_gm#vxtso5WP~&}4W978nhrt&^5dP6<`|Yu z8q`59r(mq+vmSeA{&3UaHh{#XC&o_Y-k41q)j=BdPdI`cMAG!M@9$3xy+}kB+q;&C zeqX(M4sL0i^C43Y4qq2|0$FAyMM2T9H*GqNC#iHC z7Y@#-BWsLhdS1+p7aiALnt-qGeP#)Fg$bJL)dSZ(e0b%Pa`_Bwmx4?_`Y0*t4h1B+ z4UKF~cxZ5EL+&RW-3M-^?-fF^E0p%L*KuTc4Ve?W5h-OoKnC(jcyW;oG;O#{cSM>N z&CI7FT5?}G8!HFQq>mgEN zQK#-E1)7fA{jyv+0Z9e2q(8P%p&)>=hWc&*F=0L2w+umjHJuZ8is)>%1Z;}IL>5zH zCOWX&7S0~<45VJtIicG{mnNDG_#7F=7_l0UD+PXq^lBE_R2<(8C?$@hvYl7p9+doS=sui2j7aLpHjBx?9;CGlkzYrS9 zNtu)cS~f&f_j>~b&H{cFv4xcG_SuZ>lJu46N-$NpyrTj7?U1tXOA*RaAvIwZ;zaju z|1pxUKe#^ckZ&20G%hF^AsFH$4!z3e|JRn#LZ&;Kdr#(6t$3U>!iYoXQ@w!7i4uD7 zgkm&Y({tuqq~-bR1`ajb3HNi7SnInj1hekqMMztiBI65E7j-uZwAIC7EUA+s|I89r zMI!0beqk)hnl2qRYP@&euEWJ>3xfS{%kwA4qp{7(8%d6C?%PI4*#~|>0hnEI|2&u$ z2dJ!w+c2do?iJl?LM|w0CLmeXbWUWScpfjQoaZVkGqZt=LaCVdwN%%vSpTWg)eldD z9~R#3b9P831%7Sg@*KKAqc|d6f+q7+i??sw-lPCXj4f;YmEQ-ica$M$+5X`grwY5^ z5s#{7f6<_J9x8;_c5@jamw)1dg1en>2cuL)-+C|Sm}@yu)Fmt8 zqy`EXJ=z~ScXzq-iJv$UxD1hRPk>_coV)5=e>P)l0h`aWZY%YL5l(*+#lA=We5{oX zh@DF`|8}fYR12_Tb``%gjbi)iOvJK~rCPg-`!;qzZvH0!L+k8}@Mr4ef_mqV2l00` zSzk%6=f(ty%OIw=Q|+xoA)?cLpSiP88-dJ0AKn^a#k5OqX4b z{8OvAWhKO=?3+_l<=_Az1T9Ts#Ap_R@XAlyPk>>Pnx3=N-F#wHXN!V1h2am>AC9x7 zf{xhmnh}EYZ#d;a_ktc1SIomBH`dcZN(QY(iejVWs&alLXY8py3(uz8QXgHK8k&jp zWzMvj*1ytcD)$^vj|6n=A!04(0T#y*dGI?zWM`KGYuR$dBr?h6?6}23$5-8@qWwkO%F$ia-)h{5nsa6hhpY?avCVs+0MQjuxA5V5*$KlhJ*tUiT-ax#X z@UjgxQe@a#~D~;q^qQwX`rL z$AmmXaiv9GtJ$r5BdE;e<;w*WPuh%Ter78kHQaxEHb(_F8DaF?!|z%O$s9V(K#%H8 zf(!08s%0X~3+42Scw6vOKm2LA-B)=A^ye$x=W@R0S-Y>;HKW~ItJUq^H((ji!%y2> zv@bDB3%z0t>{35rDSWrX$=^O&un!aZ!{h}vOHJJQwA)JRey4Tv2D8(abJyb+!X1n6 z1&~a%R1a>9g@>Q#?@McTeR;OmbiAfO&bTqJTwj*97$&K#BwC=W8I?0CY*>o_Ujq}d z?>DV?KY|T_sj}O4^M9+U{KWKc>dW;n!*c65cxWiY#$mezMi*DE~<9E;oQ) zfqp2%-C@Ux#s)hM-cSU>%T!#IZ|K zeLazr^Pf*X$z>GZR3*d<({L&zkLj_E%r9#K(ox7md|TajH2FInejA0 z_>IvQ$~0A$&%;_~&&R?l8iT%JU?d&BAJHBaUPVAa?J4a0$$9f*r(QW+a7%K*e%7P+ z0{_9bY23iQEx4O91X5nqzv1?vcl8?b;AeSk*+A%Dsvq&%a|jGXEB3aIhZ zRJU_VV#;VI?P-j(NtH!o+%3OG%;WO>1o1YGkge(@JSGFCXAdc!-)Wb};EvTtZ+ ze^(Z%$dmtn%Lpcz)h2z$>5ux>yL$BUvvj^nSm4^sMr^~Fu=ZCt5x{ku9% zHQ!dBz*6&@hUdjSe&}E;5CIa}(UXnae%{S)+ur_WVsG-TQ{^!>Kh4Otw%@jVSJ*lD zFr48Aj_$M>wP@+xFbJR^-tr%a?3lN?SVJpYgD-{BxdbE7P93#k6OmYhd1T_9!Dgi#OG z%gyHxM5?=@G|`XC#!=Ldv5cD@FSU@cZG6rBpL<6|dmfGqYpn%A+!t6%lNc)K_8gN9 zM^$CRLaZN95CEX6`;Q9%S;-Z^w&!sT_^_B9!1jDGWFH_?L<&EyJ9&oI_NS}~HSt`z z*G+0jsvN40HvSd)XyUt^>GXqLNXx|E=@hVeVih`f|T{6-$qt272dp z29D+MDY>+mW#DeJ9n?Jr=XAM{V9AuV>-1ck8^Uy&+(`gt0&IX9!+!1c5d~bYWZ`M3n66vYSgwEmd?7z`$E!@kcdTBtTY+h1P zV29I?Mv)bTpK5u$ZcqBV@?<^AvwsLn7U2Ol-_e=B{JI8qHTTO zg1-^$so4HydTD=KW)>Ot(kh zF>GTW^ltN=Y|XKR4YSN7xrWnR#<296inV#;2;VcfQqDVnkv~D3jg?BuD{8ucW*mY- zGpBa1RyjVR2Wd+<{aC+mzCL`FLcX47J+;-4(_Y#%jK}@7tWa>ah1^lv zca}g@3+JX*?Hb)@V$C%`T0)5QS8aS&1@o2Uq_;etGBd5{rH_(=cFpMWwYa_cmN{;`4>BG>X^ zUF$D?w2#NDexN<+H@u+V5Lk7rx0B?%@cWzjcEnY#jvSFD@MeBM1rR~3NPPUc$W1>z zNTlCbE~R~tEl??7(1IfnlS`=a8x@e5UrT^H+%#%KqrN-Dqr$8|dU5YtLuR0(?xRlIJ z;_!&fEsm}p`l2tT+3Mup@0mE^nTzdTJyS;J&_gh{idfPSjIvIb-*@W+RC83s5-oBng%SxNamK-_ggJ%n9wx=zlHl=Uxv=UAtlMeQY-ThXaVZys?Ln;bYZK#h4F_SyNx7jU<>Uw&st6w`DzUN@jvP+J3x&(%bc8- zxC(CAOj#^IPiYKc`^$SStF~r<7WssTnmZ?F9SN*a;OQ>Al4QPOAQ`PS3(x$i6;2)| zg|=Dwuy1oTDn-+;wGyB*IOg}68<_Aas%(<~CeW(mJNQhrD#l}upp0sfdipJJHN0GZ zmE`1*{B{=yJH@F|1CzT%z#%mHGSdkbeVw%>F^qeVhm9{DkHVfx1%`#Z%6#khr8_!f zNI8bsds!;i;<6Ab0HQYN3U>0NcZqtp_lJmzbm;WI`5Rn z38P%h9o|gn=^I%egmoSNu0x{^Q+C;~{RRjNrJJYotsxJSIV|1SGAnA|tnla|sXbp6 zl7w9-l6>Xa>?}XNPhfhh7}M3-Gdn_2XGl6~Yr8fQGpufGw*sAUC8hcL)9GwygQ|9@ z>--)uHj(C0$w`sF2#b5GDJ?gNL@kqo_t$Qkb5>$7MiD?!PyGHmI6;P#(6D+H0?ZBM zA`;({NgqGRmAlK{{J`NKYYSPIM%Lnay8F8LU5uB2mdA0&?k6%!S zg-58$E~v3IUL_y(CjeOb1Byq`;XAL%phQRSE;%%zZGr#7pjF!mSImWYT5sVi_4+j- zFG6|JP8C{W-O`)`tp7c%%1j)ae>v86A^VQJMU;qn0}xHAOoFOhvoY$bhF>&PD6npM zRvZG?q|Arn@>ysx_$5lunx((@c_lr!o5+Xb%v(S{6|-McLp`sN|Gy+clD@bq%-Jyk z$pE4tsq%hfbVq~x1w{OqLEMy8s%wJdn#l#So#%sufOvvI`RSdy33{|3@b`4xMmhrs zL$BgPxg2dQq-GAwza|XzA@p(}73J@A5ny^>3hh4-EIXTZDC&BqxgVedpo+QlD1_Y8 ztC9{FW)7BY3ljyXlZpz;NsD@$4!%?~Iik%)FTtc=m=LAkDox zd)R!=#koD&8?w zw+D`rNqw&MZ-OLWGj*|^e<207*lU2A(d!qgeQJhPw5Kv0I6e4W0-&o<*g7GdPH*|J zj0tQ6^MO3lc`b#?V@2Hp{sj59^rwIhe&Wuw=;Gu+WWL9XiUa%C6f5sN>m+!FhSe9w zh=DscPWMeDO24oaW&s#=rv@E@&3)*b9|(bdXrOgn;#Rgemw5r-OltM>9m~{SwNz`< z#j%6PUj3BF?GR3x}Kav2neiTlg<-)8T%RF>bBB%3kG7eG`rc-HtdXKYte z@&DP}0%F$V0)K}{M@azz67gAo%F{R*A1c3BM{^#Q+D}AzQQT}GbgFGm4FJUh79PuH z8G}JuXbi7?hQ!7vQGIZ+-Gc7nPKfLf8joJg%WxM0WvQX@1J|T^P!n1TXxjZT?JWJk zoSI=^@c1Ms@30H{lma{@MW!|4Dv>E+mITzG<2HQeU8t)wIsD#Fr%@)OY%xK_j8@!q zWX7I4+rU~IZ1b%P&MhTfQc^1s5Y=_6uvkiQLhz%;We zBa3IXsYPd1+ev#+mERFF^XG^B+l#Ym2yMjcT=8j~l>9{>W(dM2mBg__B}w`OnY5?< z=&qSSZAz7^*U>;=e5W*PIsL#2#->g0h(-3oof9&HT(lX#pYi4~GgT4=nc~p{F!}(N4uy_E^GDM_trIWBfSG3Ty zeqPk98_Kp#BpL3C^A*RnEEEcw$?2oMs9trZ`+Bq4-$^Z0@xQpP-(6iXA)|z^%Xwt~ c{oP3be20D%8E5fr*AjrX#uN1#HJix)0a^vBtN;K2 literal 0 HcmV?d00001 diff --git a/public/icon-512.png b/public/icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..97b0dff57df1d45ec51ddfd2cc8f99ae81a77dc5 GIT binary patch literal 23341 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 import('../test/i18n-mock.js')); + +let preferences; +function Spy() { + preferences = usePreferences(); + return null; +} + +const themeColor = () => document.querySelector('meta[name="theme-color"]').content; + +beforeEach(() => { + document.head.innerHTML = ''; +}); + +afterEach(() => { + cleanup(); + localStorage.clear(); +}); + +describe('PreferencesProvider theme color', () => { + it('gives the installed app a light title bar in light mode and a dark one again in dark mode', () => { + localStorage.setItem('tbp_dark_mode', 'false'); + render(); + + expect(themeColor()).toBe('#fafafa'); + + act(() => preferences.setDarkMode(true)); + expect(themeColor()).toBe('#09090b'); + }); +}); diff --git a/src/pwa.test.js b/src/pwa.test.js new file mode 100644 index 0000000..0ff0341 --- /dev/null +++ b/src/pwa.test.js @@ -0,0 +1,35 @@ +import {readFileSync} from 'node:fs'; +import path from 'node:path'; +import {describe, expect, it} from 'vitest'; + +const root = path.resolve(import.meta.dirname, '..'); +const read = (file) => readFileSync(path.join(root, file)); +const manifest = JSON.parse(read('public/manifest.webmanifest')); + +// Width and height sit at bytes 16-23 of every PNG. +const pngSize = (file) => { + const png = read(path.join('public', file)); + return `${png.readUInt32BE(16)}x${png.readUInt32BE(20)}`; +}; + +describe('PWA manifest', () => { + it('links every icon to a PNG of the size it claims', () => { + for (const icon of manifest.icons) { + expect(pngSize(icon.src)).toBe(icon.sizes); + } + }); + + it('has the icons Chrome needs to offer the install', () => { + const sizes = manifest.icons.filter((icon) => icon.purpose === 'any').map((icon) => icon.sizes); + expect(sizes).toEqual(expect.arrayContaining(['192x192', '512x512'])); + expect(manifest.display).toBe('standalone'); + expect(manifest.icons.some((icon) => icon.purpose === 'maskable')).toBe(true); + }); + + it('is linked from index.html together with the iOS icon', () => { + const html = read('index.html').toString(); + expect(html).toContain(''); + expect(html).toContain(''); + expect(pngSize('apple-touch-icon.png')).toBe('180x180'); + }); +});