diff --git a/apps/weblibre/lib/features/onboarding/presentation/onboarding.dart b/apps/weblibre/lib/features/onboarding/presentation/onboarding.dart index 2e21d88b..7abf8296 100644 --- a/apps/weblibre/lib/features/onboarding/presentation/onboarding.dart +++ b/apps/weblibre/lib/features/onboarding/presentation/onboarding.dart @@ -27,6 +27,7 @@ import 'package:weblibre/core/providers/router.dart'; import 'package:weblibre/features/geckoview/features/browser/domain/services/browser_addon.dart'; import 'package:weblibre/features/onboarding/domain/entities/onboarding_mode.dart'; import 'package:weblibre/features/onboarding/domain/providers.dart'; +import 'package:weblibre/features/onboarding/presentation/onboarding_defaults.dart'; import 'package:weblibre/features/onboarding/presentation/pages/abstract/i_form_page.dart'; import 'package:weblibre/features/onboarding/presentation/pages/ai_configuration.dart'; import 'package:weblibre/features/onboarding/presentation/pages/default_search.dart'; @@ -61,10 +62,20 @@ class OnboardingScreen extends HookConsumerWidget { final eulaAccepted = ref.watch(eulaAcceptedProvider); final onboardingMode = ref.watch(onboardingModeProvider); + final isFreshOnboarding = currentRevision < 0; final isReturningUser = currentRevision == 2; final showDetailedPages = isReturningUser || onboardingMode == OnboardingMode.detailed; + useEffect(() { + if (!isFreshOnboarding || onboardingMode == OnboardingMode.restore) { + return null; + } + + unawaited(applyOnboardingPrivacyDefaults(ref)); + return null; + }, [isFreshOnboarding, onboardingMode]); + final pages = useMemoized>(() { switch (currentRevision) { case 1: @@ -195,36 +206,34 @@ class OnboardingScreen extends HookConsumerWidget { unawaited( Navigator.of(context).push( MaterialPageRoute( - builder: (_) => - ProfileRestoreScreen( - backupFileUri: uri, - forcedTarget: - RestoreTarget.createNew, - onRestoreSuccess: - (_, profile) async { - await ref - .read( - onboardingRepositoryProvider - .notifier, - ) - .pushRevision( - targetRevision, - ); - if (profile != null) { - await ref - .read( - profileRepositoryProvider - .notifier, - ) - .switchProfile( - profile.id, - ); - await exitApp( - ref.container, - ); - } - }, - ), + builder: (_) => ProfileRestoreScreen( + backupFileUri: uri, + forcedTarget: + RestoreTarget.createNew, + onRestoreSuccess: (_, profile) async { + await ref + .read( + onboardingRepositoryProvider + .notifier, + ) + .pushRevision( + targetRevision, + ); + if (profile != null) { + await ref + .read( + profileRepositoryProvider + .notifier, + ) + .switchProfile( + profile.id, + ); + await exitApp( + ref.container, + ); + } + }, + ), ), ), ); @@ -254,6 +263,8 @@ class OnboardingScreen extends HookConsumerWidget { .read(browserAddonServiceProvider.notifier) .install('uBlock0@raymondhill.net'), ); + + await applyOnboardingOptimizedUBlockDefaults(ref); } await ref diff --git a/apps/weblibre/lib/features/onboarding/presentation/onboarding_defaults.dart b/apps/weblibre/lib/features/onboarding/presentation/onboarding_defaults.dart new file mode 100644 index 00000000..ede3b2ad --- /dev/null +++ b/apps/weblibre/lib/features/onboarding/presentation/onboarding_defaults.dart @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024-2026 Fabian Freund. + * + * This file is part of WebLibre + * (see https://weblibre.eu). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:weblibre/core/logger.dart'; +import 'package:weblibre/features/geckoview/features/preferences/data/repositories/preference_settings.dart'; +import 'package:weblibre/features/geckoview/features/tabs/utils/setting_groups_serializer.dart'; +import 'package:weblibre/features/user/data/models/engine_settings.dart'; +import 'package:weblibre/features/user/data/models/ublock_filter_list_settings.dart'; +import 'package:weblibre/features/user/data/providers/ublock_assets.dart'; +import 'package:weblibre/features/user/domain/repositories/engine_settings.dart'; + +Future applyOnboardingOptimizedUBlockDefaults(WidgetRef ref) async { + try { + final registry = await ref.read(ublockAssetsRegistryProvider.future); + final optimized = UBlockFilterListSettings.optimizedDefaults(registry); + + await ref + .read(engineSettingsRepositoryProvider.notifier) + .updateSettings( + (current) => current.copyWith.ublockFilterListSettings(optimized), + ); + } catch (e, s) { + logger.w( + 'Failed applying optimized uBlock defaults during onboarding', + error: e, + stackTrace: s, + ); + } +} + +Future applyOnboardingPrivacyDefaults(WidgetRef ref) async { + try { + await ref + .read( + unifiedPreferenceSettingsRepositoryProvider( + PreferencePartition.user, + ).notifier, + ) + .apply(); + + await ref + .read(engineSettingsRepositoryProvider.notifier) + .updateSettings( + (current) => current.copyWith(lnaEnabled: true, lnaBlocking: true), + ); + } catch (e, s) { + logger.w( + 'Failed applying privacy defaults during onboarding', + error: e, + stackTrace: s, + ); + } +} diff --git a/apps/weblibre/lib/features/onboarding/presentation/pages/ublock_opt_in.dart b/apps/weblibre/lib/features/onboarding/presentation/pages/ublock_opt_in.dart index dbfa666a..9b1e22d4 100644 --- a/apps/weblibre/lib/features/onboarding/presentation/pages/ublock_opt_in.dart +++ b/apps/weblibre/lib/features/onboarding/presentation/pages/ublock_opt_in.dart @@ -24,13 +24,9 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:weblibre/core/logger.dart'; import 'package:weblibre/features/geckoview/features/browser/domain/services/browser_addon.dart'; +import 'package:weblibre/features/onboarding/presentation/onboarding_defaults.dart'; import 'package:weblibre/features/onboarding/presentation/pages/abstract/i_form_page.dart'; -import 'package:weblibre/features/user/data/models/engine_settings.dart'; -import 'package:weblibre/features/user/data/models/ublock_filter_list_settings.dart'; -import 'package:weblibre/features/user/data/providers/ublock_assets.dart'; -import 'package:weblibre/features/user/domain/repositories/engine_settings.dart'; import 'package:weblibre/presentation/widgets/browser_page.dart'; class UBlockOptInPage extends HookConsumerWidget implements IFormPage { @@ -97,29 +93,7 @@ There are many other lists available to block even more. onSaved: (newValue) { if (newValue != true || !installUBlock.value) return; - Future applyOptimizedDefaults() async { - try { - final registry = await ref.read( - ublockAssetsRegistryProvider.future, - ); - final optimized = - UBlockFilterListSettings.optimizedDefaults(registry); - await ref - .read(engineSettingsRepositoryProvider.notifier) - .updateSettings( - (current) => current.copyWith - .ublockFilterListSettings(optimized), - ); - } catch (e, s) { - logger.w( - 'Failed applying optimized uBlock defaults during onboarding', - error: e, - stackTrace: s, - ); - } - } - - unawaited(applyOptimizedDefaults()); + unawaited(applyOnboardingOptimizedUBlockDefaults(ref)); }, builder: (field) => SwitchListTile( contentPadding: EdgeInsets.zero,