Change warp options
This commit is contained in:
@@ -243,6 +243,7 @@
|
|||||||
},
|
},
|
||||||
"generateWarpConfig": "Generate WARP config",
|
"generateWarpConfig": "Generate WARP config",
|
||||||
"missingWarpConfig": "Missing WARP config",
|
"missingWarpConfig": "Missing WARP config",
|
||||||
|
"warpConfigGenerated": "WARP config generated",
|
||||||
"pageTitle": "Config Options",
|
"pageTitle": "Config Options",
|
||||||
"logLevel": "Log Level",
|
"logLevel": "Log Level",
|
||||||
"resolveDestination": "Resolve Destination",
|
"resolveDestination": "Resolve Destination",
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ abstract interface class ConfigOptionRepository {
|
|||||||
ConfigOptionPatch patch,
|
ConfigOptionPatch patch,
|
||||||
);
|
);
|
||||||
TaskEither<ConfigOptionFailure, Unit> resetConfigOption();
|
TaskEither<ConfigOptionFailure, Unit> resetConfigOption();
|
||||||
TaskEither<ConfigOptionFailure, Unit> generateWarpConfig();
|
TaskEither<ConfigOptionFailure, String> generateWarpConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract interface class SingBoxConfigOptionRepository {
|
abstract interface class SingBoxConfigOptionRepository {
|
||||||
@@ -115,7 +115,7 @@ class ConfigOptionRepositoryImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TaskEither<ConfigOptionFailure, Unit> generateWarpConfig() {
|
TaskEither<ConfigOptionFailure, String> generateWarpConfig() {
|
||||||
return exceptionHandler(
|
return exceptionHandler(
|
||||||
() async {
|
() async {
|
||||||
final options = getConfigOption().getOrElse((l) => throw l);
|
final options = getConfigOption().getOrElse((l) => throw l);
|
||||||
@@ -131,8 +131,9 @@ class ConfigOptionRepositoryImpl
|
|||||||
ConfigOptionPatch(
|
ConfigOptionPatch(
|
||||||
warpAccountId: warp.accountId,
|
warpAccountId: warp.accountId,
|
||||||
warpAccessToken: warp.accessToken,
|
warpAccessToken: warp.accessToken,
|
||||||
|
warpWireguardConfig: warp.wireguardConfig,
|
||||||
),
|
),
|
||||||
),
|
).map((_) => warp.log),
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ class ConfigOptionEntity with _$ConfigOptionEntity {
|
|||||||
@OptionalRangeJsonConverter()
|
@OptionalRangeJsonConverter()
|
||||||
@Default(OptionalRange())
|
@Default(OptionalRange())
|
||||||
OptionalRange warpNoise,
|
OptionalRange warpNoise,
|
||||||
|
@Default("") String warpWireguardConfig,
|
||||||
}) = _ConfigOptionEntity;
|
}) = _ConfigOptionEntity;
|
||||||
|
|
||||||
factory ConfigOptionEntity.initial() => ConfigOptionEntity(
|
factory ConfigOptionEntity.initial() => ConfigOptionEntity(
|
||||||
@@ -140,6 +141,7 @@ class ConfigOptionEntity with _$ConfigOptionEntity {
|
|||||||
warpCleanIp: patch.warpCleanIp ?? warpCleanIp,
|
warpCleanIp: patch.warpCleanIp ?? warpCleanIp,
|
||||||
warpPort: patch.warpPort ?? warpPort,
|
warpPort: patch.warpPort ?? warpPort,
|
||||||
warpNoise: patch.warpNoise ?? warpNoise,
|
warpNoise: patch.warpNoise ?? warpNoise,
|
||||||
|
warpWireguardConfig: patch.warpWireguardConfig ?? warpWireguardConfig,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,17 +186,20 @@ class ConfigOptionEntity with _$ConfigOptionEntity {
|
|||||||
muxPadding: muxPadding,
|
muxPadding: muxPadding,
|
||||||
muxMaxStreams: muxMaxStreams,
|
muxMaxStreams: muxMaxStreams,
|
||||||
muxProtocol: muxProtocol,
|
muxProtocol: muxProtocol,
|
||||||
enableWarp: enableWarp,
|
|
||||||
warpDetourMode: warpDetourMode,
|
|
||||||
warpLicenseKey: warpLicenseKey,
|
|
||||||
warpAccountId: warpAccountId,
|
|
||||||
warpAccessToken: warpAccessToken,
|
|
||||||
warpCleanIp: warpCleanIp,
|
|
||||||
warpPort: warpPort,
|
|
||||||
warpNoise: warpNoise,
|
|
||||||
geoipPath: geoipPath,
|
geoipPath: geoipPath,
|
||||||
geositePath: geositePath,
|
geositePath: geositePath,
|
||||||
rules: rules,
|
rules: rules,
|
||||||
|
warp: SingboxWarpOption(
|
||||||
|
enable: enableWarp,
|
||||||
|
mode: warpDetourMode,
|
||||||
|
licenseKey: warpLicenseKey,
|
||||||
|
accountId: warpAccountId,
|
||||||
|
accessToken: warpAccessToken,
|
||||||
|
cleanIp: warpCleanIp,
|
||||||
|
cleanPort: warpPort,
|
||||||
|
warpNoise: warpNoise,
|
||||||
|
wireguardConfig: warpWireguardConfig,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,6 +253,7 @@ class ConfigOptionPatch with _$ConfigOptionPatch {
|
|||||||
String? warpCleanIp,
|
String? warpCleanIp,
|
||||||
int? warpPort,
|
int? warpPort,
|
||||||
@OptionalRangeJsonConverter() OptionalRange? warpNoise,
|
@OptionalRangeJsonConverter() OptionalRange? warpNoise,
|
||||||
|
String? warpWireguardConfig,
|
||||||
}) = _ConfigOptionPatch;
|
}) = _ConfigOptionPatch;
|
||||||
|
|
||||||
factory ConfigOptionPatch.fromJson(Map<String, dynamic> json) =>
|
factory ConfigOptionPatch.fromJson(Map<String, dynamic> json) =>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import 'package:fpdart/fpdart.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:hiddify/core/preferences/preferences_provider.dart';
|
import 'package:hiddify/core/preferences/preferences_provider.dart';
|
||||||
import 'package:hiddify/features/config_option/data/config_option_data_providers.dart';
|
import 'package:hiddify/features/config_option/data/config_option_data_providers.dart';
|
||||||
@@ -27,7 +26,7 @@ class WarpOptionNotifier extends _$WarpOptionNotifier with AppLogger {
|
|||||||
return WarpOptions(
|
return WarpOptions(
|
||||||
consentGiven: consent,
|
consentGiven: consent,
|
||||||
configGeneration: hasWarpConfig
|
configGeneration: hasWarpConfig
|
||||||
? const AsyncValue.data(unit)
|
? const AsyncValue.data("")
|
||||||
: AsyncError(const MissingWarpConfigFailure(), StackTrace.current),
|
: AsyncError(const MissingWarpConfigFailure(), StackTrace.current),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -66,6 +65,6 @@ class WarpOptionNotifier extends _$WarpOptionNotifier with AppLogger {
|
|||||||
class WarpOptions with _$WarpOptions {
|
class WarpOptions with _$WarpOptions {
|
||||||
const factory WarpOptions({
|
const factory WarpOptions({
|
||||||
required bool consentGiven,
|
required bool consentGiven,
|
||||||
required AsyncValue<Unit> configGeneration,
|
required AsyncValue<String> configGeneration,
|
||||||
}) = _WarpOptions;
|
}) = _WarpOptions;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/core/model/constants.dart';
|
import 'package:hiddify/core/model/constants.dart';
|
||||||
import 'package:hiddify/core/model/optional_range.dart';
|
import 'package:hiddify/core/model/optional_range.dart';
|
||||||
|
import 'package:hiddify/core/widget/custom_alert_dialog.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/notifier/warp_option_notifier.dart';
|
import 'package:hiddify/features/config_option/notifier/warp_option_notifier.dart';
|
||||||
import 'package:hiddify/features/settings/widgets/settings_input_dialog.dart';
|
import 'package:hiddify/features/settings/widgets/settings_input_dialog.dart';
|
||||||
@@ -32,6 +33,18 @@ class WarpOptionsTiles extends HookConsumerWidget {
|
|||||||
final warpPrefaceCompleted = warpOptions.consentGiven;
|
final warpPrefaceCompleted = warpOptions.consentGiven;
|
||||||
final canChangeOptions = warpPrefaceCompleted && options.enableWarp;
|
final canChangeOptions = warpPrefaceCompleted && options.enableWarp;
|
||||||
|
|
||||||
|
ref.listen(
|
||||||
|
warpOptionNotifierProvider.select((value) => value.configGeneration),
|
||||||
|
(previous, next) async {
|
||||||
|
if (next case AsyncData(value: final log) when log.isNotEmpty) {
|
||||||
|
await CustomAlertDialog(
|
||||||
|
title: t.settings.config.warpConfigGenerated,
|
||||||
|
message: log,
|
||||||
|
).show(context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
|
|||||||
@@ -51,17 +51,10 @@ class SingboxConfigOption with _$SingboxConfigOption {
|
|||||||
required bool muxPadding,
|
required bool muxPadding,
|
||||||
required int muxMaxStreams,
|
required int muxMaxStreams,
|
||||||
required MuxProtocol muxProtocol,
|
required MuxProtocol muxProtocol,
|
||||||
required bool enableWarp,
|
|
||||||
required WarpDetourMode warpDetourMode,
|
|
||||||
required String warpLicenseKey,
|
|
||||||
required String warpAccountId,
|
|
||||||
required String warpAccessToken,
|
|
||||||
required String warpCleanIp,
|
|
||||||
required int warpPort,
|
|
||||||
@OptionalRangeJsonConverter() required OptionalRange warpNoise,
|
|
||||||
required String geoipPath,
|
required String geoipPath,
|
||||||
required String geositePath,
|
required String geositePath,
|
||||||
required List<SingboxRule> rules,
|
required List<SingboxRule> rules,
|
||||||
|
required SingboxWarpOption warp,
|
||||||
}) = _SingboxConfigOption;
|
}) = _SingboxConfigOption;
|
||||||
|
|
||||||
String format() {
|
String format() {
|
||||||
@@ -72,3 +65,21 @@ class SingboxConfigOption with _$SingboxConfigOption {
|
|||||||
factory SingboxConfigOption.fromJson(Map<String, dynamic> json) =>
|
factory SingboxConfigOption.fromJson(Map<String, dynamic> json) =>
|
||||||
_$SingboxConfigOptionFromJson(json);
|
_$SingboxConfigOptionFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class SingboxWarpOption with _$SingboxWarpOption {
|
||||||
|
const factory SingboxWarpOption({
|
||||||
|
required bool enable,
|
||||||
|
required WarpDetourMode mode,
|
||||||
|
required String wireguardConfig,
|
||||||
|
required String licenseKey,
|
||||||
|
required String accountId,
|
||||||
|
required String accessToken,
|
||||||
|
required String cleanIp,
|
||||||
|
required int cleanPort,
|
||||||
|
@OptionalRangeJsonConverter() required OptionalRange warpNoise,
|
||||||
|
}) = _SingboxWarpOption;
|
||||||
|
|
||||||
|
factory SingboxWarpOption.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SingboxWarpOptionFromJson(json);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,17 +1,26 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'dart:convert';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
|
|
||||||
part 'warp_account.freezed.dart';
|
typedef WarpResponse = ({
|
||||||
part 'warp_account.g.dart';
|
String log,
|
||||||
|
String accountId,
|
||||||
|
String accessToken,
|
||||||
|
String wireguardConfig,
|
||||||
|
});
|
||||||
|
|
||||||
@freezed
|
WarpResponse warpFromJson(dynamic json) {
|
||||||
class WarpAccount with _$WarpAccount {
|
if (json
|
||||||
const factory WarpAccount({
|
case {
|
||||||
required String licenseKey,
|
"account-id": final String newAccountId,
|
||||||
required String accountId,
|
"access-token": final String newAccessToken,
|
||||||
required String accessToken,
|
"log": final String log,
|
||||||
}) = _WarpAccount;
|
"config": final Map<String, dynamic> wireguardConfig,
|
||||||
|
}) {
|
||||||
factory WarpAccount.fromJson(Map<String, dynamic> json) =>
|
return (
|
||||||
_$WarpAccountFromJson(json);
|
log: log,
|
||||||
|
accountId: newAccountId,
|
||||||
|
accessToken: newAccessToken,
|
||||||
|
wireguardConfig: jsonEncode(wireguardConfig),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw Exception("invalid response");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -457,7 +457,7 @@ class FFISingboxService with InfraLogger implements SingboxService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TaskEither<String, WarpAccount> generateWarpConfig({
|
TaskEither<String, WarpResponse> generateWarpConfig({
|
||||||
required String licenseKey,
|
required String licenseKey,
|
||||||
required String previousAccountId,
|
required String previousAccountId,
|
||||||
required String previousAccessToken,
|
required String previousAccessToken,
|
||||||
@@ -477,20 +477,7 @@ class FFISingboxService with InfraLogger implements SingboxService {
|
|||||||
if (response.startsWith("error:")) {
|
if (response.startsWith("error:")) {
|
||||||
return left(response.replaceFirst('error:', ""));
|
return left(response.replaceFirst('error:', ""));
|
||||||
}
|
}
|
||||||
if (jsonDecode(response)
|
return right(warpFromJson(jsonDecode(response)));
|
||||||
case {
|
|
||||||
"account-id": final String newAccountId,
|
|
||||||
"access-token": final String newAccessToken,
|
|
||||||
}) {
|
|
||||||
return right(
|
|
||||||
WarpAccount(
|
|
||||||
licenseKey: licenseKey,
|
|
||||||
accountId: newAccountId,
|
|
||||||
accessToken: newAccessToken,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return left("invalid response");
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ class PlatformSingboxService with InfraLogger implements SingboxService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TaskEither<String, WarpAccount> generateWarpConfig({
|
TaskEither<String, WarpResponse> generateWarpConfig({
|
||||||
required String licenseKey,
|
required String licenseKey,
|
||||||
required String previousAccountId,
|
required String previousAccountId,
|
||||||
required String previousAccessToken,
|
required String previousAccessToken,
|
||||||
@@ -282,20 +282,7 @@ class PlatformSingboxService with InfraLogger implements SingboxService {
|
|||||||
"previous-access-token": previousAccessToken,
|
"previous-access-token": previousAccessToken,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (jsonDecode(warpConfig as String)
|
return right(warpFromJson(jsonDecode(warpConfig as String)));
|
||||||
case {
|
|
||||||
"account-id": final String newAccountId,
|
|
||||||
"access-token": final String newAccessToken,
|
|
||||||
}) {
|
|
||||||
return right(
|
|
||||||
WarpAccount(
|
|
||||||
licenseKey: licenseKey,
|
|
||||||
accountId: newAccountId,
|
|
||||||
accessToken: newAccessToken,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return left("invalid response");
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ abstract interface class SingboxService {
|
|||||||
|
|
||||||
TaskEither<String, Unit> clearLogs();
|
TaskEither<String, Unit> clearLogs();
|
||||||
|
|
||||||
TaskEither<String, WarpAccount> generateWarpConfig({
|
TaskEither<String, WarpResponse> generateWarpConfig({
|
||||||
required String licenseKey,
|
required String licenseKey,
|
||||||
required String previousAccountId,
|
required String previousAccountId,
|
||||||
required String previousAccessToken,
|
required String previousAccessToken,
|
||||||
|
|||||||
2
libcore
2
libcore
Submodule libcore updated: 6c65b73981...298ca9b1b8
Reference in New Issue
Block a user