save & restore MeteringScreenLayoutConfig

This commit is contained in:
Vadim 2023-04-05 21:46:07 +03:00
parent a875a9c8a8
commit 82a6d70a7c
7 changed files with 53 additions and 22 deletions

View file

@ -18,7 +18,7 @@ import 'environment.dart';
import 'generated/l10n.dart'; import 'generated/l10n.dart';
import 'providers/equipment_profile_provider.dart'; import 'providers/equipment_profile_provider.dart';
import 'providers/ev_source_type_provider.dart'; import 'providers/ev_source_type_provider.dart';
import 'providers/features_provider.dart'; import 'providers/metering_screen_layout_provider.dart';
import 'providers/theme_provider.dart'; import 'providers/theme_provider.dart';
import 'screens/metering/flow_metering.dart'; import 'screens/metering/flow_metering.dart';
import 'screens/settings/flow_settings.dart'; import 'screens/settings/flow_settings.dart';

View file

@ -0,0 +1,10 @@
enum MeteringScreenLayoutFeature { extremeExposurePairs, filmPicker }
typedef MeteringScreenLayoutConfig = Map<MeteringScreenLayoutFeature, bool>;
extension MeteringScreenLayoutConfigJson on MeteringScreenLayoutConfig {
static MeteringScreenLayoutConfig fromJson(Map<String, dynamic> data) => data.map(
(key, value) => MapEntry(MeteringScreenLayoutFeature.values[int.parse(key)], value as bool));
Map<String, dynamic> toJson() => map((key, value) => MapEntry(key.index.toString(), value));
}

