mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-24 16:30:40 +00:00
Compare commits
No commits in common. "d66404e0856fe055fcad555251926c2c56f52687" and "73d0c323234a4c8268177655a80621cd7c9f4e65" have entirely different histories.
d66404e085
...
73d0c32323
25 changed files with 46 additions and 175 deletions
|
@ -1,5 +1,5 @@
|
||||||
enum Feature { showUnlockProOnMainScreen }
|
enum Feature { unlockProFeaturesText }
|
||||||
|
|
||||||
const featuresDefaultValues = {
|
const featuresDefaultValues = {
|
||||||
Feature.showUnlockProOnMainScreen: false,
|
Feature.unlockProFeaturesText: true,
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,15 +52,9 @@ class RemoteConfigService implements IRemoteConfigService {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> fetchConfig() async {
|
Future<void> fetchConfig() async {
|
||||||
try {
|
|
||||||
// https://github.com/firebase/flutterfire/issues/6196#issuecomment-927751667
|
// https://github.com/firebase/flutterfire/issues/6196#issuecomment-927751667
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
await FirebaseRemoteConfig.instance.fetch();
|
await FirebaseRemoteConfig.instance.fetch();
|
||||||
} on FirebaseException catch (e) {
|
|
||||||
_logError('Firebase exception during Firebase Remote Config fetch: $e');
|
|
||||||
} catch (e) {
|
|
||||||
_logError('Error during Firebase Remote Config fetch: $e');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -130,7 +124,7 @@ class MockRemoteConfigService implements IRemoteConfigService {
|
||||||
extension on RemoteConfigValue {
|
extension on RemoteConfigValue {
|
||||||
dynamic toValue(Feature feature) {
|
dynamic toValue(Feature feature) {
|
||||||
switch (feature) {
|
switch (feature) {
|
||||||
case Feature.showUnlockProOnMainScreen:
|
case Feature.unlockProFeaturesText:
|
||||||
return asBool();
|
return asBool();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ class UserPreferencesService {
|
||||||
|
|
||||||
static const evSourceTypeKey = "evSourceType";
|
static const evSourceTypeKey = "evSourceType";
|
||||||
static const stopTypeKey = "stopType";
|
static const stopTypeKey = "stopType";
|
||||||
static const showEv100Key = "showEv100";
|
|
||||||
static const cameraEvCalibrationKey = "cameraEvCalibration";
|
static const cameraEvCalibrationKey = "cameraEvCalibration";
|
||||||
static const lightSensorEvCalibrationKey = "lightSensorEvCalibration";
|
static const lightSensorEvCalibrationKey = "lightSensorEvCalibration";
|
||||||
static const meteringScreenLayoutKey = "meteringScreenLayout";
|
static const meteringScreenLayoutKey = "meteringScreenLayout";
|
||||||
|
@ -85,9 +84,6 @@ class UserPreferencesService {
|
||||||
StopType get stopType => StopType.values[_sharedPreferences.getInt(stopTypeKey) ?? 2];
|
StopType get stopType => StopType.values[_sharedPreferences.getInt(stopTypeKey) ?? 2];
|
||||||
set stopType(StopType value) => _sharedPreferences.setInt(stopTypeKey, value.index);
|
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 {
|
MeteringScreenLayoutConfig get meteringScreenLayout {
|
||||||
final configJson = _sharedPreferences.getString(meteringScreenLayoutKey);
|
final configJson = _sharedPreferences.getString(meteringScreenLayoutKey);
|
||||||
if (configJson != null) {
|
if (configJson != null) {
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
"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.",
|
"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",
|
"camera": "Camera",
|
||||||
"lightSensor": "Light sensor",
|
"lightSensor": "Light sensor",
|
||||||
"showEv100": "Show EV\u2081\u2080\u2080",
|
|
||||||
"meteringScreenLayout": "Metering screen layout",
|
"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.",
|
"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",
|
"meteringScreenLayoutHintEquipmentProfiles": "Equipment profile picker",
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
"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.",
|
"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",
|
"camera": "Caméra",
|
||||||
"lightSensor": "Capteur de lumière",
|
"lightSensor": "Capteur de lumière",
|
||||||
"showEv100": "Montrer EV\u2081\u2080\u2080",
|
|
||||||
"meteringScreenLayout": "Disposition de l'écran de mesure",
|
"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.",
|
"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",
|
"meteringScreenLayoutHintEquipmentProfiles": "Sélecteur de profil de l'équipement",
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
"calibrationMessageCameraOnly": "Точность измерений данного приложения полностью зависит от точности камеры вашего устройства. Поэтому рекомендуется самостоятельно подобрать калибровочное значение, которое даст желаемый результат измерений.",
|
"calibrationMessageCameraOnly": "Точность измерений данного приложения полностью зависит от точности камеры вашего устройства. Поэтому рекомендуется самостоятельно подобрать калибровочное значение, которое даст желаемый результат измерений.",
|
||||||
"camera": "Камера",
|
"camera": "Камера",
|
||||||
"lightSensor": "Датчик освещённости",
|
"lightSensor": "Датчик освещённости",
|
||||||
"showEv100": "Показывать EV\u2081\u2080\u2080",
|
|
||||||
"meteringScreenLayout": "Элементы главного экрана",
|
"meteringScreenLayout": "Элементы главного экрана",
|
||||||
"meteringScreenLayoutHint": "Здесь вы можете скрыть некоторые ненужные или неиспользуемые элементы с главного экрана.",
|
"meteringScreenLayoutHint": "Здесь вы можете скрыть некоторые ненужные или неиспользуемые элементы с главного экрана.",
|
||||||
"meteringScreenLayoutHintEquipmentProfiles": "Выбор профиля оборудования",
|
"meteringScreenLayoutHintEquipmentProfiles": "Выбор профиля оборудования",
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
"calibrationMessageCameraOnly": "此应用程序测量读数的准确s性完全取决于设备的后置摄像头。因此,请考虑测试此应用并手动设置 EV 校准,以获得准确的测量结果。",
|
"calibrationMessageCameraOnly": "此应用程序测量读数的准确s性完全取决于设备的后置摄像头。因此,请考虑测试此应用并手动设置 EV 校准,以获得准确的测量结果。",
|
||||||
"camera": "摄像头",
|
"camera": "摄像头",
|
||||||
"lightSensor": "光传感器",
|
"lightSensor": "光传感器",
|
||||||
"showEv100": "显示 EV\u2081\u2080\u2080",
|
|
||||||
"meteringScreenLayout": "布局",
|
"meteringScreenLayout": "布局",
|
||||||
"meteringScreenLayoutHint": "隐藏不需要的元素,以免浪费曝光列表空间",
|
"meteringScreenLayoutHint": "隐藏不需要的元素,以免浪费曝光列表空间",
|
||||||
"meteringScreenLayoutHintEquipmentProfiles": "设备配置选择",
|
"meteringScreenLayoutHintEquipmentProfiles": "设备配置选择",
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:lightmeter/utils/context_utils.dart';
|
|
||||||
import 'package:lightmeter/utils/selectable_provider.dart';
|
import 'package:lightmeter/utils/selectable_provider.dart';
|
||||||
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
@ -53,9 +52,9 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
||||||
return EquipmentProfiles(
|
return EquipmentProfiles(
|
||||||
values: [
|
values: [
|
||||||
_defaultProfile,
|
_defaultProfile,
|
||||||
if (context.isPro) ..._customProfiles,
|
if (IAPProducts.isPurchased(context, IAPProductType.paidFeatures)) ..._customProfiles,
|
||||||
],
|
],
|
||||||
selected: context.isPro ? _selectedProfile : _defaultProfile,
|
selected: IAPProducts.isPurchased(context, IAPProductType.paidFeatures) ? _selectedProfile : _defaultProfile,
|
||||||
child: widget.child,
|
child: widget.child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:lightmeter/utils/context_utils.dart';
|
|
||||||
import 'package:lightmeter/utils/selectable_provider.dart';
|
import 'package:lightmeter/utils/selectable_provider.dart';
|
||||||
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
@ -45,9 +44,11 @@ class FilmsProviderState extends State<FilmsProvider> {
|
||||||
],
|
],
|
||||||
filmsInUse: [
|
filmsInUse: [
|
||||||
const Film.other(),
|
const Film.other(),
|
||||||
if (context.isPro) ..._filmsInUse,
|
if (IAPProducts.isPurchased(context, IAPProductType.paidFeatures)) ..._filmsInUse,
|
||||||
],
|
],
|
||||||
selected: context.isPro ? _selected : const Film.other(),
|
selected: IAPProducts.isPurchased(context, IAPProductType.paidFeatures)
|
||||||
|
? _selected
|
||||||
|
: const Film.other(),
|
||||||
child: widget.child,
|
child: widget.child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,10 +53,6 @@ class UserPreferencesProvider extends StatefulWidget {
|
||||||
return _inheritFromEnumsModel(context, _Aspect.stopType).stopType;
|
return _inheritFromEnumsModel(context, _Aspect.stopType).stopType;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool showEv100Of(BuildContext context) {
|
|
||||||
return _inheritFromEnumsModel(context, _Aspect.showEv100).showEv100;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CameraFeaturesConfig cameraConfigOf(BuildContext context) {
|
static CameraFeaturesConfig cameraConfigOf(BuildContext context) {
|
||||||
return context.findAncestorWidgetOfExactType<_CameraFeaturesModel>()!.data;
|
return context.findAncestorWidgetOfExactType<_CameraFeaturesModel>()!.data;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +83,6 @@ class UserPreferencesProvider extends StatefulWidget {
|
||||||
class _UserPreferencesProviderState extends State<UserPreferencesProvider> with WidgetsBindingObserver {
|
class _UserPreferencesProviderState extends State<UserPreferencesProvider> with WidgetsBindingObserver {
|
||||||
late EvSourceType _evSourceType;
|
late EvSourceType _evSourceType;
|
||||||
late StopType _stopType = widget.userPreferencesService.stopType;
|
late StopType _stopType = widget.userPreferencesService.stopType;
|
||||||
late bool _showEv100 = widget.userPreferencesService.showEv100;
|
|
||||||
late MeteringScreenLayoutConfig _meteringScreenLayout = widget.userPreferencesService.meteringScreenLayout;
|
late MeteringScreenLayoutConfig _meteringScreenLayout = widget.userPreferencesService.meteringScreenLayout;
|
||||||
late CameraFeaturesConfig _cameraFeatures = widget.userPreferencesService.cameraFeatures;
|
late CameraFeaturesConfig _cameraFeatures = widget.userPreferencesService.cameraFeatures;
|
||||||
late SupportedLocale _locale = widget.userPreferencesService.locale;
|
late SupportedLocale _locale = widget.userPreferencesService.locale;
|
||||||
|
@ -140,7 +135,6 @@ class _UserPreferencesProviderState extends State<UserPreferencesProvider> with
|
||||||
evSourceType: _evSourceType,
|
evSourceType: _evSourceType,
|
||||||
locale: _locale,
|
locale: _locale,
|
||||||
primaryColor: dynamicPrimaryColor ?? _primaryColor,
|
primaryColor: dynamicPrimaryColor ?? _primaryColor,
|
||||||
showEv100: _showEv100,
|
|
||||||
stopType: _stopType,
|
stopType: _stopType,
|
||||||
themeType: _themeType,
|
themeType: _themeType,
|
||||||
child: _MeteringScreenLayoutModel(
|
child: _MeteringScreenLayoutModel(
|
||||||
|
@ -207,13 +201,6 @@ class _UserPreferencesProviderState extends State<UserPreferencesProvider> with
|
||||||
widget.userPreferencesService.primaryColor = primaryColor;
|
widget.userPreferencesService.primaryColor = primaryColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleShowEv100() {
|
|
||||||
setState(() {
|
|
||||||
_showEv100 = !_showEv100;
|
|
||||||
});
|
|
||||||
widget.userPreferencesService.showEv100 = _showEv100;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setStopType(StopType stopType) {
|
void setStopType(StopType stopType) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_stopType = stopType;
|
_stopType = stopType;
|
||||||
|
@ -244,7 +231,6 @@ enum _Aspect {
|
||||||
dynamicColorState,
|
dynamicColorState,
|
||||||
evSourceType,
|
evSourceType,
|
||||||
locale,
|
locale,
|
||||||
showEv100,
|
|
||||||
stopType,
|
stopType,
|
||||||
theme,
|
theme,
|
||||||
themeType,
|
themeType,
|
||||||
|
@ -254,7 +240,6 @@ class _UserPreferencesModel extends InheritedModel<_Aspect> {
|
||||||
final DynamicColorState dynamicColorState;
|
final DynamicColorState dynamicColorState;
|
||||||
final EvSourceType evSourceType;
|
final EvSourceType evSourceType;
|
||||||
final SupportedLocale locale;
|
final SupportedLocale locale;
|
||||||
final bool showEv100;
|
|
||||||
final StopType stopType;
|
final StopType stopType;
|
||||||
final ThemeType themeType;
|
final ThemeType themeType;
|
||||||
|
|
||||||
|
@ -267,7 +252,6 @@ class _UserPreferencesModel extends InheritedModel<_Aspect> {
|
||||||
required this.evSourceType,
|
required this.evSourceType,
|
||||||
required this.locale,
|
required this.locale,
|
||||||
required Color primaryColor,
|
required Color primaryColor,
|
||||||
required this.showEv100,
|
|
||||||
required this.stopType,
|
required this.stopType,
|
||||||
required this.themeType,
|
required this.themeType,
|
||||||
required super.child,
|
required super.child,
|
||||||
|
@ -283,7 +267,6 @@ class _UserPreferencesModel extends InheritedModel<_Aspect> {
|
||||||
evSourceType != oldWidget.evSourceType ||
|
evSourceType != oldWidget.evSourceType ||
|
||||||
locale != oldWidget.locale ||
|
locale != oldWidget.locale ||
|
||||||
_primaryColor != oldWidget._primaryColor ||
|
_primaryColor != oldWidget._primaryColor ||
|
||||||
showEv100 != oldWidget.showEv100 ||
|
|
||||||
stopType != oldWidget.stopType ||
|
stopType != oldWidget.stopType ||
|
||||||
themeType != oldWidget.themeType;
|
themeType != oldWidget.themeType;
|
||||||
}
|
}
|
||||||
|
@ -296,7 +279,6 @@ class _UserPreferencesModel extends InheritedModel<_Aspect> {
|
||||||
return (dependencies.contains(_Aspect.dynamicColorState) && dynamicColorState != oldWidget.dynamicColorState) ||
|
return (dependencies.contains(_Aspect.dynamicColorState) && dynamicColorState != oldWidget.dynamicColorState) ||
|
||||||
(dependencies.contains(_Aspect.evSourceType) && evSourceType != oldWidget.evSourceType) ||
|
(dependencies.contains(_Aspect.evSourceType) && evSourceType != oldWidget.evSourceType) ||
|
||||||
(dependencies.contains(_Aspect.locale) && locale != oldWidget.locale) ||
|
(dependencies.contains(_Aspect.locale) && locale != oldWidget.locale) ||
|
||||||
(dependencies.contains(_Aspect.showEv100) && showEv100 != oldWidget.showEv100) ||
|
|
||||||
(dependencies.contains(_Aspect.stopType) && stopType != oldWidget.stopType) ||
|
(dependencies.contains(_Aspect.stopType) && stopType != oldWidget.stopType) ||
|
||||||
(dependencies.contains(_Aspect.theme) &&
|
(dependencies.contains(_Aspect.theme) &&
|
||||||
(_brightness != oldWidget._brightness || _primaryColor != oldWidget._primaryColor)) ||
|
(_brightness != oldWidget._brightness || _primaryColor != oldWidget._primaryColor)) ||
|
||||||
|
|
|
@ -1,21 +1,15 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:lightmeter/generated/l10n.dart';
|
import 'package:lightmeter/generated/l10n.dart';
|
||||||
import 'package:lightmeter/providers/user_preferences_provider.dart';
|
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
import 'package:lightmeter/screens/shared/filled_circle/widget_circle_filled.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 {
|
class MeteringMeasureButton extends StatefulWidget {
|
||||||
final double? ev;
|
final double? ev;
|
||||||
final double? ev100;
|
|
||||||
final bool isMetering;
|
final bool isMetering;
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
|
|
||||||
const MeteringMeasureButton({
|
const MeteringMeasureButton({
|
||||||
required this.ev,
|
required this.ev,
|
||||||
required this.ev100,
|
|
||||||
required this.isMetering,
|
required this.isMetering,
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
super.key,
|
super.key,
|
||||||
|
@ -67,7 +61,7 @@ class _MeteringMeasureButtonState extends State<MeteringMeasureButton> {
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
size: Dimens.grid72 - Dimens.grid8,
|
size: Dimens.grid72 - Dimens.grid8,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: widget.ev != null ? _EvValueText(ev: widget.ev!, ev100: widget.ev100!) : null,
|
child: widget.ev != null ? _EvValueText(ev: widget.ev!) : null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -89,32 +83,16 @@ class _MeteringMeasureButtonState extends State<MeteringMeasureButton> {
|
||||||
|
|
||||||
class _EvValueText extends StatelessWidget {
|
class _EvValueText extends StatelessWidget {
|
||||||
final double ev;
|
final double ev;
|
||||||
final double ev100;
|
|
||||||
|
|
||||||
const _EvValueText({
|
const _EvValueText({required this.ev});
|
||||||
required this.ev,
|
|
||||||
required this.ev100,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
return Text(
|
return Text(
|
||||||
_text(context),
|
'${ev.toStringAsFixed(1)}\n${S.of(context).ev}',
|
||||||
style: theme.textTheme.bodyMedium?.copyWith(color: theme.colorScheme.surface),
|
style: theme.textTheme.bodyMedium?.copyWith(color: theme.colorScheme.surface),
|
||||||
textAlign: TextAlign.center,
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import 'package:lightmeter/screens/metering/components/bottom_controls/widget_bo
|
||||||
|
|
||||||
class MeteringBottomControlsProvider extends StatelessWidget {
|
class MeteringBottomControlsProvider extends StatelessWidget {
|
||||||
final double? ev;
|
final double? ev;
|
||||||
final double? ev100;
|
|
||||||
final bool isMetering;
|
final bool isMetering;
|
||||||
final VoidCallback? onSwitchEvSourceType;
|
final VoidCallback? onSwitchEvSourceType;
|
||||||
final VoidCallback onMeasure;
|
final VoidCallback onMeasure;
|
||||||
|
@ -13,7 +12,6 @@ class MeteringBottomControlsProvider extends StatelessWidget {
|
||||||
|
|
||||||
const MeteringBottomControlsProvider({
|
const MeteringBottomControlsProvider({
|
||||||
required this.ev,
|
required this.ev,
|
||||||
required this.ev100,
|
|
||||||
required this.isMetering,
|
required this.isMetering,
|
||||||
required this.onSwitchEvSourceType,
|
required this.onSwitchEvSourceType,
|
||||||
required this.onMeasure,
|
required this.onMeasure,
|
||||||
|
@ -37,7 +35,6 @@ class MeteringBottomControlsProvider extends StatelessWidget {
|
||||||
),
|
),
|
||||||
child: MeteringBottomControls(
|
child: MeteringBottomControls(
|
||||||
ev: ev,
|
ev: ev,
|
||||||
ev100: ev100,
|
|
||||||
isMetering: isMetering,
|
isMetering: isMetering,
|
||||||
onSwitchEvSourceType: onSwitchEvSourceType,
|
onSwitchEvSourceType: onSwitchEvSourceType,
|
||||||
onMeasure: onMeasure,
|
onMeasure: onMeasure,
|
||||||
|
|
|
@ -7,7 +7,6 @@ import 'package:lightmeter/screens/metering/components/bottom_controls/component
|
||||||
|
|
||||||
class MeteringBottomControls extends StatelessWidget {
|
class MeteringBottomControls extends StatelessWidget {
|
||||||
final double? ev;
|
final double? ev;
|
||||||
final double? ev100;
|
|
||||||
final bool isMetering;
|
final bool isMetering;
|
||||||
final VoidCallback? onSwitchEvSourceType;
|
final VoidCallback? onSwitchEvSourceType;
|
||||||
final VoidCallback onMeasure;
|
final VoidCallback onMeasure;
|
||||||
|
@ -15,7 +14,6 @@ class MeteringBottomControls extends StatelessWidget {
|
||||||
|
|
||||||
const MeteringBottomControls({
|
const MeteringBottomControls({
|
||||||
required this.ev,
|
required this.ev,
|
||||||
required this.ev100,
|
|
||||||
required this.isMetering,
|
required this.isMetering,
|
||||||
required this.onSwitchEvSourceType,
|
required this.onSwitchEvSourceType,
|
||||||
required this.onMeasure,
|
required this.onMeasure,
|
||||||
|
@ -60,7 +58,6 @@ class MeteringBottomControls extends StatelessWidget {
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
MeteringMeasureButton(
|
MeteringMeasureButton(
|
||||||
ev: ev,
|
ev: ev,
|
||||||
ev100: ev100,
|
|
||||||
isMetering: isMetering,
|
isMetering: isMetering,
|
||||||
onTap: onMeasure,
|
onTap: onMeasure,
|
||||||
),
|
),
|
||||||
|
|
|
@ -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/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/components/camera_preview/components/histogram/widget_histogram.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';
|
||||||
import 'package:lightmeter/utils/context_utils.dart';
|
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||||
|
|
||||||
class CameraPreview extends StatefulWidget {
|
class CameraPreview extends StatefulWidget {
|
||||||
final CameraController? controller;
|
final CameraController? controller;
|
||||||
|
@ -93,7 +93,7 @@ class _CameraPreviewBuilderState extends State<_CameraPreviewBuilder> {
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
children: [
|
children: [
|
||||||
CameraView(controller: widget.controller),
|
CameraView(controller: widget.controller),
|
||||||
if (context.isPro) ...[
|
if (IAPProducts.isPurchased(context, IAPProductType.paidFeatures)) ...[
|
||||||
if (UserPreferencesProvider.cameraFeatureOf(
|
if (UserPreferencesProvider.cameraFeatureOf(
|
||||||
context,
|
context,
|
||||||
CameraFeature.histogram,
|
CameraFeature.histogram,
|
||||||
|
|
|
@ -3,10 +3,8 @@ import 'dart:math';
|
||||||
import 'package:flutter/material.dart';
|
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/feature.dart';
|
|
||||||
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
|
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
|
||||||
import 'package:lightmeter/platform_config.dart';
|
import 'package:lightmeter/platform_config.dart';
|
||||||
import 'package:lightmeter/providers/remote_config_provider.dart';
|
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/camera_container/bloc_container_camera.dart';
|
import 'package:lightmeter/screens/metering/components/camera_container/bloc_container_camera.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_controls/widget_camera_controls.dart';
|
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_controls/widget_camera_controls.dart';
|
||||||
|
@ -19,6 +17,7 @@ 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/metering_top_bar/widget_top_bar_metering.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/shared/readings_container/widget_container_readings.dart';
|
import 'package:lightmeter/screens/metering/components/shared/readings_container/widget_container_readings.dart';
|
||||||
import 'package:lightmeter/utils/context_utils.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';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
class CameraContainer extends StatelessWidget {
|
class CameraContainer extends StatelessWidget {
|
||||||
|
@ -103,12 +102,11 @@ class CameraContainer extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
double _meteringContainerHeight(BuildContext context) {
|
double _meteringContainerHeight(BuildContext context) {
|
||||||
|
final isPro = IAPProducts.isPurchased(context, IAPProductType.paidFeatures);
|
||||||
double enabledFeaturesHeight = 0;
|
double enabledFeaturesHeight = 0;
|
||||||
if (!context.isPro) {
|
if (!isPro) {
|
||||||
if (RemoteConfig.isEnabled(context, Feature.showUnlockProOnMainScreen)) {
|
|
||||||
enabledFeaturesHeight += Dimens.readingContainerSingleValueHeight;
|
enabledFeaturesHeight += Dimens.readingContainerSingleValueHeight;
|
||||||
enabledFeaturesHeight += Dimens.paddingS;
|
enabledFeaturesHeight += Dimens.paddingS;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (context.meteringFeature(MeteringScreenLayoutFeature.equipmentProfiles)) {
|
if (context.meteringFeature(MeteringScreenLayoutFeature.equipmentProfiles)) {
|
||||||
enabledFeaturesHeight += Dimens.readingContainerSingleValueHeight;
|
enabledFeaturesHeight += Dimens.readingContainerSingleValueHeight;
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
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/feature.dart';
|
|
||||||
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
|
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
|
||||||
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
||||||
import 'package:lightmeter/providers/remote_config_provider.dart';
|
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/equipment_profile_picker/widget_picker_equipment_profiles.dart';
|
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/equipment_profile_picker/widget_picker_equipment_profiles.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/extreme_exposure_pairs_container/widget_container_extreme_exposure_pairs.dart';
|
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/extreme_exposure_pairs_container/widget_container_extreme_exposure_pairs.dart';
|
||||||
|
@ -12,6 +10,7 @@ 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/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/screens/metering/components/shared/readings_container/components/nd_picker/widget_picker_nd.dart';
|
||||||
import 'package:lightmeter/utils/context_utils.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';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
class ReadingsContainer extends StatelessWidget {
|
class ReadingsContainer extends StatelessWidget {
|
||||||
|
@ -34,14 +33,15 @@ class ReadingsContainer extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final isPro = IAPProducts.isPurchased(context, IAPProductType.paidFeatures);
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
if (!context.isPro && RemoteConfig.isEnabled(context, Feature.showUnlockProOnMainScreen)) ...[
|
if (!isPro) ...[
|
||||||
const LightmeterProAnimatedDialog(),
|
const LightmeterProAnimatedDialog(),
|
||||||
const _InnerPadding(),
|
const _InnerPadding(),
|
||||||
],
|
],
|
||||||
if (context.isPro && context.meteringFeature(MeteringScreenLayoutFeature.equipmentProfiles)) ...[
|
if (isPro && context.meteringFeature(MeteringScreenLayoutFeature.equipmentProfiles)) ...[
|
||||||
const EquipmentProfilePicker(),
|
const EquipmentProfilePicker(),
|
||||||
const _InnerPadding(),
|
const _InnerPadding(),
|
||||||
],
|
],
|
||||||
|
@ -52,7 +52,7 @@ class ReadingsContainer extends StatelessWidget {
|
||||||
),
|
),
|
||||||
const _InnerPadding(),
|
const _InnerPadding(),
|
||||||
],
|
],
|
||||||
if (context.isPro && context.meteringFeature(MeteringScreenLayoutFeature.filmPicker)) ...[
|
if (isPro && context.meteringFeature(MeteringScreenLayoutFeature.filmPicker)) ...[
|
||||||
FilmPicker(selectedIso: iso),
|
FilmPicker(selectedIso: iso),
|
||||||
const _InnerPadding(),
|
const _InnerPadding(),
|
||||||
],
|
],
|
||||||
|
|
|
@ -40,7 +40,6 @@ class MeteringScreen extends StatelessWidget {
|
||||||
BlocBuilder<MeteringBloc, MeteringState>(
|
BlocBuilder<MeteringBloc, MeteringState>(
|
||||||
builder: (context, state) => MeteringBottomControlsProvider(
|
builder: (context, state) => MeteringBottomControlsProvider(
|
||||||
ev: state is MeteringDataState ? state.ev : null,
|
ev: state is MeteringDataState ? state.ev : null,
|
||||||
ev100: state is MeteringDataState ? state.ev100 : null,
|
|
||||||
isMetering: state.isMetering,
|
isMetering: state.isMetering,
|
||||||
onSwitchEvSourceType: ServicesProvider.of(context).environment.hasLightSensor
|
onSwitchEvSourceType: ServicesProvider.of(context).environment.hasLightSensor
|
||||||
? UserPreferencesProvider.of(context).toggleEvSourceType
|
? UserPreferencesProvider.of(context).toggleEvSourceType
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
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),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,7 +6,6 @@ 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/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/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/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';
|
import 'package:lightmeter/screens/settings/components/shared/settings_section/widget_settings_section.dart';
|
||||||
|
|
||||||
class MeteringSettingsSection extends StatelessWidget {
|
class MeteringSettingsSection extends StatelessWidget {
|
||||||
|
@ -19,7 +18,6 @@ class MeteringSettingsSection extends StatelessWidget {
|
||||||
children: const [
|
children: const [
|
||||||
StopTypeListTile(),
|
StopTypeListTile(),
|
||||||
CalibrationListTile(),
|
CalibrationListTile(),
|
||||||
ShowEv100ListTile(),
|
|
||||||
MeteringScreenLayoutListTile(),
|
MeteringScreenLayoutListTile(),
|
||||||
EquipmentProfilesListTile(),
|
EquipmentProfilesListTile(),
|
||||||
FilmsListTile(),
|
FilmsListTile(),
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:lightmeter/screens/settings/components/shared/disable/widget_disable.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';
|
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||||
|
|
||||||
/// Depends on the product status and replaces [onTap] with purchase callback
|
/// Depends on the product status and replaces [onTap] with purchase callback
|
||||||
|
@ -23,8 +22,9 @@ class IAPListTile extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final isPurchased = IAPProducts.isPurchased(context, IAPProductType.paidFeatures);
|
||||||
return Disable(
|
return Disable(
|
||||||
disable: !context.isPro,
|
disable: !isPurchased,
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: leading,
|
leading: leading,
|
||||||
title: title,
|
title: title,
|
||||||
|
|
|
@ -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/components/theme/widget_settings_section_theme.dart';
|
||||||
import 'package:lightmeter/screens/settings/flow_settings.dart';
|
import 'package:lightmeter/screens/settings/flow_settings.dart';
|
||||||
import 'package:lightmeter/screens/shared/sliver_screen/screen_sliver.dart';
|
import 'package:lightmeter/screens/shared/sliver_screen/screen_sliver.dart';
|
||||||
import 'package:lightmeter/utils/context_utils.dart';
|
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||||
|
|
||||||
class SettingsScreen extends StatefulWidget {
|
class SettingsScreen extends StatefulWidget {
|
||||||
const SettingsScreen({super.key});
|
const SettingsScreen({super.key});
|
||||||
|
@ -38,7 +38,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
SliverList(
|
SliverList(
|
||||||
delegate: SliverChildListDelegate(
|
delegate: SliverChildListDelegate(
|
||||||
<Widget>[
|
<Widget>[
|
||||||
if (!context.isPro) const LightmeterProSettingsSection(),
|
if (!IAPProducts.isPurchased(context, IAPProductType.paidFeatures))
|
||||||
|
const LightmeterProSettingsSection(),
|
||||||
const MeteringSettingsSection(),
|
const MeteringSettingsSection(),
|
||||||
const GeneralSettingsSection(),
|
const GeneralSettingsSection(),
|
||||||
const ThemeSettingsSection(),
|
const ThemeSettingsSection(),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
name: lightmeter
|
name: lightmeter
|
||||||
description: Lightmeter app inspired by Material 3 design system.
|
description: Lightmeter app inspired by Material 3 design system.
|
||||||
publish_to: "none"
|
publish_to: "none"
|
||||||
version: 0.17.0+46
|
version: 0.16.0+45
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.0.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
|
|
|
@ -181,25 +181,6 @@ 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', () {
|
group('meteringScreenLayout', () {
|
||||||
test('get default', () {
|
test('get default', () {
|
||||||
when(
|
when(
|
||||||
|
|
|
@ -19,8 +19,8 @@ void main() {
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
when(() => mockRemoteConfigService.fetchConfig()).thenAnswer((_) async {});
|
when(() => mockRemoteConfigService.fetchConfig()).thenAnswer((_) async {});
|
||||||
when(() => mockRemoteConfigService.getValue(Feature.showUnlockProOnMainScreen)).thenReturn(false);
|
when(() => mockRemoteConfigService.getValue(Feature.unlockProFeaturesText)).thenReturn(false);
|
||||||
when(() => mockRemoteConfigService.getAll()).thenReturn({Feature.showUnlockProOnMainScreen: false});
|
when(() => mockRemoteConfigService.getAll()).thenReturn({Feature.unlockProFeaturesText: false});
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
|
@ -42,7 +42,7 @@ void main() {
|
||||||
when(() => mockRemoteConfigService.onConfigUpdated()).thenAnswer((_) => const Stream.empty());
|
when(() => mockRemoteConfigService.onConfigUpdated()).thenAnswer((_) => const Stream.empty());
|
||||||
|
|
||||||
await pumpTestWidget(tester);
|
await pumpTestWidget(tester);
|
||||||
expect(find.text('showUnlockProOnMainScreen: false'), findsOneWidget);
|
expect(find.text('unlockProFeaturesText: false'), findsOneWidget);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -53,34 +53,34 @@ void main() {
|
||||||
when(() => mockRemoteConfigService.onConfigUpdated()).thenAnswer((_) => remoteConfigUpdateController.stream);
|
when(() => mockRemoteConfigService.onConfigUpdated()).thenAnswer((_) => remoteConfigUpdateController.stream);
|
||||||
|
|
||||||
await pumpTestWidget(tester);
|
await pumpTestWidget(tester);
|
||||||
expect(find.text('showUnlockProOnMainScreen: false'), findsOneWidget);
|
expect(find.text('unlockProFeaturesText: false'), findsOneWidget);
|
||||||
|
|
||||||
when(() => mockRemoteConfigService.getValue(Feature.showUnlockProOnMainScreen)).thenReturn(true);
|
when(() => mockRemoteConfigService.getValue(Feature.unlockProFeaturesText)).thenReturn(true);
|
||||||
remoteConfigUpdateController.add({Feature.showUnlockProOnMainScreen});
|
remoteConfigUpdateController.add({Feature.unlockProFeaturesText});
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(find.text('showUnlockProOnMainScreen: true'), findsOneWidget);
|
expect(find.text('unlockProFeaturesText: true'), findsOneWidget);
|
||||||
|
|
||||||
await remoteConfigUpdateController.close();
|
await remoteConfigUpdateController.close();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
test('RemoteConfig.updateShouldNotifyDependent', () {
|
test('RemoteConfig.updateShouldNotifyDependent', () {
|
||||||
const config = RemoteConfig(config: {Feature.showUnlockProOnMainScreen: false}, child: SizedBox());
|
const config = RemoteConfig(config: {Feature.unlockProFeaturesText: false}, child: SizedBox());
|
||||||
expect(
|
expect(
|
||||||
config.updateShouldNotifyDependent(config, {}),
|
config.updateShouldNotifyDependent(config, {}),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
config.updateShouldNotifyDependent(
|
config.updateShouldNotifyDependent(
|
||||||
const RemoteConfig(config: {Feature.showUnlockProOnMainScreen: false}, child: SizedBox()),
|
const RemoteConfig(config: {Feature.unlockProFeaturesText: false}, child: SizedBox()),
|
||||||
{Feature.showUnlockProOnMainScreen},
|
{Feature.unlockProFeaturesText},
|
||||||
),
|
),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
config.updateShouldNotifyDependent(
|
config.updateShouldNotifyDependent(
|
||||||
const RemoteConfig(config: {Feature.showUnlockProOnMainScreen: true}, child: SizedBox()),
|
const RemoteConfig(config: {Feature.unlockProFeaturesText: true}, child: SizedBox()),
|
||||||
{Feature.showUnlockProOnMainScreen},
|
{Feature.unlockProFeaturesText},
|
||||||
),
|
),
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
@ -96,7 +96,7 @@ class _Application extends StatelessWidget {
|
||||||
home: Scaffold(
|
home: Scaffold(
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
"${Feature.showUnlockProOnMainScreen.name}: ${RemoteConfig.isEnabled(context, Feature.showUnlockProOnMainScreen)}",
|
"${Feature.unlockProFeaturesText.name}: ${RemoteConfig.isEnabled(context, Feature.unlockProFeaturesText)}",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -27,7 +27,6 @@ void main() {
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
when(() => mockUserPreferencesService.evSourceType).thenReturn(EvSourceType.camera);
|
when(() => mockUserPreferencesService.evSourceType).thenReturn(EvSourceType.camera);
|
||||||
when(() => mockUserPreferencesService.showEv100).thenReturn(false);
|
|
||||||
when(() => mockUserPreferencesService.stopType).thenReturn(StopType.third);
|
when(() => mockUserPreferencesService.stopType).thenReturn(StopType.third);
|
||||||
when(() => mockUserPreferencesService.meteringScreenLayout).thenReturn({
|
when(() => mockUserPreferencesService.meteringScreenLayout).thenReturn({
|
||||||
MeteringScreenLayoutFeature.extremeExposurePairs: true,
|
MeteringScreenLayoutFeature.extremeExposurePairs: true,
|
||||||
|
@ -165,27 +164,6 @@ 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(
|
testWidgets(
|
||||||
'Set metering screen layout config',
|
'Set metering screen layout config',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
|
|
Loading…
Reference in a new issue