One Touch, and a pickup map worth the name

Two ways to book the same parcel, and the difference said where the
choice is made rather than in a paragraph about it.

ONE TOUCH is the sphere: a state, a district, a window, and nothing
else. The door, the recipient and the weight go out omitted, which the
contract already treats as "not added yet" - the Miler writes them down
standing at the address with the parcel in hand, which is the only
moment anybody knows them.

The pick/drop form under it is the other way in. PICKUP already carries
the detected address; DROP is the only row with a question on it, and
it asks for the full door - once per destination - before the window.
Captions rather than an explainer: "Just a city and a time" under the
sphere, "Enter the full address yourself" on the row.

The pickup screen is a map screen now instead of a screen with a map on
it. Full-bleed basemap, pin nailed to the centre, floating search and
back, and a fixed sheet carrying what the pin resolved to. The
collect-from sheet can hand off to it and carry the pin back.

Also:

* Home reads what-is-running, then the one gesture, then the form. The
  live card lost its courier row and half its height.
* The sphere turns inside out on press - white floods from the centre
  and the word inverts through the clip, not by tween - and bounces
  back on release.
* Order IDs copy, on Orders and on tracking.
* Tracking says PICKUP and DROP with an arrow between them, carries the
  reference at the foot of the card it identifies, and shows every
  timing exactly once.
* The wordmark bar is gone from all three roots; Orders and Account had
  no SafeArea under it, so their titles were sitting under the notch.

flutter analyze: clean. flutter test: 90 passing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EqVJPB9B4QuieZnBAAKgYQ
This commit is contained in:
2026-09-24 15:59:06 +05:30
parent 86b6af48c2
commit 8956e818a4
42 changed files with 2059 additions and 956 deletions

View File

@@ -394,7 +394,26 @@ class AppState extends ChangeNotifier {
/// form, and cleared only when a booking actually lands.
String? _bookingIdempotencyKey;
void startBooking() {
/// Whether this booking asks the customer for the drop address.
///
/// ── Two ways to book the same parcel ──
///
/// **One Touch** asks three things: the state, the district and a pickup
/// window. Nothing else — no door number, no recipient, no weight. Those are
/// filled in by the Miler standing at the address with the parcel in their
/// hand, which is the only moment anybody actually knows them.
///
/// **The full form** is for the customer who already knows the door and
/// would rather type it than have it asked for later. It is the same
/// booking with `details` populated on the wire.
///
/// The contract has always taken both: [DestinationGroup.toBookingJson]
/// omits whatever is blank, and an omitted field is precisely the "not added
/// yet" state the Miler completes. This flag only decides what the app asks.
bool draftDetailed = false;
void startBooking({bool detailed = false}) {
draftDetailed = detailed;
draftPickup = pickup;
draftDestinations = [DestinationGroup()];
draftSlotId = null;