119 lines
3.3 KiB
Dart
119 lines
3.3 KiB
Dart
part of 'data_service.dart';
|
|
|
|
extension DataServiceTraction on DataService {
|
|
Future<void> fetchHadTraction({int offset = 0, int limit = 100}) async {
|
|
await fetchTraction(
|
|
hadOnly: true,
|
|
offset: offset,
|
|
limit: limit,
|
|
append: offset > 0,
|
|
);
|
|
}
|
|
|
|
Future<void> fetchTraction({
|
|
bool hadOnly = false,
|
|
int offset = 0,
|
|
int limit = 50,
|
|
String? locoClass,
|
|
String? locoNumber,
|
|
bool mileageFirst = true,
|
|
bool append = false,
|
|
Map<String, dynamic>? filters,
|
|
}) async {
|
|
_isTractionLoading = true;
|
|
|
|
try {
|
|
final params = StringBuffer('?limit=$limit&offset=$offset');
|
|
if (hadOnly) params.write('&had_only=true');
|
|
if (!mileageFirst) params.write('&mileage_first=false');
|
|
|
|
final payload = <String, dynamic>{};
|
|
if (locoClass != null && locoClass.isNotEmpty) {
|
|
payload['class'] = locoClass;
|
|
}
|
|
if (locoNumber != null && locoNumber.isNotEmpty) {
|
|
payload['number'] = locoNumber;
|
|
}
|
|
if (filters != null) {
|
|
filters.forEach((key, value) {
|
|
if (value == null) return;
|
|
if (value is String && value.trim().isEmpty) return;
|
|
payload[key] = value;
|
|
});
|
|
}
|
|
|
|
final json = await api.post(
|
|
'/locos/search/v2${params.toString()}',
|
|
payload.isEmpty ? null : payload,
|
|
);
|
|
|
|
if (json is List) {
|
|
final newItems = json.map((e) => LocoSummary.fromJson(e)).toList();
|
|
_traction = append ? [..._traction, ...newItems] : newItems;
|
|
_tractionHasMore = newItems.length >= limit - 1;
|
|
} else {
|
|
throw Exception('Unexpected traction response: $json');
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Failed to fetch traction: $e');
|
|
if (!append) {
|
|
_traction = [];
|
|
}
|
|
_tractionHasMore = false;
|
|
} finally {
|
|
_isTractionLoading = false;
|
|
_notifyAsync();
|
|
}
|
|
}
|
|
|
|
Future<List<LocoAttrVersion>> fetchLocoTimeline(int locoId) async {
|
|
_isLocoTimelineLoading[locoId] = true;
|
|
_notifyAsync();
|
|
try {
|
|
final json = await api.get('/loco/get-timeline/$locoId');
|
|
final timeline = LocoAttrVersion.fromGroupedJson(json);
|
|
_locoTimelines[locoId] = timeline;
|
|
return timeline;
|
|
} catch (e) {
|
|
debugPrint('Failed to fetch loco timeline for $locoId: $e');
|
|
_locoTimelines[locoId] = [];
|
|
return [];
|
|
} finally {
|
|
_isLocoTimelineLoading[locoId] = false;
|
|
_notifyAsync();
|
|
}
|
|
}
|
|
|
|
Future<dynamic> createLoco(Map<String, dynamic> payload) async {
|
|
try {
|
|
final response = await api.put('/loco/new', payload);
|
|
final locoClass = payload['class']?.toString();
|
|
if (locoClass != null &&
|
|
locoClass.isNotEmpty &&
|
|
!_locoClasses.contains(locoClass)) {
|
|
_locoClasses = [..._locoClasses, locoClass];
|
|
}
|
|
_notifyAsync();
|
|
return response;
|
|
} catch (e) {
|
|
debugPrint('Failed to create loco: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<List<String>> fetchClassList() async {
|
|
if (_locoClasses.isNotEmpty) return _locoClasses;
|
|
try {
|
|
final json = await api.get('/loco/classlist');
|
|
if (json is List) {
|
|
_locoClasses = json.map((e) => e.toString()).toList();
|
|
_notifyAsync();
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Failed to fetch class list: $e');
|
|
}
|
|
return _locoClasses;
|
|
}
|
|
}
|
|
|