From 14db60c0ff503dfa811c58b53bc733ba9b9fd4b8 Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Sat, 28 Jun 2025 20:41:08 +0200 Subject: [PATCH] improve hardening options --- .../data/models/preference_setting.dart | 6 ++- .../screens/web_engine_hardening.dart | 11 +++-- .../screens/web_engine_hardening_group.dart | 40 +++++++++++++++++-- .../lib/src/domain/services/gecko_pref.dart | 4 +- 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/app/lib/features/geckoview/features/preferences/data/models/preference_setting.dart b/app/lib/features/geckoview/features/preferences/data/models/preference_setting.dart index 2e08c208..009d532b 100644 --- a/app/lib/features/geckoview/features/preferences/data/models/preference_setting.dart +++ b/app/lib/features/geckoview/features/preferences/data/models/preference_setting.dart @@ -10,12 +10,16 @@ class PreferenceSettingGroup with FastEquatable { final Map settings; - bool get isActive => settings.values.every( + bool get isActiveOrOptional => settings.values.every( (setting) => setting.requireUserOptIn || setting.isActive, ); bool get isPartlyActive => settings.values.any((setting) => setting.isActive); + bool get hasInactiveOptional => settings.values.any( + (setting) => !setting.isActive && setting.requireUserOptIn, + ); + PreferenceSettingGroup({required this.description, required this.settings}); @override diff --git a/app/lib/features/settings/presentation/screens/web_engine_hardening.dart b/app/lib/features/settings/presentation/screens/web_engine_hardening.dart index 63e49482..ebd0a891 100644 --- a/app/lib/features/settings/presentation/screens/web_engine_hardening.dart +++ b/app/lib/features/settings/presentation/screens/web_engine_hardening.dart @@ -21,7 +21,7 @@ class WebEngineHardeningScreen extends HookConsumerWidget { final allGroupsActive = useMemoized( () => preferenceGroups.valueOrNull?.values.every( - (element) => element.isActive, + (element) => element.isActiveOrOptional, ) ?? false, [EquatableValue(preferenceGroups.valueOrNull)], @@ -78,9 +78,12 @@ class WebEngineHardeningScreen extends HookConsumerWidget { subtitle: group.value.description.mapNotNull( (description) => Text(description), ), - leading: HardeningGroupIcon( - isActive: group.value.isActive, - isPartlyActive: group.value.isPartlyActive, + leading: Badge( + isLabelVisible: group.value.hasInactiveOptional, + child: HardeningGroupIcon( + isActive: group.value.isActiveOrOptional, + isPartlyActive: group.value.isPartlyActive, + ), ), trailing: const Icon(Icons.chevron_right), onTap: () async { diff --git a/app/lib/features/settings/presentation/screens/web_engine_hardening_group.dart b/app/lib/features/settings/presentation/screens/web_engine_hardening_group.dart index 6345f1e8..3b2c556a 100644 --- a/app/lib/features/settings/presentation/screens/web_engine_hardening_group.dart +++ b/app/lib/features/settings/presentation/screens/web_engine_hardening_group.dart @@ -35,7 +35,7 @@ class WebEngineHardeningGroupScreen extends HookConsumerWidget { child: Padding( padding: const EdgeInsets.all(8.0), child: SwitchListTile( - value: group.isActive, + value: group.isActiveOrOptional, title: Text( groupName, style: TextStyle( @@ -86,8 +86,42 @@ class WebEngineHardeningGroupScreen extends HookConsumerWidget { child: SwitchListTile( value: setting.value.isActive, title: Text(setting.value.title ?? setting.key), - subtitle: setting.value.description.mapNotNull( - (description) => Text(description), + subtitle: Text.rich( + TextSpan( + children: [ + if (setting.value.requireUserOptIn) + WidgetSpan( + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, + vertical: 2, + ), + margin: const EdgeInsets.only( + right: 8, + ), + decoration: BoxDecoration( + color: theme.colorScheme.error, + borderRadius: + BorderRadius.circular(4), + ), + child: Text( + 'Optional', + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w500, + color: + theme.colorScheme.onError, + ), + ), + ), + ), + if (setting.value.description != null) + TextSpan( + text: setting.value.description, + // style: theme.textTheme.bodyMedium, + ), + ], + ), ), secondary: HardeningGroupIcon( isActive: setting.value.isActive, diff --git a/packages/flutter_mozilla_components/lib/src/domain/services/gecko_pref.dart b/packages/flutter_mozilla_components/lib/src/domain/services/gecko_pref.dart index e2d167c4..a9cded83 100644 --- a/packages/flutter_mozilla_components/lib/src/domain/services/gecko_pref.dart +++ b/packages/flutter_mozilla_components/lib/src/domain/services/gecko_pref.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart'; final _apiInstance = GeckoPrefApi(); @@ -16,7 +18,7 @@ class GeckoPrefService { final value = switch (pref.value) { final bool x => '$x', final int x => '$x', - final String x => "'$x'", //Use single ticks to allow json + final String x => jsonEncode(x), _ => throw Exception('Unknow pref type'), };