diff --git a/app/lib/features/bangs/presentation/screens/search.dart b/app/lib/features/bangs/presentation/screens/search.dart index 2555a2cc..b36470ea 100644 --- a/app/lib/features/bangs/presentation/screens/search.dart +++ b/app/lib/features/bangs/presentation/screens/search.dart @@ -6,6 +6,7 @@ import 'package:bang_navigator/features/bangs/presentation/widgets/bang_details. import 'package:bang_navigator/features/search_browser/domain/entities/modes.dart'; import 'package:bang_navigator/features/search_browser/domain/entities/sheet.dart'; import 'package:bang_navigator/features/search_browser/domain/providers.dart'; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:bang_navigator/presentation/hooks/listenable_callback.dart'; import 'package:bang_navigator/presentation/widgets/failure_widget.dart'; @@ -21,8 +22,9 @@ class BangSearchScreen extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final resultsAsync = ref.watch(bangSearchProvider); final incognitoEnabled = ref.watch( - settingsRepositoryProvider - .select((value) => value.valueOrNull?.incognitoMode ?? false), + settingsRepositoryProvider.select( + (value) => (value.valueOrNull ?? Settings.withDefaults()).incognitoMode, + ), ); final textEditingController = useTextEditingController(); diff --git a/app/lib/features/bangs/presentation/widgets/bang_details.dart b/app/lib/features/bangs/presentation/widgets/bang_details.dart index d2c3fbb3..5751b4b0 100644 --- a/app/lib/features/bangs/presentation/widgets/bang_details.dart +++ b/app/lib/features/bangs/presentation/widgets/bang_details.dart @@ -1,6 +1,7 @@ import 'package:bang_navigator/core/routing/routes.dart'; import 'package:bang_navigator/features/bangs/data/models/bang_data.dart'; import 'package:bang_navigator/features/bangs/presentation/widgets/bang_icon.dart'; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:bang_navigator/features/web_view/presentation/controllers/switch_new_tab.dart'; import 'package:bang_navigator/utils/ui_helper.dart' as ui_helper; @@ -70,11 +71,13 @@ class BangDetails extends HookConsumerWidget { onPressed: () async { final url = Uri.parse(bangData.getUrl('').origin); - final launchExternal = ref - .read(settingsRepositoryProvider) - .valueOrNull - ?.launchUrlExternal ?? - false; + final launchExternal = ref.read( + settingsRepositoryProvider.select( + (value) => + (value.valueOrNull ?? Settings.withDefaults()) + .launchUrlExternal, + ), + ); if (launchExternal) { await ui_helper.launchUrlFeedback(context, url); diff --git a/app/lib/features/bangs/presentation/widgets/search_field.dart b/app/lib/features/bangs/presentation/widgets/search_field.dart index 3e8a075d..ad0de3eb 100644 --- a/app/lib/features/bangs/presentation/widgets/search_field.dart +++ b/app/lib/features/bangs/presentation/widgets/search_field.dart @@ -3,6 +3,7 @@ import 'package:bang_navigator/features/bangs/data/models/bang_data.dart'; import 'package:bang_navigator/features/bangs/presentation/widgets/bang_icon.dart'; import 'package:bang_navigator/features/kagi/domain/repositories/autosuggest.dart'; import 'package:bang_navigator/features/search_browser/presentation/widgets/speech_to_text_button.dart'; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:bang_navigator/presentation/widgets/autocomplete.dart'; import 'package:flutter/material.dart'; @@ -30,8 +31,9 @@ class SearchField extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final incognitoEnabled = ref.watch( - settingsRepositoryProvider - .select((value) => value.valueOrNull?.incognitoMode ?? false), + settingsRepositoryProvider.select( + (value) => (value.valueOrNull ?? Settings.withDefaults()).incognitoMode, + ), ); final optionsStream = ref.watch(autosuggestRepositoryProvider); diff --git a/app/lib/features/chat_archive/presentation/screens/detail.dart b/app/lib/features/chat_archive/presentation/screens/detail.dart index f78af783..5a186686 100644 --- a/app/lib/features/chat_archive/presentation/screens/detail.dart +++ b/app/lib/features/chat_archive/presentation/screens/detail.dart @@ -3,6 +3,7 @@ import 'package:bang_navigator/features/chat_archive/data/services/file.dart'; import 'package:bang_navigator/features/chat_archive/domain/entities/chat_entity.dart'; import 'package:bang_navigator/features/chat_archive/domain/repositories/archive.dart'; import 'package:bang_navigator/features/chat_archive/utils/markdown_to_text.dart'; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:bang_navigator/features/web_view/presentation/controllers/switch_new_tab.dart'; import 'package:bang_navigator/presentation/widgets/failure_widget.dart'; @@ -102,11 +103,12 @@ class ChatArchiveDetailScreen extends HookConsumerWidget { onTapLink: (text, href, title) async { if (href != null) { if (Uri.parse(href) case final Uri url) { - final launchExternal = ref - .read(settingsRepositoryProvider) - .valueOrNull - ?.launchUrlExternal ?? - false; + final launchExternal = ref.read( + settingsRepositoryProvider.select( + (value) => (value.valueOrNull ?? Settings.withDefaults()) + .launchUrlExternal, + ), + ); if (launchExternal) { await ui_helper.launchUrlFeedback(context, Uri.parse(href)); diff --git a/app/lib/features/chat_archive/presentation/screens/search.dart b/app/lib/features/chat_archive/presentation/screens/search.dart index e90b9540..7352e2b6 100644 --- a/app/lib/features/chat_archive/presentation/screens/search.dart +++ b/app/lib/features/chat_archive/presentation/screens/search.dart @@ -4,6 +4,7 @@ import 'package:bang_navigator/core/extension/date_time.dart'; import 'package:bang_navigator/core/routing/routes.dart'; import 'package:bang_navigator/features/chat_archive/domain/entities/chat_entity.dart'; import 'package:bang_navigator/features/chat_archive/domain/repositories/search.dart'; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:bang_navigator/presentation/hooks/listenable_callback.dart'; import 'package:bang_navigator/presentation/widgets/failure_widget.dart'; @@ -20,8 +21,9 @@ class ChatArchiveSearchScreen extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final resultsAsync = ref.watch(chatArchiveSearchRepositoryProvider); final incognitoEnabled = ref.watch( - settingsRepositoryProvider - .select((value) => value.valueOrNull?.incognitoMode ?? false), + settingsRepositoryProvider.select( + (value) => (value.valueOrNull ?? Settings.withDefaults()).incognitoMode, + ), ); final textEditingController = useTextEditingController(); diff --git a/app/lib/features/search_browser/presentation/screens/browser.dart b/app/lib/features/search_browser/presentation/screens/browser.dart index 85e528b5..a4fdb9ac 100644 --- a/app/lib/features/search_browser/presentation/screens/browser.dart +++ b/app/lib/features/search_browser/presentation/screens/browser.dart @@ -10,6 +10,7 @@ import 'package:bang_navigator/features/search_browser/presentation/widgets/land import 'package:bang_navigator/features/search_browser/presentation/widgets/sheets/shared_content_sheet.dart'; import 'package:bang_navigator/features/search_browser/presentation/widgets/sheets/view_tabs_sheet.dart'; import 'package:bang_navigator/features/search_browser/presentation/widgets/tabs_action_button.dart'; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:bang_navigator/features/web_view/domain/repositories/web_view.dart'; import 'package:bang_navigator/features/web_view/presentation/controllers/switch_new_tab.dart'; @@ -41,7 +42,8 @@ class KagiScreen extends HookConsumerWidget { final showEarlyAccessFeatures = ref.watch( settingsRepositoryProvider.select( - (value) => value.valueOrNull?.showEarlyAccessFeatures ?? true, + (value) => (value.valueOrNull ?? Settings.withDefaults()) + .showEarlyAccessFeatures, ), ); diff --git a/app/lib/features/search_browser/presentation/widgets/landing/action.dart b/app/lib/features/search_browser/presentation/widgets/landing/action.dart index 983c4b73..aba5ad46 100644 --- a/app/lib/features/search_browser/presentation/widgets/landing/action.dart +++ b/app/lib/features/search_browser/presentation/widgets/landing/action.dart @@ -3,6 +3,7 @@ import 'package:bang_navigator/features/search_browser/domain/entities/modes.dar import 'package:bang_navigator/features/search_browser/domain/entities/sheet.dart'; import 'package:bang_navigator/features/search_browser/domain/services/create_tab.dart'; import 'package:bang_navigator/features/search_browser/presentation/widgets/error_container.dart'; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; @@ -22,7 +23,8 @@ class LandingAction extends HookConsumerWidget { final showEarlyAccessFeatures = ref.watch( settingsRepositoryProvider.select( - (value) => value.valueOrNull?.showEarlyAccessFeatures ?? true, + (value) => (value.valueOrNull ?? Settings.withDefaults()) + .showEarlyAccessFeatures, ), ); diff --git a/app/lib/features/search_browser/presentation/widgets/sheets/shared_content_sheet.dart b/app/lib/features/search_browser/presentation/widgets/sheets/shared_content_sheet.dart index 991ff5bd..1ba16cef 100644 --- a/app/lib/features/search_browser/presentation/widgets/sheets/shared_content_sheet.dart +++ b/app/lib/features/search_browser/presentation/widgets/sheets/shared_content_sheet.dart @@ -3,6 +3,7 @@ import 'package:bang_navigator/features/search_browser/domain/entities/sheet.dar import 'package:bang_navigator/features/search_browser/presentation/widgets/tabs/assistant_tab.dart'; import 'package:bang_navigator/features/search_browser/presentation/widgets/tabs/search_tab.dart'; import 'package:bang_navigator/features/search_browser/presentation/widgets/tabs/summarize_tab.dart'; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:bang_navigator/features/share_intent/domain/entities/shared_content.dart'; import 'package:bang_navigator/presentation/hooks/sync_page_tab.dart'; @@ -27,7 +28,8 @@ class SharedContentSheet extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final showEarlyAccessFeatures = ref.watch( settingsRepositoryProvider.select( - (value) => value.valueOrNull?.showEarlyAccessFeatures ?? true, + (value) => (value.valueOrNull ?? Settings.withDefaults()) + .showEarlyAccessFeatures, ), ); diff --git a/app/lib/features/search_browser/presentation/widgets/tabs/assistant_tab.dart b/app/lib/features/search_browser/presentation/widgets/tabs/assistant_tab.dart index 70e2165a..d9184b35 100644 --- a/app/lib/features/search_browser/presentation/widgets/tabs/assistant_tab.dart +++ b/app/lib/features/search_browser/presentation/widgets/tabs/assistant_tab.dart @@ -4,6 +4,7 @@ import 'package:bang_navigator/features/search_browser/presentation/widgets/shee import 'package:bang_navigator/features/search_browser/presentation/widgets/speech_to_text_button.dart'; import 'package:bang_navigator/features/search_browser/utils/url_builder.dart' as uri_builder; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:bang_navigator/features/share_intent/domain/entities/shared_content.dart'; import 'package:bang_navigator/presentation/hooks/sync_page_tab.dart'; @@ -26,8 +27,9 @@ class AssistantTab extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final incognitoEnabled = ref.watch( - settingsRepositoryProvider - .select((value) => value.valueOrNull?.incognitoMode ?? false), + settingsRepositoryProvider.select( + (value) => (value.valueOrNull ?? Settings.withDefaults()).incognitoMode, + ), ); final researchVariant = ref.watch(activeResearchVariantProvider); diff --git a/app/lib/features/search_browser/presentation/widgets/tabs/summarize_tab.dart b/app/lib/features/search_browser/presentation/widgets/tabs/summarize_tab.dart index 76aa52f7..9452b65a 100644 --- a/app/lib/features/search_browser/presentation/widgets/tabs/summarize_tab.dart +++ b/app/lib/features/search_browser/presentation/widgets/tabs/summarize_tab.dart @@ -4,6 +4,7 @@ import 'package:bang_navigator/features/search_browser/domain/entities/modes.dar import 'package:bang_navigator/features/search_browser/presentation/widgets/sheets/shared_content_sheet.dart'; import 'package:bang_navigator/features/search_browser/utils/url_builder.dart' as uri_builder; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:bang_navigator/features/share_intent/domain/entities/shared_content.dart'; import 'package:bang_navigator/presentation/widgets/website_title_tile.dart'; @@ -23,8 +24,9 @@ class _InputField extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final incognitoEnabled = ref.watch( - settingsRepositoryProvider - .select((value) => value.valueOrNull?.incognitoMode ?? false), + settingsRepositoryProvider.select( + (value) => (value.valueOrNull ?? Settings.withDefaults()).incognitoMode, + ), ); return TextFormField( diff --git a/app/lib/features/settings/data/models/settings.dart b/app/lib/features/settings/data/models/settings.dart index 309922fd..329f4afc 100644 --- a/app/lib/features/settings/data/models/settings.dart +++ b/app/lib/features/settings/data/models/settings.dart @@ -25,7 +25,7 @@ class Settings with FastEquatable { }); Settings.withDefaults({ - required this.kagiSession, + this.kagiSession, bool? showEarlyAccessFeatures, bool? incognitoMode, bool? enableJavascript, diff --git a/app/lib/features/web_view/domain/providers.dart b/app/lib/features/web_view/domain/providers.dart index df3cb4c7..2c4397e2 100644 --- a/app/lib/features/web_view/domain/providers.dart +++ b/app/lib/features/web_view/domain/providers.dart @@ -1,4 +1,5 @@ import 'package:bang_navigator/features/content_block/domain/repositories/host.dart'; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; @@ -8,12 +9,15 @@ part 'providers.g.dart'; Stream?> blockContentHosts(BlockContentHostsRef ref) { final hostRepository = ref.watch(hostRepositoryProvider.notifier); final enableContentBlocking = ref.watch( - settingsRepositoryProvider - .select((value) => value.valueOrNull?.enableContentBlocking ?? false), + settingsRepositoryProvider.select( + (value) => + (value.valueOrNull ?? Settings.withDefaults()).enableContentBlocking, + ), ); final enableHostList = ref.watch( - settingsRepositoryProvider - .select((value) => value.valueOrNull?.enableHostList ?? {}), + settingsRepositoryProvider.select( + (value) => (value.valueOrNull ?? Settings.withDefaults()).enableHostList, + ), ); if (!enableContentBlocking || enableHostList.isEmpty) { diff --git a/app/lib/features/web_view/presentation/widgets/web_page_dialog.dart b/app/lib/features/web_view/presentation/widgets/web_page_dialog.dart index e08df7c5..76d97834 100644 --- a/app/lib/features/web_view/presentation/widgets/web_page_dialog.dart +++ b/app/lib/features/web_view/presentation/widgets/web_page_dialog.dart @@ -5,6 +5,7 @@ import 'package:bang_navigator/features/bangs/presentation/widgets/site_search.d import 'package:bang_navigator/features/search_browser/domain/entities/modes.dart'; import 'package:bang_navigator/features/search_browser/utils/url_builder.dart' as uri_builder; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:bang_navigator/features/share_intent/domain/entities/shared_content.dart'; import 'package:bang_navigator/features/web_view/presentation/controllers/switch_new_tab.dart'; @@ -61,8 +62,9 @@ class WebPageDialog extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final incognitoEnabled = ref.watch( - settingsRepositoryProvider - .select((value) => value.valueOrNull?.incognitoMode ?? false), + settingsRepositoryProvider.select( + (value) => (value.valueOrNull ?? Settings.withDefaults()).incognitoMode, + ), ); final availableBangsAsync = ref.watch( diff --git a/app/lib/features/web_view/presentation/widgets/web_view.dart b/app/lib/features/web_view/presentation/widgets/web_view.dart index afcf6744..9e569727 100644 --- a/app/lib/features/web_view/presentation/widgets/web_view.dart +++ b/app/lib/features/web_view/presentation/widgets/web_view.dart @@ -8,6 +8,7 @@ import 'package:bang_navigator/features/chat_archive/domain/repositories/archive import 'package:bang_navigator/features/search_browser/domain/entities/modes.dart'; import 'package:bang_navigator/features/search_browser/domain/entities/sheet.dart'; import 'package:bang_navigator/features/search_browser/domain/providers.dart'; +import 'package:bang_navigator/features/settings/data/models/settings.dart'; import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart'; import 'package:bang_navigator/features/web_view/domain/entities/web_view_page.dart'; import 'package:bang_navigator/features/web_view/domain/providers.dart'; @@ -95,11 +96,9 @@ class _WebViewState extends ConsumerState { allowsLinkPreview: false, disableLongPressContextMenuOnLinks: true, useShouldOverrideUrlLoading: true, - javaScriptEnabled: ref - .read(settingsRepositoryProvider) - .valueOrNull - ?.enableJavascript ?? - true, + javaScriptEnabled: (ref.read(settingsRepositoryProvider).valueOrNull ?? + Settings.withDefaults()) + .enableJavascript, saveFormData: false, disabledActionModeMenuItems: ActionModeMenuItem.MENU_ITEM_WEB_SEARCH, ), @@ -107,7 +106,8 @@ class _WebViewState extends ConsumerState { final showEarlyAccessFeatures = ref.watch( settingsRepositoryProvider.select( - (value) => value.valueOrNull?.showEarlyAccessFeatures ?? true, + (value) => (value.valueOrNull ?? Settings.withDefaults()) + .showEarlyAccessFeatures, ), ); @@ -126,8 +126,10 @@ class _WebViewState extends ConsumerState { ); ref.listen( - settingsRepositoryProvider - .select((value) => value.valueOrNull?.enableJavascript), + settingsRepositoryProvider.select( + (value) => + (value.valueOrNull ?? Settings.withDefaults()).enableJavascript, + ), (previous, next) async { await widget.page.value.controller?.setSettings( settings: initialSettings.copy()..javaScriptEnabled = next, @@ -297,11 +299,12 @@ class _WebViewState extends ConsumerState { shouldOverrideUrlLoading: (controller, navigationAction) async { final url = navigationAction.request.url; if (url != null) { - final launchExternal = ref - .read(settingsRepositoryProvider) - .valueOrNull - ?.launchUrlExternal ?? - false; + final launchExternal = ref.read( + settingsRepositoryProvider.select( + (value) => (value.valueOrNull ?? Settings.withDefaults()) + .launchUrlExternal, + ), + ); final unhandledScheme = !_webViewSupportedSchemes.contains(url.scheme);