diff --git a/lib/application_wrapper.dart b/lib/application_wrapper.dart index 7722226..2a8256d 100644 --- a/lib/application_wrapper.dart +++ b/lib/application_wrapper.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:lightmeter/data/analytics/analytics.dart'; @@ -34,11 +36,14 @@ class _ApplicationWrapperState extends State { ? const RemoteConfigService(LightmeterAnalytics(api: LightmeterAnalyticsFirebase())) : const MockRemoteConfigService(); - late final IAPStorageService iapStorageService; late final UserPreferencesService userPreferencesService; late final bool hasLightSensor; + final equipmentProfilesStorageService = EquipmentProfilesStorageService(); + final equipmentProfilesStorageServiceCompleter = Completer(); + final filmsStorageService = FilmsStorageService(); + final filmsStorageServiceCompleter = Completer(); late final Future _initFuture; @@ -68,10 +73,11 @@ class _ApplicationWrapperState extends State { child: RemoteConfigProvider( remoteConfigService: remoteConfigService, child: EquipmentProfileProvider( - storageService: iapStorageService, + storageService: equipmentProfilesStorageService, + onInitialized: equipmentProfilesStorageServiceCompleter.complete, child: FilmsProvider( - filmsStorageService: filmsStorageService, - onInitialized: _onFilmsProviderInitialized, + storageService: filmsStorageService, + onInitialized: filmsStorageServiceCompleter.complete, child: UserPreferencesProvider( hasLightSensor: hasLightSensor, userPreferencesService: userPreferencesService, @@ -95,14 +101,12 @@ class _ApplicationWrapperState extends State { remoteConfigService.activeAndFetchFeatures(), filmsStorageService.init(), ]).then((value) { - final sharedPrefs = (value[0] as SharedPreferences?)!; - iapStorageService = IAPStorageService(sharedPrefs); - userPreferencesService = UserPreferencesService(sharedPrefs); + userPreferencesService = UserPreferencesService((value[0] as SharedPreferences?)!); hasLightSensor = value[1] as bool? ?? false; }); - } - - void _onFilmsProviderInitialized() { - FlutterNativeSplash.remove(); + await Future.wait([ + equipmentProfilesStorageServiceCompleter.future, + filmsStorageServiceCompleter.future, + ]).then((_) => FlutterNativeSplash.remove()); } } diff --git a/lib/providers/equipment_profile_provider.dart b/lib/providers/equipment_profile_provider.dart index 74397a5..4bb638f 100644 --- a/lib/providers/equipment_profile_provider.dart +++ b/lib/providers/equipment_profile_provider.dart @@ -3,14 +3,15 @@ import 'package:lightmeter/utils/context_utils.dart'; import 'package:lightmeter/utils/selectable_provider.dart'; import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; -import 'package:uuid/uuid.dart'; class EquipmentProfileProvider extends StatefulWidget { - final IAPStorageService storageService; + final EquipmentProfilesStorageService storageService; + final VoidCallback? onInitialized; final Widget child; const EquipmentProfileProvider({ required this.storageService, + this.onInitialized, required this.child, super.key, }); @@ -33,19 +34,15 @@ class EquipmentProfileProviderState extends State { isoValues: IsoValue.values, ); - List _customProfiles = []; + final Map _customProfiles = {}; String _selectedId = ''; - EquipmentProfile get _selectedProfile => _customProfiles.firstWhere( - (e) => e.id == _selectedId, - orElse: () => _defaultProfile, - ); + EquipmentProfile get _selectedProfile => _customProfiles[_selectedId] ?? _defaultProfile; @override void initState() { super.initState(); - _selectedId = widget.storageService.selectedEquipmentProfileId; - _customProfiles = widget.storageService.equipmentProfiles; + _init(); } @override @@ -53,13 +50,20 @@ class EquipmentProfileProviderState extends State { return EquipmentProfiles( values: [ _defaultProfile, - if (context.isPro) ..._customProfiles, + if (context.isPro) ..._customProfiles.values, ], selected: context.isPro ? _selectedProfile : _defaultProfile, child: widget.child, ); } + Future _init() async { + _selectedId = widget.storageService.selectedEquipmentProfileId; + _customProfiles.addAll(await widget.storageService.getProfiles()); + if (mounted) setState(() {}); + widget.onInitialized?.call(); + } + void setProfile(EquipmentProfile data) { if (_selectedId != data.id) { setState(() { @@ -69,40 +73,35 @@ class EquipmentProfileProviderState extends State { } } - /// Creates a default equipment profile - void addProfile(String name, [EquipmentProfile? copyFrom]) { - _customProfiles.add( - EquipmentProfile( - id: const Uuid().v1(), - name: name, - apertureValues: copyFrom?.apertureValues ?? ApertureValue.values, - ndValues: copyFrom?.ndValues ?? NdValue.values, - shutterSpeedValues: copyFrom?.shutterSpeedValues ?? ShutterSpeedValue.values, - isoValues: copyFrom?.isoValues ?? IsoValue.values, - ), + Future addProfile(EquipmentProfile profile) async { + await widget.storageService.addProfile(profile); + _customProfiles[profile.id] = profile; + setState(() {}); + } + + Future updateProfile(EquipmentProfile profile) async { + final oldProfile = _customProfiles[profile.id]!; + await widget.storageService.updateProfile( + id: profile.id, + name: oldProfile.name != profile.name ? profile.name : null, + apertureValues: oldProfile.apertureValues != profile.apertureValues ? profile.apertureValues : null, + shutterSpeedValues: + oldProfile.shutterSpeedValues != profile.shutterSpeedValues ? profile.shutterSpeedValues : null, + isoValues: oldProfile.isoValues != profile.isoValues ? profile.isoValues : null, + ndValues: oldProfile.ndValues != profile.ndValues ? profile.ndValues : null, + lensZoom: oldProfile.lensZoom != profile.lensZoom ? profile.lensZoom : null, ); - _refreshSavedProfiles(); + _customProfiles[profile.id] = profile; + setState(() {}); } - void updateProfile(EquipmentProfile data) { - final indexToUpdate = _customProfiles.indexWhere((element) => element.id == data.id); - if (indexToUpdate >= 0) { - _customProfiles[indexToUpdate] = data; - _refreshSavedProfiles(); - } - } - - void deleteProfile(EquipmentProfile data) { - if (data.id == _selectedId) { + Future deleteProfile(EquipmentProfile profile) async { + await widget.storageService.deleteProfile(profile.id); + if (profile.id == _selectedId) { _selectedId = _defaultProfile.id; widget.storageService.selectedEquipmentProfileId = _defaultProfile.id; } - _customProfiles.remove(data); - _refreshSavedProfiles(); - } - - void _refreshSavedProfiles() { - widget.storageService.equipmentProfiles = _customProfiles; + _customProfiles.remove(profile.id); setState(() {}); } } diff --git a/lib/providers/films_provider.dart b/lib/providers/films_provider.dart index 428fb8e..5c5c683 100644 --- a/lib/providers/films_provider.dart +++ b/lib/providers/films_provider.dart @@ -5,12 +5,12 @@ import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; class FilmsProvider extends StatefulWidget { - final FilmsStorageService filmsStorageService; + final FilmsStorageService storageService; final VoidCallback? onInitialized; final Widget child; const FilmsProvider({ - required this.filmsStorageService, + required this.storageService, this.onInitialized, required this.child, super.key, @@ -48,9 +48,9 @@ class FilmsProviderState extends State { } Future _init() async { - _selectedId = widget.filmsStorageService.selectedFilmId; - predefinedFilms.addAll(await widget.filmsStorageService.getPredefinedFilms()); - customFilms.addAll(await widget.filmsStorageService.getCustomFilms()); + _selectedId = widget.storageService.selectedFilmId; + predefinedFilms.addAll(await widget.storageService.getPredefinedFilms()); + customFilms.addAll(await widget.storageService.getCustomFilms()); _discardSelectedIfNotIncluded(); if (mounted) setState(() {}); widget.onInitialized?.call(); @@ -66,7 +66,7 @@ class FilmsProviderState extends State { } else { return; } - await widget.filmsStorageService.toggleFilm(film, enabled); + await widget.storageService.toggleFilm(film, enabled); _discardSelectedIfNotIncluded(); setState(() {}); } @@ -74,7 +74,7 @@ class FilmsProviderState extends State { void selectFilm(Film film) { if (_selectedFilm != film) { _selectedId = film.id; - widget.filmsStorageService.selectedFilmId = _selectedId; + widget.storageService.selectedFilmId = _selectedId; setState(() {}); } } @@ -83,19 +83,19 @@ class FilmsProviderState extends State { Future addCustomFilm(FilmExponential film) async { // ignore: avoid_redundant_argument_values - await widget.filmsStorageService.addFilm(film, isUsed: true); + await widget.storageService.addFilm(film, isUsed: true); customFilms[film.id] = (film: film, isUsed: true); setState(() {}); } Future updateCustomFilm(FilmExponential film) async { - await widget.filmsStorageService.updateFilm(film); + await widget.storageService.updateFilm(film); customFilms[film.id] = (film: film, isUsed: customFilms[film.id]!.isUsed); setState(() {}); } Future deleteCustomFilm(FilmExponential film) async { - await widget.filmsStorageService.deleteFilm(film); + await widget.storageService.deleteFilm(film); customFilms.remove(film.id); _discardSelectedIfNotIncluded(); setState(() {}); @@ -108,7 +108,7 @@ class FilmsProviderState extends State { final isSelectedUsed = predefinedFilms[_selectedId]?.isUsed ?? customFilms[_selectedId]?.isUsed ?? false; if (!isSelectedUsed) { _selectedId = const FilmStub().id; - widget.filmsStorageService.selectedFilmId = _selectedId; + widget.storageService.selectedFilmId = _selectedId; } } } diff --git a/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/screen_equipment_profile.dart b/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/screen_equipment_profile.dart index f13d4ff..7c7b23e 100644 --- a/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/screen_equipment_profile.dart +++ b/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/screen_equipment_profile.dart @@ -79,7 +79,7 @@ class _EquipmentProfilesScreenState extends State { builder: (_) => const EquipmentProfileNameDialog(), ).then((name) { if (name != null) { - EquipmentProfileProvider.of(context).addProfile(name, copyFrom); + //EquipmentProfileProvider.of(context).addProfile(name, copyFrom); } }); } diff --git a/pubspec.yaml b/pubspec.yaml index 3a09662..d653620 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,7 +32,7 @@ dependencies: m3_lightmeter_iap: git: url: "https://github.com/vodemn/m3_lightmeter_iap" - ref: v1.1.1 + ref: feature/MLI-15 m3_lightmeter_resources: git: url: "https://github.com/vodemn/m3_lightmeter_resources"