diff --git a/iap/lib/m3_lightmeter_iap.dart b/iap/lib/m3_lightmeter_iap.dart index 74fd60b..8fe8aa5 100644 --- a/iap/lib/m3_lightmeter_iap.dart +++ b/iap/lib/m3_lightmeter_iap.dart @@ -1,6 +1,30 @@ library m3_lightmeter_iap; +import 'package:flutter/material.dart'; +import 'package:m3_lightmeter_iap/src/providers/equipment_profile_provider.dart'; +import 'package:m3_lightmeter_iap/src/providers/iap_products_provider.dart'; + export 'src/data/models/iap_product.dart'; +export 'src/providers/equipment_profile_provider.dart' hide EquipmentProfilesAspect; export 'src/providers/iap_products_provider.dart'; -export 'src/utils/equipment_profiles_storage.dart'; \ No newline at end of file + +class IAPProviders extends StatelessWidget { + final Object sharedPreferences; + final Widget child; + + const IAPProviders({ + required this.sharedPreferences, + required this.child, + super.key, + }); + + @override + Widget build(BuildContext context) { + return IAPProductsProvider( + child: EquipmentProfileProvider( + child: child, + ), + ); + } +} diff --git a/iap/lib/src/providers/equipment_profile_provider.dart b/iap/lib/src/providers/equipment_profile_provider.dart new file mode 100644 index 0000000..4f7aa0f --- /dev/null +++ b/iap/lib/src/providers/equipment_profile_provider.dart @@ -0,0 +1,79 @@ +import 'package:flutter/material.dart'; +import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; + +class EquipmentProfileProvider extends StatefulWidget { + final Widget child; + + const EquipmentProfileProvider({required this.child, super.key}); + + static EquipmentProfileProviderState of(BuildContext context) { + return context.findAncestorStateOfType()!; + } + + @override + State createState() => EquipmentProfileProviderState(); +} + +class EquipmentProfileProviderState extends State { + static const EquipmentProfile _defaultProfile = EquipmentProfile( + id: '', + name: '', + apertureValues: ApertureValue.values, + ndValues: NdValue.values, + shutterSpeedValues: ShutterSpeedValue.values, + isoValues: IsoValue.values, + ); + + @override + Widget build(BuildContext context) { + return EquipmentProfiles( + profiles: const [_defaultProfile], + selected: _defaultProfile, + child: widget.child, + ); + } + + void setProfile(EquipmentProfile data) {} + + void addProfile(String name) {} + + void updateProdile(EquipmentProfile data) {} + + void deleteProfile(EquipmentProfile data) {} +} + +enum EquipmentProfilesAspect { list, selected } + +class EquipmentProfiles extends InheritedModel { + const EquipmentProfiles({ + super.key, + required this.profiles, + required this.selected, + required super.child, + }); + + final List profiles; + final EquipmentProfile selected; + + static List of(BuildContext context) { + return InheritedModel.inheritFrom( + context, + aspect: EquipmentProfilesAspect.list, + )! + .profiles; + } + + static EquipmentProfile selectedOf(BuildContext context) { + return InheritedModel.inheritFrom( + context, + aspect: EquipmentProfilesAspect.selected, + )! + .selected; + } + + @override + bool updateShouldNotify(EquipmentProfiles oldWidget) => false; + + @override + bool updateShouldNotifyDependent(EquipmentProfiles oldWidget, Set dependencies) => false; +} diff --git a/iap/lib/src/utils/equipment_profiles_storage.dart b/iap/lib/src/utils/equipment_profiles_storage.dart deleted file mode 100644 index 7ceff9a..0000000 --- a/iap/lib/src/utils/equipment_profiles_storage.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -extension EquipmentProfilesStorage on SharedPreferences { - String get selectedEquipmentProfileId => ''; - set selectedEquipmentProfileId(String id) {} - - List get equipmentProfiles => []; - set equipmentProfiles(List profiles) {} -} diff --git a/lib/data/shared_prefs_service.dart b/lib/data/shared_prefs_service.dart index d17cbfe..020e0b1 100644 --- a/lib/data/shared_prefs_service.dart +++ b/lib/data/shared_prefs_service.dart @@ -7,7 +7,6 @@ import 'package:lightmeter/data/models/metering_screen_layout_config.dart'; import 'package:lightmeter/data/models/supported_locale.dart'; import 'package:lightmeter/data/models/theme_type.dart'; import 'package:lightmeter/data/models/volume_action.dart'; -import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -148,14 +147,4 @@ class UserPreferencesService { orElse: () => Film.values.first, ); set film(Film value) => _sharedPreferences.setString(filmKey, value.name); - - String get selectedEquipmentProfileId => _sharedPreferences.selectedEquipmentProfileId; - set selectedEquipmentProfileId(String id) { - _sharedPreferences.selectedEquipmentProfileId = id; - } - - List get equipmentProfiles => _sharedPreferences.equipmentProfiles; - set equipmentProfiles(List profiles) { - _sharedPreferences.equipmentProfiles = profiles; - } } diff --git a/lib/providers.dart b/lib/providers.dart index afad97b..1f00c67 100644 --- a/lib/providers.dart +++ b/lib/providers.dart @@ -6,7 +6,7 @@ import 'package:lightmeter/data/permissions_service.dart'; import 'package:lightmeter/data/shared_prefs_service.dart'; import 'package:lightmeter/data/volume_events_service.dart'; import 'package:lightmeter/environment.dart'; -import 'package:lightmeter/providers/equipment_profile_provider.dart'; + import 'package:lightmeter/providers/ev_source_type_provider.dart'; import 'package:lightmeter/providers/metering_screen_layout_provider.dart'; import 'package:lightmeter/providers/stop_type_provider.dart'; @@ -32,11 +32,13 @@ class LightmeterProviders extends StatelessWidget { ]), builder: (_, snapshot) { if (snapshot.data != null) { - return IAPProductsProvider( + final sharedPrefs = snapshot.data![0] as SharedPreferences; + return IAPProviders( + sharedPreferences: sharedPrefs, child: InheritedWidgetBase( data: env.copyWith(hasLightSensor: snapshot.data![1] as bool), child: InheritedWidgetBase( - data: UserPreferencesService(snapshot.data![0] as SharedPreferences), + data: UserPreferencesService(sharedPrefs), child: InheritedWidgetBase( data: const LightSensorService(LocalPlatform()), child: InheritedWidgetBase( @@ -49,13 +51,11 @@ class LightmeterProviders extends StatelessWidget { data: const PermissionsService(), child: MeteringScreenLayoutProvider( child: StopTypeProvider( - child: EquipmentProfileProvider( - child: EvSourceTypeProvider( - child: SupportedLocaleProvider( - child: ThemeProvider( - child: Builder( - builder: (context) => builder(context, true), - ), + child: EvSourceTypeProvider( + child: SupportedLocaleProvider( + child: ThemeProvider( + child: Builder( + builder: (context) => builder(context, true), ), ), ), diff --git a/lib/providers/equipment_profile_provider.dart b/lib/providers/equipment_profile_provider.dart deleted file mode 100644 index c5ef82d..0000000 --- a/lib/providers/equipment_profile_provider.dart +++ /dev/null @@ -1,101 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:lightmeter/data/shared_prefs_service.dart'; -import 'package:lightmeter/utils/inherited_generics.dart'; -import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; -import 'package:uuid/uuid.dart'; - -typedef EquipmentProfiles = List; -typedef EquipmentProfile = EquipmentProfileData; - -class EquipmentProfileProvider extends StatefulWidget { - final Widget child; - - const EquipmentProfileProvider({required this.child, super.key}); - - static EquipmentProfileProviderState of(BuildContext context) { - return context.findAncestorStateOfType()!; - } - - @override - State createState() => EquipmentProfileProviderState(); -} - -class EquipmentProfileProviderState extends State { - static const EquipmentProfileData _defaultProfile = EquipmentProfileData( - id: '', - name: '', - apertureValues: ApertureValue.values, - ndValues: NdValue.values, - shutterSpeedValues: ShutterSpeedValue.values, - isoValues: IsoValue.values, - ); - - List _customProfiles = []; - String _selectedId = ''; - - EquipmentProfileData get _selectedProfile => _customProfiles.firstWhere( - (e) => e.id == _selectedId, - orElse: () { - context.get().selectedEquipmentProfileId = _defaultProfile.id; - return _defaultProfile; - }, - ); - - @override - void initState() { - super.initState(); - _selectedId = context.get().selectedEquipmentProfileId; - _customProfiles = context.get().equipmentProfiles; - } - - @override - Widget build(BuildContext context) { - return InheritedWidgetBase>( - data: [_defaultProfile] + _customProfiles, - child: InheritedWidgetBase( - data: _selectedProfile, - child: widget.child, - ), - ); - } - - void setProfile(EquipmentProfileData data) { - setState(() { - _selectedId = data.id; - }); - context.get().selectedEquipmentProfileId = _selectedProfile.id; - } - - /// Creates a default equipment profile - void addProfile(String name) { - _customProfiles.add( - EquipmentProfileData( - id: const Uuid().v1(), - name: name, - apertureValues: ApertureValue.values, - ndValues: NdValue.values, - shutterSpeedValues: ShutterSpeedValue.values, - isoValues: IsoValue.values, - ), - ); - _refreshSavedProfiles(); - } - - void updateProdile(EquipmentProfileData data) { - final indexToUpdate = _customProfiles.indexWhere((element) => element.id == data.id); - if (indexToUpdate >= 0) { - _customProfiles[indexToUpdate] = data; - _refreshSavedProfiles(); - } - } - - void deleteProfile(EquipmentProfileData data) { - _customProfiles.remove(data); - _refreshSavedProfiles(); - } - - void _refreshSavedProfiles() { - context.get().equipmentProfiles = _customProfiles; - setState(() {}); - } -} diff --git a/lib/screens/metering/components/shared/readings_container/widget_container_readings.dart b/lib/screens/metering/components/shared/readings_container/widget_container_readings.dart index 1a3911e..df0fd30 100644 --- a/lib/screens/metering/components/shared/readings_container/widget_container_readings.dart +++ b/lib/screens/metering/components/shared/readings_container/widget_container_readings.dart @@ -3,12 +3,12 @@ import 'package:lightmeter/data/models/exposure_pair.dart'; import 'package:lightmeter/data/models/film.dart'; import 'package:lightmeter/data/models/metering_screen_layout_config.dart'; import 'package:lightmeter/generated/l10n.dart'; -import 'package:lightmeter/providers/equipment_profile_provider.dart'; + import 'package:lightmeter/providers/metering_screen_layout_provider.dart'; import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/screens/metering/components/shared/readings_container/components/animated_dialog_picker/widget_picker_dialog_animated.dart'; import 'package:lightmeter/screens/metering/components/shared/readings_container/components/reading_value_container/widget_container_reading_value.dart'; -import 'package:lightmeter/utils/inherited_generics.dart'; +import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; class ReadingsContainer extends StatelessWidget { @@ -79,7 +79,7 @@ class ReadingsContainer extends StatelessWidget { Expanded( child: _IsoValuePicker( selectedValue: iso, - values: context.listen().isoValues, + values: EquipmentProfiles.selectedOf(context).isoValues, onChanged: onIsoChanged, ), ), @@ -87,7 +87,7 @@ class ReadingsContainer extends StatelessWidget { Expanded( child: _NdValuePicker( selectedValue: nd, - values: context.listen().ndValues, + values: EquipmentProfiles.selectedOf(context).ndValues, onChanged: onNdChanged, ), ), @@ -107,19 +107,19 @@ class _EquipmentProfilePicker extends StatelessWidget { @override Widget build(BuildContext context) { - return AnimatedDialogPicker( + return AnimatedDialogPicker( icon: Icons.camera, title: S.of(context).equipmentProfile, - selectedValue: context.listen(), - values: context.listen(), + selectedValue: EquipmentProfiles.selectedOf(context), + values: EquipmentProfiles.of(context), itemTitleBuilder: (_, value) => Text(value.id.isEmpty ? S.of(context).none : value.name), onChanged: EquipmentProfileProvider.of(context).setProfile, closedChild: ReadingValueContainer.singleValue( value: ReadingValue( label: S.of(context).equipmentProfile, - value: context.listen().id.isEmpty + value: EquipmentProfiles.selectedOf(context).id.isEmpty ? S.of(context).none - : context.listen().name, + : EquipmentProfiles.selectedOf(context).name, ), ), ); diff --git a/lib/screens/metering/screen_metering.dart b/lib/screens/metering/screen_metering.dart index bb72887..d13d8a3 100644 --- a/lib/screens/metering/screen_metering.dart +++ b/lib/screens/metering/screen_metering.dart @@ -7,7 +7,7 @@ import 'package:lightmeter/data/models/exposure_pair.dart'; import 'package:lightmeter/data/models/film.dart'; import 'package:lightmeter/data/models/metering_screen_layout_config.dart'; import 'package:lightmeter/environment.dart'; -import 'package:lightmeter/providers/equipment_profile_provider.dart'; + import 'package:lightmeter/providers/ev_source_type_provider.dart'; import 'package:lightmeter/screens/metering/bloc_metering.dart'; import 'package:lightmeter/screens/metering/components/bottom_controls/provider_bottom_controls.dart'; @@ -16,6 +16,7 @@ import 'package:lightmeter/screens/metering/components/light_sensor_container/pr import 'package:lightmeter/screens/metering/event_metering.dart'; import 'package:lightmeter/screens/metering/state_metering.dart'; import 'package:lightmeter/utils/inherited_generics.dart'; +import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; class MeteringScreen extends StatelessWidget { @@ -87,8 +88,7 @@ class _InheritedListeners extends StatelessWidget { aspect: MeteringScreenLayoutFeature.equipmentProfiles, onDidChangeDependencies: (value) { if (!value) { - EquipmentProfileProvider.of(context) - .setProfile(context.get().first); + EquipmentProfileProvider.of(context).setProfile(EquipmentProfiles.of(context).first); } }, child: child, @@ -123,7 +123,7 @@ class MeteringContainerBuidler extends StatelessWidget { ? buildExposureValues( ev!, context.listen(), - context.listen(), + EquipmentProfiles.selectedOf(context), film, ) : []; 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 25ca59a..1819e7f 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 @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:lightmeter/generated/l10n.dart'; -import 'package:lightmeter/providers/equipment_profile_provider.dart'; + import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_container/widget_container_equipment_profile.dart'; import 'package:lightmeter/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_name_dialog/widget_dialog_equipment_profile_name.dart'; import 'package:lightmeter/screens/shared/sliver_screen/screen_sliver.dart'; -import 'package:lightmeter/utils/inherited_generics.dart'; +import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; class EquipmentProfilesScreen extends StatefulWidget { @@ -19,13 +19,12 @@ class _EquipmentProfilesScreenState extends State { static const maxProfiles = 5 + 1; // replace with a constant from iap late List> profileContainersKeys = []; - int get profilesCount => context.listen().length; + int get profilesCount => EquipmentProfiles.of(context).length; @override - void initState() { - super.initState(); - profileContainersKeys = context - .get() + void didChangeDependencies() { + super.didChangeDependencies(); + profileContainersKeys = EquipmentProfiles.of(context) .map((e) => GlobalKey(debugLabel: e.id)) .toList(); } @@ -58,14 +57,14 @@ class _EquipmentProfilesScreenState extends State { ), child: EquipmentProfileContainer( key: profileContainersKeys[index], - data: context.listen()[index], + data: EquipmentProfiles.of(context)[index], onExpand: () => _keepExpandedAt(index), onUpdate: (profileData) => _updateProfileAt(profileData, index), onDelete: () => _removeProfileAt(index), ), ) : const SizedBox.shrink(), - childCount: profileContainersKeys.length, + childCount: profilesCount, ), ), ], @@ -79,18 +78,16 @@ class _EquipmentProfilesScreenState extends State { ).then((value) { if (value != null) { EquipmentProfileProvider.of(context).addProfile(value); - profileContainersKeys.add(GlobalKey()); } }); } - void _updateProfileAt(EquipmentProfileData data, int index) { + void _updateProfileAt(EquipmentProfile data, int index) { EquipmentProfileProvider.of(context).updateProdile(data); } void _removeProfileAt(int index) { - EquipmentProfileProvider.of(context).deleteProfile(context.listen()[index]); - profileContainersKeys.removeAt(index); + EquipmentProfileProvider.of(context).deleteProfile(EquipmentProfiles.of(context)[index]); } void _keepExpandedAt(int index) {