feat(setting) add use native http client

This commit is contained in:
kodjomoustapha 2024-08-03 07:37:55 +01:00
parent e9b3751f45
commit 5a4de638b4
12 changed files with 242 additions and 30 deletions

View file

@ -331,5 +331,8 @@
"add_torrent": "Add torrent",
"enter_torrent_hint_text": "Enter magnet or torrent file url",
"torrent_url": "Torrent url",
"or": "OR"
"or": "OR",
"advanced": "Advanced",
"use_native_http_client": "Use native http client",
"use_native_http_client_info": "it automatically supports platform features such VPNs, support more HTTP features such as HTTP/3 and custom redirect handling"
}

View file

@ -188,6 +188,8 @@ class Settings {
bool? useLibass;
bool? useNativeHttpClient;
Settings(
{this.id = 227,
this.displayType = DisplayType.compactGrid,
@ -270,7 +272,8 @@ class Settings {
this.mangaGridSize,
this.animeGridSize,
this.disableSectionType = SectionType.all,
this.useLibass = true});
this.useLibass = true,
this.useNativeHttpClient = false});
Settings.fromJson(Map<String, dynamic> json) {
animatePageTransitions = json['animatePageTransitions'];
@ -420,6 +423,7 @@ class Settings {
disableSectionType =
SectionType.values[json['disableSectionType'] ?? SectionType.all];
useLibass = json['useLibass'];
useNativeHttpClient = json['useNativeHttpClient'];
}
Map<String, dynamic> toJson() => {
@ -528,7 +532,8 @@ class Settings {
'mangaGridSize': mangaGridSize,
'animeGridSize': animeGridSize,
'disableSectionType': disableSectionType.index,
'useLibass': useLibass
'useLibass': useLibass,
'useNativeHttpClient': useNativeHttpClient
};
}

View file

@ -456,13 +456,18 @@ const SettingsSchema = CollectionSchema(
name: r'useLibass',
type: IsarType.bool,
),
r'usePageTapZones': PropertySchema(
r'useNativeHttpClient': PropertySchema(
id: 83,
name: r'useNativeHttpClient',
type: IsarType.bool,
),
r'usePageTapZones': PropertySchema(
id: 84,
name: r'usePageTapZones',
type: IsarType.bool,
),
r'userAgent': PropertySchema(
id: 84,
id: 85,
name: r'userAgent',
type: IsarType.string,
)
@ -917,8 +922,9 @@ void _settingsSerialize(
writer.writeBool(offsets[80], object.themeIsDark);
writer.writeBool(offsets[81], object.updateProgressAfterReading);
writer.writeBool(offsets[82], object.useLibass);
writer.writeBool(offsets[83], object.usePageTapZones);
writer.writeString(offsets[84], object.userAgent);
writer.writeBool(offsets[83], object.useNativeHttpClient);
writer.writeBool(offsets[84], object.usePageTapZones);
writer.writeString(offsets[85], object.userAgent);
}
Settings _settingsDeserialize(
@ -1080,8 +1086,9 @@ Settings _settingsDeserialize(
themeIsDark: reader.readBoolOrNull(offsets[80]),
updateProgressAfterReading: reader.readBoolOrNull(offsets[81]),
useLibass: reader.readBoolOrNull(offsets[82]),
usePageTapZones: reader.readBoolOrNull(offsets[83]),
userAgent: reader.readStringOrNull(offsets[84]),
useNativeHttpClient: reader.readBoolOrNull(offsets[83]),
usePageTapZones: reader.readBoolOrNull(offsets[84]),
userAgent: reader.readStringOrNull(offsets[85]),
);
object.chapterFilterBookmarkedList =
reader.readObjectList<ChapterFilterBookmarked>(
@ -1375,6 +1382,8 @@ P _settingsDeserializeProp<P>(
case 83:
return (reader.readBoolOrNull(offset)) as P;
case 84:
return (reader.readBoolOrNull(offset)) as P;
case 85:
return (reader.readStringOrNull(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
@ -6840,6 +6849,34 @@ extension SettingsQueryFilter
});
}
QueryBuilder<Settings, Settings, QAfterFilterCondition>
useNativeHttpClientIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'useNativeHttpClient',
));
});
}
QueryBuilder<Settings, Settings, QAfterFilterCondition>
useNativeHttpClientIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'useNativeHttpClient',
));
});
}
QueryBuilder<Settings, Settings, QAfterFilterCondition>
useNativeHttpClientEqualTo(bool? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'useNativeHttpClient',
value: value,
));
});
}
QueryBuilder<Settings, Settings, QAfterFilterCondition>
usePageTapZonesIsNull() {
return QueryBuilder.apply(this, (query) {
@ -8055,6 +8092,19 @@ extension SettingsQuerySortBy on QueryBuilder<Settings, Settings, QSortBy> {
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> sortByUseNativeHttpClient() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'useNativeHttpClient', Sort.asc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy>
sortByUseNativeHttpClientDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'useNativeHttpClient', Sort.desc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> sortByUsePageTapZones() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'usePageTapZones', Sort.asc);
@ -8955,6 +9005,19 @@ extension SettingsQuerySortThenBy
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> thenByUseNativeHttpClient() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'useNativeHttpClient', Sort.asc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy>
thenByUseNativeHttpClientDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'useNativeHttpClient', Sort.desc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> thenByUsePageTapZones() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'usePageTapZones', Sort.asc);
@ -9423,6 +9486,12 @@ extension SettingsQueryWhereDistinct
});
}
QueryBuilder<Settings, Settings, QDistinct> distinctByUseNativeHttpClient() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'useNativeHttpClient');
});
}
QueryBuilder<Settings, Settings, QDistinct> distinctByUsePageTapZones() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'usePageTapZones');
@ -9999,6 +10068,13 @@ extension SettingsQueryProperty
});
}
QueryBuilder<Settings, bool?, QQueryOperations>
useNativeHttpClientProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'useNativeHttpClient');
});
}
QueryBuilder<Settings, bool?, QQueryOperations> usePageTapZonesProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'usePageTapZones');

