From fc49b338269fa320a94330781e10c87a4eeee95a Mon Sep 17 00:00:00 2001 From: Moustapha Kodjo Amadou <107993382+kodjodevf@users.noreply.github.com> Date: Wed, 10 Dec 2025 14:14:51 +0100 Subject: [PATCH] feat(user-agent): add default user agent setting --- lib/l10n/app_en.arb | 3 +- lib/l10n/generated/app_localizations.dart | 6 ++ lib/l10n/generated/app_localizations_ar.dart | 3 + lib/l10n/generated/app_localizations_as.dart | 3 + lib/l10n/generated/app_localizations_de.dart | 3 + lib/l10n/generated/app_localizations_en.dart | 3 + lib/l10n/generated/app_localizations_es.dart | 3 + lib/l10n/generated/app_localizations_fr.dart | 3 + lib/l10n/generated/app_localizations_hi.dart | 3 + lib/l10n/generated/app_localizations_id.dart | 3 + lib/l10n/generated/app_localizations_it.dart | 3 + lib/l10n/generated/app_localizations_ja.dart | 3 + lib/l10n/generated/app_localizations_pt.dart | 3 + lib/l10n/generated/app_localizations_ru.dart | 3 + lib/l10n/generated/app_localizations_th.dart | 3 + lib/l10n/generated/app_localizations_tr.dart | 3 + lib/l10n/generated/app_localizations_zh.dart | 3 + .../more/settings/general/general_screen.dart | 82 +++++++++++++++++++ .../providers/general_state_provider.dart | 20 +++++ .../providers/general_state_provider.g.dart | 53 ++++++++++++ lib/modules/webview/webview.dart | 7 ++ 21 files changed, 215 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 3850c381..b2ed952a 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -559,5 +559,6 @@ "line_height": "Line Height", "show_scroll_percentage": "Show Scroll Percentage", "remove_extra_paragraph_spacing": "Remove Extra Paragraph Spacing", - "select_label_color": "Select {label} Color" + "select_label_color": "Select {label} Color", + "default_user_agent": "Defaul user agent" } diff --git a/lib/l10n/generated/app_localizations.dart b/lib/l10n/generated/app_localizations.dart index d502b5fd..16885429 100644 --- a/lib/l10n/generated/app_localizations.dart +++ b/lib/l10n/generated/app_localizations.dart @@ -3430,6 +3430,12 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Select {label} Color'** String select_label_color(Object label); + + /// No description provided for @default_user_agent. + /// + /// In en, this message translates to: + /// **'Defaul user agent'** + String get default_user_agent; } class _AppLocalizationsDelegate diff --git a/lib/l10n/generated/app_localizations_ar.dart b/lib/l10n/generated/app_localizations_ar.dart index b01c814e..e2da67f5 100644 --- a/lib/l10n/generated/app_localizations_ar.dart +++ b/lib/l10n/generated/app_localizations_ar.dart @@ -1775,4 +1775,7 @@ class AppLocalizationsAr extends AppLocalizations { String select_label_color(Object label) { return 'تحديد لون $label'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_as.dart b/lib/l10n/generated/app_localizations_as.dart index 124c21da..881102df 100644 --- a/lib/l10n/generated/app_localizations_as.dart +++ b/lib/l10n/generated/app_localizations_as.dart @@ -1781,4 +1781,7 @@ class AppLocalizationsAs extends AppLocalizations { String select_label_color(Object label) { return '$label ৰং নিৰ্বাচন কৰক'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_de.dart b/lib/l10n/generated/app_localizations_de.dart index 3d1a6112..79920e82 100644 --- a/lib/l10n/generated/app_localizations_de.dart +++ b/lib/l10n/generated/app_localizations_de.dart @@ -1796,4 +1796,7 @@ class AppLocalizationsDe extends AppLocalizations { String select_label_color(Object label) { return 'Farbe für $label auswählen'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_en.dart b/lib/l10n/generated/app_localizations_en.dart index 3e44fc3c..bfac54d6 100644 --- a/lib/l10n/generated/app_localizations_en.dart +++ b/lib/l10n/generated/app_localizations_en.dart @@ -1775,4 +1775,7 @@ class AppLocalizationsEn extends AppLocalizations { String select_label_color(Object label) { return 'Select $label Color'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_es.dart b/lib/l10n/generated/app_localizations_es.dart index ca2ae5f6..108c36cb 100644 --- a/lib/l10n/generated/app_localizations_es.dart +++ b/lib/l10n/generated/app_localizations_es.dart @@ -1804,6 +1804,9 @@ class AppLocalizationsEs extends AppLocalizations { String select_label_color(Object label) { return 'Seleccionar color de $label'; } + + @override + String get default_user_agent => 'Defaul user agent'; } /// The translations for Spanish Castilian, as used in Latin America and the Caribbean (`es_419`). diff --git a/lib/l10n/generated/app_localizations_fr.dart b/lib/l10n/generated/app_localizations_fr.dart index f1eef824..7a0975bc 100644 --- a/lib/l10n/generated/app_localizations_fr.dart +++ b/lib/l10n/generated/app_localizations_fr.dart @@ -1804,4 +1804,7 @@ class AppLocalizationsFr extends AppLocalizations { String select_label_color(Object label) { return 'Sélectionner la couleur $label'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_hi.dart b/lib/l10n/generated/app_localizations_hi.dart index 60331e81..12a85600 100644 --- a/lib/l10n/generated/app_localizations_hi.dart +++ b/lib/l10n/generated/app_localizations_hi.dart @@ -1781,4 +1781,7 @@ class AppLocalizationsHi extends AppLocalizations { String select_label_color(Object label) { return '$label रंग चुनें'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_id.dart b/lib/l10n/generated/app_localizations_id.dart index c1d7cc4b..e723a4bc 100644 --- a/lib/l10n/generated/app_localizations_id.dart +++ b/lib/l10n/generated/app_localizations_id.dart @@ -1787,4 +1787,7 @@ class AppLocalizationsId extends AppLocalizations { String select_label_color(Object label) { return 'Pilih Warna $label'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_it.dart b/lib/l10n/generated/app_localizations_it.dart index b00f3b96..62b7bf69 100644 --- a/lib/l10n/generated/app_localizations_it.dart +++ b/lib/l10n/generated/app_localizations_it.dart @@ -1801,4 +1801,7 @@ class AppLocalizationsIt extends AppLocalizations { String select_label_color(Object label) { return 'Seleziona colore $label'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_ja.dart b/lib/l10n/generated/app_localizations_ja.dart index a374efa7..5dfacbbf 100644 --- a/lib/l10n/generated/app_localizations_ja.dart +++ b/lib/l10n/generated/app_localizations_ja.dart @@ -1752,4 +1752,7 @@ class AppLocalizationsJa extends AppLocalizations { String select_label_color(Object label) { return '$labelの色を選択'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_pt.dart b/lib/l10n/generated/app_localizations_pt.dart index 0a819921..a061de6c 100644 --- a/lib/l10n/generated/app_localizations_pt.dart +++ b/lib/l10n/generated/app_localizations_pt.dart @@ -1799,6 +1799,9 @@ class AppLocalizationsPt extends AppLocalizations { String select_label_color(Object label) { return 'Selecionar cor de $label'; } + + @override + String get default_user_agent => 'Defaul user agent'; } /// The translations for Portuguese, as used in Brazil (`pt_BR`). diff --git a/lib/l10n/generated/app_localizations_ru.dart b/lib/l10n/generated/app_localizations_ru.dart index 53b50611..c4ccd9ff 100644 --- a/lib/l10n/generated/app_localizations_ru.dart +++ b/lib/l10n/generated/app_localizations_ru.dart @@ -1804,4 +1804,7 @@ class AppLocalizationsRu extends AppLocalizations { String select_label_color(Object label) { return 'Выбрать цвет $label'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_th.dart b/lib/l10n/generated/app_localizations_th.dart index d2c79dbd..5ab6b22e 100644 --- a/lib/l10n/generated/app_localizations_th.dart +++ b/lib/l10n/generated/app_localizations_th.dart @@ -1775,4 +1775,7 @@ class AppLocalizationsTh extends AppLocalizations { String select_label_color(Object label) { return 'เลือกสี $label'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_tr.dart b/lib/l10n/generated/app_localizations_tr.dart index 86607b5a..d2215068 100644 --- a/lib/l10n/generated/app_localizations_tr.dart +++ b/lib/l10n/generated/app_localizations_tr.dart @@ -1787,4 +1787,7 @@ class AppLocalizationsTr extends AppLocalizations { String select_label_color(Object label) { return '$label Rengini Seç'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/l10n/generated/app_localizations_zh.dart b/lib/l10n/generated/app_localizations_zh.dart index dd7bffce..5522cd0f 100644 --- a/lib/l10n/generated/app_localizations_zh.dart +++ b/lib/l10n/generated/app_localizations_zh.dart @@ -1733,4 +1733,7 @@ class AppLocalizationsZh extends AppLocalizations { String select_label_color(Object label) { return '选择 $label 颜色'; } + + @override + String get default_user_agent => 'Defaul user agent'; } diff --git a/lib/modules/more/settings/general/general_screen.dart b/lib/modules/more/settings/general/general_screen.dart index 1c69532c..ce86bf11 100644 --- a/lib/modules/more/settings/general/general_screen.dart +++ b/lib/modules/more/settings/general/general_screen.dart @@ -35,6 +35,7 @@ class _GeneralStateScreen extends ConsumerState { Widget build(BuildContext context) { final l10n = l10nLocalizations(context); final customDns = ref.watch(customDnsStateProvider); + final userAgent = ref.watch(userAgentStateProvider); final enableDiscordRpc = ref.watch(enableDiscordRpcStateProvider); final hideDiscordRpcInIncognito = ref.watch( hideDiscordRpcInIncognitoStateProvider, @@ -57,6 +58,14 @@ class _GeneralStateScreen extends ConsumerState { style: TextStyle(fontSize: 11, color: context.secondaryColor), ), ), + ListTile( + onTap: () => _showDefaultUserAgentDialog(context, ref, userAgent), + title: Text(context.l10n.default_user_agent), + subtitle: Text( + userAgent, + style: TextStyle(fontSize: 11, color: context.secondaryColor), + ), + ), Container( margin: const EdgeInsets.all(20.0), padding: const EdgeInsets.all(10.0), @@ -373,3 +382,76 @@ class _GeneralStateScreen extends ConsumerState { ); } } + +void _showDefaultUserAgentDialog( + BuildContext context, + WidgetRef ref, + String ua, +) { + final uaController = TextEditingController(text: ua); + showDialog( + context: context, + builder: (context) => StatefulBuilder( + builder: (context, setState) { + return AlertDialog( + title: Text( + context.l10n.default_user_agent, + style: const TextStyle(fontSize: 30), + ), + content: SizedBox( + width: context.width(0.8), + height: context.height(0.3), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: TextFormField( + controller: uaController, + autofocus: true, + + decoration: InputDecoration( + hintText: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...", + filled: false, + contentPadding: const EdgeInsets.all(12), + enabledBorder: OutlineInputBorder( + borderSide: const BorderSide(width: 0.4), + borderRadius: BorderRadius.circular(5), + ), + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide(), + borderRadius: BorderRadius.circular(5), + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide(), + ), + ), + ), + ), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: SizedBox( + width: context.width(1), + child: ElevatedButton( + onPressed: () async { + ref + .watch(userAgentStateProvider.notifier) + .set(uaController.text); + if (!context.mounted) return; + Navigator.pop(context); + }, + child: Text(context.l10n.dialog_confirm), + ), + ), + ), + ], + ), + ), + ); + }, + ), + ); +} diff --git a/lib/modules/more/settings/general/providers/general_state_provider.dart b/lib/modules/more/settings/general/providers/general_state_provider.dart index 0c3cbb26..8eaa3ed6 100644 --- a/lib/modules/more/settings/general/providers/general_state_provider.dart +++ b/lib/modules/more/settings/general/providers/general_state_provider.dart @@ -123,3 +123,23 @@ class RpcShowCoverImageState extends _$RpcShowCoverImageState { ); } } + +@riverpod +class UserAgentState extends _$UserAgentState { + @override + String build() { + return isar.settings.getSync(227)!.userAgent!; + } + + void set(String value) { + final settings = isar.settings.getSync(227); + state = value; + isar.writeTxnSync( + () => isar.settings.putSync( + settings! + ..userAgent = value + ..updatedAt = DateTime.now().millisecondsSinceEpoch, + ), + ); + } +} diff --git a/lib/modules/more/settings/general/providers/general_state_provider.g.dart b/lib/modules/more/settings/general/providers/general_state_provider.g.dart index 8e1cf2ea..704155f0 100644 --- a/lib/modules/more/settings/general/providers/general_state_provider.g.dart +++ b/lib/modules/more/settings/general/providers/general_state_provider.g.dart @@ -334,3 +334,56 @@ abstract class _$RpcShowCoverImageState extends $Notifier { element.handleValue(ref, created); } } + +@ProviderFor(UserAgentState) +const userAgentStateProvider = UserAgentStateProvider._(); + +final class UserAgentStateProvider + extends $NotifierProvider { + const UserAgentStateProvider._() + : super( + from: null, + argument: null, + retry: null, + name: r'userAgentStateProvider', + isAutoDispose: true, + dependencies: null, + $allTransitiveDependencies: null, + ); + + @override + String debugGetCreateSourceHash() => _$userAgentStateHash(); + + @$internal + @override + UserAgentState create() => UserAgentState(); + + /// {@macro riverpod.override_with_value} + Override overrideWithValue(String value) { + return $ProviderOverride( + origin: this, + providerOverride: $SyncValueProvider(value), + ); + } +} + +String _$userAgentStateHash() => r'e1e9ba333c5dc753813082190da4ee51ad587bb9'; + +abstract class _$UserAgentState extends $Notifier { + String build(); + @$mustCallSuper + @override + void runBuild() { + final created = build(); + final ref = this.ref as $Ref; + final element = + ref.element + as $ClassProviderElement< + AnyNotifier, + String, + Object?, + Object? + >; + element.handleValue(ref, created); + } +} diff --git a/lib/modules/webview/webview.dart b/lib/modules/webview/webview.dart index d037e95c..8d8bdac7 100644 --- a/lib/modules/webview/webview.dart +++ b/lib/modules/webview/webview.dart @@ -7,8 +7,10 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:mangayomi/main.dart'; +import 'package:mangayomi/modules/more/settings/general/providers/general_state_provider.dart'; import 'package:mangayomi/providers/l10n_providers.dart'; import 'package:mangayomi/services/http/m_client.dart'; +import 'package:mangayomi/utils/constant.dart'; import 'package:mangayomi/utils/global_style.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:share_plus/share_plus.dart'; @@ -53,6 +55,10 @@ class _MangaWebViewState extends ConsumerState { Webview? _desktopWebview; Future _runWebViewDesktop() async { + String? ua = ref.watch(userAgentStateProvider); + if (ua == defaultUserAgent) { + ua = null; + } if (Platform.isLinux) { _desktopWebview = await WebviewWindow.create(); @@ -110,6 +116,7 @@ class _MangaWebViewState extends ConsumerState { webViewSettings: InAppWebViewSettings( isInspectable: kDebugMode, useShouldOverrideUrlLoading: true, + userAgent: ua, ), ), );