updated the sheet

This commit is contained in:
2026-08-28 18:16:28 +05:30
parent 69f4f3e909
commit 074cc0eccf
43 changed files with 2617 additions and 1201 deletions

View File

@@ -17,7 +17,6 @@ import 'package:permission_handler/permission_handler.dart';
import 'package:miler/providers/pickup/pickup_provider.dart';
import 'package:miler/providers/pickuplog/pickuplog_provider.dart';
import 'package:miler/views/Dashboard/orders/orderstaus_button.dart';
import 'package:miler/views/helpers/constants/apiconstants.dart';
import 'package:miler/views/helpers/constants/Colorconstants.dart';
import 'package:miler/views/helpers/constants/miler_surface.dart';
import 'package:miler/views/helpers/widgets/app_widgets.dart';
@@ -59,6 +58,7 @@ import 'package:miler/views/Dashboard/pickups/pickups.dart' as pickups;
import 'package:miler/background/live_tracking_service.dart';
import 'package:miler/data/accepted_store.dart';
import 'package:miler/data/api_config.dart';
import 'package:miler/data/heartbeat.dart';
import 'package:miler/data/consignment_state.dart';
import 'package:miler/views/Dashboard/pickups/collect_payment.dart';
import 'package:miler/views/Dashboard/pickups/stop_type.dart';
@@ -1699,11 +1699,13 @@ class _HomepageState extends State<Homepage>
Future<Duration> _getLogInterval() async {
try {
final prefs = await SharedPreferences.getInstance();
final secs = prefs.getInt('logseconds');
final int interval = (secs != null && secs > 0) ? secs : 30;
// Already correct — routed through the shared resolver so the 30 lives in
// one place. See [kDefaultLogSeconds] for what a zero here used to cost
// the rider-log loop, which read the same pref and did not guard it.
final int interval = resolveLogSeconds(prefs.getInt('logseconds'));
return Duration(seconds: interval);
} catch (_) {
return const Duration(seconds: 30);
return const Duration(seconds: kDefaultLogSeconds);
}
}

View File

@@ -932,7 +932,15 @@ class _PickupMapScreenState extends State<_PickupMapScreen>
final top = media.padding.top + 72;
await _camera.fit(
<LatLng>[_routeStart, _routeEnd],
padding: EdgeInsets.fromLTRB(48, top, 48, viewport * _sheetWorking + 24),
// The sheet is lifted by the gesture bar, so the space it covers is
// taller than the bare fraction — see [_sheetLift]. Framing against the
// old figure would tuck the route's near end under the sheet.
padding: EdgeInsets.fromLTRB(
48,
top,
48,
viewport * (_sheetWorking + _sheetLift(media)) + 24,
),
);
}
@@ -1102,18 +1110,49 @@ class _PickupMapScreenState extends State<_PickupMapScreen>
/// Three stops and no more: a glance, the working height, and the detail
/// view. A drag with many arbitrary rest points feels loose and gives the
/// rider nothing to aim at.
/// The system's own bar at the foot of the screen, as a fraction of the
/// viewport — so the three snap fractions below can be lifted clear of it.
///
/// The snaps are fractions and the bar is an absolute height, so the two only
/// meet through the viewport. Clamped because a fraction derived from a
/// measurement should never be able to swallow the sheet on a device that
/// reports something strange.
double _sheetLift(MediaQueryData media) {
final double height = media.size.height;
if (height <= 0) return 0;
final double bar = math.max(
media.viewInsets.bottom,
media.viewPadding.bottom,
);
return (bar / height).clamp(0.0, 0.15);
}
static const double _sheetGlance = 0.35;
static const double _sheetWorking = 0.45;
static const double _sheetDetail = 0.75;
Widget _buildDraggableBottomSheet() {
// ── Every stop is lifted by the height of the gesture bar ──
//
// Padding the content alone would have kept the sheet the same height and
// simply moved everything in it up, costing the rider a bar's worth of the
// stop he is reading. Growing the sheet by the same amount puts the glass
// *behind* the bar and leaves the visible content area exactly the size it
// was — which is what "the sheet is touching the navigation" actually asks
// for. The two work together: this makes room, the list's bottom padding
// keeps the CTA out of it.
final double lift = _sheetLift(MediaQuery.of(context));
final double glance = (_sheetGlance + lift).clamp(0.0, 1.0);
final double working = (_sheetWorking + lift).clamp(0.0, 1.0);
final double detail = (_sheetDetail + lift).clamp(0.0, 1.0);
return DraggableScrollableSheet(
initialChildSize: _sheetWorking,
minChildSize: _sheetGlance,
maxChildSize: _sheetDetail,
initialChildSize: working,
minChildSize: glance,
maxChildSize: detail,
// Snap to the three, so the sheet always settles somewhere meant.
snap: true,
snapSizes: const [_sheetGlance, _sheetWorking, _sheetDetail],
snapSizes: [glance, working, detail],
// ── Frosted, not opaque ──
//
// A solid white slab over a map takes away 45% of the one thing this
@@ -1157,7 +1196,32 @@ class _PickupMapScreenState extends State<_PickupMapScreen>
// has, and it is why that sheet reads at arm's length.
child: ListView(
controller: scrollController,
padding: EdgeInsets.fromLTRB(20.w, 16.h, 20.w, 8.h),
// ── The gesture bar sat on top of the CTA ──
//
// Eight points of bottom padding, on a sheet anchored to
// the bottom of the screen: the last thing in this list is
// [_buildPrimaryAction] — the slide control that closes the
// stop — and on a gesture-navigation phone the system's own
// bar was drawn across it. The rider's swipe either missed
// the control or went to the OS.
//
// The glass still bleeds to the screen edge, which is what
// it is for; what has to clear the bar is the *content*.
// Same rule the sheet kit applies to every modal sheet —
// `max(keyboard, gesture bar)`, never the sum, because the
// keyboard replaces the bar rather than stacking with it.
// This sheet is hand-built rather than presented through
// [MilerSheetScaffold], so it never inherited that rule.
padding: EdgeInsets.fromLTRB(
20.w,
16.h,
20.w,
8.h +
math.max(
MediaQuery.viewInsetsOf(context).bottom,
MediaQuery.viewPaddingOf(context).bottom,
),
),
children: [
_LiveEtaHeader(
meters: _liveMetersToStop,
@@ -1635,13 +1699,11 @@ class _PickupMapScreenState extends State<_PickupMapScreen>
if (_isNavigating || !mounted) return;
final outcome = await DeliveryProofPage.askOutcome(context);
if (!mounted || outcome == null) return;
await _closeDelivery(
switch (outcome) {
ProofOutcome.delivered => DeliveryOutcome.delivered,
ProofOutcome.skipped => DeliveryOutcome.skipped,
ProofOutcome.cancelled => DeliveryOutcome.cancelled,
},
);
await _closeDelivery(switch (outcome) {
ProofOutcome.delivered => DeliveryOutcome.delivered,
ProofOutcome.skipped => DeliveryOutcome.skipped,
ProofOutcome.cancelled => DeliveryOutcome.cancelled,
});
}
/// The end of the stop, whichever of the three it is.