View file

@ -63,7 +63,6 @@ class MoreScreen extends StatelessWidget {
title: l10n.backup_and_restore,
),
const Divider(),
ListTileWidget(
onTap: () {
context.push('/settings');

View file

@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/modules/more/settings/advanced/providers/native_http_client.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
class AdvancedScreen extends ConsumerWidget {
const AdvancedScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = l10nLocalizations(context)!;
final useNativeHttpClient = ref.watch(useNativeHttpClientStateProvider);
return Scaffold(
appBar: AppBar(
title: Text(l10n.advanced),
),
body: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: SwitchListTile(
title: Text(l10n.use_native_http_client),
subtitle: Text(
l10n.use_native_http_client_info,
style:
TextStyle(fontSize: 11, color: context.secondaryColor),
),
value: useNativeHttpClient,
onChanged: (value) {
ref
.read(useNativeHttpClientStateProvider.notifier)
.set(value);
}),
),
],
),
),
);
}
}

View file

@ -0,0 +1,19 @@
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'native_http_client.g.dart';
@riverpod
class UseNativeHttpClientState extends _$UseNativeHttpClientState {
@override
bool build() {
return isar.settings.getSync(227)!.useNativeHttpClient ?? false;
}
void set(bool value) {
final settings = isar.settings.getSync(227);
state = value;
isar.writeTxnSync(
() => isar.settings.putSync(settings!..useNativeHttpClient = value));
}
}

View file

@ -0,0 +1,27 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'native_http_client.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$useNativeHttpClientStateHash() =>
r'477bc54ed73067db40dc291532818108a2a37536';
/// See also [UseNativeHttpClientState].
@ProviderFor(UseNativeHttpClientState)
final useNativeHttpClientStateProvider =
AutoDisposeNotifierProvider<UseNativeHttpClientState, bool>.internal(
UseNativeHttpClientState.new,
name: r'useNativeHttpClientStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$useNativeHttpClientStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$UseNativeHttpClientState = AutoDisposeNotifier<bool>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:mangayomi/modules/more/widgets/list_tile_widget.dart';
@ -46,6 +48,12 @@ class SettingsScreen extends StatelessWidget {
subtitle: l10n.browse_subtitle,
icon: Icons.explore_rounded,
onTap: () => context.push('/browseS')),
if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS)
ListTileWidget(
title: l10n.advanced,
subtitle: l10n.browse_subtitle,
icon: Icons.code_rounded,
onTap: () => context.push('/advancedScreen')),
ListTileWidget(
onTap: () {
context.push('/about');

View file

@ -12,6 +12,7 @@ import 'package:mangayomi/modules/browse/extension/widgets/create_extension.dart
import 'package:mangayomi/modules/browse/sources/sources_filter_screen.dart';
import 'package:mangayomi/modules/more/backup_and_restore/backup_and_restore.dart';
import 'package:mangayomi/modules/more/categories/categories_screen.dart';
import 'package:mangayomi/modules/more/settings/advanced/advanced.dart';
import 'package:mangayomi/modules/more/settings/downloads/downloads_screen.dart';
import 'package:mangayomi/modules/more/settings/player/player_screen.dart';
import 'package:mangayomi/modules/more/settings/track/track.dart';
@ -533,6 +534,19 @@ class RouterNotifier extends ChangeNotifier {
);
},
),
GoRoute(
path: "/advancedScreen",
name: "advancedScreen",
builder: (context, state) {
return const AdvancedScreen();
},
pageBuilder: (context, state) {
return transitionPage(
key: state.pageKey,
child: const AdvancedScreen(),
);
},
),
];
}

