diff --git a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/dialogs/clear_container_data_dialog.dart b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/dialogs/clear_container_data_dialog.dart index 97ad4006..6368aa12 100644 --- a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/dialogs/clear_container_data_dialog.dart +++ b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/dialogs/clear_container_data_dialog.dart @@ -18,50 +18,100 @@ * along with this program. If not, see . */ import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_material_design_icons/flutter_material_design_icons.dart'; -Future showClearContainerDataDialog(BuildContext context, int tabCount) { - return showDialog( +class ClearContainerDataResult { + final bool confirmed; + final bool reopenTabs; + + const ClearContainerDataResult({ + required this.confirmed, + required this.reopenTabs, + }); +} + +Future showClearContainerDataDialog( + BuildContext context, + int tabCount, +) { + return showDialog( context: context, builder: (BuildContext context) { - return AlertDialog( - icon: const Icon(MdiIcons.databaseRemove), - title: const Text('Clear Container Data?'), - content: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text('This will clear all data for this container:'), - const SizedBox(height: 8), - const Text('• Cookies'), - const Text('• Site data'), - const Text('• Cache'), - const Text('• Permissions'), - const SizedBox(height: 8), - Text( - '$tabCount tab(s) will be closed and reopened fresh.', - style: TextStyle( - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.tertiary, - ), - ), - ], - ), - actions: [ - TextButton( - onPressed: () { - Navigator.pop(context, false); - }, - child: const Text('Cancel'), - ), - TextButton( - onPressed: () { - Navigator.pop(context, true); - }, - child: const Text('Clear Data'), - ), - ], - ); + return _ClearContainerDataDialog(tabCount: tabCount); }, ); } + +class _ClearContainerDataDialog extends HookWidget { + final int tabCount; + + const _ClearContainerDataDialog({required this.tabCount}); + + @override + Widget build(BuildContext context) { + final reopenTabs = useState(false); + + return AlertDialog( + icon: const Icon(MdiIcons.databaseRemove), + title: const Text('Clear Container Data'), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('This will clear all data for this container:'), + const SizedBox(height: 8), + const Text('• Cookies'), + const Text('• Site data'), + const Text('• Cache'), + const Text('• Permissions'), + const SizedBox(height: 8), + Text( + '$tabCount tab(s) will be closed.', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Theme.of(context).colorScheme.tertiary, + ), + ), + CheckboxListTile( + value: reopenTabs.value, + onChanged: (value) { + if (value != null) { + reopenTabs.value = value; + } + }, + title: const Text('Recreate tabs after clearing'), + contentPadding: EdgeInsets.zero, + controlAffinity: ListTileControlAffinity.trailing, + ), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.pop( + context, + const ClearContainerDataResult( + confirmed: false, + reopenTabs: false, + ), + ); + }, + child: const Text('Cancel'), + ), + TextButton( + onPressed: () { + Navigator.pop( + context, + ClearContainerDataResult( + confirmed: true, + reopenTabs: reopenTabs.value, + ), + ); + }, + child: const Text('Clear Data'), + ), + ], + ); + } +} diff --git a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_view_header.dart b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_view_header.dart index 107179b7..156a025f 100644 --- a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_view_header.dart +++ b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_view_header.dart @@ -378,7 +378,9 @@ class TabViewHeader extends HookConsumerWidget { tabs.length, ); - if (result == true) { + if (result?.confirmed == true) { + final shouldReopenTabs = result!.reopenTabs; + try { final closedTabIds = await ref .read( @@ -398,52 +400,56 @@ class TabViewHeader extends HookConsumerWidget { .contextualIdentity!, ); - await ref - .read( - tabRepositoryProvider.notifier, - ) - .addMultipleTabs( - tabs: tabs.map((tab) { - var parentId = tab.parentId; - while (parentId != null && - closedTabIds.contains( - parentId, - )) { - parentId = tabs - .firstWhereOrNull( - (old) => - old.id == parentId, - ) - ?.parentId; - } + if (shouldReopenTabs) { + await ref + .read( + tabRepositoryProvider.notifier, + ) + .addMultipleTabs( + tabs: tabs.map((tab) { + var parentId = tab.parentId; + while (parentId != null && + closedTabIds.contains( + parentId, + )) { + parentId = tabs + .firstWhereOrNull( + (old) => + old.id == parentId, + ) + ?.parentId; + } - return AddTabParams( - url: tab.url.toString(), - startLoading: true, - parentId: parentId, - private: - tab.isPrivate ?? false, - flags: LoadUrlFlags.NONE - .toValue(), - source: Internal.newTab - .toValue(), - contextId: selectedContainer - .metadata - .contextualIdentity, - ); - }).toList(), - container: Value( - selectedContainer, - ), - ); + return AddTabParams( + url: tab.url.toString(), + startLoading: true, + parentId: parentId, + private: + tab.isPrivate ?? false, + flags: LoadUrlFlags.NONE + .toValue(), + source: Internal.newTab + .toValue(), + contextId: selectedContainer + .metadata + .contextualIdentity, + ); + }).toList(), + container: Value( + selectedContainer, + ), + ); + } if (context.mounted) { ScaffoldMessenger.of( context, ).showSnackBar( - const SnackBar( + SnackBar( content: Text( - 'Container data cleared successfully', + shouldReopenTabs + ? 'Container data cleared successfully' + : 'Container data cleared. ${tabs.length} tab(s) closed.', ), ), );