feat(pwa): Add icons and a scan shortcut to the PWA app shortcuts#128
Conversation
Changes: - Add scripts/generate-shortcut-icons.mjs, rendering the nav's own lucide components to 192x192 PNGs on a rounded white tile - Give every manifest shortcut an icon and an accessible description - Add a "Skeniraj" shortcut at /?scan=1, served by a new ScanShortcut component that opens the scanner modal and routes the code to its product - Switch launch_handler to navigate-existing, since focus-existing only focused the window and left the url to an unconsumed launchQueue - Match the scanner's camera reset button to the modal footer's, icon-only - Document app shortcuts in PWA.md and their icons in BRAND.md - Flag the Karta and Digitalne kartice follow-up with TODO(#127) The shortcuts had no artwork at all, so the long-press menu showed bare labels next to Chrome's own Site settings entry. Notes: - Chrome accepts PNG only for shortcut icons, hence the generator rather than reusing the brand SVGs. - Android shows 3 shortcuts (Chrome 92 took a fourth slot for Site settings), so array order decides what a phone surfaces. See #127. - Android caches the WebAPK; reinstall the PWA to see the new icons.
❌ Deploy Preview for disscount failed. Why did it fail? →
|
|
Warning Review limit reached
Next review available in: 9 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (8)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The PWA app shortcuts had no
iconsmember at all, so long-pressing the installed icon showed bare labels. This adds artwork, a Skeniraj shortcut, and fixes alaunch_handlervalue that was quietly breaking every shortcut.Icons
manifest.tsbuiltshortcutsfromuserNavItemsbut only ever emittedname,short_nameandurl.Chrome accepts PNG only for shortcut icons, so the brand SVGs cannot be linked. New generator
frontend/scripts/generate-shortcut-icons.mjsfollows the same one-off pattern asgenerate-pwa-icons.mjsand needs no new dependency:sharpwas already a devDependency,react-domandlucide-reactalready dependencies.It renders the same
lucide-reactcomponent the nav uses throughrenderToStaticMarkup, then rasterizes with sharp. Rendering the component rather than copying a path is what stops a shortcut icon from drifting away from its nav icon.Output is 192x192, brand green on a rounded white tile, glyph at 52% so a launcher's circular mask cannot clip it. The rounding is for desktop, where Chrome and Edge draw jump-list icons unmasked and a hard square would read as a blank block.
manifest.tsderives eachsrcfrom the nav item'sid, so dropping acomingSoonflag wires a shortcut up by itself. Each shortcut also gains adescription, which browsers hand to assistive tech and which was missing entirely.The Skeniraj shortcut
The scanner is imperative (
context/scanner-context.tsx) and has no route, so the shortcut points at/?scan=1. A newcomponents/custom/pwa/scan-shortcut.tsxreads the flag through the existinguseClientSearchParams, strips it withreplaceStatebefore opening the camera (so a refresh or a back navigation does not reopen it), and routes the scanned code through the existinguseProductNavigation.Deliberately not
?modal=scan: the?modal=params are durable, shareable modal state, which is wrong for a camera. This is a one-shot launch intent.It is first in the array. Chrome for Android shows 3 shortcuts (it allowed 4 until Chrome 92 started injecting its own "Site settings" entry, which takes a slot), and scanning is the fastest path from launcher to a price. Desktop shows up to 10.
/?scan=1ScanBarcode/shopping-listsListChecks/watchlistEyeBug found on the way:
launch_handlerlaunch_handlerwas{ client_mode: "focus-existing" }. Per the spec, that focuses an already-open window without navigating, and hands the target url towindow.launchQueuefor the app to handle. Nothing in this codebase consumeslaunchQueue.So launching any shortcut while the PWA was already open did nothing at all. That silently affected Popisi and Praćenje, and very likely
/share-targettoo.Changed to
navigate-existing, which still reuses the open window (the original comment's stated intent) but actually navigates to the url. Happy to split this out if it should not ride along.Also here
icon/iconPlacementform. Kept icon-only at every width with its tooltip, per review feedback.docs/PWA.mdgains an App shortcuts section (slot math, the icon pipeline, why Skeniraj needs a url flag), a correctedlaunch_handlerrow, key-file entries, and two gotchas: thefocus-existingtrap above, and the fact that Android caches the WebAPK so manifest changes need a reinstall.docs/BRAND.mdnotes that shortcut icons are the deliberate exception to "everything derives from the cart".TODO(#127)on thedigital-cardsandmapnav entries.Follow-up
#127 tracks adding Karta and Digitalne kartice once they ship. It is really a "pick the final three" decision rather than an append, since six candidates will eventually compete for three Android slots. It also records the trap that Kartice will appear by itself when its flag drops, pointing at a PNG that does not exist yet.
Verification
tsc --noEmiteslint srcprettier --checksrc,scripts,docsAlso confirmed directly that
Slottablewith undefined children renders on React 19.2.8, since a self-closing<Button icon=... />is a new shape for this repo.Not verified: the runtime scan flow, since the dev server is not mine to run. Worth a click-through of
/?scan=1, and a reinstall on a phone to see the icons.