device infos
This commit is contained in:
@@ -66,10 +66,10 @@ class StopCard extends StatelessWidget {
|
||||
/// Time at the door, shown in the card's header.
|
||||
final Duration service;
|
||||
|
||||
/// Which bag this order travels in — `Bag 3`, or the label the kitchen
|
||||
/// printed. One order, one bag; the count is never a separate figure. See
|
||||
/// [BagManifest].
|
||||
final String bag;
|
||||
/// Which label this order travels in — `Bag 3`, or the label the kitchen
|
||||
/// printed. One order, one label; the count is never a separate figure. See
|
||||
/// [OrderManifest].
|
||||
final String label;
|
||||
|
||||
/// True when this card sits under a heading that already names its pickup
|
||||
/// location.
|
||||
@@ -122,7 +122,7 @@ class StopCard extends StatelessWidget {
|
||||
required this.state,
|
||||
required this.address,
|
||||
required this.service,
|
||||
this.bag = '',
|
||||
this.label = '',
|
||||
this.groupedUnderSource = false,
|
||||
this.selected = false,
|
||||
this.busy = false,
|
||||
@@ -256,7 +256,7 @@ class StopCard extends StatelessWidget {
|
||||
SizedBox(height: 12.h),
|
||||
_factsRow(
|
||||
kind,
|
||||
bagShownAbove: twoLeg && !grouped && bag.isNotEmpty,
|
||||
labelShownAbove: twoLeg && !grouped && label.isNotEmpty,
|
||||
),
|
||||
if (action != null) ...[SizedBox(height: 16.h), action],
|
||||
],
|
||||
@@ -318,7 +318,7 @@ class StopCard extends StatelessWidget {
|
||||
/// `→ Joe · Bag 1` — the far end, in one line.
|
||||
///
|
||||
/// Everything the second leg used to spend a whole block on: who it is for,
|
||||
/// and which bag it is. The address is one tap away in the detail sheet,
|
||||
/// and which label it is. The address is one tap away in the detail sheet,
|
||||
/// where a rider going to a *kitchen* has no use for it yet.
|
||||
Widget _dropLine(String customer) {
|
||||
return Row(
|
||||
@@ -343,7 +343,10 @@ class StopCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (bag.isNotEmpty) ...[SizedBox(width: 10.w), _BagChip(label: bag)],
|
||||
if (label.isNotEmpty) ...[
|
||||
SizedBox(width: 10.w),
|
||||
_LabelChip(label: label),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -352,7 +355,7 @@ class StopCard extends StatelessWidget {
|
||||
///
|
||||
/// This is the line a rider re-reads at a red light, so nothing on it is
|
||||
/// under 14sp and none of it is in a box.
|
||||
Widget _factsRow(StopKind kind, {required bool bagShownAbove}) {
|
||||
Widget _factsRow(StopKind kind, {required bool labelShownAbove}) {
|
||||
final due = DateTime.tryParse(
|
||||
(stop['expected_pickup_time'] ?? stop['eta'] ?? '').toString().trim(),
|
||||
);
|
||||
@@ -393,33 +396,33 @@ class StopCard extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
// What is in it, and which bag it is. The bag appears here whenever the
|
||||
// drop line above is not already carrying it — a card must never be
|
||||
// silent about which box this order is, and it must never say it twice.
|
||||
// What is in it, and the counter's own label where there is one. It
|
||||
// appears here whenever the drop line above is not already carrying it:
|
||||
// a card must never say the same thing twice.
|
||||
Builder(
|
||||
builder: (_) {
|
||||
final label = bag.isNotEmpty ? bag : stopBagLabel(stop);
|
||||
final printed = label.isNotEmpty ? label : stopPrintedLabel(stop);
|
||||
final meta = _MetaLine(
|
||||
deliver: kind.hasDelivery ? _qty(deliveryParcelCount(stop)) : 0,
|
||||
collect: kind.hasPickup ? _qty(pickupParcelCount(stop)) : 0,
|
||||
cash: cash,
|
||||
muted: _rejected || state == StopState.done,
|
||||
// On a meal run the parcel counts are the one-bag rule restated
|
||||
// On a meal run the parcel counts are the one-label rule restated
|
||||
// as an item count, which is exactly the second number this app
|
||||
// does not allow. Only the money survives.
|
||||
countsHidden: ServiceProfile.active.deliversToCustomer,
|
||||
);
|
||||
final showBag = !bagShownAbove && label.isNotEmpty;
|
||||
if (!showBag && meta.isEmpty) return const SizedBox.shrink();
|
||||
final showLabel = !labelShownAbove && printed.isNotEmpty;
|
||||
if (!showLabel && meta.isEmpty) return const SizedBox.shrink();
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: 8.h),
|
||||
child: Row(
|
||||
children: [
|
||||
if (!meta.isEmpty) Flexible(child: meta),
|
||||
if (showBag) ...[
|
||||
if (showLabel) ...[
|
||||
if (!meta.isEmpty) SizedBox(width: 10.w),
|
||||
_BagChip(label: label),
|
||||
_LabelChip(label: printed),
|
||||
],
|
||||
],
|
||||
),
|
||||
@@ -441,7 +444,7 @@ class StopCard extends StatelessWidget {
|
||||
/// journey and the bar offers the claim, and neither duplicates the other.
|
||||
///
|
||||
/// A stop that is already *arrived* is the one exception: the single-order
|
||||
/// case ("one bag, one counter") would otherwise make him tick a card he is
|
||||
/// case ("one label, one counter") would otherwise make him tick a card he is
|
||||
/// looking at to reach a control that talks about "the selection". That
|
||||
/// button opens the same slide sheet the bar does, over the same batch.
|
||||
Widget? _primaryAction() {
|
||||
@@ -598,16 +601,19 @@ class _IconAction extends StatelessWidget {
|
||||
/// the card has exactly one colour to spend. It is a chip rather than plain
|
||||
/// text because it is read *against an object* — a bordered word is findable on
|
||||
/// a card at arm's length in a way a run of grey text is not.
|
||||
class _BagChip extends StatelessWidget {
|
||||
class _LabelChip extends StatelessWidget {
|
||||
final String label;
|
||||
const _BagChip({required this.label});
|
||||
const _LabelChip({required this.label});
|
||||
|
||||
/// Backend labels are codes — `DG-1042`, `BAG-1` — and derived ones already
|
||||
/// read `Bag 3`. The word belongs on both, and the test for "already has it"
|
||||
/// is the *word*, not the prefix: `BAG-1` starts with those three letters and
|
||||
/// is still a code, so it becomes `Bag BAG-1` exactly as it always read.
|
||||
String get _text =>
|
||||
label.toLowerCase().startsWith('bag ') ? label : 'Bag $label';
|
||||
/// ── The word is gone; the code is not ──
|
||||
///
|
||||
/// This prefixed everything with `Bag ` — so a counter's own code rendered
|
||||
/// as `Bag DG-1042`, and a number the app had derived rendered as `Bag 3`
|
||||
/// and read like something stencilled on an object nobody had stencilled.
|
||||
///
|
||||
/// What a counter prints is printed on it already. It is shown exactly as it
|
||||
/// was sent, and nothing is shown at all where nothing was sent.
|
||||
String get _text => label;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
Reference in New Issue
Block a user