integrated EquipmentProfilesStorageService

This commit is contained in:
Vadim 2024-11-06 14:04:11 +01:00
parent c66381f813
commit 5ddaed8dfb
5 changed files with 65 additions and 62 deletions

View file

@ -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<ApplicationWrapper> {
? 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<void>();
final filmsStorageService = FilmsStorageService();
final filmsStorageServiceCompleter = Completer<void>();
late final Future<void> _initFuture;
@ -68,10 +73,11 @@ class _ApplicationWrapperState extends State<ApplicationWrapper> {
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<ApplicationWrapper> {
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());
}
}

View file

@ -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<EquipmentProfileProvider> {
isoValues: IsoValue.values,
);
List<EquipmentProfile> _customProfiles = [];
final Map<String, EquipmentProfile> _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<EquipmentProfileProvider> {
return EquipmentProfiles(
values: [
_defaultProfile,
if (context.isPro) ..._customProfiles,
if (context.isPro) ..._customProfiles.values,
],
selected: context.isPro ? _selectedProfile : _defaultProfile,
child: widget.child,
);
}
Future<void> _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<EquipmentProfileProvider> {
}
}
/// 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<void> addProfile(EquipmentProfile profile) async {
await widget.storageService.addProfile(profile);
_customProfiles[profile.id] = profile;
setState(() {});
}
Future<void> 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<void> 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(() {});
}
}

View file

@ -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<FilmsProvider> {
}
Future<void> _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<FilmsProvider> {
} else {
return;
}
await widget.filmsStorageService.toggleFilm(film, enabled);
await widget.storageService.toggleFilm(film, enabled);
_discardSelectedIfNotIncluded();
setState(() {});
}
@ -74,7 +74,7 @@ class FilmsProviderState extends State<FilmsProvider> {
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<FilmsProvider> {
Future<void> 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<void> 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<void> 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<FilmsProvider> {
final isSelectedUsed = predefinedFilms[_selectedId]?.isUsed ?? customFilms[_selectedId]?.isUsed ?? false;
if (!isSelectedUsed) {
_selectedId = const FilmStub().id;
widget.filmsStorageService.selectedFilmId = _selectedId;
widget.storageService.selectedFilmId = _selectedId;
}
}
}

View file

@ -79,7 +79,7 @@ class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> {
builder: (_) => const EquipmentProfileNameDialog(),
).then((name) {
if (name != null) {
EquipmentProfileProvider.of(context).addProfile(name, copyFrom);
//EquipmentProfileProvider.of(context).addProfile(name, copyFrom);
}
});
}

View file

@ -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"