mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
DNS overrides
This commit is contained in:
@@ -258,7 +258,9 @@
|
|||||||
"View Detail": "查看详情",
|
"View Detail": "查看详情",
|
||||||
"Select a directory which contains multiple cbz/zip files." : "选择一个包含多个cbz/zip文件的目录",
|
"Select a directory which contains multiple cbz/zip files." : "选择一个包含多个cbz/zip文件的目录",
|
||||||
"Multiple cbz files" : "多个cbz文件",
|
"Multiple cbz files" : "多个cbz文件",
|
||||||
"No valid comics found" : "未找到有效的漫画"
|
"No valid comics found" : "未找到有效的漫画",
|
||||||
|
"Enable DNS Overrides": "启用DNS覆写",
|
||||||
|
"DNS Overrides": "DNS覆写"
|
||||||
},
|
},
|
||||||
"zh_TW": {
|
"zh_TW": {
|
||||||
"Home": "首頁",
|
"Home": "首頁",
|
||||||
@@ -519,6 +521,8 @@
|
|||||||
"View Detail": "查看詳情",
|
"View Detail": "查看詳情",
|
||||||
"Select a directory which contains multiple cbz/zip files." : "選擇一個包含多個cbz/zip文件的目錄",
|
"Select a directory which contains multiple cbz/zip files." : "選擇一個包含多個cbz/zip文件的目錄",
|
||||||
"Multiple cbz files" : "多個cbz文件",
|
"Multiple cbz files" : "多個cbz文件",
|
||||||
"No valid comics found" : "未找到有效的漫畫"
|
"No valid comics found" : "未找到有效的漫畫",
|
||||||
|
"Enable DNS Overrides": "啟用DNS覆寫",
|
||||||
|
"DNS Overrides": "DNS覆寫"
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -123,6 +123,8 @@ class _Settings with ChangeNotifier {
|
|||||||
'ignoreCertificateErrors': false,
|
'ignoreCertificateErrors': false,
|
||||||
'authorizationRequired': false,
|
'authorizationRequired': false,
|
||||||
'onClickFavorite': 'viewDetail', // viewDetail, read
|
'onClickFavorite': 'viewDetail', // viewDetail, read
|
||||||
|
'enableDnsOverrides': false,
|
||||||
|
'dnsOverrides': {},
|
||||||
};
|
};
|
||||||
|
|
||||||
operator [](String key) {
|
operator [](String key) {
|
||||||
|
@@ -58,6 +58,11 @@ class JsEngine with _JSEngineApi {
|
|||||||
JsEngine().init();
|
JsEngine().init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resetDio() {
|
||||||
|
_dio = AppDio(BaseOptions(
|
||||||
|
responseType: ResponseType.plain, validateStatus: (status) => true));
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
if (!_closed) {
|
if (!_closed) {
|
||||||
return;
|
return;
|
||||||
@@ -198,7 +203,8 @@ class JsEngine with _JSEngineApi {
|
|||||||
..findProxy = (uri) => proxy == null ? "DIRECT" : "PROXY $proxy";
|
..findProxy = (uri) => proxy == null ? "DIRECT" : "PROXY $proxy";
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
dio.interceptors.add(CookieManagerSql(SingleInstanceCookieJar.instance!));
|
dio.interceptors
|
||||||
|
.add(CookieManagerSql(SingleInstanceCookieJar.instance!));
|
||||||
dio.interceptors.add(LogInterceptor());
|
dio.interceptors.add(LogInterceptor());
|
||||||
}
|
}
|
||||||
response = await dio!.request(req["url"],
|
response = await dio!.request(req["url"],
|
||||||
|
@@ -222,6 +222,22 @@ class AppDio with DioMixin {
|
|||||||
class RHttpAdapter implements HttpClientAdapter {
|
class RHttpAdapter implements HttpClientAdapter {
|
||||||
rhttp.ClientSettings settings;
|
rhttp.ClientSettings settings;
|
||||||
|
|
||||||
|
static Map<String, List<String>> _getOverrides() {
|
||||||
|
if (!appdata.settings['enableDnsOverrides'] == true) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
var config = appdata.settings["dnsOverrides"];
|
||||||
|
var result = <String, List<String>>{};
|
||||||
|
if (config is Map) {
|
||||||
|
for (var entry in config.entries) {
|
||||||
|
if (entry.key is String && entry.value is String) {
|
||||||
|
result[entry.key] = [entry.value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
RHttpAdapter([this.settings = const rhttp.ClientSettings()]) {
|
RHttpAdapter([this.settings = const rhttp.ClientSettings()]) {
|
||||||
settings = settings.copyWith(
|
settings = settings.copyWith(
|
||||||
redirectSettings: const rhttp.RedirectSettings.limited(5),
|
redirectSettings: const rhttp.RedirectSettings.limited(5),
|
||||||
@@ -234,6 +250,7 @@ class RHttpAdapter implements HttpClientAdapter {
|
|||||||
tlsSettings: rhttp.TlsSettings(
|
tlsSettings: rhttp.TlsSettings(
|
||||||
verifyCertificates: !AppDio.ignoreCertificateErrors,
|
verifyCertificates: !AppDio.ignoreCertificateErrors,
|
||||||
),
|
),
|
||||||
|
dnsSettings: rhttp.DnsSettings.static(overrides: _getOverrides()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,6 +17,10 @@ class _NetworkSettingsState extends State<NetworkSettings> {
|
|||||||
title: "Proxy".tl,
|
title: "Proxy".tl,
|
||||||
builder: () => const _ProxySettingView(),
|
builder: () => const _ProxySettingView(),
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
|
_PopupWindowSetting(
|
||||||
|
title: "DNS Overrides".tl,
|
||||||
|
builder: () => const _DNSOverrides(),
|
||||||
|
).toSliver(),
|
||||||
_SliderSetting(
|
_SliderSetting(
|
||||||
title: "Download Threads".tl,
|
title: "Download Threads".tl,
|
||||||
settingsIndex: 'downloadThreads',
|
settingsIndex: 'downloadThreads',
|
||||||
@@ -100,7 +104,8 @@ class _ProxySettingViewState extends State<_ProxySettingView> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
var proxy = appdata.settings['proxy'];
|
var proxy = appdata.settings['proxy'];
|
||||||
parseProxyString(proxy);
|
parseProxyString(proxy);
|
||||||
ignoreCertificateErrors = appdata.settings['ignoreCertificateErrors'] ?? false;
|
ignoreCertificateErrors =
|
||||||
|
appdata.settings['ignoreCertificateErrors'] ?? false;
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +158,8 @@ class _ProxySettingViewState extends State<_ProxySettingView> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
ignoreCertificateErrors = v;
|
ignoreCertificateErrors = v;
|
||||||
});
|
});
|
||||||
appdata.settings['ignoreCertificateErrors'] = ignoreCertificateErrors;
|
appdata.settings['ignoreCertificateErrors'] =
|
||||||
|
ignoreCertificateErrors;
|
||||||
appdata.saveData();
|
appdata.saveData();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -250,3 +256,135 @@ class _ProxySettingViewState extends State<_ProxySettingView> {
|
|||||||
).paddingHorizontal(16).paddingTop(16);
|
).paddingHorizontal(16).paddingTop(16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _DNSOverrides extends StatefulWidget {
|
||||||
|
const _DNSOverrides();
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_DNSOverrides> createState() => __DNSOverridesState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class __DNSOverridesState extends State<_DNSOverrides> {
|
||||||
|
var overrides = <(String, String)>[];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
for (var entry in (appdata.settings['dnsOverrides'] as Map).entries) {
|
||||||
|
if (entry.key is String && entry.value is String) {
|
||||||
|
overrides.add((entry.key, entry.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
var map = <String, String>{};
|
||||||
|
for (var entry in overrides) {
|
||||||
|
map[entry.$1] = entry.$2;
|
||||||
|
}
|
||||||
|
appdata.settings['dnsOverrides'] = map;
|
||||||
|
appdata.saveData();
|
||||||
|
JsEngine().resetDio();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return PopUpWidgetScaffold(
|
||||||
|
title: "DNS Overrides".tl,
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_SwitchSetting(
|
||||||
|
title: "Enable DNS Overrides".tl,
|
||||||
|
settingKey: "enableDnsOverrides",
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Container(
|
||||||
|
height: 1,
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
color: context.colorScheme.outlineVariant,
|
||||||
|
),
|
||||||
|
for (var i = 0; i < overrides.length; i++) buildOverride(i),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
overrides.add(('', ''));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
label: Text("Add".tl),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildOverride(int index) {
|
||||||
|
var entry = overrides[index];
|
||||||
|
return Container(
|
||||||
|
height: 48,
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(
|
||||||
|
color: context.colorScheme.outlineVariant,
|
||||||
|
),
|
||||||
|
left: BorderSide(
|
||||||
|
color: context.colorScheme.outlineVariant,
|
||||||
|
),
|
||||||
|
right: BorderSide(
|
||||||
|
color: context.colorScheme.outlineVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: TextField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
hintText: "Domain".tl,
|
||||||
|
),
|
||||||
|
controller: TextEditingController(text: entry.$1),
|
||||||
|
onChanged: (v) {
|
||||||
|
overrides[index] = (v, entry.$2);
|
||||||
|
},
|
||||||
|
).paddingHorizontal(8),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 1,
|
||||||
|
color: context.colorScheme.outlineVariant,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: TextField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
hintText: "IP".tl,
|
||||||
|
),
|
||||||
|
controller: TextEditingController(text: entry.$2),
|
||||||
|
onChanged: (v) {
|
||||||
|
overrides[index] = (entry.$1, v);
|
||||||
|
},
|
||||||
|
).paddingHorizontal(8),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 1,
|
||||||
|
color: context.colorScheme.outlineVariant,
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.delete_outline),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
overrides.removeAt(index);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -12,6 +12,7 @@ import 'package:venera/foundation/appdata.dart';
|
|||||||
import 'package:venera/foundation/cache_manager.dart';
|
import 'package:venera/foundation/cache_manager.dart';
|
||||||
import 'package:venera/foundation/comic_source/comic_source.dart';
|
import 'package:venera/foundation/comic_source/comic_source.dart';
|
||||||
import 'package:venera/foundation/favorites.dart';
|
import 'package:venera/foundation/favorites.dart';
|
||||||
|
import 'package:venera/foundation/js_engine.dart';
|
||||||
import 'package:venera/foundation/local.dart';
|
import 'package:venera/foundation/local.dart';
|
||||||
import 'package:venera/foundation/log.dart';
|
import 'package:venera/foundation/log.dart';
|
||||||
import 'package:venera/network/app_dio.dart';
|
import 'package:venera/network/app_dio.dart';
|
||||||
|
@@ -408,8 +408,8 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "1657f62fe7545ac43a339e0a5ee2b82bacd81e9f"
|
ref: "9c99ac258a11f8e91761a5466a190efba3ca64af"
|
||||||
resolved-ref: "1657f62fe7545ac43a339e0a5ee2b82bacd81e9f"
|
resolved-ref: "9c99ac258a11f8e91761a5466a190efba3ca64af"
|
||||||
url: "https://github.com/wgh136/flutter_qjs"
|
url: "https://github.com/wgh136/flutter_qjs"
|
||||||
source: git
|
source: git
|
||||||
version: "0.3.7"
|
version: "0.3.7"
|
||||||
@@ -1125,10 +1125,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: zip_flutter
|
name: zip_flutter
|
||||||
sha256: "955b53d58709fcd9feefbed3d41b5522bc5273e677603e9fc67017a81e568d24"
|
sha256: be21152c35fcb6d0ef4ce89fc3aed681f7adc0db5490ca3eb5893f23fd20e646
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.5"
|
version: "0.0.6"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.6.0 <4.0.0"
|
dart: ">=3.6.0 <4.0.0"
|
||||||
flutter: ">=3.27.1"
|
flutter: ">=3.27.1"
|
||||||
|
Reference in New Issue
Block a user