From ddccf4cb73b9c6badc555bbe75fe4b44efad3be0 Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Sun, 5 Oct 2025 10:35:24 +0200 Subject: [PATCH] consolidated radio groups --- .../presentation/screens/doh_settings.dart | 81 +++------ .../screens/general_settings.dart | 45 ++--- .../screens/web_engine_settings.dart | 68 +++----- .../tor/presentation/screens/tor_proxy.dart | 156 +++++++----------- 4 files changed, 117 insertions(+), 233 deletions(-) diff --git a/app/lib/features/settings/presentation/screens/doh_settings.dart b/app/lib/features/settings/presentation/screens/doh_settings.dart index 0236ba41..770dab49 100644 --- a/app/lib/features/settings/presentation/screens/doh_settings.dart +++ b/app/lib/features/settings/presentation/screens/doh_settings.dart @@ -49,64 +49,29 @@ class DohSettingsScreen extends HookConsumerWidget { ); } }, - child: const RadioListTile.adaptive( - value: DohSettingsMode.geckoDefault, - title: Text('Default Protection'), - subtitle: Text('DoH used only when default DNS fails'), - ), - ), - RadioGroup( - groupValue: dohSettings.dohSettingsMode, - onChanged: (value) async { - if (value != null) { - await ref - .read(saveEngineSettingsControllerProvider.notifier) - .save( - (currentSettings) => - currentSettings.copyWith.dohSettingsMode(value), - ); - } - }, - child: const RadioListTile.adaptive( - value: DohSettingsMode.increased, - title: Text('Increased Protection'), - subtitle: Text('DoH preferred, default DNS as fallback'), - ), - ), - RadioGroup( - groupValue: dohSettings.dohSettingsMode, - onChanged: (value) async { - if (value != null) { - await ref - .read(saveEngineSettingsControllerProvider.notifier) - .save( - (currentSettings) => - currentSettings.copyWith.dohSettingsMode(value), - ); - } - }, - child: const RadioListTile.adaptive( - value: DohSettingsMode.max, - title: Text('Max Protection'), - subtitle: Text('DoH only, no fallback'), - ), - ), - RadioGroup( - groupValue: dohSettings.dohSettingsMode, - onChanged: (value) async { - if (value != null) { - await ref - .read(saveEngineSettingsControllerProvider.notifier) - .save( - (currentSettings) => - currentSettings.copyWith.dohSettingsMode(value), - ); - } - }, - child: const RadioListTile.adaptive( - value: DohSettingsMode.off, - title: Text('Off'), - subtitle: Text('Use your default DNS resolver'), + child: const Column( + children: [ + RadioListTile.adaptive( + value: DohSettingsMode.geckoDefault, + title: Text('Default Protection'), + subtitle: Text('DoH used only when default DNS fails'), + ), + RadioListTile.adaptive( + value: DohSettingsMode.increased, + title: Text('Increased Protection'), + subtitle: Text('DoH preferred, default DNS as fallback'), + ), + RadioListTile.adaptive( + value: DohSettingsMode.max, + title: Text('Max Protection'), + subtitle: Text('DoH only, no fallback'), + ), + RadioListTile.adaptive( + value: DohSettingsMode.off, + title: Text('Off'), + subtitle: Text('Use your default DNS resolver'), + ), + ], ), ), const ListTile( diff --git a/app/lib/features/settings/presentation/screens/general_settings.dart b/app/lib/features/settings/presentation/screens/general_settings.dart index 5ecfafeb..b4713617 100644 --- a/app/lib/features/settings/presentation/screens/general_settings.dart +++ b/app/lib/features/settings/presentation/screens/general_settings.dart @@ -420,34 +420,23 @@ class GeneralSettingsScreen extends HookConsumerWidget { ); } }, - child: const RadioListTile.adaptive( - value: TabBarSwipeAction.switchLastOpened, - title: Text('Switch to Last Used Tab'), - subtitle: Text( - 'Swipe to toggle between current and previously opened tab', - ), - ), - ), - RadioGroup( - groupValue: generalSettings.tabBarSwipeAction, - onChanged: (value) async { - if (value != null) { - await ref - .read( - saveGeneralSettingsControllerProvider.notifier, - ) - .save( - (currentSettings) => currentSettings.copyWith - .tabBarSwipeAction(value), - ); - } - }, - child: const RadioListTile.adaptive( - value: TabBarSwipeAction.navigateOrderedTabs, - title: Text('Navigate Sequential Tabs'), - subtitle: Text( - 'Swipe left/right to move through tabs in order', - ), + child: const Column( + children: [ + RadioListTile.adaptive( + value: TabBarSwipeAction.switchLastOpened, + title: Text('Switch to Last Used Tab'), + subtitle: Text( + 'Swipe to toggle between current and previously opened tab', + ), + ), + RadioListTile.adaptive( + value: TabBarSwipeAction.navigateOrderedTabs, + title: Text('Navigate Sequential Tabs'), + subtitle: Text( + 'Swipe left/right to move through tabs in order', + ), + ), + ], ), ), ], diff --git a/app/lib/features/settings/presentation/screens/web_engine_settings.dart b/app/lib/features/settings/presentation/screens/web_engine_settings.dart index 30d98696..ce64009b 100644 --- a/app/lib/features/settings/presentation/screens/web_engine_settings.dart +++ b/app/lib/features/settings/presentation/screens/web_engine_settings.dart @@ -298,63 +298,35 @@ class WebEngineSettingsScreen extends HookConsumerWidget { .trackingProtectionPolicy(value), ); }, - child: - const RadioListTile< - TrackingProtectionPolicy - >.adaptive( + child: const Column( + children: [ + RadioListTile.adaptive( value: TrackingProtectionPolicy.none, title: Text('Disabled'), ), - ), - RadioGroup( - groupValue: engineSettings.trackingProtectionPolicy, - onChanged: (value) async { - await ref - .read(saveEngineSettingsControllerProvider.notifier) - .save( - (currentSettings) => currentSettings.copyWith - .trackingProtectionPolicy(value), - ); - }, - child: const RadioListTile.adaptive( - value: TrackingProtectionPolicy.recommended, - title: Text('Standard'), - subtitle: Text( - 'Pages will load normally, but block fewer trackers.', - ), - ), - ), - RadioGroup( - groupValue: engineSettings.trackingProtectionPolicy, - onChanged: (value) async { - await ref - .read(saveEngineSettingsControllerProvider.notifier) - .save( - (currentSettings) => currentSettings.copyWith - .trackingProtectionPolicy(value), - ); - }, - child: const RadioListTile.adaptive( - value: TrackingProtectionPolicy.strict, - title: Text('Strict'), - subtitle: Text( - 'Stronger tracking protection and faster performance, but some sites may not work properly.', - ), - ), - ), - RadioGroup( - groupValue: engineSettings.trackingProtectionPolicy, - onChanged: (_) {}, - child: - const RadioListTile< - TrackingProtectionPolicy - >.adaptive( + RadioListTile.adaptive( + value: TrackingProtectionPolicy.recommended, + title: Text('Standard'), + subtitle: Text( + 'Pages will load normally, but block fewer trackers.', + ), + ), + RadioListTile.adaptive( + value: TrackingProtectionPolicy.strict, + title: Text('Strict'), + subtitle: Text( + 'Stronger tracking protection and faster performance, but some sites may not work properly.', + ), + ), + RadioListTile.adaptive( value: TrackingProtectionPolicy.custom, title: Text('Custom'), subtitle: Text( 'Choose which trackers and scripts to block.', ), ), + ], + ), ), ], ), diff --git a/app/lib/features/tor/presentation/screens/tor_proxy.dart b/app/lib/features/tor/presentation/screens/tor_proxy.dart index e3b566c5..a901f669 100644 --- a/app/lib/features/tor/presentation/screens/tor_proxy.dart +++ b/app/lib/features/tor/presentation/screens/tor_proxy.dart @@ -167,38 +167,26 @@ class TorProxyScreen extends HookConsumerWidget { ); } }, - child: const RadioListTile.adaptive( - value: TorRegularTabProxyMode.container, - title: Text('Container-Based Routing'), - subtitle: Text( - 'Route only tabs in Tor containers through the Tor network. Private tabs remain unaffected.', - ), - ), - ), - RadioGroup( - groupValue: torSettings.proxyRegularTabsMode, - onChanged: (value) async { - if (value != null) { - await ref - .read( - saveTorSettingsControllerProvider - .notifier, - ) - .save( - (currentSettings) => currentSettings - .copyWith - .proxyRegularTabsMode(value), - ); - } - }, - child: const RadioListTile.adaptive( - value: TorRegularTabProxyMode.all, - title: Text('Global Routing'), - subtitle: Text( - 'Route all regular tabs through the Tor network. Private tabs remain unaffected.', - ), + child: const Column( + children: [ + RadioListTile.adaptive( + value: TorRegularTabProxyMode.container, + title: Text('Container-Based Routing'), + subtitle: Text( + 'Route only tabs in Tor containers through the Tor network. Private tabs remain unaffected.', + ), + ), + RadioListTile.adaptive( + value: TorRegularTabProxyMode.all, + title: Text('Global Routing'), + subtitle: Text( + 'Route all regular tabs through the Tor network. Private tabs remain unaffected.', + ), + ), + ], ), ), + SwitchListTile.adaptive( inactiveThumbColor: Colors.white, activeThumbColor: const Color(0xFF68B030), @@ -337,75 +325,45 @@ class TorProxyScreen extends HookConsumerWidget { ); } }, - child: RadioListTile.adaptive( - value: TorConnectionConfig.direct, - enabled: !torProxyPort.isLoading, - contentPadding: const EdgeInsets.only( - left: 56, - right: 24, - ), - title: const Text('Direct Connection'), - subtitle: const Text( - 'The best way to connect to Tor if Tor is not blocked', - ), - ), - ), - RadioGroup( - groupValue: torSettings.config, - onChanged: (value) async { - if (value != null) { - await ref - .read( - saveTorSettingsControllerProvider - .notifier, - ) - .save( - (currentSettings) => currentSettings - .copyWith - .config(value), - ); - } - }, - child: RadioListTile.adaptive( - value: TorConnectionConfig.obfs4, - enabled: !torProxyPort.isLoading, - contentPadding: const EdgeInsets.only( - left: 56, - right: 24, - ), - title: const Text('obfs4'), - subtitle: const Text( - 'Suitable for light censorship and high bandwidth needs', - ), - ), - ), - RadioGroup( - groupValue: torSettings.config, - onChanged: (value) async { - if (value != null) { - await ref - .read( - saveTorSettingsControllerProvider - .notifier, - ) - .save( - (currentSettings) => currentSettings - .copyWith - .config(value), - ); - } - }, - child: RadioListTile.adaptive( - value: TorConnectionConfig.snowflake, - enabled: !torProxyPort.isLoading, - contentPadding: const EdgeInsets.only( - left: 56, - right: 24, - ), - title: const Text('Snowflake'), - subtitle: const Text( - 'Suitable for heavy censorship', - ), + child: Column( + children: [ + RadioListTile.adaptive( + value: TorConnectionConfig.direct, + enabled: !torProxyPort.isLoading, + contentPadding: const EdgeInsets.only( + left: 56, + right: 24, + ), + title: const Text('Direct Connection'), + subtitle: const Text( + 'The best way to connect to Tor if Tor is not blocked', + ), + ), + RadioListTile.adaptive( + value: TorConnectionConfig.obfs4, + enabled: !torProxyPort.isLoading, + contentPadding: const EdgeInsets.only( + left: 56, + right: 24, + ), + title: const Text('obfs4'), + subtitle: const Text( + 'Suitable for light censorship and high bandwidth needs', + ), + ), + RadioListTile.adaptive( + value: TorConnectionConfig.snowflake, + enabled: !torProxyPort.isLoading, + contentPadding: const EdgeInsets.only( + left: 56, + right: 24, + ), + title: const Text('Snowflake'), + subtitle: const Text( + 'Suitable for heavy censorship', + ), + ), + ], ), ), CheckboxListTile.adaptive(