implemented RMV public transit module including trip search, station departures, and nearby stop lookup, added "Marianum Connect" API integration with bearer token authentication and auto-refresh logic, integrated geolocator for location-based station search, added persistent storage for favorite stations and recent trip queries, and implemented comprehensive UI for journey details, trip results, and disruption alerts
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../extensions/date_time.dart';
|
||||
|
||||
/// Shows a scheduled time with optional realtime delay overlay.
|
||||
///
|
||||
/// Examples:
|
||||
/// - on-time: `14:35`
|
||||
/// - 2 minutes late: `14:35` + green/red `+2'` chip
|
||||
/// - cancelled: scheduled time struck through, red `Ausfall` chip
|
||||
class RealtimeTime extends StatelessWidget {
|
||||
final DateTime scheduled;
|
||||
final DateTime? realtime;
|
||||
final int? delayMinutes;
|
||||
final bool cancelled;
|
||||
final TextStyle? style;
|
||||
|
||||
const RealtimeTime({
|
||||
super.key,
|
||||
required this.scheduled,
|
||||
this.realtime,
|
||||
this.delayMinutes,
|
||||
this.cancelled = false,
|
||||
this.style,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final base = style ?? Theme.of(context).textTheme.bodyMedium ?? const TextStyle();
|
||||
final scheduledText = Text(
|
||||
scheduled.formatHm(),
|
||||
style: base.copyWith(
|
||||
decoration: cancelled ? TextDecoration.lineThrough : null,
|
||||
),
|
||||
);
|
||||
if (cancelled) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
scheduledText,
|
||||
const SizedBox(width: 6),
|
||||
_badge(context, 'Ausfall', Colors.red),
|
||||
],
|
||||
);
|
||||
}
|
||||
final delay = delayMinutes;
|
||||
if (delay != null && delay != 0) {
|
||||
final positive = delay > 0;
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
scheduledText,
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'${positive ? '+' : ''}$delay\'',
|
||||
style: base.copyWith(
|
||||
color: positive ? Colors.red : Colors.green,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return scheduledText;
|
||||
}
|
||||
|
||||
Widget _badge(BuildContext context, String text, Color color) => Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 1),
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user