maps/mobile/lib/features/places/providers/places_provider.dart
2026-03-30 09:22:16 +02:00

91 lines
2.2 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/database/app_database.dart';
import '../data/places_repository.dart';
class PlacesState {
final List<PlaceData> pois;
final List<Favorite> favorites;
final bool isLoading;
final String? error;
const PlacesState({
this.pois = const [],
this.favorites = const [],
this.isLoading = false,
this.error,
});
PlacesState copyWith({
List<PlaceData>? pois,
List<Favorite>? favorites,
bool? isLoading,
String? error,
bool clearError = false,
}) {
return PlacesState(
pois: pois ?? this.pois,
favorites: favorites ?? this.favorites,
isLoading: isLoading ?? this.isLoading,
error: clearError ? null : (error ?? this.error),
);
}
}
class PlacesNotifier extends StateNotifier<PlacesState> {
final PlacesRepository _repository;
PlacesNotifier(this._repository) : super(const PlacesState()) {
_loadFavorites();
}
Future<void> _loadFavorites() async {
final favorites = await _repository.getAllFavorites();
if (mounted) {
state = state.copyWith(favorites: favorites);
}
}
Future<void> loadPoisInViewport({
required double minLon,
required double minLat,
required double maxLon,
required double maxLat,
String? category,
}) async {
state = state.copyWith(isLoading: true, clearError: true);
try {
final pois = await _repository.getPoisInBbox(
minLon: minLon,
minLat: minLat,
maxLon: maxLon,
maxLat: maxLat,
category: category,
);
if (mounted) {
state = state.copyWith(pois: pois, isLoading: false);
}
} catch (e) {
if (mounted) {
state = state.copyWith(
isLoading: false,
error: 'Could not load places.',
);
}
}
}
Future<void> addToFavorites(PlaceData place) async {
await _repository.addFavorite(place);
await _loadFavorites();
}
Future<void> removeFromFavorites(int id) async {
await _repository.removeFavorite(id);
await _loadFavorites();
}
}
final placesProvider =
StateNotifierProvider<PlacesNotifier, PlacesState>((ref) {
return PlacesNotifier(ref.watch(placesRepositoryProvider));
});