From 2ecaa0ff8278cfdedceee8afb3d2ead6f0053fdf Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Sun, 26 Oct 2025 18:09:32 +0100 Subject: [PATCH] added support for desktop mode --- .../domain/providers/desktop_mode.dart | 29 +++++ .../domain/providers/desktop_mode.g.dart | 100 ++++++++++++++++++ .../domain/providers/tab_session.dart | 4 + .../domain/providers/tab_session.g.dart | 2 +- .../browser/domain/providers/intent.g.dart | 2 +- .../browser_modules/bottom_app_bar.dart | 32 ++++++ 6 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 app/lib/features/geckoview/domain/providers/desktop_mode.dart create mode 100644 app/lib/features/geckoview/domain/providers/desktop_mode.g.dart diff --git a/app/lib/features/geckoview/domain/providers/desktop_mode.dart b/app/lib/features/geckoview/domain/providers/desktop_mode.dart new file mode 100644 index 00000000..5b5ec721 --- /dev/null +++ b/app/lib/features/geckoview/domain/providers/desktop_mode.dart @@ -0,0 +1,29 @@ +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:weblibre/features/geckoview/domain/providers/tab_session.dart'; + +part 'desktop_mode.g.dart'; + +@Riverpod(keepAlive: true) +class DesktopMode extends _$DesktopMode { + // ignore: use_setters_to_change_properties + void enabled(bool value) { + state = value; + } + + void toggle() { + state = !state; + } + + @override + bool build(String tabId) { + listenSelf((previous, next) async { + if (previous != null) { + await ref + .read(tabSessionProvider(tabId: tabId).notifier) + .requestDesktopSite(next); + } + }); + + return false; + } +} diff --git a/app/lib/features/geckoview/domain/providers/desktop_mode.g.dart b/app/lib/features/geckoview/domain/providers/desktop_mode.g.dart new file mode 100644 index 00000000..b8433719 --- /dev/null +++ b/app/lib/features/geckoview/domain/providers/desktop_mode.g.dart @@ -0,0 +1,100 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'desktop_mode.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint, type=warning + +@ProviderFor(DesktopMode) +const desktopModeProvider = DesktopModeFamily._(); + +final class DesktopModeProvider extends $NotifierProvider { + const DesktopModeProvider._({ + required DesktopModeFamily super.from, + required String super.argument, + }) : super( + retry: null, + name: r'desktopModeProvider', + isAutoDispose: false, + dependencies: null, + $allTransitiveDependencies: null, + ); + + @override + String debugGetCreateSourceHash() => _$desktopModeHash(); + + @override + String toString() { + return r'desktopModeProvider' + '' + '($argument)'; + } + + @$internal + @override + DesktopMode create() => DesktopMode(); + + /// {@macro riverpod.override_with_value} + Override overrideWithValue(bool value) { + return $ProviderOverride( + origin: this, + providerOverride: $SyncValueProvider(value), + ); + } + + @override + bool operator ==(Object other) { + return other is DesktopModeProvider && other.argument == argument; + } + + @override + int get hashCode { + return argument.hashCode; + } +} + +String _$desktopModeHash() => r'18550009e95a23ff82d30206ce81daa859c57c26'; + +final class DesktopModeFamily extends $Family + with $ClassFamilyOverride { + const DesktopModeFamily._() + : super( + retry: null, + name: r'desktopModeProvider', + dependencies: null, + $allTransitiveDependencies: null, + isAutoDispose: false, + ); + + DesktopModeProvider call(String tabId) => + DesktopModeProvider._(argument: tabId, from: this); + + @override + String toString() => r'desktopModeProvider'; +} + +abstract class _$DesktopMode extends $Notifier { + late final _$args = ref.$arg as String; + String get tabId => _$args; + + bool build(String tabId); + @$mustCallSuper + @override + void runBuild() { + final created = build(_$args); + final ref = this.ref as $Ref; + final element = + ref.element + as $ClassProviderElement< + AnyNotifier, + bool, + Object?, + Object? + >; + element.handleValue(ref, created); + } +} diff --git a/app/lib/features/geckoview/domain/providers/tab_session.dart b/app/lib/features/geckoview/domain/providers/tab_session.dart index 0fd4bedb..88531bbe 100644 --- a/app/lib/features/geckoview/domain/providers/tab_session.dart +++ b/app/lib/features/geckoview/domain/providers/tab_session.dart @@ -64,6 +64,10 @@ class TabSession extends _$TabSession { return _sessionService.requestScreenshot(requireImageResult); } + Future requestDesktopSite(bool enable) { + return _sessionService.requestDesktopSite(enable: enable); + } + @override void build({required String? tabId}) { _sessionService = (tabId != null) 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 7388dff5..39d5d595 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'1b42eb21212df2c88be9f2cb10bc4ca5df437b3b'; +String _$tabSessionHash() => r'f0a3aca70719afd37cad260c5d36621455252bfb'; final class TabSessionFamily extends $Family with $ClassFamilyOverride { diff --git a/app/lib/features/geckoview/features/browser/domain/providers/intent.g.dart b/app/lib/features/geckoview/features/browser/domain/providers/intent.g.dart index eeb2157d..264643d1 100644 --- a/app/lib/features/geckoview/features/browser/domain/providers/intent.g.dart +++ b/app/lib/features/geckoview/features/browser/domain/providers/intent.g.dart @@ -34,7 +34,7 @@ final class EngineBoundIntentStreamProvider } String _$engineBoundIntentStreamHash() => - r'fa7c3e0277b25e8129a12feaadf39db6b65a1cd5'; + r'ab9804f97e0222b2306683d2fcfa71d3d57ecd21'; abstract class _$EngineBoundIntentStream extends $StreamNotifier { 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 fc15cb82..ee4d9dbd 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 @@ -29,6 +29,7 @@ import 'package:weblibre/core/providers/defaults.dart'; import 'package:weblibre/core/routing/routes.dart'; import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart'; 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/selected_tab.dart'; import 'package:weblibre/features/geckoview/domain/providers/tab_session.dart'; import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart'; @@ -410,6 +411,37 @@ class BrowserBottomAppBar extends HookConsumerWidget { leadingIcon: const Icon(Icons.search), child: const Text('Find in page'), ), + if (selectedTabId != null) + Consumer( + builder: (context, childRef, child) { + final enabled = childRef.watch( + desktopModeProvider(selectedTabId), + ); + + return MenuItemButton( + onPressed: () { + ref + .read(desktopModeProvider(selectedTabId).notifier) + .toggle(); + }, + leadingIcon: const Icon(MdiIcons.monitor), + trailingIcon: Checkbox( + value: enabled, + onChanged: (value) { + if (value != null) { + ref + .read( + desktopModeProvider(selectedTabId).notifier, + ) + .enabled(value); + trippleDotMenuController.close(); + } + }, + ), + child: const Text('Desktop Mode'), + ); + }, + ), if (selectedTabId != null) const Divider(), if (selectedTabId != null) MenuItemButton(