production
This commit is contained in:
@@ -79,6 +79,10 @@ class TripCard extends StatelessWidget {
|
||||
/// Opens a single stop's detail sheet (map + full order details).
|
||||
final void Function(Map<String, dynamic> stop)? onStopTap;
|
||||
|
||||
/// One order's sheet, from a row inside an expanded place — see
|
||||
/// [RouteTimeline.onOrderTap]. Falls back to [onStopTap] when unset.
|
||||
final void Function(Map<String, dynamic> stop)? onOrderTap;
|
||||
|
||||
/// Rings the customer for this stop.
|
||||
final void Function(Map<String, dynamic> stop)? onCallStop;
|
||||
|
||||
@@ -145,6 +149,7 @@ class TripCard extends StatelessWidget {
|
||||
this.onSelectAll,
|
||||
this.onUnrejectStop,
|
||||
this.onStopTap,
|
||||
this.onOrderTap,
|
||||
this.onCallStop,
|
||||
this.onViewRoute,
|
||||
this.onContinueStop,
|
||||
@@ -175,7 +180,7 @@ class TripCard extends StatelessWidget {
|
||||
static bool _isChoosable(StopState state) =>
|
||||
state == StopState.pending ||
|
||||
(ServiceProfile.active.handsOffAtCollection &&
|
||||
(state == StopState.accepted || state == StopState.active));
|
||||
(state == StopState.accepted || state.isAtSource));
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -247,6 +252,15 @@ class TripCard extends StatelessWidget {
|
||||
/// four surfaces it replaced were the wrong price for the information.
|
||||
Widget buildSummary() => TripBriefStrip(
|
||||
trip: trip,
|
||||
// What the four figures describe: the collections still owed, measured
|
||||
// from where the rider is standing — the same origin the page used to
|
||||
// build the trip in the first place, so the recount and the original are
|
||||
// on the same footing. See [Trip.outstanding].
|
||||
remaining: trip.outstanding(
|
||||
collectedIds: collectedIds,
|
||||
originLat: riderLat,
|
||||
originLng: riderLng,
|
||||
),
|
||||
brief: brief ?? RouteBrief.empty,
|
||||
percent: trip.completionPercent(
|
||||
acceptedIds: acceptedIds,
|
||||
@@ -287,7 +301,13 @@ class TripCard extends StatelessWidget {
|
||||
int index,
|
||||
})?
|
||||
_nextGroup() {
|
||||
for (final rung in const [StopState.active, StopState.accepted]) {
|
||||
// Arrived outranks active: he is at that counter now, and a stop he has
|
||||
// only been routed to can wait.
|
||||
for (final rung in const [
|
||||
StopState.arrived,
|
||||
StopState.active,
|
||||
StopState.accepted,
|
||||
]) {
|
||||
for (var i = 0; i < trip.stops.length; i++) {
|
||||
if (_stateOf(trip.stops[i]) != rung) continue;
|
||||
final stop = trip.stops[i];
|
||||
@@ -351,6 +371,7 @@ class TripCard extends StatelessWidget {
|
||||
onSelectAll: onSelectAll,
|
||||
onToggleSelect: onToggleSelect,
|
||||
onStopTap: onStopTap,
|
||||
onOrderTap: onOrderTap ?? onStopTap,
|
||||
// One journey action per place. Five Navigate buttons pointing at
|
||||
// one counter was the largest single source of clutter on the old
|
||||
// screen, and the rider had to work out whether they differed.
|
||||
@@ -477,6 +498,10 @@ class TripCard extends StatelessWidget {
|
||||
firstIndex: indices.first,
|
||||
state: stops.isEmpty ? StopState.collected : _groupRung(stops),
|
||||
stopStates: [for (final s in stops) _stateOf(s)],
|
||||
// The whole bucket's states, so the card can tell an order that is
|
||||
// still this counter's business from one already delivered — see
|
||||
// [RouteGroup.groupSize].
|
||||
allStopStates: [for (final s in all) _stateOf(s)],
|
||||
travel: trip.travelTimeToStop(indices.first),
|
||||
// ── Measured, or absent ──
|
||||
//
|
||||
@@ -530,7 +555,7 @@ class TripCard extends StatelessWidget {
|
||||
// give. `trip_brief_layout_test.dart` sweeps for exactly this.
|
||||
Flexible(
|
||||
child: Text(
|
||||
ServiceProfile.active.endsAtHub ? 'RETURN · HUB' : 'END · HOME',
|
||||
ServiceProfile.active.endsAtHub ? 'RETURN · BASE' : 'END · HOME',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: MilerType.eyebrow,
|
||||
@@ -901,17 +926,17 @@ class TripCard extends StatelessWidget {
|
||||
isStart
|
||||
? (ServiceProfile.active.sourceIsKitchen
|
||||
? 'START · KITCHEN'
|
||||
: 'START · HUB')
|
||||
: 'START · BASE')
|
||||
// ── A milk run does not return anything ──
|
||||
//
|
||||
// He loads at the kitchen and his last address is a
|
||||
// customer's door: there is no hub at the end of
|
||||
// customer's door: there is no base at the end of
|
||||
// his day and nothing to carry back to one. The
|
||||
// logistics rider genuinely does return collected
|
||||
// shipments to the depot, so the label follows the
|
||||
// capability rather than the screen position.
|
||||
: (ServiceProfile.active.endsAtHub
|
||||
? 'RETURN · HUB'
|
||||
? 'RETURN · BASE'
|
||||
: 'END · HOME'),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -1076,7 +1101,9 @@ class TripCard extends StatelessWidget {
|
||||
/// what kept the row here in the first place.
|
||||
static bool _showsOnHome(StopState state) =>
|
||||
state == StopState.pending ||
|
||||
state == StopState.active ||
|
||||
// Arrived belongs here for the same reason active does, and it is the
|
||||
// reason this reads as a predicate: see [StopStateX.isAtSource].
|
||||
state.isAtSource ||
|
||||
// Accepted stays only where the rider works that rung from this screen;
|
||||
// on a parcel route it moves to Bookings the moment he takes it.
|
||||
(state == StopState.accepted &&
|
||||
@@ -1089,7 +1116,9 @@ class TripCard extends StatelessWidget {
|
||||
/// heading cannot end up describing different rungs.
|
||||
StopStatus _rungOf(StopState state) => switch (state) {
|
||||
StopState.accepted => StopStatus.accepted,
|
||||
StopState.active => StopStatus.arrived,
|
||||
// Both: this answers *which rung is the stop on*, and it is the same for
|
||||
// either — he is at the counter and the next thing he does is collect.
|
||||
StopState.arrived || StopState.active => StopStatus.arrived,
|
||||
_ => StopStatus.unknown,
|
||||
};
|
||||
|
||||
@@ -1161,7 +1190,7 @@ class TripCard extends StatelessWidget {
|
||||
// An **arrived** stop keeps a card-level rung, because by then the batch
|
||||
// question is settled: he is at the counter, and the sheet it opens acts
|
||||
// on every order from that counter anyway ([_advanceStopWithSheet]).
|
||||
final advance = state == StopState.active
|
||||
final advance = state.isAtSource
|
||||
? (MilkRun.nextActionLabel(_rungOf(state)) == null
|
||||
? null
|
||||
: 'Mark as picked')
|
||||
@@ -1281,7 +1310,7 @@ class TripCard extends StatelessWidget {
|
||||
// shrinking.
|
||||
Flexible(
|
||||
child: Text(
|
||||
'Trip complete · head back to the hub',
|
||||
'Trip complete · head back to base',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
|
||||
Reference in New Issue
Block a user