feat(android): align native preview with measured PWA design
Android validation / emulator (37.0) (push) Failing after 3s
Android validation / emulator (35) (push) Failing after 4s
iOS validation / simulator (push) Successful in 59s
Android validation / build (push) Successful in 5m30s

This commit is contained in:
Yuvomi Mobile Contributors committed 2026-10-21 10:45:16 +02:00
1 parent bd0e4cc4fb
commit 7ac9882307
30 files changed
+2793 -750

No files matched your search

+33
View File
@@ -13,6 +13,39 @@ Read [native parity](native-parity.md), [architecture](architecture.md), and
shopping slices exist, but **no module has accepted full visual/functional parity**.
The remaining pages/settings/auth/file/offline/notification work is explicit.
### Android design follow-up: 0.2.2 native preview / code 4
The user confirmed the login fix and requested the PWA design 1:1. The Android
slice now uses PWA-derived native primitives in `PwaDesign.kt`, `PwaIcons.kt`,
`PwaShell.kt`, `NativePages.kt` and `NativeForms.kt`, instead of the first generic
Material layout. `PwaPresentation.kt` handles greeting/timezone/config filtering;
the controller reads personal preferences and auto-selects the first shopping list.
The confirmed cookie/session transport was not changed.
Read [design comparison](native-design.md) before making visual claims. External
Playwright 1.55.1/Chromium 140 tooling captures the actual unmodified PWA; the
emulator exports ten light/dark native views with viewport metadata. Match the
360 × 592 content viewport and Android variable Roboto, not the system-bar-inclusive
root. The earlier clipped tab labels were caused by per-tab circular clipping.
The apparent second white capsule segment occurred where subsequent dashboard
content remained visible beneath the translucent navigation; inspect actual
matched captures rather than treating any visible card edge as a second bar.
Reference generation uses `/tmp/opencode/yuvomi-visual-tools/node_modules/playwright`,
`/tmp/opencode/yuvomi-visual-tools/fonts.conf` and persistent browsers at
`/home/neste/yuvomi-tools/playwright-browsers`. The temporary font config points to
the emulator's variable `/system/fonts/Roboto-Regular.ttf`; it includes all weights.
Set `PLAYWRIGHT_HOST_PLATFORM_OVERRIDE=ubuntu24.04-x64` on this Ubuntu 26 host.
Reference output is ignored under `artifacts/visual/pwa-360x592`; native screenshots
are in the external build's `app/outputs/native-screenshots`. The side-by-side
compositor is tooling only; screenshots are evidence, not automated parity approval.
iOS is unchanged. No module has accepted full functional/visual parity, the rest
of the inventory remains open, and signing stays paused. Continue refinement from
actual comparison images, including non-default font sizes/devices and native
module functionality; do not declare the whole user request finished from this
Android slice alone.
### Android login follow-up: 0.2.1 native preview / code 3
A user reported immediate HTTP-401 login failure although the same direct password
Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

+91
View File
@@ -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)
+5 -1
View File
@@ -17,7 +17,11 @@ Use these states honestly:
- **Slice**: real native UI/API interaction exists, with the listed limitations.
- **Pending**: not implemented. No fake screen, raw-JSON editor or WebView fallback.
- **Parity accepted**: requires functional and visual evidence on both platforms.
**No module currently has this status.**
**No module currently has this status.**
Android 0.2.2 has a PWA-derived design pass on the supported slice, with real
reference/native light/dark captures. See [design comparison](native-design.md).
This does not change the acceptance status or certify the unchanged iOS UI.
## Page inventory
+29
View File
@@ -8,6 +8,35 @@ tests are in `androidTestNative` / `androidTestNativeIntegration`, JVM native po
tests, and Swift production contracts/transport tests. Archived WebView tests are
not included in the native suites or counted toward native completion.
## Android 0.2.2 / code 4: PWA-derived design pass
Local API-35 validation after the design pass:
| Check | Observed result |
| --- | --- |
| JVM policy/presentation tests | 23 passed, zero failures/errors/skips |
| Native Compose UI/security/presentation tests | 9 passed, zero failures/errors/skips |
| Real upstream, default non-Secure cookie over HTTPS | 10 passed, zero failures/errors/skips |
| Real upstream, Secure cookie | 10 passed, zero failures/errors/skips |
| Android lint and packages | Both lint variants; debug and unsigned release APK/AAB passed |
| Screenshot evidence | Ten light/dark native views, viewport metadata, ten actual-PWA references and ten matched-size side-by-side images |
| Script checks | 9 screenshot-collection, 8 JUnit-verifier and 14 runner/probe regressions passed; repository/Python/Node/workflow checks passed |
| Dependency scan | OSV listed no advisories for 266 locked/direct Maven coordinates/plugins |
The first ordinary device-test attempt ran **zero tests** because a leftover
CI-signed 0.2.1 preview had a different debug certificate. The verifier rejected
that run despite Gradle's successful exit. AGP cleanup removed the package; the
clean rerun executed all nine tests. Both complete integration harnesses then
exited successfully and retained the rejected-password/successful-retry regression.
Logs: `/home/neste/yuvomi-design-build-final.log`,
`/home/neste/yuvomi-design-cookie-final.log`,
`/home/neste/yuvomi-design-secure-final.log`.
The [design comparison](native-design.md) includes reviewed synthetic images and
documents the exact 360 × 592 content viewport and intentional fixture scope.
**This is not accepted 1:1 parity.** iOS was not changed or newly validated.
Remote KVM/CoreSimulator prerequisites and production signing remain open.
## Android 0.2.1 / code 3: reproduced login regression
The user reported immediate login failure despite a working direct browser login.