SHA256
feat(android): align native preview with measured PWA design
This commit is contained in:
1 parent
bd0e4cc4fb
commit
7ac9882307
30 files changed
+2793
-750
No files matched your search
@@ -0,0 +1,91 @@
|
||||
# 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.
|
||||
- Apple UI/build validation remains blocked as recorded in [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)
|
||||
Reference in new issue
Block a user