QoL changes
All checks were successful
Release / meta (push) Successful in 22s
Release / linux-build (push) Successful in 4m32s
Release / android-build (push) Successful in 7m10s
Release / release-dev (push) Successful in 9s
Release / release-master (push) Successful in 9s

This commit is contained in:
2025-12-14 09:45:32 +00:00
parent 8116cfe7b1
commit f0dfbd185b
11 changed files with 887 additions and 321 deletions

View File

@@ -269,51 +269,85 @@ class _TripsPageState extends State<TripsPage> {
context: context,
isScrollControlled: true,
builder: (_) {
final data = context.read<DataService>();
return SafeArea(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
child: FutureBuilder<List<TripLocoStat>>(
future: data.fetchTripLocoStats(trip.id),
builder: (ctx, snapshot) {
final items = snapshot.data ?? [];
final loading =
snapshot.connectionState == ConnectionState.waiting;
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Navigator.of(context).pop(),
),
Text(
trip.name,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const Spacer(),
Text('${trip.mileage.toStringAsFixed(1)} mi'),
],
),
const SizedBox(height: 8),
SizedBox(
height: MediaQuery.of(context).size.height * 0.6,
child: ListView.builder(
itemCount: trip.legs.length,
itemBuilder: (context, index) {
final leg = trip.legs[index];
return ListTile(
leading: const Icon(Icons.train),
title: Text('${leg.start}${leg.end}'),
subtitle: Text(_formatDate(leg.beginTime)),
trailing: Text(
leg.mileage?.toStringAsFixed(1) ?? '-',
style: Theme.of(context).textTheme.labelLarge
Row(
children: [
IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Navigator.of(context).pop(),
),
Text(
trip.name,
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(fontWeight: FontWeight.bold),
),
);
},
),
const Spacer(),
Text('${trip.mileage.toStringAsFixed(1)} mi'),
],
),
const SizedBox(height: 8),
if (loading)
const Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 24.0),
child: CircularProgressIndicator(),
),
)
else if (items.isEmpty)
const Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text('No traction recorded for this trip yet.'),
)
else
SizedBox(
height: MediaQuery.of(context).size.height * 0.6,
child: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final loco = items[index];
final won = loco.won;
final isWon = won == true;
return ListTile(
leading: const Icon(Icons.train),
title: Text('${loco.locoClass} ${loco.number}'),
subtitle:
loco.name == null || loco.name!.isEmpty
? null
: Text(loco.name!),
trailing: Chip(
label: Text(isWon ? 'Won' : 'Dud'),
backgroundColor: isWon
? Colors.green.shade100
: Colors.grey.shade300,
labelStyle: TextStyle(
color: isWon
? Colors.green.shade900
: Colors.grey.shade800,
),
),
);
},
),
),
],
),
],
),
);
},
),
);
},