diff --git a/lib/data/shared_prefs_service.dart b/lib/data/shared_prefs_service.dart index 443f2e5..3bb6dfb 100644 --- a/lib/data/shared_prefs_service.dart +++ b/lib/data/shared_prefs_service.dart @@ -16,6 +16,7 @@ class UserPreferencesService { static const evSourceTypeKey = "evSourceType"; static const stopTypeKey = "stopType"; + static const showEv100Key = "showEv100"; static const cameraEvCalibrationKey = "cameraEvCalibration"; static const lightSensorEvCalibrationKey = "lightSensorEvCalibration"; static const meteringScreenLayoutKey = "meteringScreenLayout"; @@ -84,6 +85,9 @@ class UserPreferencesService { StopType get stopType => StopType.values[_sharedPreferences.getInt(stopTypeKey) ?? 2]; set stopType(StopType value) => _sharedPreferences.setInt(stopTypeKey, value.index); + bool get showEv100 => _sharedPreferences.getBool(showEv100Key) ?? false; + set showEv100(bool value) => _sharedPreferences.setBool(showEv100Key, value); + MeteringScreenLayoutConfig get meteringScreenLayout { final configJson = _sharedPreferences.getString(meteringScreenLayoutKey); if (configJson != null) { diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 13d5cbd..02dbb3d 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -34,6 +34,7 @@ "calibrationMessageCameraOnly": "The accuracy of the readings measured by this application depends entirely on the rear camera of the device. Therefore, consider testing this application and setting up an EV calibration value that will give you the desired measurement results.", "camera": "Camera", "lightSensor": "Light sensor", + "showEv100": "Show EV\u2081\u2080\u2080", "meteringScreenLayout": "Metering screen layout", "meteringScreenLayoutHint": "Hide elements on the metering screen that you don't need so that they don't waste exposure pairs list space.", "meteringScreenLayoutHintEquipmentProfiles": "Equipment profile picker", diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb index 66dc9fb..590976d 100644 --- a/lib/l10n/intl_fr.arb +++ b/lib/l10n/intl_fr.arb @@ -34,6 +34,7 @@ "calibrationMessageCameraOnly": "La précision des lectures mesurées par cette application dépend entièrement de la caméra arrière de l'appareil. Par conséquent, envisagez de tester cette application et de configurer une valeur d'étalonnage EV qui vous donnera les résultats de mesure souhaités.", "camera": "Caméra", "lightSensor": "Capteur de lumière", + "showEv100": "Montrer EV\u2081\u2080\u2080", "meteringScreenLayout": "Disposition de l'écran de mesure", "meteringScreenLayoutHint": "Masquer les éléments sur l'écran de mesure dont vous n'avez pas besoin pour qu'ils ne gaspillent pas de l'espace dans les paires d'exposition.", "meteringScreenLayoutHintEquipmentProfiles": "Sélecteur de profil de l'équipement", diff --git a/lib/l10n/intl_ru.arb b/lib/l10n/intl_ru.arb index 367b707..e7f0743 100644 --- a/lib/l10n/intl_ru.arb +++ b/lib/l10n/intl_ru.arb @@ -34,6 +34,7 @@ "calibrationMessageCameraOnly": "Точность измерений данного приложения полностью зависит от точности камеры вашего устройства. Поэтому рекомендуется самостоятельно подобрать калибровочное значение, которое даст желаемый результат измерений.", "camera": "Камера", "lightSensor": "Датчик освещённости", + "showEv100": "Показывать EV\u2081\u2080\u2080", "meteringScreenLayout": "Элементы главного экрана", "meteringScreenLayoutHint": "Здесь вы можете скрыть некоторые ненужные или неиспользуемые элементы с главного экрана.", "meteringScreenLayoutHintEquipmentProfiles": "Выбор профиля оборудования", diff --git a/lib/l10n/intl_zh.arb b/lib/l10n/intl_zh.arb index 0055685..71fe757 100644 --- a/lib/l10n/intl_zh.arb +++ b/lib/l10n/intl_zh.arb @@ -34,6 +34,7 @@ "calibrationMessageCameraOnly": "此应用程序测量读数的准确s性完全取决于设备的后置摄像头。因此,请考虑测试此应用并手动设置 EV 校准,以获得准确的测量结果。", "camera": "摄像头", "lightSensor": "光传感器", + "showEv100": "显示 EV\u2081\u2080\u2080", "meteringScreenLayout": "布局", "meteringScreenLayoutHint": "隐藏不需要的元素,以免浪费曝光列表空间", "meteringScreenLayoutHintEquipmentProfiles": "设备配置选择", diff --git a/lib/providers/equipment_profile_provider.dart b/lib/providers/equipment_profile_provider.dart index 564c5ef..74397a5 100644 --- a/lib/providers/equipment_profile_provider.dart +++ b/lib/providers/equipment_profile_provider.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +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'; @@ -52,9 +53,9 @@ class EquipmentProfileProviderState extends State { return EquipmentProfiles( values: [ _defaultProfile, - if (IAPProducts.isPurchased(context, IAPProductType.paidFeatures)) ..._customProfiles, + if (context.isPro) ..._customProfiles, ], - selected: IAPProducts.isPurchased(context, IAPProductType.paidFeatures) ? _selectedProfile : _defaultProfile, + selected: context.isPro ? _selectedProfile : _defaultProfile, child: widget.child, ); } diff --git a/lib/providers/films_provider.dart b/lib/providers/films_provider.dart index aff6d01..3e9d02d 100644 --- a/lib/providers/films_provider.dart +++ b/lib/providers/films_provider.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +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'; @@ -44,11 +45,9 @@ class FilmsProviderState extends State { ], filmsInUse: [ const Film.other(), - if (IAPProducts.isPurchased(context, IAPProductType.paidFeatures)) ..._filmsInUse, + if (context.isPro) ..._filmsInUse, ], - selected: IAPProducts.isPurchased(context, IAPProductType.paidFeatures) - ? _selected - : const Film.other(), + selected: context.isPro ? _selected : const Film.other(), child: widget.child, ); } diff --git a/lib/providers/user_preferences_provider.dart b/lib/providers/user_preferences_provider.dart index 764f282..e2eecd7 100644 --- a/lib/providers/user_preferences_provider.dart +++ b/lib/providers/user_preferences_provider.dart @@ -53,6 +53,10 @@ class UserPreferencesProvider extends StatefulWidget { return _inheritFromEnumsModel(context, _Aspect.stopType).stopType; } + static bool showEv100Of(BuildContext context) { + return _inheritFromEnumsModel(context, _Aspect.showEv100).showEv100; + } + static CameraFeaturesConfig cameraConfigOf(BuildContext context) { return context.findAncestorWidgetOfExactType<_CameraFeaturesModel>()!.data; } @@ -83,6 +87,7 @@ class UserPreferencesProvider extends StatefulWidget { class _UserPreferencesProviderState extends State with WidgetsBindingObserver { late EvSourceType _evSourceType; late StopType _stopType = widget.userPreferencesService.stopType; + late bool _showEv100 = widget.userPreferencesService.showEv100; late MeteringScreenLayoutConfig _meteringScreenLayout = widget.userPreferencesService.meteringScreenLayout; late CameraFeaturesConfig _cameraFeatures = widget.userPreferencesService.cameraFeatures; late SupportedLocale _locale = widget.userPreferencesService.locale; @@ -135,6 +140,7 @@ class _UserPreferencesProviderState extends State with evSourceType: _evSourceType, locale: _locale, primaryColor: dynamicPrimaryColor ?? _primaryColor, + showEv100: _showEv100, stopType: _stopType, themeType: _themeType, child: _MeteringScreenLayoutModel( @@ -201,6 +207,13 @@ class _UserPreferencesProviderState extends State with widget.userPreferencesService.primaryColor = primaryColor; } + void toggleShowEv100() { + setState(() { + _showEv100 = !_showEv100; + }); + widget.userPreferencesService.showEv100 = _showEv100; + } + void setStopType(StopType stopType) { setState(() { _stopType = stopType; @@ -231,6 +244,7 @@ enum _Aspect { dynamicColorState, evSourceType, locale, + showEv100, stopType, theme, themeType, @@ -240,6 +254,7 @@ class _UserPreferencesModel extends InheritedModel<_Aspect> { final DynamicColorState dynamicColorState; final EvSourceType evSourceType; final SupportedLocale locale; + final bool showEv100; final StopType stopType; final ThemeType themeType; @@ -252,6 +267,7 @@ class _UserPreferencesModel extends InheritedModel<_Aspect> { required this.evSourceType, required this.locale, required Color primaryColor, + required this.showEv100, required this.stopType, required this.themeType, required super.child, @@ -267,6 +283,7 @@ class _UserPreferencesModel extends InheritedModel<_Aspect> { evSourceType != oldWidget.evSourceType || locale != oldWidget.locale || _primaryColor != oldWidget._primaryColor || + showEv100 != oldWidget.showEv100 || stopType != oldWidget.stopType || themeType != oldWidget.themeType; } @@ -279,6 +296,7 @@ class _UserPreferencesModel extends InheritedModel<_Aspect> { return (dependencies.contains(_Aspect.dynamicColorState) && dynamicColorState != oldWidget.dynamicColorState) || (dependencies.contains(_Aspect.evSourceType) && evSourceType != oldWidget.evSourceType) || (dependencies.contains(_Aspect.locale) && locale != oldWidget.locale) || + (dependencies.contains(_Aspect.showEv100) && showEv100 != oldWidget.showEv100) || (dependencies.contains(_Aspect.stopType) && stopType != oldWidget.stopType) || (dependencies.contains(_Aspect.theme) && (_brightness != oldWidget._brightness || _primaryColor != oldWidget._primaryColor)) || diff --git a/lib/screens/metering/components/bottom_controls/components/measure_button/widget_button_measure.dart b/lib/screens/metering/components/bottom_controls/components/measure_button/widget_button_measure.dart index 99bd2ae..e918557 100644 --- a/lib/screens/metering/components/bottom_controls/components/measure_button/widget_button_measure.dart +++ b/lib/screens/metering/components/bottom_controls/components/measure_button/widget_button_measure.dart @@ -1,15 +1,21 @@ import 'package:flutter/material.dart'; import 'package:lightmeter/generated/l10n.dart'; +import 'package:lightmeter/providers/user_preferences_provider.dart'; import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/screens/shared/filled_circle/widget_circle_filled.dart'; +import 'package:lightmeter/utils/context_utils.dart'; + +const String _subscript100 = '\u2081\u2080\u2080'; class MeteringMeasureButton extends StatefulWidget { final double? ev; + final double? ev100; final bool isMetering; final VoidCallback onTap; const MeteringMeasureButton({ required this.ev, + required this.ev100, required this.isMetering, required this.onTap, super.key, @@ -61,7 +67,7 @@ class _MeteringMeasureButtonState extends State { color: Theme.of(context).colorScheme.onSurface, size: Dimens.grid72 - Dimens.grid8, child: Center( - child: widget.ev != null ? _EvValueText(ev: widget.ev!) : null, + child: widget.ev != null ? _EvValueText(ev: widget.ev!, ev100: widget.ev100!) : null, ), ), ), @@ -83,16 +89,32 @@ class _MeteringMeasureButtonState extends State { class _EvValueText extends StatelessWidget { final double ev; + final double ev100; - const _EvValueText({required this.ev}); + const _EvValueText({ + required this.ev, + required this.ev100, + }); @override Widget build(BuildContext context) { final theme = Theme.of(context); return Text( - '${ev.toStringAsFixed(1)}\n${S.of(context).ev}', + _text(context), style: theme.textTheme.bodyMedium?.copyWith(color: theme.colorScheme.surface), textAlign: TextAlign.center, ); } + + String _text(BuildContext context) { + final bool showEv100 = context.isPro && UserPreferencesProvider.showEv100Of(context); + final StringBuffer buffer = StringBuffer() + ..writeAll([ + (showEv100 ? ev100 : ev).toStringAsFixed(1), + '\n', + S.of(context).ev, + if (showEv100) _subscript100, + ]); + return buffer.toString(); + } } diff --git a/lib/screens/metering/components/bottom_controls/provider_bottom_controls.dart b/lib/screens/metering/components/bottom_controls/provider_bottom_controls.dart index dd4a9be..f9d6d47 100644 --- a/lib/screens/metering/components/bottom_controls/provider_bottom_controls.dart +++ b/lib/screens/metering/components/bottom_controls/provider_bottom_controls.dart @@ -5,6 +5,7 @@ import 'package:lightmeter/screens/metering/components/bottom_controls/widget_bo class MeteringBottomControlsProvider extends StatelessWidget { final double? ev; + final double? ev100; final bool isMetering; final VoidCallback? onSwitchEvSourceType; final VoidCallback onMeasure; @@ -12,6 +13,7 @@ class MeteringBottomControlsProvider extends StatelessWidget { const MeteringBottomControlsProvider({ required this.ev, + required this.ev100, required this.isMetering, required this.onSwitchEvSourceType, required this.onMeasure, @@ -35,6 +37,7 @@ class MeteringBottomControlsProvider extends StatelessWidget { ), child: MeteringBottomControls( ev: ev, + ev100: ev100, isMetering: isMetering, onSwitchEvSourceType: onSwitchEvSourceType, onMeasure: onMeasure, diff --git a/lib/screens/metering/components/bottom_controls/widget_bottom_controls.dart b/lib/screens/metering/components/bottom_controls/widget_bottom_controls.dart index 31ecac4..0eef568 100644 --- a/lib/screens/metering/components/bottom_controls/widget_bottom_controls.dart +++ b/lib/screens/metering/components/bottom_controls/widget_bottom_controls.dart @@ -7,6 +7,7 @@ import 'package:lightmeter/screens/metering/components/bottom_controls/component class MeteringBottomControls extends StatelessWidget { final double? ev; + final double? ev100; final bool isMetering; final VoidCallback? onSwitchEvSourceType; final VoidCallback onMeasure; @@ -14,6 +15,7 @@ class MeteringBottomControls extends StatelessWidget { const MeteringBottomControls({ required this.ev, + required this.ev100, required this.isMetering, required this.onSwitchEvSourceType, required this.onMeasure, @@ -58,6 +60,7 @@ class MeteringBottomControls extends StatelessWidget { const Spacer(), MeteringMeasureButton( ev: ev, + ev100: ev100, isMetering: isMetering, onTap: onMeasure, ), diff --git a/lib/screens/metering/components/camera_container/components/camera_preview/widget_camera_preview.dart b/lib/screens/metering/components/camera_container/components/camera_preview/widget_camera_preview.dart index e6f1699..464228f 100644 --- a/lib/screens/metering/components/camera_container/components/camera_preview/widget_camera_preview.dart +++ b/lib/screens/metering/components/camera_container/components/camera_preview/widget_camera_preview.dart @@ -9,7 +9,7 @@ import 'package:lightmeter/screens/metering/components/camera_container/componen import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/camera_view_placeholder/widget_placeholder_camera_view.dart'; import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/histogram/widget_histogram.dart'; import 'package:lightmeter/screens/metering/components/camera_container/models/camera_error_type.dart'; -import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; +import 'package:lightmeter/utils/context_utils.dart'; class CameraPreview extends StatefulWidget { final CameraController? controller; @@ -93,7 +93,7 @@ class _CameraPreviewBuilderState extends State<_CameraPreviewBuilder> { alignment: Alignment.bottomCenter, children: [ CameraView(controller: widget.controller), - if (IAPProducts.isPurchased(context, IAPProductType.paidFeatures)) ...[ + if (context.isPro) ...[ if (UserPreferencesProvider.cameraFeatureOf( context, CameraFeature.histogram, diff --git a/lib/screens/metering/components/camera_container/widget_container_camera.dart b/lib/screens/metering/components/camera_container/widget_container_camera.dart index a4cb3e8..5ed2b43 100644 --- a/lib/screens/metering/components/camera_container/widget_container_camera.dart +++ b/lib/screens/metering/components/camera_container/widget_container_camera.dart @@ -17,7 +17,6 @@ import 'package:lightmeter/screens/metering/components/shared/exposure_pairs_lis import 'package:lightmeter/screens/metering/components/shared/metering_top_bar/widget_top_bar_metering.dart'; import 'package:lightmeter/screens/metering/components/shared/readings_container/widget_container_readings.dart'; import 'package:lightmeter/utils/context_utils.dart'; -import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; class CameraContainer extends StatelessWidget { @@ -102,9 +101,8 @@ class CameraContainer extends StatelessWidget { } double _meteringContainerHeight(BuildContext context) { - final isPro = IAPProducts.isPurchased(context, IAPProductType.paidFeatures); double enabledFeaturesHeight = 0; - if (!isPro) { + if (!context.isPro) { enabledFeaturesHeight += Dimens.readingContainerSingleValueHeight; enabledFeaturesHeight += Dimens.paddingS; } else { 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 30d1392..ce373a8 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 @@ -10,7 +10,6 @@ import 'package:lightmeter/screens/metering/components/shared/readings_container import 'package:lightmeter/screens/metering/components/shared/readings_container/components/lightmeter_pro/widget_lightmeter_pro.dart'; import 'package:lightmeter/screens/metering/components/shared/readings_container/components/nd_picker/widget_picker_nd.dart'; import 'package:lightmeter/utils/context_utils.dart'; -import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; class ReadingsContainer extends StatelessWidget { @@ -33,15 +32,14 @@ class ReadingsContainer extends StatelessWidget { @override Widget build(BuildContext context) { - final isPro = IAPProducts.isPurchased(context, IAPProductType.paidFeatures); return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - if (!isPro) ...[ + if (!context.isPro) ...[ const LightmeterProAnimatedDialog(), const _InnerPadding(), ], - if (isPro && context.meteringFeature(MeteringScreenLayoutFeature.equipmentProfiles)) ...[ + if (context.isPro && context.meteringFeature(MeteringScreenLayoutFeature.equipmentProfiles)) ...[ const EquipmentProfilePicker(), const _InnerPadding(), ], @@ -52,7 +50,7 @@ class ReadingsContainer extends StatelessWidget { ), const _InnerPadding(), ], - if (isPro && context.meteringFeature(MeteringScreenLayoutFeature.filmPicker)) ...[ + if (context.isPro && context.meteringFeature(MeteringScreenLayoutFeature.filmPicker)) ...[ FilmPicker(selectedIso: iso), const _InnerPadding(), ], diff --git a/lib/screens/metering/screen_metering.dart b/lib/screens/metering/screen_metering.dart index 380411f..836e6d0 100644 --- a/lib/screens/metering/screen_metering.dart +++ b/lib/screens/metering/screen_metering.dart @@ -40,6 +40,7 @@ class MeteringScreen extends StatelessWidget { BlocBuilder( builder: (context, state) => MeteringBottomControlsProvider( ev: state is MeteringDataState ? state.ev : null, + ev100: state is MeteringDataState ? state.ev100 : null, isMetering: state.isMetering, onSwitchEvSourceType: ServicesProvider.of(context).environment.hasLightSensor ? UserPreferencesProvider.of(context).toggleEvSourceType diff --git a/lib/screens/settings/components/metering/components/show_ev_100/widget_list_tile_show_ev_100.dart b/lib/screens/settings/components/metering/components/show_ev_100/widget_list_tile_show_ev_100.dart new file mode 100644 index 0000000..a92623e --- /dev/null +++ b/lib/screens/settings/components/metering/components/show_ev_100/widget_list_tile_show_ev_100.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; +import 'package:lightmeter/generated/l10n.dart'; +import 'package:lightmeter/providers/user_preferences_provider.dart'; +import 'package:lightmeter/res/dimens.dart'; +import 'package:lightmeter/screens/settings/components/shared/disable/widget_disable.dart'; +import 'package:lightmeter/utils/context_utils.dart'; + +class ShowEv100ListTile extends StatelessWidget { + const ShowEv100ListTile({super.key}); + + @override + Widget build(BuildContext context) { + return Disable( + disable: !context.isPro, + child: SwitchListTile( + secondary: const Icon(Icons.adjust), + title: Text(S.of(context).showEv100), + value: context.isPro && UserPreferencesProvider.showEv100Of(context), + onChanged: (_) => UserPreferencesProvider.of(context).toggleShowEv100(), + contentPadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM), + ), + ); + } +} diff --git a/lib/screens/settings/components/metering/widget_settings_section_metering.dart b/lib/screens/settings/components/metering/widget_settings_section_metering.dart index 0c6c07d..becf531 100644 --- a/lib/screens/settings/components/metering/widget_settings_section_metering.dart +++ b/lib/screens/settings/components/metering/widget_settings_section_metering.dart @@ -6,6 +6,7 @@ import 'package:lightmeter/screens/settings/components/metering/components/equip import 'package:lightmeter/screens/settings/components/metering/components/films/widget_list_tile_films.dart'; import 'package:lightmeter/screens/settings/components/metering/components/fractional_stops/widget_list_tile_fractional_stops.dart'; import 'package:lightmeter/screens/settings/components/metering/components/metering_screen_layout/widget_list_tile_metering_screen_layout.dart'; +import 'package:lightmeter/screens/settings/components/metering/components/show_ev_100/widget_list_tile_show_ev_100.dart'; import 'package:lightmeter/screens/settings/components/shared/settings_section/widget_settings_section.dart'; class MeteringSettingsSection extends StatelessWidget { @@ -18,6 +19,7 @@ class MeteringSettingsSection extends StatelessWidget { children: const [ StopTypeListTile(), CalibrationListTile(), + ShowEv100ListTile(), MeteringScreenLayoutListTile(), EquipmentProfilesListTile(), FilmsListTile(), diff --git a/lib/screens/settings/components/shared/iap_list_tile/widget_list_tile_iap.dart b/lib/screens/settings/components/shared/iap_list_tile/widget_list_tile_iap.dart index 5fd1d3d..8cc522a 100644 --- a/lib/screens/settings/components/shared/iap_list_tile/widget_list_tile_iap.dart +++ b/lib/screens/settings/components/shared/iap_list_tile/widget_list_tile_iap.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:lightmeter/screens/settings/components/shared/disable/widget_disable.dart'; +import 'package:lightmeter/utils/context_utils.dart'; import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; /// Depends on the product status and replaces [onTap] with purchase callback @@ -22,9 +23,8 @@ class IAPListTile extends StatelessWidget { @override Widget build(BuildContext context) { - final isPurchased = IAPProducts.isPurchased(context, IAPProductType.paidFeatures); return Disable( - disable: !isPurchased, + disable: !context.isPro, child: ListTile( leading: leading, title: title, diff --git a/lib/screens/settings/screen_settings.dart b/lib/screens/settings/screen_settings.dart index ea8e1c5..295e01c 100644 --- a/lib/screens/settings/screen_settings.dart +++ b/lib/screens/settings/screen_settings.dart @@ -7,7 +7,7 @@ import 'package:lightmeter/screens/settings/components/metering/widget_settings_ import 'package:lightmeter/screens/settings/components/theme/widget_settings_section_theme.dart'; import 'package:lightmeter/screens/settings/flow_settings.dart'; import 'package:lightmeter/screens/shared/sliver_screen/screen_sliver.dart'; -import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; +import 'package:lightmeter/utils/context_utils.dart'; class SettingsScreen extends StatefulWidget { const SettingsScreen({super.key}); @@ -38,8 +38,7 @@ class _SettingsScreenState extends State { SliverList( delegate: SliverChildListDelegate( [ - if (!IAPProducts.isPurchased(context, IAPProductType.paidFeatures)) - const LightmeterProSettingsSection(), + if (!context.isPro) const LightmeterProSettingsSection(), const MeteringSettingsSection(), const GeneralSettingsSection(), const ThemeSettingsSection(), diff --git a/test/data/shared_prefs_service_test.dart b/test/data/shared_prefs_service_test.dart index 96f4e1e..269d002 100644 --- a/test/data/shared_prefs_service_test.dart +++ b/test/data/shared_prefs_service_test.dart @@ -181,6 +181,25 @@ void main() { }); }); + group('showEv100', () { + test('get default', () { + when(() => sharedPreferences.getBool(UserPreferencesService.showEv100Key)).thenReturn(null); + expect(service.showEv100, false); + }); + + test('get', () { + when(() => sharedPreferences.getBool(UserPreferencesService.showEv100Key)).thenReturn(true); + expect(service.showEv100, true); + }); + + test('set', () { + when(() => sharedPreferences.setBool(UserPreferencesService.showEv100Key, false)) + .thenAnswer((_) => Future.value(true)); + service.showEv100 = false; + verify(() => sharedPreferences.setBool(UserPreferencesService.showEv100Key, false)).called(1); + }); + }); + group('meteringScreenLayout', () { test('get default', () { when( diff --git a/test/providers/user_preferences_provider_test.dart b/test/providers/user_preferences_provider_test.dart index b6dc2ae..1a91419 100644 --- a/test/providers/user_preferences_provider_test.dart +++ b/test/providers/user_preferences_provider_test.dart @@ -27,6 +27,7 @@ void main() { setUp(() { when(() => mockUserPreferencesService.evSourceType).thenReturn(EvSourceType.camera); + when(() => mockUserPreferencesService.showEv100).thenReturn(false); when(() => mockUserPreferencesService.stopType).thenReturn(StopType.third); when(() => mockUserPreferencesService.meteringScreenLayout).thenReturn({ MeteringScreenLayoutFeature.extremeExposurePairs: true, @@ -164,6 +165,27 @@ void main() { }, ); + testWidgets( + 'Toggle Ev100', + (tester) async { + when(() => mockUserPreferencesService.showEv100).thenReturn(false); + await pumpTestWidget( + tester, + builder: (context) => ElevatedButton( + onPressed: () => UserPreferencesProvider.of(context).toggleShowEv100(), + child: Text('${UserPreferencesProvider.showEv100Of(context)}'), + ), + ); + await tester.pumpAndSettle(); + expect(find.text("${false}"), findsOneWidget); + + await tester.tap(find.text("${false}")); + await tester.pumpAndSettle(); + expect(find.text("${true}"), findsOneWidget); + verify(() => mockUserPreferencesService.showEv100 = true).called(1); + }, + ); + testWidgets( 'Set metering screen layout config', (tester) async {