import 'package:flutter/material.dart'; import 'package:async/async.dart'; import '../model/flood_station.dart'; import 'api.dart'; class FloodStationProvider extends ChangeNotifier { // since the getter and setter for the following two fields would be empty, they are publicly accessible FloodStation? selectedStation; bool filtered = false; List _allStations = []; List _filteredStations = []; CancelableOperation? _filteredStationsFuture; List get allStations => _allStations; List get filteredStations => _filteredStations; CancelableOperation? get filteredStationsFuture => _filteredStationsFuture; /// loads all stations in batches of 500 and notifies listeners with every loop except if [silent] = true /// this has lower performance than loading them all at once an shouldn't be used Future loadAllStationsInBatches({silent = false}) { int offset = 0; return Future.doWhile(() async { final stations = await Api.fetchStationsByRange(500, offset); if (stations.isNotEmpty) { _allStations.addAll(stations); if (!silent) { notifyListeners(); } offset += 500; return true; } else { return false; } }); } /// loads all flood stations and notifies listeners when done Future loadAllStations({silent = false}) { return Api.fetchAllStations().then( (value) { _allStations = value; if (!silent) { notifyListeners(); } }, ); } /// loads all stations whose label contains [filter] Future loadFilteredStations(String filter, {silent = false}) { if (_filteredStationsFuture != null) { _filteredStationsFuture!.cancel(); } final future = Api.fetchFilteredStations(filter); _filteredStationsFuture = CancelableOperation.fromFuture(future).then( (value) { _filteredStations = value; if (!silent) { notifyListeners(); } }, ); return future; } /// cancels loading of filtered results. void cancelFilterLoading() { if (_filteredStationsFuture != null) { _filteredStationsFuture!.cancel(); } } }