View file

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/supported_locale.dart'; import 'package:lightmeter/data/models/supported_locale.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
@ -5,6 +7,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'models/ev_source_type.dart'; import 'models/ev_source_type.dart';
import 'models/film.dart'; import 'models/film.dart';
import 'models/metering_screen_layout_config.dart';
import 'models/theme_type.dart'; import 'models/theme_type.dart';
class UserPreferencesService { class UserPreferencesService {
@ -14,6 +17,7 @@ class UserPreferencesService {
static const _evSourceTypeKey = "evSourceType"; static const _evSourceTypeKey = "evSourceType";
static const _cameraEvCalibrationKey = "cameraEvCalibration"; static const _cameraEvCalibrationKey = "cameraEvCalibration";
static const _lightSensorEvCalibrationKey = "lightSensorEvCalibration"; static const _lightSensorEvCalibrationKey = "lightSensorEvCalibration";
static const _meteringScreenLayoutKey = "meteringScreenLayout";
static const _filmKey = "film"; static const _filmKey = "film";
static const _caffeineKey = "caffeine"; static const _caffeineKey = "caffeine";
@ -80,6 +84,20 @@ class UserPreferencesService {
bool get caffeine => _sharedPreferences.getBool(_caffeineKey) ?? false; bool get caffeine => _sharedPreferences.getBool(_caffeineKey) ?? false;
set caffeine(bool value) => _sharedPreferences.setBool(_caffeineKey, value); set caffeine(bool value) => _sharedPreferences.setBool(_caffeineKey, value);
MeteringScreenLayoutConfig get meteringScreenLayout {
final configJson = _sharedPreferences.getString(_meteringScreenLayoutKey);
if (configJson != null) {
return MeteringScreenLayoutConfigJson.fromJson(json.decode(configJson));
} else {
return {
MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true,
};
}
}
set meteringScreenLayout(MeteringScreenLayoutConfig value) =>
_sharedPreferences.setString(_meteringScreenLayoutKey, json.encode(value.toJson()));
bool get haptics => _sharedPreferences.getBool(_hapticsKey) ?? true; bool get haptics => _sharedPreferences.getBool(_hapticsKey) ?? true;
set haptics(bool value) => _sharedPreferences.setBool(_hapticsKey, value); set haptics(bool value) => _sharedPreferences.setBool(_hapticsKey, value);

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
enum MeteringScreenLayoutFeature { extremeExposurePairs, filmPicker } import 'package:lightmeter/data/shared_prefs_service.dart';
import 'package:provider/provider.dart';
class MeteringScreenLayoutProvider extends StatefulWidget { class MeteringScreenLayoutProvider extends StatefulWidget {
final Widget child; final Widget child;
@ -16,52 +17,51 @@ class MeteringScreenLayoutProvider extends StatefulWidget {
} }
class MeteringScreenLayoutProviderState extends State<MeteringScreenLayoutProvider> { class MeteringScreenLayoutProviderState extends State<MeteringScreenLayoutProvider> {
final Map<MeteringScreenLayoutFeature, bool> _features = { late final MeteringScreenLayoutConfig _config =
MeteringScreenLayoutFeature.extremeExposurePairs: true, context.read<UserPreferencesService>().meteringScreenLayout;
MeteringScreenLayoutFeature.filmPicker: true,
};
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MeteringScreenLayout( return MeteringScreenLayout(
features: Map<MeteringScreenLayoutFeature, bool>.from(_features), config: MeteringScreenLayoutConfig.from(_config),
child: widget.child, child: widget.child,
); );
} }
void updateFeatures(Map<MeteringScreenLayoutFeature, bool> features) { void updateFeatures(MeteringScreenLayoutConfig config) {
setState(() { setState(() {
features.forEach((key, value) { config.forEach((key, value) {
_features.update( _config.update(
key, key,
(_) => value, (_) => value,
ifAbsent: () => value, ifAbsent: () => value,
); );
}); });
}); });
context.read<UserPreferencesService>().meteringScreenLayout = _config;
} }
} }
class MeteringScreenLayout extends InheritedModel<MeteringScreenLayoutFeature> { class MeteringScreenLayout extends InheritedModel<MeteringScreenLayoutFeature> {
final Map<MeteringScreenLayoutFeature, bool> features; final MeteringScreenLayoutConfig config;
const MeteringScreenLayout({ const MeteringScreenLayout({
required this.features, required this.config,
required super.child, required super.child,
super.key, super.key,
}); });
static Map<MeteringScreenLayoutFeature, bool> of(BuildContext context, {bool listen = true}) { static MeteringScreenLayoutConfig of(BuildContext context, {bool listen = true}) {
if (listen) { if (listen) {
return context.dependOnInheritedWidgetOfExactType<MeteringScreenLayout>()!.features; return context.dependOnInheritedWidgetOfExactType<MeteringScreenLayout>()!.config;
} else { } else {
return context.findAncestorWidgetOfExactType<MeteringScreenLayout>()!.features; return context.findAncestorWidgetOfExactType<MeteringScreenLayout>()!.config;
} }
} }
static bool featureStatusOf(BuildContext context, MeteringScreenLayoutFeature feature) { static bool featureStatusOf(BuildContext context, MeteringScreenLayoutFeature feature) {
return InheritedModel.inheritFrom<MeteringScreenLayout>(context, aspect: feature)! return InheritedModel.inheritFrom<MeteringScreenLayout>(context, aspect: feature)!
.features[feature]!; .config[feature]!;
} }
@override @override
@ -73,7 +73,7 @@ class MeteringScreenLayout extends InheritedModel<MeteringScreenLayoutFeature> {
Set<MeteringScreenLayoutFeature> dependencies, Set<MeteringScreenLayoutFeature> dependencies,
) { ) {
for (final dependecy in dependencies) { for (final dependecy in dependencies) {
if (oldWidget.features[dependecy] != features[dependecy]) { if (oldWidget.config[dependecy] != config[dependecy]) {
return true; return true;
} }
} }

View file

@ -2,9 +2,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lightmeter/data/models/exposure_pair.dart'; import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart'; import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/features.dart'; import 'package:lightmeter/features.dart';
import 'package:lightmeter/platform_config.dart'; import 'package:lightmeter/platform_config.dart';
import 'package:lightmeter/providers/features_provider.dart'; import 'package:lightmeter/providers/metering_screen_layout_provider.dart';
import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/res/dimens.dart';
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_view/widget_camera_view.dart'; import 'package:lightmeter/screens/metering/components/camera_container/components/camera_view/widget_camera_view.dart';
import 'package:lightmeter/screens/metering/components/camera_container/models/camera_error_type.dart'; import 'package:lightmeter/screens/metering/components/camera_container/models/camera_error_type.dart';

View file

@ -1,10 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/exposure_pair.dart'; import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart'; import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/features.dart'; import 'package:lightmeter/features.dart';
import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/providers/equipment_profile_provider.dart'; import 'package:lightmeter/providers/equipment_profile_provider.dart';
import 'package:lightmeter/providers/features_provider.dart'; import 'package:lightmeter/providers/metering_screen_layout_provider.dart';
import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/res/dimens.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/providers/features_provider.dart'; import 'package:lightmeter/providers/metering_screen_layout_provider.dart';
import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/res/dimens.dart';
class MeteringScreenLayoutFeaturesDialog extends StatefulWidget { class MeteringScreenLayoutFeaturesDialog extends StatefulWidget {
@ -13,7 +14,7 @@ class MeteringScreenLayoutFeaturesDialog extends StatefulWidget {
class _MeteringScreenLayoutFeaturesDialogState extends State<MeteringScreenLayoutFeaturesDialog> { class _MeteringScreenLayoutFeaturesDialogState extends State<MeteringScreenLayoutFeaturesDialog> {
late final _features = late final _features =
Map<MeteringScreenLayoutFeature, bool>.from(MeteringScreenLayout.of(context, listen: false)); MeteringScreenLayoutConfig.from(MeteringScreenLayout.of(context, listen: false));
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {