Files
Client/lib/view/pages/rmv/widgets/departure_arrival_tile.dart
T

120 lines
3.1 KiB
Dart

import 'package:flutter/material.dart';
import '../../../../api/connect/rmv/rmv_models.dart';
import 'product_chip.dart';
import 'realtime_time.dart';
/// Renders a single departure or arrival row. Used in the station detail view.
class DepartureArrivalTile extends StatelessWidget {
final Product? product;
final String name;
/// Direction (for departures) or origin (for arrivals).
final String towards;
final DateTime scheduled;
final DateTime? realtime;
final int? delayMinutes;
final String? track;
final String? realTrack;
final bool cancelled;
final VoidCallback? onTap;
const DepartureArrivalTile({
super.key,
required this.product,
required this.name,
required this.towards,
required this.scheduled,
this.realtime,
this.delayMinutes,
this.track,
this.realTrack,
this.cancelled = false,
this.onTap,
});
factory DepartureArrivalTile.fromDeparture(
Departure d, {
VoidCallback? onTap,
}) => DepartureArrivalTile(
product: d.product,
name: d.name,
towards: 'nach ${d.direction}',
scheduled: d.scheduledTime,
realtime: d.realTime,
delayMinutes: d.delayMinutes,
track: d.track,
realTrack: d.realTrack,
cancelled: d.cancelled,
onTap: onTap,
);
factory DepartureArrivalTile.fromArrival(
Arrival a, {
VoidCallback? onTap,
}) => DepartureArrivalTile(
product: a.product,
name: a.name,
towards: 'von ${a.origin}',
scheduled: a.scheduledTime,
realtime: a.realTime,
delayMinutes: a.delayMinutes,
track: a.track,
realTrack: a.realTrack,
cancelled: a.cancelled,
onTap: onTap,
);
@override
Widget build(BuildContext context) {
final effectiveTrack = (realTrack?.isNotEmpty ?? false)
? realTrack!
: (track ?? '');
final trackChanged =
realTrack != null && track != null && realTrack != track;
return ListTile(
onTap: onTap,
leading: SizedBox(
width: 72,
child: ProductChip(product: product, fallbackLabel: name),
),
title: Text(
towards,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
decoration: cancelled ? TextDecoration.lineThrough : null,
),
),
subtitle: effectiveTrack.isEmpty
? null
: Row(
children: [
Icon(
Icons.directions_transit,
size: 14,
color: Theme.of(context).colorScheme.secondary,
),
const SizedBox(width: 4),
Text(
'Gleis $effectiveTrack',
style: TextStyle(
color: trackChanged
? Colors.red
: Theme.of(context).colorScheme.secondary,
fontWeight: trackChanged ? FontWeight.bold : null,
),
),
],
),
trailing: RealtimeTime(
scheduled: scheduled,
realtime: realtime,
delayMinutes: delayMinutes,
cancelled: cancelled,
style: Theme.of(context).textTheme.titleMedium,
),
);
}
}