View file

@ -15,20 +15,24 @@ import 'package:mangayomi/utils/log/log.dart';
class MClient {
MClient();
static Client httpClient() {
if (Platform.isAndroid) {
final engine = CronetEngine.build(
enablePublicKeyPinningBypassForLocalTrustAnchors: true,
enableHttp2: true,
enableBrotli: true,
cacheMode: CacheMode.memory,
cacheMaxSize: 5 * 1024 * 1024);
return CronetClient.fromCronetEngine(engine, closeEngine: true);
}
if (Platform.isIOS || Platform.isMacOS) {
final config = URLSessionConfiguration.ephemeralSessionConfiguration()
..cache = URLCache.withCapacity(memoryCapacity: 5 * 1024 * 1024);
return CupertinoClient.fromSessionConfiguration(config);
if ((Platform.isAndroid || Platform.isIOS || Platform.isMacOS) &&
(isar.settings.getSync(227)?.useNativeHttpClient ?? false)) {
if (Platform.isAndroid) {
final engine = CronetEngine.build(
enablePublicKeyPinningBypassForLocalTrustAnchors: true,
enableHttp2: true,
enableBrotli: true,
cacheMode: CacheMode.memory,
cacheMaxSize: 5 * 1024 * 1024);
return CronetClient.fromCronetEngine(engine, closeEngine: true);
}
if (Platform.isIOS || Platform.isMacOS) {
final config = URLSessionConfiguration.ephemeralSessionConfiguration()
..cache = URLCache.withCapacity(memoryCapacity: 5 * 1024 * 1024);
return CupertinoClient.fromSessionConfiguration(config);
}
}
return IOClient(HttpClient());
}

View file

@ -5,18 +5,23 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7"
sha256: "5aaf60d96c4cd00fe7f21594b5ad6a1b699c80a27420f8a837f4d68473ef09e3"
url: "https://pub.dev"
source: hosted
version: "67.0.0"
version: "68.0.0"
_macros:
dependency: transitive
description: dart
source: sdk
version: "0.1.0"
analyzer:
dependency: "direct overridden"
description:
name: analyzer
sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d"
sha256: "21f1d3720fd1c70316399d5e2bccaebb415c434592d778cce8acb967b8578808"
url: "https://pub.dev"
source: hosted
version: "6.4.1"
version: "6.5.0"
analyzer_plugin:
dependency: transitive
description:
@ -880,6 +885,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
macros:
dependency: transitive
description:
name: macros
sha256: "12e8a9842b5a7390de7a781ec63d793527582398d16ea26c60fed58833c9ae79"
url: "https://pub.dev"
source: hosted
version: "0.1.0-main.0"
matcher:
dependency: transitive
description:
@ -980,13 +993,13 @@ packages:
source: git
version: "1.2.4"
meta:
dependency: transitive
dependency: "direct overridden"
description:
name: meta
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted
version: "1.12.0"
version: "1.15.0"
mime:
dependency: transitive
description:

View file

@ -98,6 +98,7 @@ dependency_overrides:
url: https://github.com/media-kit/media-kit.git
path: media_kit_video
ref: 50c510d018cc5286eb6730f3ea165290f19dc5f6
meta: ^1.15.0
dev_dependencies:
flutter_test: