show tabmenu for quick tabs
This commit is contained in:
+28
-5
@@ -331,12 +331,13 @@ class BrowserTabBar extends HookConsumerWidget {
|
||||
TabMenu(
|
||||
controller: trippleDotMenuController,
|
||||
selectedTabId: selectedTabId,
|
||||
child: InkWell(
|
||||
builder: (context, controller, child) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
if (trippleDotMenuController.isOpen) {
|
||||
trippleDotMenuController.close();
|
||||
if (controller.isOpen) {
|
||||
controller.close();
|
||||
} else {
|
||||
trippleDotMenuController.open();
|
||||
controller.open();
|
||||
}
|
||||
},
|
||||
child: const Padding(
|
||||
@@ -346,7 +347,8 @@ class BrowserTabBar extends HookConsumerWidget {
|
||||
),
|
||||
child: Icon(MdiIcons.dotsVertical),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (showMainToolbarTabsCount)
|
||||
TabsCountButton(
|
||||
@@ -500,6 +502,27 @@ class QuickTabSwitcher extends HookConsumerWidget {
|
||||
}
|
||||
await animation;
|
||||
},
|
||||
itemWrap: (child, item) {
|
||||
return TabMenu(
|
||||
selectedTabId: item.id,
|
||||
enableFindInPage: false,
|
||||
enableFetchFeeds: false,
|
||||
enableDesktopMode: false,
|
||||
enableReaderMode: false,
|
||||
builder: (context, controller, _) {
|
||||
return InkWell(
|
||||
onLongPress: () {
|
||||
if (controller.isOpen) {
|
||||
controller.close();
|
||||
} else {
|
||||
controller.open();
|
||||
}
|
||||
},
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
availableItems: tabStates.value
|
||||
.map(
|
||||
(state) => (
|
||||
|
||||
@@ -40,34 +40,56 @@ import 'package:weblibre/features/geckoview/features/tabs/data/models/container_
|
||||
import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/container.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart';
|
||||
import 'package:weblibre/presentation/hooks/menu_controller.dart';
|
||||
import 'package:weblibre/presentation/widgets/website_feed_menu_button.dart';
|
||||
import 'package:weblibre/utils/ui_helper.dart' as ui_helper;
|
||||
|
||||
class TabMenu extends HookConsumerWidget {
|
||||
final Widget child;
|
||||
final MenuController controller;
|
||||
final MenuAnchorChildBuilder builder;
|
||||
final MenuController? controller;
|
||||
final String selectedTabId;
|
||||
final bool enableFindInPage;
|
||||
final bool enableReaderMode;
|
||||
final bool enableDesktopMode;
|
||||
final bool enableFetchFeeds;
|
||||
final bool enableAddBookmark;
|
||||
final bool enableCloneTab;
|
||||
final bool enableContainer;
|
||||
final bool enableShare;
|
||||
final bool enableExport;
|
||||
final bool enableCloseTab;
|
||||
|
||||
const TabMenu({
|
||||
super.key,
|
||||
required this.child,
|
||||
required this.controller,
|
||||
required this.builder,
|
||||
required this.selectedTabId,
|
||||
this.controller,
|
||||
this.enableFindInPage = true,
|
||||
this.enableReaderMode = true,
|
||||
this.enableDesktopMode = true,
|
||||
this.enableFetchFeeds = true,
|
||||
this.enableAddBookmark = true,
|
||||
this.enableCloneTab = true,
|
||||
this.enableContainer = true,
|
||||
this.enableShare = true,
|
||||
this.enableExport = true,
|
||||
this.enableCloseTab = true,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final showFeeds = useState(false);
|
||||
|
||||
final controller = this.controller ?? useMenuController();
|
||||
|
||||
return MenuAnchor(
|
||||
controller: controller,
|
||||
onClose: () {
|
||||
showFeeds.value = false;
|
||||
},
|
||||
builder: (context, controller, child) {
|
||||
return child!;
|
||||
},
|
||||
builder: builder,
|
||||
menuChildren: [
|
||||
if (enableFindInPage)
|
||||
MenuItemButton(
|
||||
onPressed: () {
|
||||
ref.read(bottomSheetControllerProvider.notifier).requestDismiss();
|
||||
@@ -79,6 +101,7 @@ class TabMenu extends HookConsumerWidget {
|
||||
leadingIcon: const Icon(Icons.search),
|
||||
child: const Text('Find in page'),
|
||||
),
|
||||
if (enableReaderMode)
|
||||
ReaderButton(
|
||||
buttonBuilder: (isLoading, readerActive, icon) => MenuItemButton(
|
||||
onPressed: isLoading
|
||||
@@ -103,13 +126,18 @@ class TabMenu extends HookConsumerWidget {
|
||||
child: const Text('Reader Mode'),
|
||||
),
|
||||
),
|
||||
if (enableDesktopMode)
|
||||
Consumer(
|
||||
builder: (context, childRef, child) {
|
||||
final enabled = childRef.watch(desktopModeProvider(selectedTabId));
|
||||
final enabled = childRef.watch(
|
||||
desktopModeProvider(selectedTabId),
|
||||
);
|
||||
|
||||
return MenuItemButton(
|
||||
onPressed: () {
|
||||
ref.read(desktopModeProvider(selectedTabId).notifier).toggle();
|
||||
ref
|
||||
.read(desktopModeProvider(selectedTabId).notifier)
|
||||
.toggle();
|
||||
},
|
||||
leadingIcon: const Icon(MdiIcons.monitor),
|
||||
trailingIcon: Checkbox(
|
||||
@@ -127,7 +155,9 @@ class TabMenu extends HookConsumerWidget {
|
||||
);
|
||||
},
|
||||
),
|
||||
if (enableFindInPage || enableReaderMode || enableDesktopMode)
|
||||
const Divider(),
|
||||
if (enableFetchFeeds)
|
||||
Visibility(
|
||||
visible: showFeeds.value,
|
||||
replacement: MenuItemButton(
|
||||
@@ -140,6 +170,7 @@ class TabMenu extends HookConsumerWidget {
|
||||
),
|
||||
child: WebsiteFeedMenuButton(selectedTabId),
|
||||
),
|
||||
if (enableAddBookmark)
|
||||
MenuItemButton(
|
||||
leadingIcon: const Icon(MdiIcons.bookmarkPlus),
|
||||
child: const Text('Add Bookmark'),
|
||||
@@ -156,6 +187,7 @@ class TabMenu extends HookConsumerWidget {
|
||||
).push(context);
|
||||
},
|
||||
),
|
||||
if (enableCloneTab)
|
||||
SubmenuButton(
|
||||
menuChildren: [
|
||||
MenuItemButton(
|
||||
@@ -193,7 +225,11 @@ class TabMenu extends HookConsumerWidget {
|
||||
|
||||
final tabId = await ref
|
||||
.read(tabRepositoryProvider.notifier)
|
||||
.addTab(url: tabState.url, private: true, selectTab: false);
|
||||
.addTab(
|
||||
url: tabState.url,
|
||||
private: true,
|
||||
selectTab: false,
|
||||
);
|
||||
|
||||
if (context.mounted) {
|
||||
//save reference before pop `ref` gets disposed
|
||||
@@ -212,14 +248,17 @@ class TabMenu extends HookConsumerWidget {
|
||||
leadingIcon: const Icon(MdiIcons.tabPlus),
|
||||
child: const Text('Clone Tab'),
|
||||
),
|
||||
if (enableContainer)
|
||||
SubmenuButton(
|
||||
menuChildren: [
|
||||
MenuItemButton(
|
||||
leadingIcon: const Icon(MdiIcons.folderArrowUpDownOutline),
|
||||
child: const Text('Assign Container'),
|
||||
onPressed: () async {
|
||||
final targetContainerId = await const ContainerSelectionRoute()
|
||||
.push<String?>(context);
|
||||
final targetContainerId =
|
||||
await const ContainerSelectionRoute().push<String?>(
|
||||
context,
|
||||
);
|
||||
|
||||
if (targetContainerId != null) {
|
||||
final containerData = await ref
|
||||
@@ -227,7 +266,9 @@ class TabMenu extends HookConsumerWidget {
|
||||
.getContainerData(targetContainerId);
|
||||
|
||||
if (containerData != null) {
|
||||
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
||||
final tabState = ref.read(
|
||||
tabStateProvider(selectedTabId),
|
||||
)!;
|
||||
|
||||
await ref
|
||||
.read(tabDataRepositoryProvider.notifier)
|
||||
@@ -255,17 +296,21 @@ class TabMenu extends HookConsumerWidget {
|
||||
final tabState = ref.read(
|
||||
tabStateProvider(selectedTabId),
|
||||
);
|
||||
final origin = tabState?.url.origin.mapNotNull(Uri.parse);
|
||||
final origin = tabState?.url.origin.mapNotNull(
|
||||
Uri.parse,
|
||||
);
|
||||
|
||||
if (origin != null) {
|
||||
await ref
|
||||
.read(containerRepositoryProvider.notifier)
|
||||
.replaceContainer(
|
||||
containerData.copyWith.metadata(
|
||||
containerData.metadata.copyWith.assignedSites([
|
||||
containerData.metadata.copyWith.assignedSites(
|
||||
[
|
||||
...?containerData.metadata.assignedSites,
|
||||
origin,
|
||||
]),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -304,13 +349,17 @@ class TabMenu extends HookConsumerWidget {
|
||||
).select((value) => value.value),
|
||||
);
|
||||
|
||||
return Visibility(visible: containerId != null, child: child!);
|
||||
return Visibility(
|
||||
visible: containerId != null,
|
||||
child: child!,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
leadingIcon: const Icon(MdiIcons.folder),
|
||||
child: const Text('Container'),
|
||||
),
|
||||
if (enableShare)
|
||||
SubmenuButton(
|
||||
menuChildren: [
|
||||
CopyAddressMenuItemButton(selectedTabId: selectedTabId),
|
||||
@@ -322,6 +371,7 @@ class TabMenu extends HookConsumerWidget {
|
||||
leadingIcon: const Icon(Icons.share),
|
||||
child: const Text('Share'),
|
||||
),
|
||||
if (enableExport)
|
||||
SubmenuButton(
|
||||
menuChildren: [
|
||||
ShareMarkdownActionMenuItemButton(
|
||||
@@ -359,6 +409,7 @@ class TabMenu extends HookConsumerWidget {
|
||||
leadingIcon: const Icon(MdiIcons.fileExport),
|
||||
child: const Text('Export'),
|
||||
),
|
||||
if (enableCloseTab)
|
||||
MenuItemButton(
|
||||
onPressed: () async {
|
||||
await ref
|
||||
@@ -376,7 +427,6 @@ class TabMenu extends HookConsumerWidget {
|
||||
child: const Text('Close Tab'),
|
||||
),
|
||||
],
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user