114 lines
3.0 KiB
Dart
114 lines
3.0 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:mileograph_flutter/objects/objects.dart';
|
|
import 'package:mileograph_flutter/services/apiService.dart'; // assumes you've moved HomepageStats + submodels to a separate file
|
|
|
|
class DataService extends ChangeNotifier {
|
|
final ApiService api;
|
|
|
|
DataService({required this.api});
|
|
|
|
// Homepage Data
|
|
HomepageStats? _homepageStats;
|
|
HomepageStats? get homepageStats => _homepageStats;
|
|
|
|
// Legs Data
|
|
List<Leg> _legs = [];
|
|
List<Leg> get legs => _legs;
|
|
|
|
// Traction Data
|
|
List<LocoSummary> _traction = [];
|
|
List<LocoSummary> get traction => _traction;
|
|
|
|
// Station Data
|
|
List<Station>? _cachedStations;
|
|
DateTime? _stationsFetchedAt;
|
|
|
|
bool _isHomepageLoading = false;
|
|
bool get isHomepageLoading => _isHomepageLoading;
|
|
|
|
Future<void> fetchHomepageStats() async {
|
|
_isHomepageLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
final json = await api.get('/stats/homepage');
|
|
_homepageStats = HomepageStats.fromJson(json);
|
|
} catch (e) {
|
|
debugPrint('Failed to fetch homepage stats: $e');
|
|
_homepageStats = null;
|
|
} finally {
|
|
_isHomepageLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> fetchLegs({
|
|
int offset = 0,
|
|
int limit = 100,
|
|
String sortBy = 'date',
|
|
int sortDirection = 0,
|
|
}) async {
|
|
final query =
|
|
'?sort_direction=$sortDirection&sort_by=$sortBy&offset=$offset&limit=$limit';
|
|
final json = await api.get('/user/legs$query');
|
|
|
|
if (json is List) {
|
|
_legs = json.map((e) => Leg.fromJson(e)).toList();
|
|
notifyListeners();
|
|
} else {
|
|
throw Exception('Unexpected legs response: $json');
|
|
}
|
|
}
|
|
|
|
Future<void> fetchHadTraction({int offset = 0, int limit = 100}) async {
|
|
final query = '?offset=$offset&limit=$limit';
|
|
final json = await api.get('/loco/mileage$query');
|
|
|
|
if (json is List) {
|
|
_traction = json.map((e) => LocoSummary.fromJson(e)).toList();
|
|
notifyListeners();
|
|
} else {
|
|
throw Exception('Unexpected traction response: $json');
|
|
}
|
|
}
|
|
|
|
void clear() {
|
|
_homepageStats = null;
|
|
notifyListeners();
|
|
}
|
|
|
|
double getMileageForCurrentYear() {
|
|
final currentYear = DateTime.now().year;
|
|
return getMileageForYear(currentYear) ?? 0;
|
|
}
|
|
|
|
double? getMileageForYear(int year) {
|
|
return _homepageStats?.yearlyMileage
|
|
.firstWhere(
|
|
(entry) => entry.year == year,
|
|
orElse: () => YearlyMileage(year: null, mileage: 0),
|
|
)
|
|
.mileage ??
|
|
0;
|
|
}
|
|
|
|
Future<List<Station>> fetchStations() async {
|
|
final now = DateTime.now();
|
|
|
|
// If cache exists and is less than 30 minutes old, return it
|
|
if (_cachedStations != null &&
|
|
_stationsFetchedAt != null &&
|
|
now.difference(_stationsFetchedAt!) < Duration(minutes: 30)) {
|
|
return _cachedStations!;
|
|
}
|
|
|
|
final response = await api.get('/location');
|
|
final parsed = (response as List).map((e) => Station.fromJson(e)).toList();
|
|
|
|
_cachedStations = parsed;
|
|
_stationsFetchedAt = now;
|
|
|
|
return parsed;
|
|
}
|
|
}
|