Files
mileograph_flutter/lib/services/data_service/data_service_traction.dart

154 lines
4.4 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;
}
Future<void> fetchLatestLocoChanges({int limit = 25, int offset = 0}) async {
_isLatestLocoChangesLoading = true;
_notifyAsync();
try {
final json =
await api.get('/loco/changes/latest?limit=$limit&offset=$offset');
dynamic results = json;
if (json is Map && json['data'] is List) {
results = json['data'];
}
if (results is List) {
final parsed = <LocoChange>[];
for (final item in results) {
if (item is Map<String, dynamic>) {
parsed.add(LocoChange.fromJson(item));
} else if (item is Map) {
parsed.add(
LocoChange.fromJson(
item.map((key, value) => MapEntry(key.toString(), value)),
),
);
}
}
_latestLocoChanges = parsed;
} else {
throw Exception('Unexpected latest loco changes response: $json');
}
} catch (e) {
debugPrint('Failed to fetch latest loco changes: $e');
_latestLocoChanges = [];
} finally {
_isLatestLocoChangesLoading = false;
_notifyAsync();
}
}
}