Add config option reset
This commit is contained in:
@@ -178,6 +178,7 @@
|
|||||||
"clearSelection": "Clear selection"
|
"clearSelection": "Clear selection"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
|
"resetBtn": "Reset options",
|
||||||
"serviceMode": "Service Mode",
|
"serviceMode": "Service Mode",
|
||||||
"serviceModes": {
|
"serviceModes": {
|
||||||
"proxy": "Proxy",
|
"proxy": "Proxy",
|
||||||
|
|||||||
@@ -223,7 +223,8 @@
|
|||||||
"tlsFragmentSleep": "TLS Fragment Sleep",
|
"tlsFragmentSleep": "TLS Fragment Sleep",
|
||||||
"enableTlsMixedSniCase": "Enable TLS Mixed SNI Case",
|
"enableTlsMixedSniCase": "Enable TLS Mixed SNI Case",
|
||||||
"enableTlsPadding": "Enable TLS Padding",
|
"enableTlsPadding": "Enable TLS Padding",
|
||||||
"tlsPaddingSize": "TLS Padding"
|
"tlsPaddingSize": "TLS Padding",
|
||||||
|
"resetBtn": "گزینه ها را بازنشانی کنید"
|
||||||
},
|
},
|
||||||
"geoAssets": {
|
"geoAssets": {
|
||||||
"pageTitle": "فایلهای مسیریابی",
|
"pageTitle": "فایلهای مسیریابی",
|
||||||
|
|||||||
@@ -223,7 +223,8 @@
|
|||||||
"tlsFragmentSleep": "TLS Fragment Sleep",
|
"tlsFragmentSleep": "TLS Fragment Sleep",
|
||||||
"enableTlsMixedSniCase": "Enable TLS Mixed SNI Case",
|
"enableTlsMixedSniCase": "Enable TLS Mixed SNI Case",
|
||||||
"enableTlsPadding": "Enable TLS Padding",
|
"enableTlsPadding": "Enable TLS Padding",
|
||||||
"tlsPaddingSize": "TLS Padding"
|
"tlsPaddingSize": "TLS Padding",
|
||||||
|
"resetBtn": "Сбросить параметры"
|
||||||
},
|
},
|
||||||
"geoAssets": {
|
"geoAssets": {
|
||||||
"pageTitle": "Активы маршрутизации",
|
"pageTitle": "Активы маршрутизации",
|
||||||
|
|||||||
@@ -223,7 +223,8 @@
|
|||||||
"tlsFragmentSleep": "TLS Fragment Sleep",
|
"tlsFragmentSleep": "TLS Fragment Sleep",
|
||||||
"enableTlsMixedSniCase": "Enable TLS Mixed SNI Case",
|
"enableTlsMixedSniCase": "Enable TLS Mixed SNI Case",
|
||||||
"enableTlsPadding": "Enable TLS Padding",
|
"enableTlsPadding": "Enable TLS Padding",
|
||||||
"tlsPaddingSize": "TLS Padding"
|
"tlsPaddingSize": "TLS Padding",
|
||||||
|
"resetBtn": "Ayarları sıfırla"
|
||||||
},
|
},
|
||||||
"geoAssets": {
|
"geoAssets": {
|
||||||
"pageTitle": "Varlıkları Yönlendirme",
|
"pageTitle": "Varlıkları Yönlendirme",
|
||||||
|
|||||||
@@ -223,7 +223,8 @@
|
|||||||
"tlsFragmentSleep": "TLS Fragment Sleep",
|
"tlsFragmentSleep": "TLS Fragment Sleep",
|
||||||
"enableTlsMixedSniCase": "Enable TLS Mixed SNI Case",
|
"enableTlsMixedSniCase": "Enable TLS Mixed SNI Case",
|
||||||
"enableTlsPadding": "Enable TLS Padding",
|
"enableTlsPadding": "Enable TLS Padding",
|
||||||
"tlsPaddingSize": "TLS Padding"
|
"tlsPaddingSize": "TLS Padding",
|
||||||
|
"resetBtn": "重置选项"
|
||||||
},
|
},
|
||||||
"geoAssets": {
|
"geoAssets": {
|
||||||
"pageTitle": "路由资源文件",
|
"pageTitle": "路由资源文件",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import 'package:hiddify/singbox/model/singbox_config_enum.dart';
|
|||||||
import 'package:hiddify/singbox/model/singbox_config_option.dart';
|
import 'package:hiddify/singbox/model/singbox_config_option.dart';
|
||||||
import 'package:hiddify/singbox/model/singbox_rule.dart';
|
import 'package:hiddify/singbox/model/singbox_rule.dart';
|
||||||
import 'package:hiddify/utils/utils.dart';
|
import 'package:hiddify/utils/utils.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
abstract interface class ConfigOptionRepository {
|
abstract interface class ConfigOptionRepository {
|
||||||
@@ -19,6 +20,7 @@ abstract interface class ConfigOptionRepository {
|
|||||||
TaskEither<ConfigOptionFailure, Unit> updateConfigOption(
|
TaskEither<ConfigOptionFailure, Unit> updateConfigOption(
|
||||||
ConfigOptionPatch patch,
|
ConfigOptionPatch patch,
|
||||||
);
|
);
|
||||||
|
TaskEither<ConfigOptionFailure, Unit> resetConfigOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigOptionRepositoryImpl
|
class ConfigOptionRepositoryImpl
|
||||||
@@ -151,8 +153,32 @@ class ConfigOptionRepositoryImpl
|
|||||||
return exceptionHandler(
|
return exceptionHandler(
|
||||||
() async {
|
() async {
|
||||||
final map = patch.toJson();
|
final map = patch.toJson();
|
||||||
|
await updateByJson(map);
|
||||||
|
return right(unit);
|
||||||
|
},
|
||||||
|
ConfigOptionUnexpectedFailure.new,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
TaskEither<ConfigOptionFailure, Unit> resetConfigOption() {
|
||||||
|
return exceptionHandler(
|
||||||
|
() async {
|
||||||
|
final map = ConfigOptionEntity.initial.toJson();
|
||||||
|
await updateByJson(map);
|
||||||
|
return right(unit);
|
||||||
|
},
|
||||||
|
ConfigOptionUnexpectedFailure.new,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@visibleForTesting
|
||||||
|
Future<void> updateByJson(
|
||||||
|
Map<String, dynamic> options,
|
||||||
|
) async {
|
||||||
|
final map = ConfigOptionEntity.initial.toJson();
|
||||||
for (final key in map.keys) {
|
for (final key in map.keys) {
|
||||||
final value = map[key];
|
final value = options[key];
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
loggy.debug("updating [$key] to [$value]");
|
loggy.debug("updating [$key] to [$value]");
|
||||||
|
|
||||||
@@ -170,9 +196,5 @@ class ConfigOptionRepositoryImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return right(unit);
|
|
||||||
},
|
|
||||||
ConfigOptionUnexpectedFailure.new,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,4 +28,9 @@ class ConfigOptionNotifier extends _$ConfigOptionNotifier with AppLogger {
|
|||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> resetOption() async {
|
||||||
|
await ref.read(configOptionRepositoryProvider).resetConfigOption().run();
|
||||||
|
ref.invalidateSelf();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
|
import 'package:hiddify/core/model/failures.dart';
|
||||||
import 'package:hiddify/core/model/range.dart';
|
import 'package:hiddify/core/model/range.dart';
|
||||||
import 'package:hiddify/features/config_option/model/config_option_entity.dart';
|
import 'package:hiddify/features/config_option/model/config_option_entity.dart';
|
||||||
import 'package:hiddify/features/config_option/model/config_option_patch.dart';
|
import 'package:hiddify/features/config_option/model/config_option_patch.dart';
|
||||||
@@ -45,6 +46,14 @@ class ConfigOptionsPage extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
child: Text(t.settings.config.resetBtn),
|
||||||
|
onTap: () async {
|
||||||
|
await ref
|
||||||
|
.read(configOptionNotifierProvider.notifier)
|
||||||
|
.resetOption();
|
||||||
|
},
|
||||||
|
),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -377,7 +386,26 @@ class ConfigOptionsPage extends HookConsumerWidget {
|
|||||||
const Gap(24),
|
const Gap(24),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// TODO show appropriate error/loading widgets
|
AsyncError(:final error) => Center(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.error),
|
||||||
|
const Gap(2),
|
||||||
|
Text(t.presentShortError(error)),
|
||||||
|
const Gap(2),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () async {
|
||||||
|
await ref
|
||||||
|
.read(configOptionNotifierProvider.notifier)
|
||||||
|
.resetOption();
|
||||||
|
},
|
||||||
|
child: Text(t.settings.config.resetBtn),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
_ => const SizedBox(),
|
_ => const SizedBox(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user