production

This commit is contained in:
2026-08-28 11:13:15 +05:30
parent d7348e253f
commit 5723d373b2
162 changed files with 17924 additions and 7026 deletions

View File

@@ -136,7 +136,9 @@ class StopCard extends StatelessWidget {
this.advanceLabel,
});
bool get _live => state == StopState.active;
/// Both rungs a rider can be standing on. They render the same mark; what
/// differs is the word — see [LiveMark.label].
bool get _live => state == StopState.active || state == StopState.arrived;
bool get _rejected => state == StopState.rejected;
@override
@@ -274,7 +276,7 @@ class StopCard extends StatelessWidget {
/// is the only one that changes.
Widget _statusRow(StopKind kind) {
final chip = _live
? const LiveMark()
? LiveMark(label: state == StopState.arrived ? 'Arrived' : 'Active')
: (state == StopState.pending &&
!ServiceProfile.active.handsOffAtCollection)
? null
@@ -719,7 +721,20 @@ class SelectBox extends StatelessWidget {
/// a `dispose()` on a card that never painted cannot construct a ticker during
/// teardown — the same trap the banner hit, documented in `homepage_banner.dart`.
class LiveMark extends StatefulWidget {
const LiveMark({super.key});
/// The word beside the pulse.
///
/// It was the literal `'Active'`, always. Since `stopStateOf` folded arrival
/// into [StopState.active], sliding *confirm arrival* moved the rung, fired
/// `/reached` and wrote the local record — and then printed **Active** on the
/// row. From the rider's side that is indistinguishable from the arrival not
/// registering at all, which is exactly how it was reported.
///
/// The two states are separate now; this is how the mark says which one it
/// is. `Active` stays the default because the delivery half of the day is
/// where most live stops are.
final String label;
const LiveMark({super.key, this.label = 'Active'});
@override
State<LiveMark> createState() => _LiveMarkState();
@@ -793,7 +808,7 @@ class _LiveMarkState extends State<LiveMark>
SizedBox(width: 6.w),
Flexible(
child: Text(
'Active',
widget.label,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
@@ -834,6 +849,13 @@ class StopStateChip extends StatelessWidget {
color: ColorConstants.serviceAccent,
icon: LucideIcons.shoppingBag,
),
// At the door, not on the road: the pin, not the bike. The two used to
// share this row and the chip printed `Active` for both — see
// [StopState.arrived].
StopState.arrived => (
color: ColorConstants.primary,
icon: LucideIcons.mapPin,
),
StopState.active => (color: ColorConstants.primary, icon: LucideIcons.bike),
StopState.done => (
color: ColorConstants.acceptGreen,