diff --git a/app/lib/features/geckoview/domain/providers/tab_session.dart b/app/lib/features/geckoview/domain/providers/tab_session.dart index fa9238b7..95a71bfc 100644 --- a/app/lib/features/geckoview/domain/providers/tab_session.dart +++ b/app/lib/features/geckoview/domain/providers/tab_session.dart @@ -44,8 +44,8 @@ class TabSession extends _$TabSession { return _sessionService.stopLoading(); } - Future reload() { - return _sessionService.reload(); + Future reload({LoadUrlFlags flags = LoadUrlFlags.NONE}) { + return _sessionService.reload(flags: flags); } Future goBack() { diff --git a/app/lib/features/geckoview/domain/providers/tab_session.g.dart b/app/lib/features/geckoview/domain/providers/tab_session.g.dart index 6b4772c5..9d5ef887 100644 --- a/app/lib/features/geckoview/domain/providers/tab_session.g.dart +++ b/app/lib/features/geckoview/domain/providers/tab_session.g.dart @@ -57,7 +57,7 @@ final class TabSessionProvider extends $NotifierProvider { } } -String _$tabSessionHash() => r'b9381c334672fd3f733a4cc86ce696fb7de6fa5d'; +String _$tabSessionHash() => r'be44598ad023c2fb23e48d3fa4bf805c4640c599'; final class TabSessionFamily extends $Family with $ClassFamilyOverride { diff --git a/app/lib/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_id.dart b/app/lib/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_id.dart index f239a748..3e07e21d 100644 --- a/app/lib/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_id.dart +++ b/app/lib/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_id.dart @@ -40,4 +40,5 @@ enum ToolbarButtonId { pageUp, pageDown, font, + extensionShortcut, } diff --git a/app/lib/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_spec.dart b/app/lib/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_spec.dart index 4e94fb60..5c792eb7 100644 --- a/app/lib/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_spec.dart +++ b/app/lib/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_spec.dart @@ -147,6 +147,12 @@ const fontToolbarButtonSpec = ToolbarButtonSpec( defaultVisible: false, ); +const extensionShortcutToolbarButtonSpec = ToolbarButtonSpec( + id: ToolbarButtonId.extensionShortcut, + defaultVisible: false, + canBeFallbackTarget: false, +); + const toolbarButtonSpecs = [ backToolbarButtonSpec, forwardToolbarButtonSpec, @@ -169,6 +175,7 @@ const toolbarButtonSpecs = [ pageUpToolbarButtonSpec, pageDownToolbarButtonSpec, fontToolbarButtonSpec, + extensionShortcutToolbarButtonSpec, ]; final Map toolbarButtonSpecsById = { diff --git a/app/lib/features/geckoview/features/browser/features/contextual_toolbar/presentation/toolbar_button_registry.dart b/app/lib/features/geckoview/features/browser/features/contextual_toolbar/presentation/toolbar_button_registry.dart index 3b568e6f..6946685b 100644 --- a/app/lib/features/geckoview/features/browser/features/contextual_toolbar/presentation/toolbar_button_registry.dart +++ b/app/lib/features/geckoview/features/browser/features/contextual_toolbar/presentation/toolbar_button_registry.dart @@ -18,6 +18,7 @@ * 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'; import 'package:flutter_mozilla_components/flutter_mozilla_components.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -27,11 +28,15 @@ import 'package:weblibre/features/geckoview/domain/providers.dart'; import 'package:weblibre/features/geckoview/domain/providers/desktop_mode.dart'; import 'package:weblibre/features/geckoview/domain/providers/tab_session.dart'; import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart'; +import 'package:weblibre/features/geckoview/domain/providers/web_extensions_state.dart'; import 'package:weblibre/features/geckoview/domain/repositories/tab.dart'; +import 'package:weblibre/features/geckoview/features/bookmarks/domain/entities/bookmark_item.dart'; +import 'package:weblibre/features/geckoview/features/bookmarks/domain/repositories/bookmarks.dart'; import 'package:weblibre/features/geckoview/features/browser/domain/entities/font_size_constants.dart'; import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_spec.dart'; import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/models/contextual_toolbar_scope.dart'; import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/widgets/contextual_bar_buttons.dart'; +import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/extension_shortcut_menu.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/font_size_bottom_sheet.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/navigation_buttons.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tabs_action_button.dart'; @@ -112,18 +117,7 @@ final List toolbarButtonRegistry = [ spec: bookmarksToolbarButtonSpec, label: 'Bookmarks', icon: MdiIcons.bookmarkMultiple, - builder: (scope, context, ref) { - return IconButton( - onPressed: scope.isPreview - ? () {} - : () async { - await BookmarkListRoute( - entryGuid: BookmarkRoot.root.id, - ).push(context); - }, - icon: const Icon(MdiIcons.bookmarkMultiple), - ); - }, + builder: (scope, context, ref) => _BookmarkToolbarButton(scope: scope), ), ToolbarButtonDefinition( spec: shareToolbarButtonSpec, @@ -177,21 +171,7 @@ final List toolbarButtonRegistry = [ spec: reloadToolbarButtonSpec, label: 'Reload', icon: Icons.refresh, - builder: (scope, context, ref) { - return IconButton( - onPressed: scope.isPreview - ? () {} - : () async { - final tabId = scope.selectedTabId; - if (tabId != null) { - await ref - .read(tabSessionProvider(tabId: tabId).notifier) - .reload(); - } - }, - icon: const Icon(Icons.refresh), - ); - }, + builder: (scope, context, ref) => _ReloadToolbarButton(scope: scope), ), ToolbarButtonDefinition( spec: readerModeToolbarButtonSpec, @@ -276,14 +256,7 @@ final List toolbarButtonRegistry = [ spec: closeTabToolbarButtonSpec, label: 'Close Tab', icon: MdiIcons.tabMinus, - builder: (scope, context, ref) { - return IconButton( - onPressed: scope.isPreview - ? () {} - : () => _closeTab(context, ref, scope.selectedTabId), - icon: const Icon(MdiIcons.tabMinus), - ); - }, + builder: (scope, context, ref) => _CloseTabToolbarButton(scope: scope), ), ToolbarButtonDefinition( spec: inputUrlToolbarButtonSpec, @@ -417,6 +390,24 @@ final List toolbarButtonRegistry = [ return _FontToolbarButton(selectedTabId: scope.selectedTabId); }, ), + ToolbarButtonDefinition( + spec: extensionShortcutToolbarButtonSpec, + label: 'Extensions', + icon: MdiIcons.puzzle, + isPrimaryAvailable: (scope, ref) => ref + .read( + webExtensionsStateProvider( + WebExtensionActionType.browser, + ).select((value) => value.values), + ) + .isNotEmpty, + builder: (scope, context, ref) { + if (scope.isPreview) { + return IconButton(onPressed: () {}, icon: const Icon(MdiIcons.puzzle)); + } + return const _ExtensionShortcutToolbarButton(); + }, + ), ]; final Map toolbarButtonRegistryById = { @@ -452,6 +443,224 @@ Future _closeTab( } } +class _ExtensionShortcutToolbarButton extends HookConsumerWidget { + const _ExtensionShortcutToolbarButton(); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final menuController = useMemoized(MenuController.new); + + return ExtensionShortcutMenu( + controller: menuController, + child: IconButton( + onPressed: menuController.open, + icon: const Icon(MdiIcons.puzzle), + ), + ); + } +} + +class _ReloadToolbarButton extends HookConsumerWidget { + final ContextualToolbarScope scope; + + const _ReloadToolbarButton({required this.scope}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final menuController = useMemoized(MenuController.new); + + return MenuAnchor( + controller: menuController, + builder: (context, controller, child) => child!, + menuChildren: [ + MenuItemButton( + leadingIcon: const Icon(Icons.refresh), + onPressed: () async { + final tabId = scope.selectedTabId; + if (tabId != null) { + await ref + .read(tabSessionProvider(tabId: tabId).notifier) + .reload(flags: LoadUrlFlags.BYPASS_CACHE); + } + }, + child: const Text('Hard Refresh'), + ), + ], + child: IconButton( + onPressed: scope.isPreview + ? () {} + : () async { + final tabId = scope.selectedTabId; + if (tabId != null) { + await ref + .read(tabSessionProvider(tabId: tabId).notifier) + .reload(); + } + }, + onLongPress: scope.isPreview ? null : menuController.open, + icon: const Icon(Icons.refresh), + ), + ); + } +} + +class _CloseTabToolbarButton extends HookConsumerWidget { + final ContextualToolbarScope scope; + + const _CloseTabToolbarButton({required this.scope}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final menuController = useMemoized(MenuController.new); + final host = ref.watch( + tabStateProvider(scope.selectedTabId).select((s) => s?.url.host), + ); + + return MenuAnchor( + controller: menuController, + builder: (context, controller, child) => child!, + menuChildren: [ + MenuItemButton( + leadingIcon: const Icon(Icons.tab), + onPressed: () async { + final tabStates = ref.read(tabStatesProvider); + final otherIds = tabStates.keys + .where((id) => id != scope.selectedTabId) + .toList(); + if (otherIds.isNotEmpty) { + await ref + .read(tabRepositoryProvider.notifier) + .closeTabs(otherIds); + } + }, + child: const Text('Close Others'), + ), + if (host != null && host.isNotEmpty) + MenuItemButton( + leadingIcon: const Icon(Icons.language), + onPressed: () async { + final tabStates = ref.read(tabStatesProvider); + final sameHostIds = tabStates.entries + .where((e) => e.value.url.host == host) + .map((e) => e.key) + .toList(); + if (sameHostIds.isNotEmpty) { + await ref + .read(tabRepositoryProvider.notifier) + .closeTabs(sameHostIds); + } + }, + child: const Text('Close from Same Host'), + ), + ], + child: IconButton( + onPressed: scope.isPreview + ? () {} + : () => _closeTab(context, ref, scope.selectedTabId), + onLongPress: scope.isPreview ? null : menuController.open, + icon: const Icon(MdiIcons.tabMinus), + ), + ); + } +} + +class _BookmarkToolbarButton extends HookConsumerWidget { + final ContextualToolbarScope scope; + + const _BookmarkToolbarButton({required this.scope}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final menuController = useMemoized(MenuController.new); + + final tabUrl = scope.tabState?.url; + final bookmarkable = tabUrl != null && !scope.isPreview; + + // Walk the in-memory bookmark tree to find GUIDs for the current URL. + final existingGuids = ref.watch( + bookmarksRepositoryProvider.select((async) { + final result = []; + + if (!bookmarkable) return const []; + + final root = async.value; + if (root == null) return const []; + + void collect(BookmarkItem item) { + if (item is BookmarkEntry && item.url == tabUrl) { + result.add(item.guid); + } + + if (item is BookmarkFolder) { + for (final child in item.children ?? const []) { + collect(child); + } + } + } + + collect(root); + + return result; + }), + ); + + final isBookmarked = existingGuids.isNotEmpty; + + return MenuAnchor( + controller: menuController, + builder: (context, controller, child) => child!, + menuChildren: [ + if (isBookmarked) + MenuItemButton( + leadingIcon: const Icon(MdiIcons.bookmarkRemove), + onPressed: () async { + for (final guid in existingGuids) { + await ref + .read(bookmarksRepositoryProvider.notifier) + .delete(guid); + } + if (context.mounted) { + ui_helper.showInfoMessage(context, 'Bookmark removed'); + } + }, + child: const Text('Remove Bookmark'), + ) + else + MenuItemButton( + leadingIcon: const Icon(MdiIcons.bookmarkPlus), + onPressed: !bookmarkable + ? null + : () async { + await ref + .read(bookmarksRepositoryProvider.notifier) + .addBookmark( + parentGuid: BookmarkRoot.mobile.id, + url: tabUrl, + title: scope.tabState!.titleOrAuthority, + ); + + if (context.mounted) { + ui_helper.showInfoMessage(context, 'Bookmark added'); + } + }, + child: const Text('Add Bookmark'), + ), + ], + child: IconButton( + onPressed: scope.isPreview + ? () {} + : () async { + await BookmarkListRoute( + entryGuid: BookmarkRoot.root.id, + ).push(context); + }, + onLongPress: scope.isPreview ? null : menuController.open, + icon: const Icon(MdiIcons.bookmarkMultiple), + ), + ); + } +} + Future _adjustFontSize( BuildContext context, WidgetRef ref, { diff --git a/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart b/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart index 459044a1..3de74887 100644 --- a/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart +++ b/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart @@ -28,28 +28,23 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:weblibre/core/design/app_colors.dart'; import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart'; -import 'package:weblibre/features/geckoview/domain/entities/states/readerable.dart'; import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart'; -import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart'; import 'package:weblibre/features/geckoview/domain/repositories/tab.dart'; import 'package:weblibre/features/geckoview/features/browser/domain/entities/sheet.dart'; import 'package:weblibre/features/geckoview/features/browser/domain/providers.dart'; +import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/data/providers/toolbar_button_configs.dart'; +import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_id.dart'; import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/widgets/contextual_bar_buttons.dart'; import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/widgets/contextual_toolbar.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/controllers/toolbar_visibility.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/app_bar_title.dart'; -import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/extension_shortcut_menu.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_icon.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_menu.dart'; -import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/toolbar_button.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/entities/tab_mode.dart'; import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart'; import 'package:weblibre/features/geckoview/features/tabs/utils/container_colors.dart'; import 'package:weblibre/features/user/data/models/general_settings.dart'; import 'package:weblibre/features/user/domain/repositories/general_settings.dart'; -import 'package:weblibre/presentation/hooks/menu_controller.dart'; import 'package:weblibre/presentation/widgets/selectable_chips.dart'; import 'package:weblibre/presentation/widgets/url_icon.dart'; @@ -72,8 +67,6 @@ class BrowserTopAppBar extends StatelessWidget { displayedSheet: null, showContextualToolbar: false, showQuickTabSwitcherBar: false, - showMainToolbarNavigationButton: !showContextualToolbar, - showMainToolbarTabsCount: !showContextualToolbar, ); } @@ -108,8 +101,6 @@ class BrowserBottomAppBar extends StatelessWidget { showMainToolbar: showMainToolbar, showContextualToolbar: showContextualToolbar, showQuickTabSwitcherBar: showQuickTabSwitcherBar, - showMainToolbarNavigationButton: !showContextualToolbar, - showMainToolbarTabsCount: !showContextualToolbar, ); } @@ -137,17 +128,12 @@ class BrowserTabBar extends HookConsumerWidget { final bool showQuickTabSwitcherBar; final Sheet? displayedSheet; - final bool showMainToolbarTabsCount; - final bool showMainToolbarNavigationButton; - const BrowserTabBar({ super.key, required this.showMainToolbar, required this.displayedSheet, required this.showContextualToolbar, required this.showQuickTabSwitcherBar, - required this.showMainToolbarTabsCount, - required this.showMainToolbarNavigationButton, }); static const contextualToolabarHeight = 54.0; @@ -180,18 +166,37 @@ class BrowserTabBar extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final extensionMenuController = useMenuController(); - final selectedTabId = ref.watch(selectedTabProvider); final settings = ref.watch(generalSettingsWithDefaultsProvider); + // Determine which buttons are actually visible in the contextual toolbar + // so we only hide them from the main toolbar when they're genuinely present there. + final contextualConfigs = ref + .watch(effectiveToolbarButtonConfigsProvider) + .value; + + final tabsCountInContextual = + showContextualToolbar && + contextualConfigs.any( + (c) => c.buttonId == ToolbarButtonId.tabsCount.name && c.isVisible, + ); + + final menuInContextual = + showContextualToolbar && + contextualConfigs.any( + (c) => + c.buttonId == ToolbarButtonId.navigationMenu.name && c.isVisible, + ); + + final showMainToolbarTabsCount = !tabsCountInContextual; + final showMainToolbarNavigationButton = !menuInContextual; + final containerColor = ref.watch( watchTabContainerDataProvider( selectedTabId, ).select((data) => data.value?.color), ); - final showExtensionShortcut = settings.showExtensionShortcut; final quickTabSwitcherMode = settings.effectiveUiQuickTabSwitcherMode(); final tabBarPosition = settings.tabBarPosition; @@ -221,58 +226,6 @@ class BrowserTabBar extends HookConsumerWidget { : const AppBarTitle() : null, actions: [ - if (showTabTitle) - Consumer( - builder: (context, ref, child) { - final tabBarReaderView = ref.watch( - generalSettingsWithDefaultsProvider.select( - (value) => value.tabBarReaderView, - ), - ); - - final readerabilityStateActive = ref.watch( - selectedTabStateProvider.select( - (state) => - (state?.readerableState ?? ReaderableState.$default()) - .active, - ), - ); - - return Visibility( - visible: tabBarReaderView || readerabilityStateActive, - child: ReaderButton( - buttonBuilder: (isLoading, readerActive, icon) => - ToolbarButton( - onTap: isLoading - ? null - : () async { - await ref - .read( - readerableScreenControllerProvider - .notifier, - ) - .toggleReaderView(!readerActive); - }, - child: icon, - ), - ), - ); - }, - ), - if (showExtensionShortcut) - ExtensionShortcutMenu( - controller: extensionMenuController, - child: ToolbarButton( - onTap: () { - if (extensionMenuController.isOpen) { - extensionMenuController.close(); - } else { - extensionMenuController.open(); - } - }, - child: const Icon(MdiIcons.puzzle), - ), - ), if (showMainToolbarTabsCount) TabsCountButton( selectedTabId: selectedTabId, diff --git a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_preview.dart b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_preview.dart index 8021f9c8..f208508c 100644 --- a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_preview.dart +++ b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_preview.dart @@ -234,8 +234,8 @@ class GridTabPreview extends HookConsumerWidget { onPressed: () { onDeleteAll?.call(tabState.url.host); }, - leadingIcon: const Icon(MdiIcons.closeBoxMultiple), - child: Text('Close all from ${tabState.url.host}'), + leadingIcon: const Icon(Icons.language), + child: const Text('Close from Same Host'), ), ], child: SizedBox( @@ -567,8 +567,8 @@ class ListTabPreview extends HookConsumerWidget { onPressed: () { onDeleteAll?.call(tabState.url.host); }, - leadingIcon: const Icon(MdiIcons.closeBoxMultiple), - child: Text('Close all from ${tabState.url.host}'), + leadingIcon: const Icon(Icons.language), + child: const Text('Close from Same Host'), ), ], child: IconButton( diff --git a/app/lib/features/settings/presentation/screens/contextual_toolbar_settings.dart b/app/lib/features/settings/presentation/screens/contextual_toolbar_settings.dart index 009f450f..1eba27ca 100644 --- a/app/lib/features/settings/presentation/screens/contextual_toolbar_settings.dart +++ b/app/lib/features/settings/presentation/screens/contextual_toolbar_settings.dart @@ -27,6 +27,7 @@ import 'package:weblibre/features/geckoview/features/browser/features/contextual import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/models/contextual_toolbar_scope.dart'; import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/toolbar_button_registry.dart'; import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/widgets/contextual_toolbar.dart'; +import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart'; import 'package:weblibre/features/user/data/database/definitions.drift.dart'; class ContextualToolbarSettingsScreen extends HookConsumerWidget { @@ -273,10 +274,12 @@ class _ToolbarPreviewDelegate extends SliverPersistentHeaderDelegate { final List configs; + static const _previewHeight = BrowserTabBar.contextualToolabarHeight; + @override - double get minExtent => 56.0; + double get minExtent => _previewHeight; @override - double get maxExtent => 56.0; + double get maxExtent => _previewHeight; @override Widget build( @@ -284,9 +287,12 @@ class _ToolbarPreviewDelegate extends SliverPersistentHeaderDelegate { double shrinkOffset, bool overlapsContent, ) { - return ColoredBox( - color: Theme.of(context).colorScheme.surfaceContainer, - child: _ToolbarPreview(configs: configs), + return SizedBox( + height: maxExtent, + child: ColoredBox( + color: Theme.of(context).colorScheme.surfaceContainer, + child: _ToolbarPreview(configs: configs), + ), ); } diff --git a/app/lib/features/settings/presentation/screens/search_content_settings.dart b/app/lib/features/settings/presentation/screens/search_content_settings.dart index 48f79a2d..5ed5dd50 100644 --- a/app/lib/features/settings/presentation/screens/search_content_settings.dart +++ b/app/lib/features/settings/presentation/screens/search_content_settings.dart @@ -91,7 +91,6 @@ class _ContentViewingSection extends StatelessWidget { SettingSection(name: 'Content Viewing'), _PdfViewerTile(), _EnableReaderModeTile(), - _ReaderModeInTabBarTile(), _EnforceReaderModeTile(), ], ); @@ -416,34 +415,6 @@ class _EnforceReaderModeTile extends HookConsumerWidget { } } -class _ReaderModeInTabBarTile extends HookConsumerWidget { - const _ReaderModeInTabBarTile(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final tabBarReaderView = ref.watch( - generalSettingsWithDefaultsProvider.select((s) => s.tabBarReaderView), - ); - - return SwitchListTile.adaptive( - title: const Text('Reader Mode in Tab Bar'), - subtitle: const Text( - 'Show reader mode button in the tab bar instead of only in the tab menu', - ), - secondary: const Icon(MdiIcons.bookHeart), - value: tabBarReaderView, - onChanged: (value) async { - await ref - .read(saveGeneralSettingsControllerProvider.notifier) - .save( - (currentSettings) => - currentSettings.copyWith.tabBarReaderView(value), - ); - }, - ); - } -} - class _PdfViewerTile extends HookConsumerWidget { const _PdfViewerTile(); diff --git a/app/lib/features/settings/presentation/screens/tab_bar_settings.dart b/app/lib/features/settings/presentation/screens/tab_bar_settings.dart index 5527af8d..580dfb93 100644 --- a/app/lib/features/settings/presentation/screens/tab_bar_settings.dart +++ b/app/lib/features/settings/presentation/screens/tab_bar_settings.dart @@ -78,7 +78,6 @@ class _TabBarLayoutSection extends StatelessWidget { children: [ _TabBarPositionSection(), _TabBarLayoutModeSection(), - _ShowExtensionShortcutTile(), _ShowContextualTabBarTile(), _CustomizeToolbarButtonsTile(), _AutoHideTabBarTile(), @@ -256,12 +255,6 @@ class _TabBarPreviewCard extends HookWidget { } final mainToolbarActions = [ - if (settings.showExtensionShortcut) - IconButton( - onPressed: () {}, - icon: const Icon(MdiIcons.puzzle), - tooltip: 'Extensions', - ), if (showMainToolbarActionButtons) tabCountButton, if (showMainToolbarActionButtons) NavigationMenuButtonView(onTap: () {}), ]; @@ -639,34 +632,6 @@ class _CustomizeToolbarButtonsTile extends HookConsumerWidget { } } -class _ShowExtensionShortcutTile extends HookConsumerWidget { - const _ShowExtensionShortcutTile(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final showExtensionShortcut = ref.watch( - generalSettingsWithDefaultsProvider.select( - (s) => s.showExtensionShortcut, - ), - ); - - return SwitchListTile.adaptive( - title: const Text('Show Extension Shortcut'), - subtitle: const Text('Display an extension menu directly on the tab bar'), - secondary: const Icon(MdiIcons.puzzleHeart), - value: showExtensionShortcut, - onChanged: (value) async { - await ref - .read(saveGeneralSettingsControllerProvider.notifier) - .save( - (currentSettings) => - currentSettings.copyWith.showExtensionShortcut(value), - ); - }, - ); - } -} - class _ShowQuickTabSwitcherBarTile extends HookConsumerWidget { const _ShowQuickTabSwitcherBarTile(); diff --git a/app/lib/features/user/data/models/engine_settings.dart b/app/lib/features/user/data/models/engine_settings.dart index e8aec7aa..9d9f636b 100644 --- a/app/lib/features/user/data/models/engine_settings.dart +++ b/app/lib/features/user/data/models/engine_settings.dart @@ -248,15 +248,15 @@ class EngineSettings extends GeckoEngineSettings with FastEquatable { bool? automaticFontSizeAdjustment, double? fontSizeFactor, bool? fontInflationEnabled, - double? displayDensityOverride, - int? screenWidthOverride, - int? screenHeightOverride, + super.displayDensityOverride, + super.screenWidthOverride, + super.screenHeightOverride, bool? inputAutoZoomEnabled, bool? fissionEnabled, bool? isolatedProcessEnabled, bool? appZygoteProcessEnabled, bool? extensionsWebAPIEnabled, - bool? lnaBlocking, + super.lnaBlocking, bool? lnaBlockTrackers, bool? lnaEnabled, }) : queryParameterStripping = @@ -314,17 +314,13 @@ class EngineSettings extends GeckoEngineSettings with FastEquatable { automaticFontSizeAdjustment: automaticFontSizeAdjustment ?? true, fontSizeFactor: fontSizeFactor ?? 1.0, fontInflationEnabled: fontInflationEnabled ?? false, - displayDensityOverride: displayDensityOverride, - screenWidthOverride: screenWidthOverride, - screenHeightOverride: screenHeightOverride, inputAutoZoomEnabled: inputAutoZoomEnabled ?? true, fissionEnabled: fissionEnabled ?? true, isolatedProcessEnabled: isolatedProcessEnabled ?? false, appZygoteProcessEnabled: appZygoteProcessEnabled ?? false, extensionsWebAPIEnabled: extensionsWebAPIEnabled ?? true, - lnaBlocking: lnaBlocking, - lnaBlockTrackers: lnaBlockTrackers, - lnaEnabled: lnaEnabled, + lnaBlockTrackers: lnaBlockTrackers ?? true, + lnaEnabled: lnaEnabled ?? true, ); static AddonCollection? _addonCollectionFromJson(String? json) => diff --git a/app/lib/features/user/data/models/general_settings.dart b/app/lib/features/user/data/models/general_settings.dart index 1ccd7cfc..8c95b1ac 100644 --- a/app/lib/features/user/data/models/general_settings.dart +++ b/app/lib/features/user/data/models/general_settings.dart @@ -77,7 +77,6 @@ class GeneralSettings with FastEquatable { final BangKey? defaultSearchProvider; final SearchSuggestionProviders defaultSearchSuggestionsProvider; final bool createChildTabsOption; - final bool showExtensionShortcut; final bool enableLocalAiFeatures; final bool showContainerUi; final bool showIsolatedTabUi; @@ -88,7 +87,6 @@ class GeneralSettings with FastEquatable { final TabBarSwipeAction tabBarSwipeAction; final Duration historyAutoCleanInterval; final bool tabViewBottomSheet; - final bool tabBarReaderView; final bool tabBarShowContextualBar; final bool tabBarShowQuickTabSwitcherBar; final TabBarPosition tabBarPosition; @@ -127,7 +125,6 @@ class GeneralSettings with FastEquatable { required this.defaultSearchProvider, required this.defaultSearchSuggestionsProvider, required this.createChildTabsOption, - required this.showExtensionShortcut, required this.enableLocalAiFeatures, required this.showContainerUi, required this.showIsolatedTabUi, @@ -137,7 +134,6 @@ class GeneralSettings with FastEquatable { required this.tabBarSwipeAction, required this.historyAutoCleanInterval, required this.tabViewBottomSheet, - required this.tabBarReaderView, required this.tabBarShowContextualBar, required this.tabBarShowQuickTabSwitcherBar, required this.tabBarPosition, @@ -177,7 +173,6 @@ class GeneralSettings with FastEquatable { BangKey? defaultSearchProvider, SearchSuggestionProviders? defaultSearchSuggestionsProvider, bool? createChildTabsOption, - bool? showExtensionShortcut, bool? enableLocalAiFeatures, bool? showContainerUi, bool? showIsolatedTabUi, @@ -187,7 +182,6 @@ class GeneralSettings with FastEquatable { TabBarSwipeAction? tabBarSwipeAction, Duration? historyAutoCleanInterval, bool? tabViewBottomSheet, - bool? tabBarReaderView, bool? tabBarShowContextualBar, bool? tabBarShowQuickTabSwitcherBar, TabBarPosition? tabBarPosition, @@ -224,7 +218,6 @@ class GeneralSettings with FastEquatable { defaultSearchSuggestionsProvider = defaultSearchSuggestionsProvider ?? _fallbackAutocompleteProvider, createChildTabsOption = createChildTabsOption ?? false, - showExtensionShortcut = showExtensionShortcut ?? false, enableLocalAiFeatures = enableLocalAiFeatures ?? true, showContainerUi = showContainerUi ?? true, showIsolatedTabUi = showIsolatedTabUi ?? true, @@ -237,7 +230,6 @@ class GeneralSettings with FastEquatable { historyAutoCleanInterval = historyAutoCleanInterval ?? const Duration(days: 90), tabViewBottomSheet = tabViewBottomSheet ?? false, - tabBarReaderView = tabBarReaderView ?? false, tabBarShowContextualBar = tabBarShowContextualBar ?? true, tabBarShowQuickTabSwitcherBar = tabBarShowQuickTabSwitcherBar ?? true, tabBarPosition = tabBarPosition ?? TabBarPosition.bottom, @@ -304,7 +296,6 @@ class GeneralSettings with FastEquatable { defaultSearchProvider, defaultSearchSuggestionsProvider, createChildTabsOption, - showExtensionShortcut, enableLocalAiFeatures, showContainerUi, showIsolatedTabUi, @@ -314,7 +305,6 @@ class GeneralSettings with FastEquatable { tabBarSwipeAction, historyAutoCleanInterval, tabViewBottomSheet, - tabBarReaderView, tabBarShowContextualBar, tabBarShowQuickTabSwitcherBar, tabBarPosition, diff --git a/app/lib/features/user/data/models/general_settings.g.dart b/app/lib/features/user/data/models/general_settings.g.dart index c91eed57..19abce8a 100644 --- a/app/lib/features/user/data/models/general_settings.g.dart +++ b/app/lib/features/user/data/models/general_settings.g.dart @@ -31,8 +31,6 @@ abstract class _$GeneralSettingsCWProxy { GeneralSettings createChildTabsOption(bool createChildTabsOption); - GeneralSettings showExtensionShortcut(bool showExtensionShortcut); - GeneralSettings enableLocalAiFeatures(bool enableLocalAiFeatures); GeneralSettings showContainerUi(bool showContainerUi); @@ -55,8 +53,6 @@ abstract class _$GeneralSettingsCWProxy { GeneralSettings tabViewBottomSheet(bool tabViewBottomSheet); - GeneralSettings tabBarReaderView(bool tabBarReaderView); - GeneralSettings tabBarShowContextualBar(bool tabBarShowContextualBar); GeneralSettings tabBarShowQuickTabSwitcherBar( @@ -137,7 +133,6 @@ abstract class _$GeneralSettingsCWProxy { BangKey? defaultSearchProvider, SearchSuggestionProviders defaultSearchSuggestionsProvider, bool createChildTabsOption, - bool showExtensionShortcut, bool enableLocalAiFeatures, bool showContainerUi, bool showIsolatedTabUi, @@ -147,7 +142,6 @@ abstract class _$GeneralSettingsCWProxy { TabBarSwipeAction tabBarSwipeAction, Duration historyAutoCleanInterval, bool tabViewBottomSheet, - bool tabBarReaderView, bool tabBarShowContextualBar, bool tabBarShowQuickTabSwitcherBar, TabBarPosition tabBarPosition, @@ -225,10 +219,6 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy { GeneralSettings createChildTabsOption(bool createChildTabsOption) => call(createChildTabsOption: createChildTabsOption); - @override - GeneralSettings showExtensionShortcut(bool showExtensionShortcut) => - call(showExtensionShortcut: showExtensionShortcut); - @override GeneralSettings enableLocalAiFeatures(bool enableLocalAiFeatures) => call(enableLocalAiFeatures: enableLocalAiFeatures); @@ -267,10 +257,6 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy { GeneralSettings tabViewBottomSheet(bool tabViewBottomSheet) => call(tabViewBottomSheet: tabViewBottomSheet); - @override - GeneralSettings tabBarReaderView(bool tabBarReaderView) => - call(tabBarReaderView: tabBarReaderView); - @override GeneralSettings tabBarShowContextualBar(bool tabBarShowContextualBar) => call(tabBarShowContextualBar: tabBarShowContextualBar); @@ -403,7 +389,6 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy { Object? defaultSearchProvider = const $CopyWithPlaceholder(), Object? defaultSearchSuggestionsProvider = const $CopyWithPlaceholder(), Object? createChildTabsOption = const $CopyWithPlaceholder(), - Object? showExtensionShortcut = const $CopyWithPlaceholder(), Object? enableLocalAiFeatures = const $CopyWithPlaceholder(), Object? showContainerUi = const $CopyWithPlaceholder(), Object? showIsolatedTabUi = const $CopyWithPlaceholder(), @@ -413,7 +398,6 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy { Object? tabBarSwipeAction = const $CopyWithPlaceholder(), Object? historyAutoCleanInterval = const $CopyWithPlaceholder(), Object? tabViewBottomSheet = const $CopyWithPlaceholder(), - Object? tabBarReaderView = const $CopyWithPlaceholder(), Object? tabBarShowContextualBar = const $CopyWithPlaceholder(), Object? tabBarShowQuickTabSwitcherBar = const $CopyWithPlaceholder(), Object? tabBarPosition = const $CopyWithPlaceholder(), @@ -498,12 +482,6 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy { ? _value.createChildTabsOption // ignore: cast_nullable_to_non_nullable : createChildTabsOption as bool, - showExtensionShortcut: - showExtensionShortcut == const $CopyWithPlaceholder() || - showExtensionShortcut == null - ? _value.showExtensionShortcut - // ignore: cast_nullable_to_non_nullable - : showExtensionShortcut as bool, enableLocalAiFeatures: enableLocalAiFeatures == const $CopyWithPlaceholder() || enableLocalAiFeatures == null @@ -558,12 +536,6 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy { ? _value.tabViewBottomSheet // ignore: cast_nullable_to_non_nullable : tabViewBottomSheet as bool, - tabBarReaderView: - tabBarReaderView == const $CopyWithPlaceholder() || - tabBarReaderView == null - ? _value.tabBarReaderView - // ignore: cast_nullable_to_non_nullable - : tabBarReaderView as bool, tabBarShowContextualBar: tabBarShowContextualBar == const $CopyWithPlaceholder() || tabBarShowContextualBar == null @@ -754,7 +726,6 @@ GeneralSettings _$GeneralSettingsFromJson( json['defaultSearchSuggestionsProvider'], ), createChildTabsOption: json['createChildTabsOption'] as bool?, - showExtensionShortcut: json['showExtensionShortcut'] as bool?, enableLocalAiFeatures: json['enableLocalAiFeatures'] as bool?, showContainerUi: json['showContainerUi'] as bool?, showIsolatedTabUi: json['showIsolatedTabUi'] as bool?, @@ -777,7 +748,6 @@ GeneralSettings _$GeneralSettingsFromJson( microseconds: (json['historyAutoCleanInterval'] as num).toInt(), ), tabViewBottomSheet: json['tabViewBottomSheet'] as bool?, - tabBarReaderView: json['tabBarReaderView'] as bool?, tabBarShowContextualBar: json['tabBarShowContextualBar'] as bool?, tabBarShowQuickTabSwitcherBar: json['tabBarShowQuickTabSwitcherBar'] as bool?, tabBarPosition: $enumDecodeNullable( @@ -843,7 +813,6 @@ Map _$GeneralSettingsToJson( _$SearchSuggestionProvidersEnumMap[instance .defaultSearchSuggestionsProvider]!, 'createChildTabsOption': instance.createChildTabsOption, - 'showExtensionShortcut': instance.showExtensionShortcut, 'enableLocalAiFeatures': instance.enableLocalAiFeatures, 'showContainerUi': instance.showContainerUi, 'showIsolatedTabUi': instance.showIsolatedTabUi, @@ -855,7 +824,6 @@ Map _$GeneralSettingsToJson( 'tabBarSwipeAction': _$TabBarSwipeActionEnumMap[instance.tabBarSwipeAction]!, 'historyAutoCleanInterval': instance.historyAutoCleanInterval.inMicroseconds, 'tabViewBottomSheet': instance.tabViewBottomSheet, - 'tabBarReaderView': instance.tabBarReaderView, 'tabBarShowContextualBar': instance.tabBarShowContextualBar, 'tabBarShowQuickTabSwitcherBar': instance.tabBarShowQuickTabSwitcherBar, 'tabBarPosition': _$TabBarPositionEnumMap[instance.tabBarPosition]!, diff --git a/app/lib/features/user/domain/repositories/general_settings.dart b/app/lib/features/user/domain/repositories/general_settings.dart index 748440fe..b34e4213 100644 --- a/app/lib/features/user/domain/repositories/general_settings.dart +++ b/app/lib/features/user/domain/repositories/general_settings.dart @@ -84,10 +84,6 @@ class GeneralSettingsRepository extends _$GeneralSettingsRepository { DriftSqlType.bool, db.typeMapping, ), - 'showExtensionShortcut': settings['showExtensionShortcut']?.readAs( - DriftSqlType.bool, - db.typeMapping, - ), 'enableLocalAiFeatures': settings['enableLocalAiFeatures']?.readAs( DriftSqlType.bool, db.typeMapping, @@ -124,10 +120,6 @@ class GeneralSettingsRepository extends _$GeneralSettingsRepository { DriftSqlType.bool, db.typeMapping, ), - 'tabBarReaderView': settings['tabBarReaderView']?.readAs( - DriftSqlType.bool, - db.typeMapping, - ), 'tabBarShowContextualBar': settings['tabBarShowContextualBar']?.readAs( DriftSqlType.bool, db.typeMapping, diff --git a/app/lib/features/user/domain/repositories/general_settings.g.dart b/app/lib/features/user/domain/repositories/general_settings.g.dart index 31a880ff..a761542e 100644 --- a/app/lib/features/user/domain/repositories/general_settings.g.dart +++ b/app/lib/features/user/domain/repositories/general_settings.g.dart @@ -35,7 +35,7 @@ final class GeneralSettingsRepositoryProvider } String _$generalSettingsRepositoryHash() => - r'7a30fefa2cdc934232e08e8809c62a83e99635fd'; + r'44aaf9f3c8c6e1a8c6569ed59b76fa0360528578'; abstract class _$GeneralSettingsRepository extends $StreamNotifier {