Skip to content

feat: PWA Install + Offline Support#2

Draft
Jasper-Ben wants to merge 3 commits into
mbentancour:mainfrom
Jasper-Ben:add_pwa_support
Draft

feat: PWA Install + Offline Support#2
Jasper-Ben wants to merge 3 commits into
mbentancour:mainfrom
Jasper-Ben:add_pwa_support

Conversation

@Jasper-Ben

Copy link
Copy Markdown
Contributor

Hi @mbentancour,

I have been working on progressive web app support.

General idea: Ability to add babytracker as PWA App to Phone and Desktop devices makes it easier to use without dedicated mounted screen (as in your setup). Also using PWA we can have limited offline support, with the app writing pending changes to a local cache and replaying the change once connection to the server has been restored. This improves usage on mobile devices where network accesss might be limited.

I am not yet confident that everything works 100% as expected (therefore draft), but there are a few things I'd like to discuss, also since you released new changes since I've started working on this:

  1. For PWA we need multiple icons in different resolutions. I have taken the liberty of taking your existing icon and let AI create a SVG roughly based on your icon. If you have a better idea, I am all ears 🙂

  2. For E2E tests my feature fork introduces playwright (https://playwright.dev/). Since I started working on this you have added tests via a different test suite. Do you see a conflict here? I haven't looked into your changes in detail yet.

Thanks!

Completed slices:
- S01: App Manifest + Icons + Install Prompt
- S02: Service Worker + IndexedDB Caching
- S03: Offline Write Queue + Reconnect
- S04: Offline UI + Integration

Completed tasks:
- S01/T01: Installed sharp 0.34.5 and vite-plugin-pwa 1.0.0, generated 192px/512px PNG icons from SVG source including maskable variant
- S01/T02: Configured VitePWA plugin in vite.config.js, created InstallPrompt component with Android banner + iOS hint, and registered it in App.jsx
- S01/T03: Verified build pipeline produces valid manifest.webmanifest, service worker, and registerSW.js with 20/20 checks passed
- S01/T04: Playwright smoke tests covering PWA manifest, icons, service worker, iOS meta tags, InstallPrompt component, and beforeinstallprompt event — 36/36 passed across Chromium, Firefox, and WebKit
- S02/T01: Installed idb-keyval and created cache wrapper module with all required exports
- S02/T02: Added Workbox runtime caching: NetworkOnly for gallery/photos paths, NetworkFirst for API GET with 24h cache
- S02/T03: Created offline status store with dual detection (navigator.onLine + fetch-failure ring buffer) and reactive useOfflineStatus React hook
- S02/T04: Added 19 Playwright smoke tests across 4 S02 test suites covering SW runtime caching, IndexedDB cache module, offline status store, and offline data serving
- S03/T01: Created IndexedDB-backed write queue module with 10 exported functions for offline persistence and replay of POST/PUT/DELETE operations
- S03/T02: Integrated write queue into API layer with offline interception and automatic reconnect replay
- S03/T03: Created useFailedWrites React hook and FailedWritesList component with queueSubscribe observer pattern for reactive write queue state in React
- S03/T04: Add Playwright tests for write queue, replay, and failure marking
- S04/T01: Created OfflineBanner React component with amber offline and green reconnecting states, styled with fixed-position CSS banner
- S04/T02: Wired OfflineBanner and WriteQueueIndicator into Dashboard header/layout, passed isOffline to GalleryTab
- S04/T03: Wired isOffline prop into GalleryTab: upload button disabled + shows offline text, empty gallery displays distinct offline message with reconnecting hint
- S04/T04: Added i18n translations for offline messaging (already present) and wrote Playwright browser test for offline UI

Milestone: M001 - PWA Install + Offline Support
GSD-Milestone: M001
Branch: milestone/M001
@Jasper-Ben Jasper-Ben marked this pull request as draft July 8, 2026 09:13
@mbentancour

Copy link
Copy Markdown
Owner

Hi @Jasper-Ben,

Thanks for creating this PR, I will look at it later and provide feedback. It's a big PR so it might take me a bit of time.

I'm happy to add features that I might missed, I initially built it for myself since I didn't know if anyone else would actually use it, but I'm glad you took the time to improve it :)

The conflicting test suites are unfortunate (you had no way of knowing I was already working on a different one), we'll probably have to pick one going forward. We can see what makes sense, I don't have a strong preference for either so I'm open to choosing whatever makes the most sense.

I really appreciate the effort, I think it's a great idea that could make it useful for more people.

@Jasper-Ben

Copy link
Copy Markdown
Contributor Author

Thanks for creating this PR, I will look at it later and provide feedback. It's a big PR so it might take me a bit of time.

No worries, I understand that this is a lot of code for such a "minor" feature (although a lot of the code is just e2e testing and the package lock). From one parent to another I would also totally understand if you'd say it's too much of an effort to review right now.

Again, right now I am not sure the code in this PR is mature enough (I successfully installing the PWA in Chromium on Linux but haven't done any manual tests on offline capabilities or other Browsers/Operating Systems yet) and I wouldn't have opened this PR yet if you hadn't just added the test suite.

I'm happy to add features that I might missed, I initially built it for myself since I didn't know if anyone else would actually use it, but I'm glad you took the time to improve it :)

Awesome project! Just the level of over-engineering that I like! (Didn't even have to write my own helm chart) 😉

I stumbled upon this repo by total chance while trying to chase down a non-existent, AI-hallucinated open source Android app with the same name (which is probably why my first thought went to PWA. Same problem, different approach - Wall mounted monitor vs. phone app).

I also have a few more potential improvements, some of them "urgent" (really just one I think) for my own use-case others more of a "nice-to-have", but I will open separate issues on these. They are probably also way smaller in scale than this feature. So don't be surprised if I add some more PRs 🙂

Stop the install prompt from re-appearing after the user dismisses
it by storing the dismissal state in localStorage. The component
checks this flag on mount and skips showing the Android beforeinstallprompt
banner or iOS hint if the user already dismissed.

Also persists state when the user accepts the install action. Includes
3 unit tests for the persistence behavior.
@mbentancour

Copy link
Copy Markdown
Owner

Ha! Good to hear that you appreciate the level of over engineering. There are a few features that are really overkill (encryption on remote backups, DNS management, granular RBAC, etc) but I couldn't help myself :D

Was the urgent one #3 ? It's released now, I took the liberty to make some changes before merging, I hope you don't mind.

Cheers!

@Jasper-Ben

Copy link
Copy Markdown
Contributor Author

Ha! Good to hear that you appreciate the level of over engineering. There are a few features that are really overkill (encryption on remote backups, DNS management, granular RBAC, etc)

love it! Was also considering adding s3 compatible storage support & HA

Was the urgent one #3 ? It's released now, I took the liberty to make some changes before merging, I hope you don't mind.

jup, exactly. Thanks! Was following along the changes, LGTM 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants