import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'api.dart'; import 'format.dart'; import 'models.dart'; final apiProvider = Provider((ref) => throw UnimplementedError()); final startDateProvider = Provider( (ref) => throw UnimplementedError(), ); class DataVersion extends Notifier { @override int build() => 0; void bump() => state++; } final dataVersionProvider = NotifierProvider(DataVersion.new); class SessionNotifier extends Notifier { SessionNotifier(this.initial); final AppUser? initial; @override AppUser? build() { final sub = ref.read(apiProvider).sessionEnded.listen((_) => _end()); ref.onDispose(sub.cancel); return initial; } Future login(String username, String password) async { final api = ref.read(apiProvider); final u = await api.login(username, password); state = u; try { ref.read(selectedDateProvider.notifier).set(await api.latestDrawDate()); } on ApiException {// ignore: empty_catches } } Future logout() async { ref.read(apiProvider).logout(); _end(); } void _end() { state = null; ref.invalidate(selectedDateProvider); } } final sessionProvider = NotifierProvider( () => SessionNotifier(null), ); class SelectedDate extends Notifier { @override DateTime build() => ref.read(startDateProvider); void set(DateTime d) => state = dateOnly(d); } final selectedDateProvider = NotifierProvider( SelectedDate.new, ); final resultsProvider = FutureProvider.family((ref, d) { ref.watch(dataVersionProvider); return ref.read(apiProvider).results(d); }); final shopsProvider = FutureProvider.family, DateTime>((ref, d) { ref.watch(dataVersionProvider); return ref.read(apiProvider).shops(d); }); final shopDetailProvider = FutureProvider.family(( ref, k, ) { ref.watch(dataVersionProvider); return ref.read(apiProvider).shopDetail(k.$1, k.$2); }); final ordersProvider = FutureProvider.family, DateTime>((ref, d) { ref.watch(dataVersionProvider); return ref.read(apiProvider).orders(d); }); final orderProvider = FutureProvider.family((ref, id) { ref.watch(dataVersionProvider); return ref.read(apiProvider).order(id); }); final monthProvider = FutureProvider.family, (int, int)>(( ref, k, ) { ref.watch(dataVersionProvider); return ref.read(apiProvider).month(k.$1, k.$2); }); final activeShopsProvider = FutureProvider>((ref) { ref.watch(dataVersionProvider); return ref.read(apiProvider).activeShops(); }); final usersProvider = FutureProvider>((ref) { ref.watch(dataVersionProvider); return ref.read(apiProvider).users(); }); final userProvider = FutureProvider.family((ref, id) { ref.watch(dataVersionProvider); return ref.read(apiProvider).user(id); }); Future mutate(WidgetRef ref, Future Function() fn) async { final r = await fn(); ref.read(dataVersionProvider.notifier).bump(); return r; }