From 173ac562a2c816da1ba0a8a88c94beafc0e42256 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Oct 2025 13:11:28 -0400 Subject: [PATCH] Add select all button to the delete space dialog (#4353) * Initial plan * Add select all button to delete space dialog Co-authored-by: ggurdin <46800240+ggurdin@users.noreply.github.com> * Style select all button as CheckboxListTile Co-authored-by: ggurdin <46800240+ggurdin@users.noreply.github.com> * update copy --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ggurdin <46800240+ggurdin@users.noreply.github.com> Co-authored-by: ggurdin --- lib/l10n/intl_en.arb | 4 +- .../widgets/delete_space_dialog.dart | 93 +++++++++++++------ 2 files changed, 69 insertions(+), 28 deletions(-) diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 7098e8b4d..c45857708 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -5312,5 +5312,7 @@ "noCourseTemplatesFound": "We couldn't find any courses for your target language. You can chat with Pangea Bot in the meantime, and check back later for more courses.", "botActivityJoinFailMessage": "Pangea Bot is taking a while to respond. Please try again later, or invite a friend.", "unsubscribedResponseError": "This feature requires a subscription", - "leaveDesc": "Leave this space and all chats within it" + "leaveDesc": "Leave this space and all chats within it", + "selectAll": "Select all", + "deselectAll": "Deselect all" } diff --git a/lib/pangea/chat_settings/widgets/delete_space_dialog.dart b/lib/pangea/chat_settings/widgets/delete_space_dialog.dart index 184ba65e7..f1d311992 100644 --- a/lib/pangea/chat_settings/widgets/delete_space_dialog.dart +++ b/lib/pangea/chat_settings/widgets/delete_space_dialog.dart @@ -77,6 +77,27 @@ class DeleteSpaceDialogState extends State { }); } + void _toggleSelectAll() { + setState(() { + if (_roomsToDelete.length == _selectableRooms.length) { + _roomsToDelete.clear(); + } else { + _roomsToDelete + ..clear() + ..addAll(_selectableRooms); + } + }); + } + + List get _selectableRooms { + return _rooms.where((chunk) { + final room = widget.space.client.getRoomById(chunk.roomId); + return room != null && + room.membership == Membership.join && + room.isRoomAdmin; + }).toList(); + } + Future _deleteSpace() async { setState(() { _deleting = true; @@ -174,35 +195,53 @@ class DeleteSpaceDialogState extends State { return Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), - child: ListView.builder( - shrinkWrap: true, - itemCount: _rooms.length, - itemBuilder: (context, index) { - final chunk = _rooms[index]; - - final room = - widget.space.client.getRoomById(chunk.roomId); - final isMember = room != null && - room.membership == Membership.join && - room.isRoomAdmin; - - final displayname = chunk.name ?? - chunk.canonicalAlias ?? - L10n.of(context).emptyChat; - - return AnimatedOpacity( - duration: FluffyThemes.animationDuration, - opacity: isMember ? 1 : 0.5, - child: CheckboxListTile( - value: _roomsToDelete.contains(chunk), - onChanged: isMember - ? (value) => _onRoomSelected(value, chunk) - : null, - title: Text(displayname), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (_selectableRooms.length > 1) + CheckboxListTile( + value: _roomsToDelete.length == + _selectableRooms.length, + onChanged: (_) => _toggleSelectAll(), + title: Text( + _roomsToDelete.length == _selectableRooms.length + ? L10n.of(context).deselectAll + : L10n.of(context).selectAll, + ), controlAffinity: ListTileControlAffinity.leading, ), - ); - }, + ListView.builder( + shrinkWrap: true, + itemCount: _rooms.length, + itemBuilder: (context, index) { + final chunk = _rooms[index]; + + final room = + widget.space.client.getRoomById(chunk.roomId); + final isMember = room != null && + room.membership == Membership.join && + room.isRoomAdmin; + + final displayname = chunk.name ?? + chunk.canonicalAlias ?? + L10n.of(context).emptyChat; + + return AnimatedOpacity( + duration: FluffyThemes.animationDuration, + opacity: isMember ? 1 : 0.5, + child: CheckboxListTile( + value: _roomsToDelete.contains(chunk), + onChanged: isMember + ? (value) => _onRoomSelected(value, chunk) + : null, + title: Text(displayname), + controlAffinity: + ListTileControlAffinity.leading, + ), + ); + }, + ), + ], ), ); },