bookmark all option dialog fast/detailed
This commit is contained in:
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2024-2025 Fabian Freund.
|
||||
*
|
||||
* This file is part of WebLibre
|
||||
* (see https://weblibre.eu).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||
|
||||
enum BookmarkAllChoice { fast, detailed }
|
||||
|
||||
/// Dialog to select between fast (automatic) or detailed (one-by-one) bookmark import.
|
||||
Future<BookmarkAllChoice?> showBookmarkAllDialog(BuildContext context) {
|
||||
return showDialog<BookmarkAllChoice>(
|
||||
context: context,
|
||||
builder: (context) => SimpleDialog(
|
||||
title: const Text('Bookmark All Tabs'),
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(MdiIcons.fastForward),
|
||||
title: const Text('Fast'),
|
||||
subtitle: const Text(
|
||||
'Automatically add all tabs to a selected folder',
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop(BookmarkAllChoice.fast);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(MdiIcons.stepForward),
|
||||
title: const Text('Detailed'),
|
||||
subtitle: const Text('Review and edit each bookmark individually'),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop(BookmarkAllChoice.detailed);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2024-2025 Fabian Freund.
|
||||
*
|
||||
* This file is part of WebLibre
|
||||
* (see https://weblibre.eu).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:weblibre/features/geckoview/features/bookmarks/presentation/widgets/folder_tree_picker.dart';
|
||||
|
||||
/// Dialog to select a bookmark folder.
|
||||
/// Returns the selected folder GUID or null if cancelled.
|
||||
Future<String?> showSelectFolderDialog(BuildContext context) {
|
||||
return showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => const _SelectFolderDialog(),
|
||||
);
|
||||
}
|
||||
|
||||
class _SelectFolderDialog extends HookConsumerWidget {
|
||||
const _SelectFolderDialog();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final selectedFolderGuid = useState(BookmarkRoot.mobile.id);
|
||||
|
||||
return AlertDialog(
|
||||
title: const Text('Select folder'),
|
||||
content: SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: SingleChildScrollView(
|
||||
child: FolderTreePicker(
|
||||
selectedFolderGuid: selectedFolderGuid,
|
||||
entryGuid: BookmarkRoot.root.id,
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () => Navigator.of(context).pop(selectedFolderGuid.value),
|
||||
child: const Text('Select'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
+43
-9
@@ -10,8 +10,11 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||
import 'package:weblibre/features/geckoview/features/bookmarks/domain/repositories/bookmarks.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/domain/services/browser_data.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/controllers/tab_view_controllers.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/bookmark_all_dialog.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/select_folder_dialog.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/dialogs/clear_container_data_dialog.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/dialogs/close_all_private_tabs_dialog.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/dialogs/close_all_tabs_dialog.dart';
|
||||
@@ -252,6 +255,9 @@ class TabViewHeader extends HookConsumerWidget {
|
||||
leadingIcon: const Icon(MdiIcons.bookmarkPlusOutline),
|
||||
child: const Text('Bookmark all'),
|
||||
onPressed: () async {
|
||||
final choice = await showBookmarkAllDialog(context);
|
||||
if (choice == null || !context.mounted) return;
|
||||
|
||||
final containerId = ref.read(
|
||||
selectedContainerProvider,
|
||||
);
|
||||
@@ -260,16 +266,44 @@ class TabViewHeader extends HookConsumerWidget {
|
||||
.read(tabDataRepositoryProvider.notifier)
|
||||
.getContainerTabsData(containerId);
|
||||
|
||||
for (final tab in tabData) {
|
||||
if (choice == BookmarkAllChoice.fast) {
|
||||
if (!context.mounted) return;
|
||||
final folderGuid = await showSelectFolderDialog(
|
||||
context,
|
||||
);
|
||||
if (folderGuid == null) return;
|
||||
|
||||
final repo = ref.read(
|
||||
bookmarksRepositoryProvider.notifier,
|
||||
);
|
||||
for (final tab in tabData) {
|
||||
if (tab.url != null) {
|
||||
await repo.addBookmark(
|
||||
parentGuid: folderGuid,
|
||||
url: tab.url!,
|
||||
title: tab.title ?? tab.url.toString(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (context.mounted) {
|
||||
await BookmarkEntryAddRoute(
|
||||
bookmarkInfo: jsonEncode(
|
||||
BookmarkInfo(
|
||||
title: tab.title,
|
||||
url: tab.url.toString(),
|
||||
).encode(),
|
||||
),
|
||||
).push(context);
|
||||
ui_helper.showInfoMessage(
|
||||
context,
|
||||
'${tabData.length} bookmark(s) added',
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (final tab in tabData) {
|
||||
if (context.mounted) {
|
||||
await BookmarkEntryAddRoute(
|
||||
bookmarkInfo: jsonEncode(
|
||||
BookmarkInfo(
|
||||
title: tab.title,
|
||||
url: tab.url.toString(),
|
||||
).encode(),
|
||||
),
|
||||
).push(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user