add ability to toggle equipment profiles

This commit is contained in:
Vadim 2024-11-11 13:18:13 +01:00
parent 7d1c1ebc9f
commit 371274efa7
3 changed files with 55 additions and 10 deletions

View file

@ -37,7 +37,8 @@ class EquipmentProfilesProviderState extends State<EquipmentProfilesProvider> {
final SelectableMap<EquipmentProfile> _customProfiles = {}; final SelectableMap<EquipmentProfile> _customProfiles = {};
String _selectedId = ''; String _selectedId = '';
EquipmentProfile get _selectedProfile => _customProfiles[_selectedId] ?? EquipmentProfilesProvider.defaultProfile; EquipmentProfile get _selectedProfile =>
_customProfiles[_selectedId]?.value ?? EquipmentProfilesProvider.defaultProfile;
@override @override
void initState() { void initState() {
@ -57,18 +58,19 @@ class EquipmentProfilesProviderState extends State<EquipmentProfilesProvider> {
Future<void> _init() async { Future<void> _init() async {
_selectedId = widget.storageService.selectedEquipmentProfileId; _selectedId = widget.storageService.selectedEquipmentProfileId;
_customProfiles.addAll(await widget.storageService.getProfiles()); _customProfiles.addAll(await widget.storageService.getProfiles());
_discardSelectedIfNotIncluded();
if (mounted) setState(() {}); if (mounted) setState(() {});
widget.onInitialized?.call(); widget.onInitialized?.call();
} }
Future<void> addProfile(EquipmentProfile profile) async { Future<void> addProfile(EquipmentProfile profile) async {
await widget.storageService.addProfile(profile); await widget.storageService.addProfile(profile);
_customProfiles[profile.id] = profile; _customProfiles[profile.id] = (value: profile, isUsed: true);
setState(() {}); setState(() {});
} }
Future<void> updateProfile(EquipmentProfile profile) async { Future<void> updateProfile(EquipmentProfile profile) async {
final oldProfile = _customProfiles[profile.id]!; final oldProfile = _customProfiles[profile.id]!.value;
await widget.storageService.updateProfile( await widget.storageService.updateProfile(
id: profile.id, id: profile.id,
name: oldProfile.name != profile.name ? profile.name : null, name: oldProfile.name != profile.name ? profile.name : null,
@ -79,7 +81,7 @@ class EquipmentProfilesProviderState extends State<EquipmentProfilesProvider> {
ndValues: oldProfile.ndValues != profile.ndValues ? profile.ndValues : null, ndValues: oldProfile.ndValues != profile.ndValues ? profile.ndValues : null,
lensZoom: oldProfile.lensZoom != profile.lensZoom ? profile.lensZoom : null, lensZoom: oldProfile.lensZoom != profile.lensZoom ? profile.lensZoom : null,
); );
_customProfiles[profile.id] = profile; _customProfiles[profile.id] = (value: profile, isUsed: _customProfiles[profile.id]!.isUsed);
setState(() {}); setState(() {});
} }
@ -90,6 +92,7 @@ class EquipmentProfilesProviderState extends State<EquipmentProfilesProvider> {
widget.storageService.selectedEquipmentProfileId = EquipmentProfilesProvider.defaultProfile.id; widget.storageService.selectedEquipmentProfileId = EquipmentProfilesProvider.defaultProfile.id;
} }
_customProfiles.remove(profile.id); _customProfiles.remove(profile.id);
_discardSelectedIfNotIncluded();
setState(() {}); setState(() {});
} }
@ -101,15 +104,38 @@ class EquipmentProfilesProviderState extends State<EquipmentProfilesProvider> {
widget.storageService.selectedEquipmentProfileId = _selectedProfile.id; widget.storageService.selectedEquipmentProfileId = _selectedProfile.id;
} }
} }
Future<void> toggleProfile(EquipmentProfile profile, bool enabled) async {
if (_customProfiles.containsKey(profile.id)) {
_customProfiles[profile.id] = (value: profile, isUsed: enabled);
} else {
return;
}
await widget.storageService.updateProfile(id: profile.id, isUsed: enabled);
_discardSelectedIfNotIncluded();
setState(() {});
}
void _discardSelectedIfNotIncluded() {
if (_selectedId == EquipmentProfilesProvider.defaultProfile.id) {
return;
}
final isSelectedUsed = _customProfiles[_selectedId]?.isUsed ?? false;
if (!isSelectedUsed) {
_selectedId = EquipmentProfilesProvider.defaultProfile.id;
widget.storageService.selectedEquipmentProfileId = _selectedId;
}
}
} }
enum _EquipmentProfilesModelAspect { enum _EquipmentProfilesModelAspect {
profiles, profiles,
profilesInUse,
selected, selected,
} }
class EquipmentProfiles extends InheritedModel<_EquipmentProfilesModelAspect> { class EquipmentProfiles extends InheritedModel<_EquipmentProfilesModelAspect> {
final Map<String, EquipmentProfile> profiles; final SelectableMap<EquipmentProfile> profiles;
final EquipmentProfile selected; final EquipmentProfile selected;
const EquipmentProfiles({ const EquipmentProfiles({
@ -122,7 +148,23 @@ class EquipmentProfiles extends InheritedModel<_EquipmentProfilesModelAspect> {
static List<EquipmentProfile> of(BuildContext context) { static List<EquipmentProfile> of(BuildContext context) {
final model = final model =
InheritedModel.inheritFrom<EquipmentProfiles>(context, aspect: _EquipmentProfilesModelAspect.profiles)!; InheritedModel.inheritFrom<EquipmentProfiles>(context, aspect: _EquipmentProfilesModelAspect.profiles)!;
return List.from([EquipmentProfilesProvider.defaultProfile, ...model.profiles.values]); return List<EquipmentProfile>.from(
[
EquipmentProfilesProvider.defaultProfile,
...model.profiles.values.map((p) => p.value),
],
);
}
static List<EquipmentProfile> inUseOf(BuildContext context) {
final model =
InheritedModel.inheritFrom<EquipmentProfiles>(context, aspect: _EquipmentProfilesModelAspect.profilesInUse)!;
return List<EquipmentProfile>.from(
[
EquipmentProfilesProvider.defaultProfile,
...model.profiles.values.where((p) => p.isUsed).map((p) => p.value),
],
);
} }
static EquipmentProfile selectedOf(BuildContext context) { static EquipmentProfile selectedOf(BuildContext context) {
@ -137,7 +179,7 @@ class EquipmentProfiles extends InheritedModel<_EquipmentProfilesModelAspect> {
bool updateShouldNotifyDependent(EquipmentProfiles oldWidget, Set<_EquipmentProfilesModelAspect> dependencies) { bool updateShouldNotifyDependent(EquipmentProfiles oldWidget, Set<_EquipmentProfilesModelAspect> dependencies) {
return (dependencies.contains(_EquipmentProfilesModelAspect.selected) && oldWidget.selected != selected) || return (dependencies.contains(_EquipmentProfilesModelAspect.selected) && oldWidget.selected != selected) ||
((dependencies.contains(_EquipmentProfilesModelAspect.profiles) || ((dependencies.contains(_EquipmentProfilesModelAspect.profiles) ||
dependencies.contains(_EquipmentProfilesModelAspect.profiles)) && dependencies.contains(_EquipmentProfilesModelAspect.profilesInUse)) &&
const DeepCollectionEquality().equals(oldWidget.profiles, profiles)); const DeepCollectionEquality().equals(oldWidget.profiles, profiles));
} }
} }

View file

@ -32,6 +32,7 @@ class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> with
_EquipmentProfilesListBuilder( _EquipmentProfilesListBuilder(
values: EquipmentProfiles.of(context).skip(1).toList(), values: EquipmentProfiles.of(context).skip(1).toList(),
onEdit: _editProfile, onEdit: _editProfile,
onCheckbox: EquipmentProfilesProvider.of(context).toggleProfile,
) )
else else
SliverPlaceholder(onTap: _addProfile), SliverPlaceholder(onTap: _addProfile),
@ -60,10 +61,12 @@ class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> with
class _EquipmentProfilesListBuilder extends StatelessWidget { class _EquipmentProfilesListBuilder extends StatelessWidget {
final List<EquipmentProfile> values; final List<EquipmentProfile> values;
final void Function(EquipmentProfile film) onEdit; final void Function(EquipmentProfile film) onEdit;
final void Function(EquipmentProfile film, bool value) onCheckbox;
const _EquipmentProfilesListBuilder({ const _EquipmentProfilesListBuilder({
required this.values, required this.values,
required this.onEdit, required this.onEdit,
required this.onCheckbox,
}); });
@override @override
@ -92,8 +95,8 @@ class _EquipmentProfilesListBuilder extends StatelessWidget {
child: CheckboxListTile( child: CheckboxListTile(
title: Text(values[index].name), title: Text(values[index].name),
controlAffinity: ListTileControlAffinity.leading, controlAffinity: ListTileControlAffinity.leading,
value: false, value: EquipmentProfiles.inUseOf(context).contains(values[index]),
onChanged: (value) {}, onChanged: (value) => onCheckbox(values[index], value ?? false),
secondary: IconButton( secondary: IconButton(
onPressed: () => onEdit(values[index]), onPressed: () => onEdit(values[index]),
icon: const Icon(Icons.edit), icon: const Icon(Icons.edit),

View file

@ -14,7 +14,7 @@ class EquipmentProfilePicker extends StatelessWidget {
icon: Icons.camera_outlined, icon: Icons.camera_outlined,
title: S.of(context).equipmentProfile, title: S.of(context).equipmentProfile,
selectedValue: EquipmentProfiles.selectedOf(context), selectedValue: EquipmentProfiles.selectedOf(context),
values: EquipmentProfiles.of(context), values: EquipmentProfiles.inUseOf(context),
itemTitleBuilder: (_, value) => Text(value.id.isEmpty ? S.of(context).none : value.name), itemTitleBuilder: (_, value) => Text(value.id.isEmpty ? S.of(context).none : value.name),
onChanged: EquipmentProfilesProvider.of(context).selectProfile, onChanged: EquipmentProfilesProvider.of(context).selectProfile,
closedChild: ReadingValueContainer.singleValue( closedChild: ReadingValueContainer.singleValue(