From f39177919ce9d7b2ce8f65da22b0640b8e5cc102 Mon Sep 17 00:00:00 2001 From: Vadim <44135514+vodemn@users.noreply.github.com> Date: Sat, 2 Sep 2023 22:29:35 +0200 Subject: [PATCH] Equipment profiles issues (#112) * Fixed equipment profiles sections collapsing * Fixed range picker dialog * Refined equipment profiles sections handling --- .../widget_dialog_picker_range.dart | 4 +- .../widget_container_equipment_profile.dart | 11 ++- .../screen_equipment_profile.dart | 96 ++++++++++++------- 3 files changed, 70 insertions(+), 41 deletions(-) diff --git a/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_container/components/equipment_list_tiles/components/dialog_range_picker/widget_dialog_picker_range.dart b/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_container/components/equipment_list_tiles/components/dialog_range_picker/widget_dialog_picker_range.dart index 24f684a..cc3f4ca 100644 --- a/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_container/components/equipment_list_tiles/components/dialog_range_picker/widget_dialog_picker_range.dart +++ b/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_container/components/equipment_list_tiles/components/dialog_range_picker/widget_dialog_picker_range.dart @@ -68,8 +68,8 @@ class _DialogRangePickerState extends State widget.onExpand(); _controller.forward(); SchedulerBinding.instance.addPostFrameCallback((_) { - Scrollable.ensureVisible( - context, - alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd, - ); + Future.delayed(_controller.duration!).then((_) { + Scrollable.ensureVisible( + context, + alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd, + duration: _controller.duration!, + ); + }); }); } diff --git a/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/screen_equipment_profile.dart b/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/screen_equipment_profile.dart index 0168608..5307145 100644 --- a/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/screen_equipment_profile.dart +++ b/lib/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/screen_equipment_profile.dart @@ -17,17 +17,13 @@ class EquipmentProfilesScreen extends StatefulWidget { } class _EquipmentProfilesScreenState extends State { - static const maxProfiles = 5 + 1; // replace with a constant from iap - - late List> profileContainersKeys = []; - int get profilesCount => EquipmentProfiles.of(context).length; + final Map> keysMap = {}; + int get profilesCount => keysMap.length; @override void didChangeDependencies() { super.didChangeDependencies(); - profileContainersKeys = EquipmentProfiles.of(context) - .map((e) => GlobalKey(debugLabel: e.id)) - .toList(); + _updateProfilesKeys(); } @override @@ -35,11 +31,10 @@ class _EquipmentProfilesScreenState extends State { return SliverScreen( title: S.of(context).equipmentProfiles, appBarActions: [ - if (profilesCount < maxProfiles) - IconButton( - onPressed: _addProfile, - icon: const Icon(Icons.add), - ), + IconButton( + onPressed: _addProfile, + icon: const Icon(Icons.add), + ), IconButton( onPressed: Navigator.of(context).pop, icon: const Icon(Icons.close), @@ -55,24 +50,30 @@ class _EquipmentProfilesScreenState extends State { : [ SliverList( delegate: SliverChildBuilderDelegate( - (context, index) => index > 0 // skip default - ? Padding( - padding: EdgeInsets.fromLTRB( - Dimens.paddingM, - index == 0 ? Dimens.paddingM : 0, - Dimens.paddingM, - Dimens.paddingM, - ), - child: EquipmentProfileContainer( - key: profileContainersKeys[index], - data: EquipmentProfiles.of(context)[index], - onExpand: () => _keepExpandedAt(index), - onUpdate: (profileData) => _updateProfileAt(profileData, index), - onDelete: () => _removeProfileAt(index), - ), - ) - : const SizedBox.shrink(), - childCount: profilesCount, + (context, index) { + if (index == 0) { + // skip default profile + return const SizedBox.shrink(); + } + + final profile = EquipmentProfiles.of(context)[index]; + return Padding( + padding: EdgeInsets.fromLTRB( + Dimens.paddingM, + index == 0 ? Dimens.paddingM : 0, + Dimens.paddingM, + Dimens.paddingM, + ), + child: EquipmentProfileContainer( + key: keysMap[profile.id], + data: profile, + onExpand: () => _keepExpandedAt(index), + onUpdate: _updateProfileAt, + onDelete: () => _removeProfileAt(profile), + ), + ); + }, + childCount: EquipmentProfiles.of(context).length, ), ), SliverToBoxAdapter(child: SizedBox(height: MediaQuery.paddingOf(context).bottom)), @@ -91,22 +92,47 @@ class _EquipmentProfilesScreenState extends State { }); } - void _updateProfileAt(EquipmentProfile data, int index) { + void _updateProfileAt(EquipmentProfile data) { EquipmentProfileProvider.of(context).updateProdile(data); } - void _removeProfileAt(int index) { - EquipmentProfileProvider.of(context).deleteProfile(EquipmentProfiles.of(context)[index]); + void _removeProfileAt(EquipmentProfile data) { + EquipmentProfileProvider.of(context).deleteProfile(data); } void _keepExpandedAt(int index) { - profileContainersKeys.getRange(0, index).forEach((element) { + keysMap.values.toList().getRange(0, index).forEach((element) { element.currentState?.collapse(); }); - profileContainersKeys.getRange(index + 1, profilesCount).forEach((element) { + keysMap.values.toList().getRange(index + 1, profilesCount).forEach((element) { element.currentState?.collapse(); }); } + + void _updateProfilesKeys() { + final profiles = EquipmentProfiles.of(context); + if (profiles.length > keysMap.length) { + // profile added + final List idsToAdd = []; + for (final profile in profiles) { + if (!keysMap.keys.contains(profile.id)) idsToAdd.add(profile.id); + } + for (final id in idsToAdd) { + keysMap[id] = GlobalKey(debugLabel: id); + } + idsToAdd.clear(); + } else if (profiles.length < keysMap.length) { + // profile deleted + final List 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 {