Files

173 lines
6.8 KiB
Dart

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<PipInfoCard> createState() => _PipInfoCardState();
}
class _PipInfoCardState extends State<PipInfoCard> {
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<void> _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,
),
),
],
),
),
),
),
),
);
}
}