import 'dart:async'; import 'dart:developer'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:info_tren/api/station_data.dart'; import 'package:info_tren/api/train_data.dart'; import 'package:info_tren/models.dart'; import 'package:info_tren/pages/station_arrdep_page/view_station/view_station.dart'; import 'package:info_tren/pages/train_info_page/view_train/train_info.dart'; import 'package:info_tren/utils/default_ui_design.dart'; import 'package:info_tren/utils/iterable_extensions.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:shared_preferences/shared_preferences.dart'; part 'providers.g.dart'; final sharedPreferencesProvider = Provider( (_) => throw UnimplementedError('Please override in ProviderScope'), ); class UiDesignNotifier extends StateNotifier { final SharedPreferences sharedPreferences; UiDesignNotifier({required this.sharedPreferences,}) : super(UiDesign.MATERIAL) { final stored = sharedPreferences.getString('uiDesign'); final design = UiDesign.values.where((element) => element.name == stored).firstOrNull ?? defaultUiDesign; state = design; } void set(UiDesign? design) async { if (design != null) { await sharedPreferences.setString('uiDesign', design.name); } else { await sharedPreferences.remove('uiDesign'); } state = design ?? defaultUiDesign; } } final uiDesignProvider = StateNotifierProvider( (ref) => UiDesignNotifier( sharedPreferences: ref.watch(sharedPreferencesProvider), ), dependencies: [sharedPreferencesProvider], ); class UiTimeZoneNotifier extends StateNotifier { final SharedPreferences sharedPreferences; UiTimeZoneNotifier({required this.sharedPreferences,}) : super(const RoUiTimeZone()) { final stored = sharedPreferences.getString('uiTimeZone'); if (stored != null) { try { state = UiTimeZone.fromSerString(stored); } catch (e) { log('Invalid UiTimeZone ser: $stored, error: $e', level: 1000); } } } void set(UiTimeZone? timeZone) async { if (timeZone != null) { await sharedPreferences.setString('uiTimeZone', timeZone.toSerString()); } else { await sharedPreferences.remove('uiTimeZone'); } state = timeZone ?? const LocalUiTimeZone(); } } final uiTimeZoneProvider = StateNotifierProvider( (ref) => UiTimeZoneNotifier( sharedPreferences: ref.watch(sharedPreferencesProvider), ), dependencies: [sharedPreferencesProvider], ); final trainInfoArgumentsProvider = Provider( (_) => throw UnimplementedError('Please override in ProviderScope'), ); final stationDataProvider = FutureProvider.family((ref, ViewStationArguments args) async { final data = await getStationData(args.stationName, args.date); final timer = Timer(const Duration(minutes: 2), () { ref.invalidateSelf(); }); ref.onDispose(() { timer.cancel(); }); return data; }); final viewStationArgumentsProvider = Provider( (_) => throw UnimplementedError('Please override in ProviderScope'), ); final viewStationDataProvider = Provider((ref) { final args = ref.watch(viewStationArgumentsProvider); final data = ref.watch(stationDataProvider(args)); return data; }, dependencies: [viewStationArgumentsProvider, stationDataProvider]); @Riverpod(keepAlive: true) Future trainInfo(TrainInfoRef ref, {required String trainNumber, DateTime? date}) => getTrain(trainNumber, date: date);