Compare commits

...

3 commits

Author SHA1 Message Date
Vadim
7633f3fd27 reset selected equipment profile when layout feature is disabled 2023-07-14 00:06:18 +02:00
Vadim
b42ad01b7c fixed UserPreferencesService tests 2023-07-13 23:49:28 +02:00
Vadim
93d8d46bf0 fixed MeteringScreenLayoutConfigJson tests 2023-07-13 23:47:21 +02:00
5 changed files with 85 additions and 37 deletions

View file

@ -1,11 +1,17 @@
enum MeteringScreenLayoutFeature { equipmentProfiles, extremeExposurePairs, filmPicker } enum MeteringScreenLayoutFeature {
extremeExposurePairs,
filmPicker,
equipmentProfiles,
}
typedef MeteringScreenLayoutConfig = Map<MeteringScreenLayoutFeature, bool>; typedef MeteringScreenLayoutConfig = Map<MeteringScreenLayoutFeature, bool>;
extension MeteringScreenLayoutConfigJson on MeteringScreenLayoutConfig { extension MeteringScreenLayoutConfigJson on MeteringScreenLayoutConfig {
static MeteringScreenLayoutConfig fromJson(Map<String, dynamic> data) => data.map( static MeteringScreenLayoutConfig fromJson(Map<String, dynamic> data) =>
(key, value) => MapEntry(MeteringScreenLayoutFeature.values[int.parse(key)], value as bool), <MeteringScreenLayoutFeature, bool>{
); for (final f in MeteringScreenLayoutFeature.values)
f: data[f.index.toString()] as bool? ?? true
};
Map<String, dynamic> toJson() => map((key, value) => MapEntry(key.index.toString(), value)); Map<String, dynamic> toJson() => map((key, value) => MapEntry(key.index.toString(), value));
} }

View file

@ -76,13 +76,23 @@ class _InheritedListeners extends StatelessWidget {
onDidChangeDependencies: (value) { onDidChangeDependencies: (value) {
context.read<MeteringBloc>().add(EquipmentProfileChangedEvent(value)); context.read<MeteringBloc>().add(EquipmentProfileChangedEvent(value));
}, },
child: InheritedModelAspectListener<MeteringScreenLayoutFeature, bool>(
aspect: MeteringScreenLayoutFeature.equipmentProfiles,
onDidChangeDependencies: (value) {
if (!value) {
EquipmentProfileProvider.of(context).setProfile(context.get<EquipmentProfiles>().first);
}
},
child: InheritedModelAspectListener<MeteringScreenLayoutFeature, bool>( child: InheritedModelAspectListener<MeteringScreenLayoutFeature, bool>(
aspect: MeteringScreenLayoutFeature.filmPicker, aspect: MeteringScreenLayoutFeature.filmPicker,
onDidChangeDependencies: (value) { onDidChangeDependencies: (value) {
if (!value) context.read<MeteringBloc>().add(const FilmChangedEvent(Film.other())); if (!value) {
context.read<MeteringBloc>().add(const FilmChangedEvent(Film.other()));
}
}, },
child: child, child: child,
), ),
),
); );
} }
} }

View file

@ -33,18 +33,9 @@ class _MeteringScreenLayoutFeaturesDialogState extends State<MeteringScreenLayou
child: Text(S.of(context).meteringScreenLayoutHint), child: Text(S.of(context).meteringScreenLayoutHint),
), ),
const SizedBox(height: Dimens.grid16), const SizedBox(height: Dimens.grid16),
...MeteringScreenLayoutFeature.values.map( _featureListTile(MeteringScreenLayoutFeature.equipmentProfiles),
(f) => SwitchListTile( _featureListTile(MeteringScreenLayoutFeature.extremeExposurePairs),
contentPadding: EdgeInsets.symmetric(horizontal: Dimens.dialogTitlePadding.left), _featureListTile(MeteringScreenLayoutFeature.filmPicker),
title: Text(_toStringLocalized(context, f)),
value: _features[f]!,
onChanged: (value) {
setState(() {
_features.update(f, (_) => value);
});
},
),
),
], ],
), ),
), ),
@ -65,6 +56,19 @@ class _MeteringScreenLayoutFeaturesDialogState extends State<MeteringScreenLayou
); );
} }
Widget _featureListTile(MeteringScreenLayoutFeature f) {
return SwitchListTile(
contentPadding: EdgeInsets.symmetric(horizontal: Dimens.dialogTitlePadding.left),
title: Text(_toStringLocalized(context, f)),
value: _features[f]!,
onChanged: (value) {
setState(() {
_features.update(f, (_) => value);
});
},
);
}
String _toStringLocalized(BuildContext context, MeteringScreenLayoutFeature feature) { String _toStringLocalized(BuildContext context, MeteringScreenLayoutFeature feature) {
switch (feature) { switch (feature) {
case MeteringScreenLayoutFeature.equipmentProfiles: case MeteringScreenLayoutFeature.equipmentProfiles:

View file

@ -2,30 +2,56 @@ import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
void main() { void main() {
test('fromJson', () { group(
'fromJson()',
() {
test('All keys', () {
expect( expect(
MeteringScreenLayoutConfigJson.fromJson({'0': true, '1': true}), MeteringScreenLayoutConfigJson.fromJson(
{
'0': true,
'1': true,
'2': true,
},
),
{ {
MeteringScreenLayoutFeature.extremeExposurePairs: true, MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true, MeteringScreenLayoutFeature.filmPicker: true,
}, MeteringScreenLayoutFeature.equipmentProfiles: true,
);
expect(
MeteringScreenLayoutConfigJson.fromJson({'0': false, '1': false}),
{
MeteringScreenLayoutFeature.extremeExposurePairs: false,
MeteringScreenLayoutFeature.filmPicker: false,
}, },
); );
}); });
test('toJson', () { test('Legacy (no equipment profiles)', () {
expect( expect(
MeteringScreenLayoutConfigJson.fromJson(
{
'0': true,
'1': true,
},
),
{ {
MeteringScreenLayoutFeature.extremeExposurePairs: true, MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true, MeteringScreenLayoutFeature.filmPicker: true,
MeteringScreenLayoutFeature.equipmentProfiles: true,
},
);
});
},
);
test('toJson()', () {
expect(
{
MeteringScreenLayoutFeature.equipmentProfiles: true,
MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true,
}.toJson(), }.toJson(),
{'0': true, '1': true}, {
'2': true,
'0': true,
'1': true,
},
); );
}); });
} }

View file

@ -193,6 +193,7 @@ void main() {
{ {
MeteringScreenLayoutFeature.extremeExposurePairs: true, MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true, MeteringScreenLayoutFeature.filmPicker: true,
MeteringScreenLayoutFeature.equipmentProfiles: true,
}, },
); );
}); });
@ -206,6 +207,7 @@ void main() {
{ {
MeteringScreenLayoutFeature.extremeExposurePairs: false, MeteringScreenLayoutFeature.extremeExposurePairs: false,
MeteringScreenLayoutFeature.filmPicker: true, MeteringScreenLayoutFeature.filmPicker: true,
MeteringScreenLayoutFeature.equipmentProfiles: true,
}, },
); );
}); });