Skip to content

Android: swipeable station sheet, area menu, overlapping stations and an optimized release APK - #4

Merged
AKolenda merged 15 commits into
mainfrom
android-ux-overhaul
Oct 2, 2026
Merged

AKolenda merged 15 commits into
mainfrom
android-ux-overhaul

Conversation

@AKolenda

@AKolenda AKolenda commented Oct 2, 2026

Copy link
Copy Markdown
Owner

Android UX overhaul for version 0.3.3-live (code 7).

Station sheet. The sheet has three stops (collapsed, half-open, expanded) and follows the finger while dragging. A drag on the list raises the sheet to the expanded stop before the list scrolls, and lowers it once the list is at its top. Flings move one stop. Back, landscape and narrow screens are handled. A stationary pointer observer fixes the dropped pointer moves in Compose that made swipes register as taps, and sideways swipes on the header no longer count as taps.

Top controls. The area dropdown opens below its chip and stays below it on short screens. It lists recent cities and has an inline city search with debounced, cancellable lookups. "Search here" sits beside the area chip.

Map. The map is framed around the controls, and a station's detail lists the other stations at the same spot, so overlapping markers can be told apart without zooming.

Smoothness and storage. Menus animate when they close or change content. Station snapshots are written to files off the UI thread, migrated from the old preferences cache.

Downloads. The release APK is now an optimized, non-debuggable R8 build (about 1.9 MB instead of 18 MB). It is signed with the same key as earlier downloads, so installed copies update in place. CI builds and uploads the release APK.

Validation:

  • 25 JVM tests and 34 Android instrumentation tests passed on an API 35 emulator at 1080x2400. The 19 sheet and top-control tests also passed at 360 dp with font scale 1.3.
  • tools/project.py check passed: repository 77, API 45, registry 20, plus generated resources, contracts and fixtures. Map JavaScript syntax and Gitleaks passed.
  • Release smoke on the emulator: map tiles and logos, city lookup with the keyboard up, switching between overlapping stations, the area dropdown and the collapsed sheet at 360 dp with font scale 1.3.
  • Installing over the published 0.3.2 APK kept the saved city and the saved station.
  • One software-emulator comparison showed list UI-thread p95 falling from 28.2 ms to 4.5 ms. Rendering still dropped frames on the emulator, so this makes no claim about frame rates on real phones.
  • The record is in evidence/android-native/ux-0.3.3.json, with screenshots in evidence/android-native/ux-0.3.3/.

Baseline profiles are deferred, and gesture feel has not been checked on a physical phone. This PR does not publish a GitHub release or deploy anything.

A refactor with no change in behaviour or appearance, so the station
sheet, the top controls, the map bridge and the menus can be worked on
in separate files.

- AppChrome.kt: colour tokens, Menu, Detent, MapChrome (the sheet stop,
  whether the map is covered, the half-open sheet top and the bottom of
  the top controls) and MapMove. MapChrome follows the current M3 sheet.
- CommonUi.kt: Price, SheetTitle, OptionRow, SettingSwitch, the label
  helpers and resetTime.
- StationSheet.kt: the sheet handle, StationSheetContent, LimitNotice,
  SheetOverlays (map credit and location button) and ShowStationsButton.
- StationRow.kt: StationRow and GoButton.
- TopControls.kt: TopControls and SearchAreaButton.
- MenuHost.kt: MenuHost reads the open menu itself, so opening a menu no
  longer recomposes OpenFuelApp. MenuBody sends every close through one
  closeMenu. Also SettingsContent, PriceForm and ProposalForm.
- StationDetail.kt: the station detail sheet.
- AreaSearch.kt: LocationSearch.

OpenFuelApp gains openDetail(station, stack) for the list and the map and
onMapMove(MapMove). The LiveMap call has one argument per line, and each
map overlay is its own call. native-root exposes test tags as resource
ids for uiautomator.
# Conflicts:
#	apps/android/app/src/main/java/ca/openfuel/prototype/MenuHost.kt
On a 360 dp screen with large text, HALF to FULL is shorter than the
fixed 500 px swipe, so the swipe carried on into the list. Measure both
stops first and keep each swipe within that distance.
…ot writes

- Finish a snapshot write even when a newer refresh cancels its job, so
  the saved file never falls behind the stations on screen.
- Open the area menu, its chevron and its Back handling only when the
  menu has room below the chip.
- In a window so short that FULL is the collapsed stop, stop treating
  the sheet as covering the map.
- Name the release APK as the build output in docs/BUILD.md.
The record lists the release APK's size, hash and signing key, the unit
and instrumentation results at both screen sizes, the upgrade check and
the emulator performance comparison with its limits. Screenshots taken
before the last two visual fixes are labelled as such.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@chatgpt-codex-connector

Copy link
Copy Markdown

The account paying for this security review has reached its Codex usage limits. The payer can check the Codex usage dashboard. For personal accounts, using credits requires enabling “Use credits for security reviews” in Code review settings. If you do not manage the paying account, contact this repository's admins.

@AKolenda
AKolenda merged commit 4ae84d1 into main Oct 2, 2026
7 checks passed
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.

1 participant