diff --git a/lib/screens/settings/components/camera/camera_features/widget_list_tile_camera_features.dart b/lib/screens/settings/components/camera/camera_features/widget_list_tile_camera_features.dart index f9687c2..86f86c3 100644 --- a/lib/screens/settings/components/camera/camera_features/widget_list_tile_camera_features.dart +++ b/lib/screens/settings/components/camera/camera_features/widget_list_tile_camera_features.dart @@ -4,7 +4,6 @@ import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/providers/services_provider.dart'; import 'package:lightmeter/providers/user_preferences_provider.dart'; import 'package:lightmeter/screens/settings/components/shared/dialog_switch/widget_dialog_switch.dart'; -import 'package:lightmeter/screens/settings/components/shared/iap_list_tile/widget_list_tile_iap.dart'; class CameraFeaturesListTile extends StatelessWidget { const CameraFeaturesListTile({super.key}); @@ -15,28 +14,43 @@ class CameraFeaturesListTile extends StatelessWidget { leading: const Icon(Icons.camera_alt_outlined), title: Text(S.of(context).cameraFeatures), onTap: () { + UserPreferencesProvider.cameraConfigOf(context).entries.map( + (entry) => DialogSwitchListItem( + value: CameraFeature.spotMetering, + title: S.of(context).cameraFeatureSpotMetering, + subtitle: S.of(context).cameraFeatureSpotMeteringHint, + initialValue: UserPreferencesProvider.cameraFeatureOf(context, CameraFeature.spotMetering), + isProRequired: true, + ), + ); showDialog( context: context, builder: (_) => DialogSwitch( icon: Icons.camera_alt_outlined, title: S.of(context).cameraFeatures, - values: UserPreferencesProvider.cameraConfigOf(context), - enabledAdapter: (feature) => switch (feature) { - CameraFeature.spotMetering => true, - CameraFeature.histogram => true, - CameraFeature.showFocalLength => - ServicesProvider.of(context).userPreferencesService.cameraFocalLength != null, - }, - titleAdapter: (context, feature) => switch (feature) { - CameraFeature.spotMetering => S.of(context).cameraFeatureSpotMetering, - CameraFeature.histogram => S.of(context).cameraFeatureHistogram, - CameraFeature.showFocalLength => S.of(context).cameraFeaturesShowFocalLength, - }, - subtitleAdapter: (context, feature) => switch (feature) { - CameraFeature.spotMetering => S.of(context).cameraFeatureSpotMeteringHint, - CameraFeature.histogram => S.of(context).cameraFeatureHistogramHint, - CameraFeature.showFocalLength => S.of(context).cameraFeaturesShowFocalLengthHint, - }, + items: [ + DialogSwitchListItem( + value: CameraFeature.showFocalLength, + title: S.of(context).cameraFeaturesShowFocalLength, + subtitle: S.of(context).cameraFeaturesShowFocalLengthHint, + initialValue: UserPreferencesProvider.cameraFeatureOf(context, CameraFeature.showFocalLength), + isEnabled: ServicesProvider.of(context).userPreferencesService.cameraFocalLength != null, + ), + DialogSwitchListItem( + value: CameraFeature.spotMetering, + title: S.of(context).cameraFeatureSpotMetering, + subtitle: S.of(context).cameraFeatureSpotMeteringHint, + initialValue: UserPreferencesProvider.cameraFeatureOf(context, CameraFeature.spotMetering), + isProRequired: true, + ), + DialogSwitchListItem( + value: CameraFeature.histogram, + title: S.of(context).cameraFeatureHistogram, + subtitle: S.of(context).cameraFeatureHistogramHint, + initialValue: UserPreferencesProvider.cameraFeatureOf(context, CameraFeature.histogram), + isProRequired: true, + ), + ], onSave: UserPreferencesProvider.of(context).setCameraFeature, ), ); diff --git a/lib/screens/settings/components/metering/components/metering_screen_layout/widget_list_tile_metering_screen_layout.dart b/lib/screens/settings/components/metering/components/metering_screen_layout/widget_list_tile_metering_screen_layout.dart index 985e4d7..0898541 100644 --- a/lib/screens/settings/components/metering/components/metering_screen_layout/widget_list_tile_metering_screen_layout.dart +++ b/lib/screens/settings/components/metering/components/metering_screen_layout/widget_list_tile_metering_screen_layout.dart @@ -22,8 +22,16 @@ class MeteringScreenLayoutListTile extends StatelessWidget { icon: Icons.layers_outlined, title: S.of(context).meteringScreenLayout, description: S.of(context).meteringScreenLayoutHint, - values: UserPreferencesProvider.meteringScreenConfigOf(context), - titleAdapter: _toStringLocalized, + items: UserPreferencesProvider.meteringScreenConfigOf(context) + .entries + .map( + (entry) => DialogSwitchListItem( + value: entry.key, + title: _toStringLocalized(context, entry.key), + initialValue: UserPreferencesProvider.meteringScreenFeatureOf(context, entry.key), + ), + ) + .toList(growable: false), onSave: (value) { if (!value[MeteringScreenLayoutFeature.equipmentProfiles]!) { EquipmentProfilesProvider.of(context).selectProfile(EquipmentProfiles.of(context).first); diff --git a/lib/screens/settings/components/shared/dialog_switch/widget_dialog_switch.dart b/lib/screens/settings/components/shared/dialog_switch/widget_dialog_switch.dart index 56a66c0..8b66209 100644 --- a/lib/screens/settings/components/shared/dialog_switch/widget_dialog_switch.dart +++ b/lib/screens/settings/components/shared/dialog_switch/widget_dialog_switch.dart @@ -1,27 +1,41 @@ import 'package:flutter/material.dart'; import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/res/dimens.dart'; +import 'package:lightmeter/utils/context_utils.dart'; +import 'package:lightmeter/utils/guard_pro_tap.dart'; typedef StringAdapter = String Function(BuildContext context, T value); +class DialogSwitchListItem { + final T value; + final String title; + final String? subtitle; + final bool initialValue; + final bool isEnabled; + final bool isProRequired; + + const DialogSwitchListItem({ + required this.value, + required this.title, + this.subtitle, + required this.initialValue, + this.isEnabled = true, + this.isProRequired = false, + }); +} + class DialogSwitch extends StatefulWidget { final IconData icon; final String title; final String? description; - final Map values; - final StringAdapter titleAdapter; - final StringAdapter? subtitleAdapter; - final bool Function(T value)? enabledAdapter; + final List> items; final ValueChanged> onSave; const DialogSwitch({ required this.icon, required this.title, this.description, - required this.values, - required this.titleAdapter, - this.subtitleAdapter, - this.enabledAdapter, + required this.items, required this.onSave, super.key, }); @@ -31,7 +45,11 @@ class DialogSwitch extends StatefulWidget { } class _DialogSwitchState extends State> { - late final Map _features = Map.from(widget.values); + late final Map _features = Map.fromEntries( + widget.items.map( + (item) => MapEntry(item.value, item.initialValue), + ), + ); @override Widget build(BuildContext context) { @@ -54,22 +72,15 @@ class _DialogSwitchState extends State> { ], ListView( shrinkWrap: true, - children: _features.entries.map( - (entry) { - final isEnabled = widget.enabledAdapter?.call(entry.key) ?? true; + children: widget.items.map( + (item) { + final value = _features[item.value]!; return SwitchListTile( contentPadding: EdgeInsets.symmetric(horizontal: Dimens.dialogTitlePadding.left), - title: Text(widget.titleAdapter(context, entry.key)), - subtitle: - widget.subtitleAdapter != null ? Text(widget.subtitleAdapter!.call(context, entry.key)) : null, - value: _features[entry.key]!, - onChanged: isEnabled - ? (value) { - setState(() { - _features.update(entry.key, (_) => value); - }); - } - : null, + title: Text(item.title), + subtitle: item.subtitle != null ? Text(item.subtitle!) : null, + value: item.isProRequired ? context.isPro && value : value, + onChanged: item.isEnabled ? (value) => _setItem(item, value) : null, ); }, ).toList(), @@ -93,4 +104,18 @@ class _DialogSwitchState extends State> { ], ); } + + void _setItem(DialogSwitchListItem item, bool value) { + void setItemState() { + setState(() { + _features.update(item.value, (_) => value); + }); + } + + if (item.isProRequired) { + guardProTap(context, setItemState); + } else { + setItemState(); + } + } } diff --git a/lib/utils/guard_pro_tap.dart b/lib/utils/guard_pro_tap.dart new file mode 100644 index 0000000..624bd05 --- /dev/null +++ b/lib/utils/guard_pro_tap.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; +import 'package:lightmeter/navigation/routes.dart'; +import 'package:lightmeter/utils/context_utils.dart'; + +void guardProTap(BuildContext context, VoidCallback callback) { + if (context.isPro) { + callback(); + } else { + Navigator.of(context).pushNamed(NavigationRoutes.proFeaturesScreen.name); + } +}