Refined equipment profiles sections handling

This commit is contained in:
Vadim 2023-09-02 22:20:18 +02:00
parent 79b9ae60c3
commit 243047a1f7
2 changed files with 64 additions and 35 deletions

View file

@ -143,10 +143,13 @@ class EquipmentProfileContainerState extends State<EquipmentProfileContainer>
widget.onExpand(); widget.onExpand();
_controller.forward(); _controller.forward();
SchedulerBinding.instance.addPostFrameCallback((_) { SchedulerBinding.instance.addPostFrameCallback((_) {
Scrollable.ensureVisible( Future.delayed(_controller.duration!).then((_) {
context, Scrollable.ensureVisible(
alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd, context,
); alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd,
duration: _controller.duration!,
);
});
}); });
} }

View file

@ -17,17 +17,13 @@ class EquipmentProfilesScreen extends StatefulWidget {
} }
class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> { class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> {
static const maxProfiles = 5 + 1; // replace with a constant from iap
final Map<String, GlobalKey<EquipmentProfileContainerState>> keysMap = {}; final Map<String, GlobalKey<EquipmentProfileContainerState>> keysMap = {};
int get profilesCount => keysMap.length; int get profilesCount => keysMap.length;
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
EquipmentProfiles.of(context).forEach((profile) { _updateProfilesKeys();
keysMap[profile.id] ??= GlobalKey<EquipmentProfileContainerState>(debugLabel: profile.id);
});
} }
@override @override
@ -35,11 +31,10 @@ class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> {
return SliverScreen( return SliverScreen(
title: S.of(context).equipmentProfiles, title: S.of(context).equipmentProfiles,
appBarActions: [ appBarActions: [
if (profilesCount < maxProfiles) IconButton(
IconButton( onPressed: _addProfile,
onPressed: _addProfile, icon: const Icon(Icons.add),
icon: const Icon(Icons.add), ),
),
IconButton( IconButton(
onPressed: Navigator.of(context).pop, onPressed: Navigator.of(context).pop,
icon: const Icon(Icons.close), icon: const Icon(Icons.close),
@ -55,24 +50,30 @@ class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> {
: [ : [
SliverList( SliverList(
delegate: SliverChildBuilderDelegate( delegate: SliverChildBuilderDelegate(
(context, index) => index > 0 // skip default (context, index) {
? Padding( if (index == 0) {
padding: EdgeInsets.fromLTRB( // skip default profile
Dimens.paddingM, return const SizedBox.shrink();
index == 0 ? Dimens.paddingM : 0, }
Dimens.paddingM,
Dimens.paddingM, final profile = EquipmentProfiles.of(context)[index];
), return Padding(
child: EquipmentProfileContainer( padding: EdgeInsets.fromLTRB(
key: keysMap.values.toList()[index], Dimens.paddingM,
data: EquipmentProfiles.of(context)[index], index == 0 ? Dimens.paddingM : 0,
onExpand: () => _keepExpandedAt(index), Dimens.paddingM,
onUpdate: (profileData) => _updateProfileAt(profileData, index), Dimens.paddingM,
onDelete: () => _removeProfileAt(index), ),
), child: EquipmentProfileContainer(
) key: keysMap[profile.id],
: const SizedBox.shrink(), data: profile,
childCount: keysMap.length, onExpand: () => _keepExpandedAt(index),
onUpdate: _updateProfileAt,
onDelete: () => _removeProfileAt(profile),
),
);
},
childCount: EquipmentProfiles.of(context).length,
), ),
), ),
SliverToBoxAdapter(child: SizedBox(height: MediaQuery.paddingOf(context).bottom)), SliverToBoxAdapter(child: SizedBox(height: MediaQuery.paddingOf(context).bottom)),
@ -91,12 +92,12 @@ class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> {
}); });
} }
void _updateProfileAt(EquipmentProfile data, int index) { void _updateProfileAt(EquipmentProfile data) {
EquipmentProfileProvider.of(context).updateProdile(data); EquipmentProfileProvider.of(context).updateProdile(data);
} }
void _removeProfileAt(int index) { void _removeProfileAt(EquipmentProfile data) {
EquipmentProfileProvider.of(context).deleteProfile(EquipmentProfiles.of(context)[index]); EquipmentProfileProvider.of(context).deleteProfile(data);
} }
void _keepExpandedAt(int index) { void _keepExpandedAt(int index) {
@ -107,6 +108,31 @@ class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> {
element.currentState?.collapse(); element.currentState?.collapse();
}); });
} }
void _updateProfilesKeys() {
final profiles = EquipmentProfiles.of(context);
if (profiles.length > keysMap.length) {
// profile added
final List<String> idsToAdd = [];
for (final profile in profiles) {
if (!keysMap.keys.contains(profile.id)) idsToAdd.add(profile.id);
}
for (final id in idsToAdd) {
keysMap[id] = GlobalKey<EquipmentProfileContainerState>(debugLabel: id);
}
idsToAdd.clear();
} else if (profiles.length < keysMap.length) {
// profile deleted
final List<String> idsToDelete = [];
for (final id in keysMap.keys) {
if (!profiles.any((p) => p.id == id)) idsToDelete.add(id);
}
idsToDelete.forEach(keysMap.remove);
idsToDelete.clear();
} else {
// profile updated, no need to updated keys
}
}
} }
class _EquipmentProfilesListPlaceholder extends StatelessWidget { class _EquipmentProfilesListPlaceholder extends StatelessWidget {