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

@@ -12,6 +12,7 @@ class TractionPage extends StatefulWidget {
this.selectionMode = false,
this.selectionSingle = false,
this.replacementPendingLocoId,
this.transferFromLocoId,
this.onSelect,
this.selectedKeys = const {},
});
@@ -19,6 +20,7 @@ class TractionPage extends StatefulWidget {
final bool selectionMode;
final bool selectionSingle;
final int? replacementPendingLocoId;
final int? transferFromLocoId;
final ValueChanged<LocoSummary>? onSelect;
final Set<String> selectedKeys;
@@ -33,6 +35,7 @@ class _TractionPageState extends State<TractionPage> {
final _nameController = TextEditingController();
bool _mileageFirst = true;
bool _initialised = false;
int? get _transferFromLocoId => widget.transferFromLocoId;
bool _showAdvancedFilters = false;
String? _selectedClass;
late Set<String> _selectedKeys;
@@ -1200,6 +1203,53 @@ class _TractionPageState extends State<TractionPage> {
}
}
Future<void> _confirmTransfer(LocoSummary target) async {
final fromId = _transferFromLocoId;
if (fromId == null) return;
final navContext = context;
final messenger = ScaffoldMessenger.of(navContext);
final confirmed = await showDialog<bool>(
context: navContext,
builder: (dialogContext) {
return AlertDialog(
title: const Text('Transfer allocations?'),
content: Text(
'Transfer all allocations from this loco to ${target.locoClass} ${target.number}?',
),
actions: [
TextButton(
onPressed: () => Navigator.of(dialogContext).pop(false),
child: const Text('Cancel'),
),
FilledButton(
onPressed: () => Navigator.of(dialogContext).pop(true),
child: const Text('Transfer'),
),
],
);
},
);
if (confirmed != true) return;
if (!navContext.mounted) return;
try {
final data = navContext.read<DataService>();
await data.transferAllocations(fromLocoId: fromId, toLocoId: target.id);
if (navContext.mounted) {
messenger.showSnackBar(
const SnackBar(content: Text('Allocations transferred')),
);
}
await _refreshTraction(preservePosition: true);
if (navContext.mounted) navContext.pop();
} catch (e) {
if (navContext.mounted) {
messenger.showSnackBar(
SnackBar(content: Text('Failed to transfer allocations: $e')),
);
}
}
}
bool _isSelected(LocoSummary loco) {
final keyVal = '${loco.locoClass}-${loco.number}';
return _selectedKeys.contains(keyVal);
@@ -1348,12 +1398,18 @@ class _TractionPageState extends State<TractionPage> {
widget.replacementPendingLocoId == null
? () => _toggleSelection(loco)
: null,
onReplacePending: widget.selectionMode &&
widget.selectionSingle &&
widget.replacementPendingLocoId != null
? () => _confirmReplacePending(loco)
: null,
);
onReplacePending: widget.selectionMode &&
widget.selectionSingle &&
widget.replacementPendingLocoId != null
? () => _confirmReplacePending(loco)
: null,
onTransferAllocations: widget.selectionMode &&
widget.selectionSingle &&
widget.transferFromLocoId != null &&
widget.transferFromLocoId != loco.id
? () => _confirmTransfer(loco)
: null,
);
}
return Padding(