part of 'deliveries.dart'; // ------------------------------------------------------------------------- // PIP INFO CARD (Shown when PiP mode is enabled) // ------------------------------------------------------------------------- class PipInfoCard extends StatefulWidget { final String orderId; final int etaMinutes; // ETA in minutes from API (always treat as minutes) const PipInfoCard({ super.key, required this.orderId, required this.etaMinutes, }); @override State createState() => _PipInfoCardState(); } class _PipInfoCardState extends State { late final CountDownController _controller; int _durationSeconds = 0; @override void initState() { super.initState(); _controller = CountDownController(); // Load remaining ETA from SharedPreferences so timer doesn't reset _initDuration(); } Future _initDuration() async { try { final prefs = await SharedPreferences.getInstance(); final endKey = 'eta_endtime_${widget.orderId}'; final endSeconds = prefs.getInt(endKey); final nowSeconds = DateTime.now().millisecondsSinceEpoch ~/ 1000; int remaining = 0; if (endSeconds != null && endSeconds > nowSeconds) { remaining = endSeconds - nowSeconds; } else { // Fallback: use full ETA from API final int safeEtaMinutes = widget.etaMinutes < 0 ? 0 : widget.etaMinutes; remaining = safeEtaMinutes * 60; } if (!mounted) return; setState(() { _durationSeconds = remaining.clamp(0, 24 * 60 * 60); }); } catch (_) { // In case of error, just fall back to raw ETA minutes final int safeEtaMinutes = widget.etaMinutes < 0 ? 0 : widget.etaMinutes; if (!mounted) return; setState(() { _durationSeconds = safeEtaMinutes * 60; }); } } @override Widget build(BuildContext context) { return Scaffold( // Expanded PiP: timer + key delivery details, but still relatively compact body: Center( child: widget.orderId.isEmpty || widget.orderId == 'N/A' ? Text( 'No Active Order', style: TextStyle( fontSize: 12, fontFamily: FontConstants.fontFamily, color: ColorConstants.primaryColor, ), ) : Card( color: Colors.white, elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Container( width: 220, padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 6, ), child: FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.center, child: Column( mainAxisSize: MainAxisSize.min, children: [ // Timer SizedBox( width: 72, height: 72, child: _durationSeconds <= 0 ? Container( decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: ColorConstants.primaryColor, width: 3, ), color: Colors.white, ), alignment: Alignment.center, child: Text( 'Out', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: ColorConstants.primaryColor, fontFamily: FontConstants.fontFamily, ), ), ) : CircularCountDownTimer( duration: _durationSeconds, initialDuration: 0, controller: _controller, width: 72, height: 72, ringColor: ColorConstants.primaryColor .withValues(alpha: 0.15), fillColor: ColorConstants.primaryColor, backgroundColor: Colors.white, strokeWidth: 5, strokeCap: StrokeCap.round, textStyle: TextStyle( fontSize: 17, fontWeight: FontWeight.bold, color: ColorConstants.primaryColor, fontFamily: FontConstants.fontFamily, ), isReverse: true, isReverseAnimation: true, isTimerTextShown: true, autoStart: true, timeFormatterFunction: (defaultFormatter, duration) { return duration.inSeconds <= 0 ? 'Out' : defaultFormatter(duration); }, ), ), const SizedBox(height: 4), // Active order id Text( 'Active Order ID: ${widget.orderId}', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: Colors.black87, fontFamily: FontConstants.fontFamily, ), ), ], ), ), ), ), ), ); } }