173 lines
6.8 KiB
Dart
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,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|