Add accent colour picker, fix empty user card when accepting friend request, add button to transfer allocations
All checks were successful
Release / meta (push) Successful in 8s
Release / linux-build (push) Successful in 56s
Release / web-build (push) Successful in 2m15s
Release / android-build (push) Successful in 6m47s
Release / release-master (push) Successful in 19s
Release / release-dev (push) Successful in 21s

This commit is contained in:
2026-01-06 00:21:19 +00:00
parent d5083e1cc7
commit 06bed86a49
11 changed files with 427 additions and 45 deletions

View File

@@ -20,6 +20,7 @@ class TractionCard extends StatelessWidget {
this.onToggleSelect,
this.onReplacePending,
this.onActionComplete,
this.onTransferAllocations,
});
final LocoSummary loco;
@@ -31,6 +32,7 @@ class TractionCard extends StatelessWidget {
final VoidCallback? onToggleSelect;
final VoidCallback? onReplacePending;
final Future<void> Function()? onActionComplete;
final VoidCallback? onTransferAllocations;
@override
Widget build(BuildContext context) {
@@ -145,23 +147,30 @@ class TractionCard extends StatelessWidget {
];
// Prefer replace action when picking a replacement loco.
final addButton = onReplacePending != null
final addButton = onTransferAllocations != null
? TextButton.icon(
onPressed: onReplacePending,
onPressed: onTransferAllocations,
icon: const Icon(Icons.swap_horiz),
label: const Text('Replace'),
label: const Text('Transfer'),
)
: (!isRejected && selectionMode && onToggleSelect != null)
: onReplacePending != null
? TextButton.icon(
onPressed: onToggleSelect,
icon: Icon(
isSelected
? Icons.remove_circle_outline
: Icons.add_circle_outline,
),
label: Text(isSelected ? 'Remove' : 'Add to entry'),
onPressed: onReplacePending,
icon: const Icon(Icons.swap_horiz),
label: const Text('Replace'),
)
: null;
: (!isRejected && selectionMode && onToggleSelect != null)
? TextButton.icon(
onPressed: onToggleSelect,
icon: Icon(
isSelected
? Icons.remove_circle_outline
: Icons.add_circle_outline,
),
label:
Text(isSelected ? 'Remove' : 'Add to entry'),
)
: null;
if (isNarrow) {
return Column(
@@ -551,6 +560,7 @@ Future<void> showTractionDetails(
LocoSummary loco, {
Future<void> Function()? onActionComplete,
}) async {
final navContext = context;
final hasMileageOrTrips = _hasMileageOrTrips(loco);
final isVisibilityPending =
(loco.visibility ?? '').toLowerCase().trim() == 'pending';
@@ -583,11 +593,11 @@ Future<void> showTractionDetails(
builder: (_, controller) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
IconButton(
icon: const Icon(Icons.close),
onPressed: () => Navigator.of(ctx).pop(),
@@ -620,16 +630,37 @@ Future<void> showTractionDetails(
style: Theme.of(context).textTheme.bodyMedium,
),
),
const SizedBox(height: 4),
Expanded(
child: ListView(
controller: controller,
children: [
if (isRejected && rejectedReason.isNotEmpty)
...[
_detailRow(
context,
'Rejection reason',
const SizedBox(height: 4),
Expanded(
child: ListView(
controller: controller,
children: [
FilledButton.icon(
onPressed: () {
Navigator.of(ctx).pop();
navContext.push(
Uri(
path: '/traction',
queryParameters: {
'selection': 'single',
'transferFromLocoId': loco.id.toString(),
},
).toString(),
extra: {
'selection': 'single',
'transferFromLocoId': loco.id,
},
);
},
icon: const Icon(Icons.swap_horiz),
label: const Text('Transfer allocations'),
),
const SizedBox(height: 12),
if (isRejected && rejectedReason.isNotEmpty)
...[
_detailRow(
context,
'Rejection reason',
rejectedReason,
),
const Divider(),