SHA256
94 lines
5.3 KiB
Markdown
94 lines
5.3 KiB
Markdown
# Native PWA design comparison
|
||
|
||
The target is the actual unmodified Yuvomi 2.78.0 PWA, revision
|
||
`10bfef7686ed7303b4c74c7fcc55a5eb16356c9d`, not a new Material reinterpretation.
|
||
Android 0.2.2/code 4 is a design pass on the existing native slice. **No page has
|
||
accepted 1:1 visual/functional parity.** iOS has not received this Android pass.
|
||
|
||
## Implementation
|
||
|
||
`PwaDesign.kt` maps measured palette/type roles, field shapes and module seals.
|
||
`PwaIcons.kt` draws upstream module geometry on the native canvas.
|
||
`PwaShell.kt` provides the capsule/FAB and native sheets; API 31+ uses an in-memory
|
||
recorded native drawing layer for the blurred backdrop, with opaque older-API
|
||
fallback. No HTML, JavaScript or browser surface is shipped.
|
||
`NativePages.kt` / `NativeForms.kt` compose the supported native screens.
|
||
Personal preferences and shopping lists are loaded from the real API. Widget
|
||
visibility writes retain other stored widget entries/options; they are personal,
|
||
not household default edits. Entries hidden/denied to this native UI are retained;
|
||
new supported selections can be added. Saving is disabled if preference loading
|
||
did not provide a known configuration, rather than overwriting unknown data.
|
||
|
||
## Reproducible comparison
|
||
|
||
The fixture has synthetic account/data only: one task, pinned note, list/item,
|
||
four widgets (`tasks`, `calendar`, `shopping`, `notes`) and three supported mobile
|
||
favorites (`tasks`, `kitchen`, `notes`). This deliberate **supported-slice** setup
|
||
is not the PWA's complete/default dashboard or a full navigation comparison.
|
||
|
||
Native integration exports `login`, `dashboard`, `tasks`, `notes`, `shopping`, each
|
||
in light/dark, plus the compatible `native-dashboard.png` and `viewport.json`.
|
||
Capture clears `FLAG_SECURE` only in that temporary-fixture test and restores it in
|
||
`finally`. It waits for IME/window settling and crops `native-screen`, excluding
|
||
system bars. Ordinary builds remain screenshot-protected.
|
||
The collector requires the whole allow-listed gallery from exactly one device,
|
||
rejects missing/invalid/ambiguous output and removes only known stale evidence.
|
||
|
||
Observed API-35 content viewport: **720 × 1184 px, density 2, fontScale 1**, hence
|
||
360 × 592 CSS pixels for the browser reference. Root bounds are
|
||
`[0,48,720,1232]` on the 720 × 1280 emulator. Do not compare a full native root
|
||
image against a 360 × 640 PWA content viewport.
|
||
|
||
```sh
|
||
ANDROID_SERIAL=emulator-5554 python3 scripts/test-integration.py /path/to/pinned-upstream --android --cookie-without-secure
|
||
PLAYWRIGHT_HOST_PLATFORM_OVERRIDE=ubuntu24.04-x64 \
|
||
PLAYWRIGHT_BROWSERS_PATH=/path/to/external/browsers \
|
||
FONTCONFIG_FILE=/path/to/isolated/android-roboto/fonts.conf \
|
||
python3 scripts/capture-pwa-reference.py /path/to/pinned-upstream \
|
||
--playwright-module /path/to/external/node_modules/playwright \
|
||
--width 360 --height 592 --output artifacts/visual/pwa-360x592
|
||
node scripts/compare-native-pwa.mjs /path/to/external/node_modules/playwright \
|
||
/path/to/build/app/outputs/native-screenshots artifacts/visual/pwa-360x592 \
|
||
artifacts/visual/comparisons
|
||
```
|
||
|
||
Playwright/Chromium and the emulator's variable Roboto are external tooling, not
|
||
application dependencies. The reference recorder captures real browser PNGs and
|
||
computed styles, without editing upstream files. It uses a temporary loopback-only
|
||
HTTPS fixture, blocks external browser requests and does not export credentials,
|
||
cookies, generated certificates or keys. Dates/greetings and initial account colors
|
||
can vary; compare those separately from geometry. Native integration keeps OIDC
|
||
enabled for the redirect-refusal regression, whereas the password-login reference
|
||
disables it; their extra SSO controls are not a valid exact login comparison.
|
||
The comparison compositor refuses mismatched viewport/image sizes or font scale,
|
||
places the actual captures side by side and records their SHA-256 hashes. It does
|
||
not replace either screenshot, normalize away UI differences or assert acceptance.
|
||
|
||
## Explicit remaining differences
|
||
|
||
- Full calendar navigation and its widget action are absent, not fake buttons.
|
||
- Native SSO/recovery/invites and most modules/settings remain unimplemented.
|
||
- Advanced task categories/assignment/statuses, note rendering/categories and
|
||
shopping quick-add/details do not yet match all PWA interactions.
|
||
- Card internals, utility icons, shadows/glass and form geometry still require
|
||
visual refinement and broader device/font-size/accessibility testing.
|
||
- The three supported favorites stand in for unavailable native destinations;
|
||
this is not full preference/navigation parity.
|
||
- The unchanged iOS slice now has a verified Apple simulator build/test/archive
|
||
run, but no new design comparison or native real-server parity acceptance;
|
||
see [validation](validation.md).
|
||
|
||
Screenshot existence and passing CRUD tests are evidence, **not visual acceptance**.
|
||
See [native parity](native-parity.md) for the complete scope.
|
||
|
||
## Reviewed examples from this pass
|
||
|
||
Left is the real PWA, right the actual native capture. Remaining differences are
|
||
deliberately visible, including the absent calendar action, widget spacing,
|
||
utility icon/control differences and upstream's dashboard-customization hint.
|
||
|
||
- [Dashboard, light](images/dashboard-light-comparison.png)
|
||
- [Dashboard, dark](images/dashboard-dark-comparison.png)
|
||
- [Tasks, light](images/tasks-light-comparison.png)
|
||
- [Notes, dark](images/notes-dark-comparison.png)
|