From 0d35359da0b4f156c3edf56cd6c3ed0a86a94c5f Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Sun, 16 Nov 2025 06:12:55 +0100 Subject: [PATCH] site assign context menu --- .../presentation/widgets/tab_menu.dart | 46 +++++++++++++++++++ .../features/tabs/domain/providers.dart | 17 +++++++ .../features/tabs/domain/providers.g.dart | 36 +++++++++++++++ 3 files changed, 99 insertions(+) diff --git a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_menu.dart b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_menu.dart index e2fb6d75..ede0975f 100644 --- a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_menu.dart +++ b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_menu.dart @@ -24,6 +24,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_material_design_icons/flutter_material_design_icons.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:nullability/nullability.dart'; import 'package:share_plus/share_plus.dart'; import 'package:weblibre/core/routing/routes.dart'; import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart'; @@ -35,6 +36,7 @@ import 'package:weblibre/features/geckoview/features/browser/presentation/dialog import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart'; import 'package:weblibre/features/geckoview/features/readerview/presentation/controllers/readerable.dart'; import 'package:weblibre/features/geckoview/features/readerview/presentation/widgets/reader_button.dart'; +import 'package:weblibre/features/geckoview/features/tabs/data/models/container_data.dart'; 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'; @@ -214,6 +216,50 @@ class TabMenu extends HookConsumerWidget { } }, ), + Consumer( + child: MenuItemButton( + leadingIcon: const Icon(MdiIcons.webPlus), + child: const Text('Assign Site to Container'), + onPressed: () async { + final targetContainerId = await ContainerSelectionRoute() + .push(context); + + if (targetContainerId != null) { + final containerData = await ref + .read(containerRepositoryProvider.notifier) + .getContainerData(targetContainerId); + + if (containerData != null) { + final tabState = ref.read(tabStateProvider(selectedTabId)); + 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.assignedSites, + origin, + ]), + ), + ); + } + } + } + }, + ), + builder: (context, ref, child) { + final isSiteAssigned = ref.watch( + watchIsCurrentSiteAssignedToContainerProvider, + ); + + return Visibility( + visible: isSiteAssigned.hasValue && !isSiteAssigned.requireValue, + child: child!, + ); + }, + ), Consumer( child: MenuItemButton( leadingIcon: const Icon(MdiIcons.folderCancelOutline), diff --git a/app/lib/features/geckoview/features/tabs/domain/providers.dart b/app/lib/features/geckoview/features/tabs/domain/providers.dart index 02da66ba..b69c1fb5 100644 --- a/app/lib/features/geckoview/features/tabs/domain/providers.dart +++ b/app/lib/features/geckoview/features/tabs/domain/providers.dart @@ -20,6 +20,8 @@ import 'package:nullability/nullability.dart'; import 'package:riverpod/riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:weblibre/features/geckoview/domain/entities/states/tab.dart'; +import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart'; import 'package:weblibre/features/geckoview/features/tabs/data/database/definitions.drift.dart'; import 'package:weblibre/features/geckoview/features/tabs/data/entities/container_filter.dart'; import 'package:weblibre/features/geckoview/features/tabs/data/models/container_data.dart'; @@ -124,3 +126,18 @@ Stream watchContainerTabId(Ref ref, String tabId) { Stream> watchAllAssignedSites(Ref ref) { return ref.read(tabDatabaseProvider).containerDao.allAssignedSites().watch(); } + +@Riverpod() +Stream watchIsCurrentSiteAssignedToContainer(Ref ref) { + final currentUri = ref.watch( + selectedTabStateProvider.select( + (value) => value?.url ?? TabState.$default('').url, + ), + ); + + return ref + .read(tabDatabaseProvider) + .containerDao + .isSiteAssignedToContainer(currentUri) + .watchSingle(); +} diff --git a/app/lib/features/geckoview/features/tabs/domain/providers.g.dart b/app/lib/features/geckoview/features/tabs/domain/providers.g.dart index 6be6956a..fa1faf7e 100644 --- a/app/lib/features/geckoview/features/tabs/domain/providers.g.dart +++ b/app/lib/features/geckoview/features/tabs/domain/providers.g.dart @@ -673,3 +673,39 @@ final class WatchAllAssignedSitesProvider String _$watchAllAssignedSitesHash() => r'd755451be0ad7e03db36ba39c64f6f0b5c1d9ba3'; + +@ProviderFor(watchIsCurrentSiteAssignedToContainer) +const watchIsCurrentSiteAssignedToContainerProvider = + WatchIsCurrentSiteAssignedToContainerProvider._(); + +final class WatchIsCurrentSiteAssignedToContainerProvider + extends $FunctionalProvider, bool, Stream> + with $FutureModifier, $StreamProvider { + const WatchIsCurrentSiteAssignedToContainerProvider._() + : super( + from: null, + argument: null, + retry: null, + name: r'watchIsCurrentSiteAssignedToContainerProvider', + isAutoDispose: true, + dependencies: null, + $allTransitiveDependencies: null, + ); + + @override + String debugGetCreateSourceHash() => + _$watchIsCurrentSiteAssignedToContainerHash(); + + @$internal + @override + $StreamProviderElement $createElement($ProviderPointer pointer) => + $StreamProviderElement(pointer); + + @override + Stream create(Ref ref) { + return watchIsCurrentSiteAssignedToContainer(ref); + } +} + +String _$watchIsCurrentSiteAssignedToContainerHash() => + r'2942672c75b671fbe84489606e5341f0290502c3';