Remove unused clash api
This commit is contained in:
@@ -1,145 +0,0 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:hiddify/domain/clash/clash.dart';
|
||||
import 'package:hiddify/domain/constants.dart';
|
||||
import 'package:hiddify/utils/utils.dart';
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
|
||||
class ClashApi with InfraLogger {
|
||||
ClashApi(int port) : address = "${Constants.localHost}:$port";
|
||||
|
||||
final String address;
|
||||
|
||||
late final _clashDio = Dio(
|
||||
BaseOptions(
|
||||
baseUrl: "http://$address",
|
||||
connectTimeout: const Duration(seconds: 3),
|
||||
receiveTimeout: const Duration(seconds: 10),
|
||||
sendTimeout: const Duration(seconds: 3),
|
||||
),
|
||||
);
|
||||
|
||||
TaskEither<String, List<ClashProxy>> getProxies() {
|
||||
return TaskEither(
|
||||
() async {
|
||||
final response = await _clashDio.get("/proxies");
|
||||
if (response.statusCode != 200 || response.data == null) {
|
||||
return left(response.statusMessage ?? "");
|
||||
}
|
||||
final proxies = ((jsonDecode(response.data! as String)
|
||||
as Map<String, dynamic>)["proxies"] as Map<String, dynamic>)
|
||||
.entries
|
||||
.map(
|
||||
(e) {
|
||||
final proxyMap = (e.value as Map<String, dynamic>)
|
||||
..putIfAbsent('name', () => e.key);
|
||||
return ClashProxy.fromJson(proxyMap);
|
||||
},
|
||||
);
|
||||
return right(proxies.toList());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
TaskEither<String, Unit> changeProxy(String selectorName, String proxyName) {
|
||||
return TaskEither(
|
||||
() async {
|
||||
final response = await _clashDio.put(
|
||||
"/proxies/$selectorName",
|
||||
data: {"name": proxyName},
|
||||
);
|
||||
if (response.statusCode != HttpStatus.noContent) {
|
||||
return left(response.statusMessage ?? "");
|
||||
}
|
||||
return right(unit);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
TaskEither<String, int> getProxyDelay(
|
||||
String name,
|
||||
String url, {
|
||||
Duration timeout = const Duration(seconds: 10),
|
||||
}) {
|
||||
return TaskEither(
|
||||
() async {
|
||||
final response = await _clashDio.get<Map>(
|
||||
"/proxies/$name/delay",
|
||||
queryParameters: {
|
||||
"timeout": timeout.inMilliseconds,
|
||||
"url": url,
|
||||
},
|
||||
);
|
||||
if (response.statusCode != 200 || response.data == null) {
|
||||
return left(response.statusMessage ?? "");
|
||||
}
|
||||
return right(response.data!["delay"] as int);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
TaskEither<String, ClashConfig> getConfigs() {
|
||||
return TaskEither(
|
||||
() async {
|
||||
final response = await _clashDio.get("/configs");
|
||||
if (response.statusCode != 200 || response.data == null) {
|
||||
return left(response.statusMessage ?? "");
|
||||
}
|
||||
final config =
|
||||
ClashConfig.fromJson(response.data as Map<String, dynamic>);
|
||||
return right(config);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
TaskEither<String, Unit> updateConfigs(String path) {
|
||||
return TaskEither.of(unit);
|
||||
}
|
||||
|
||||
TaskEither<String, Unit> patchConfigs(ClashConfig config) {
|
||||
return TaskEither(
|
||||
() async {
|
||||
final response = await _clashDio.patch(
|
||||
"/configs",
|
||||
data: config.toJson(),
|
||||
);
|
||||
if (response.statusCode != HttpStatus.noContent) {
|
||||
return left(response.statusMessage ?? "");
|
||||
}
|
||||
return right(unit);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Stream<ClashLog> watchLogs(LogLevel level) {
|
||||
return const Stream.empty();
|
||||
}
|
||||
|
||||
Stream<ClashTraffic> watchTraffic() {
|
||||
final channel = WebSocketChannel.connect(
|
||||
Uri.parse("ws://$address/traffic"),
|
||||
);
|
||||
return channel.stream.map(
|
||||
(event) {
|
||||
return ClashTraffic.fromJson(
|
||||
jsonDecode(event as String) as Map<String, dynamic>,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
TaskEither<String, ClashTraffic> getTraffic() {
|
||||
return TaskEither(
|
||||
() async {
|
||||
final response = await _clashDio.get<Map<String, dynamic>>("/traffic");
|
||||
if (response.statusCode != 200 || response.data == null) {
|
||||
return left(response.statusMessage ?? "");
|
||||
}
|
||||
return right(ClashTraffic.fromJson(response.data!));
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,11 @@ import 'dart:io';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:hiddify/core/core_providers.dart';
|
||||
import 'package:hiddify/core/prefs/general_prefs.dart';
|
||||
import 'package:hiddify/data/api/clash_api.dart';
|
||||
import 'package:hiddify/data/local/database.dart';
|
||||
import 'package:hiddify/data/repository/app_repository_impl.dart';
|
||||
import 'package:hiddify/data/repository/config_options_store.dart';
|
||||
import 'package:hiddify/data/repository/repository.dart';
|
||||
import 'package:hiddify/domain/app/app.dart';
|
||||
import 'package:hiddify/domain/constants.dart';
|
||||
import 'package:hiddify/domain/core_facade.dart';
|
||||
import 'package:hiddify/domain/singbox/singbox.dart';
|
||||
import 'package:hiddify/features/geo_asset/data/geo_asset_data_providers.dart';
|
||||
@@ -51,9 +49,6 @@ Dio dio(DioRef ref) {
|
||||
AppRepository appRepository(AppRepositoryRef ref) =>
|
||||
AppRepositoryImpl(ref.watch(dioProvider));
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
ClashApi clashApi(ClashApiRef ref) => ClashApi(Defaults.clashApiPort);
|
||||
|
||||
@riverpod
|
||||
Future<ConfigOptions> configOptions(ConfigOptionsRef ref) async {
|
||||
final geoAssets = await ref
|
||||
@@ -86,7 +81,6 @@ CoreFacade coreFacade(CoreFacadeRef ref) => CoreFacadeImpl(
|
||||
ref.watch(geoAssetPathResolverProvider),
|
||||
ref.watch(profilePathResolverProvider),
|
||||
ref.watch(platformServicesProvider),
|
||||
ref.watch(clashApiProvider),
|
||||
ref.read(debugModeNotifierProvider),
|
||||
() => ref.read(configOptionsProvider.future),
|
||||
);
|
||||
|
||||
@@ -2,11 +2,8 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:hiddify/data/api/clash_api.dart';
|
||||
import 'package:hiddify/data/repository/exception_handlers.dart';
|
||||
import 'package:hiddify/domain/clash/clash.dart';
|
||||
import 'package:hiddify/domain/connectivity/connection_status.dart';
|
||||
import 'package:hiddify/domain/constants.dart';
|
||||
import 'package:hiddify/domain/core_facade.dart';
|
||||
import 'package:hiddify/domain/core_service_failure.dart';
|
||||
import 'package:hiddify/domain/singbox/singbox.dart';
|
||||
@@ -24,7 +21,6 @@ class CoreFacadeImpl with ExceptionHandler, InfraLogger implements CoreFacade {
|
||||
this.geoAssetPathResolver,
|
||||
this.profilePathResolver,
|
||||
this.platformServices,
|
||||
this.clash,
|
||||
this.debug,
|
||||
this.configOptions,
|
||||
);
|
||||
@@ -34,7 +30,6 @@ class CoreFacadeImpl with ExceptionHandler, InfraLogger implements CoreFacade {
|
||||
final GeoAssetPathResolver geoAssetPathResolver;
|
||||
final ProfilePathResolver profilePathResolver;
|
||||
final PlatformServices platformServices;
|
||||
final ClashApi clash;
|
||||
final bool debug;
|
||||
final Future<ConfigOptions> Function() configOptions;
|
||||
|
||||
@@ -263,67 +258,6 @@ class CoreFacadeImpl with ExceptionHandler, InfraLogger implements CoreFacade {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<CoreServiceFailure, ClashConfig> getConfigs() {
|
||||
return exceptionHandler(
|
||||
() async => clash.getConfigs().mapLeft(CoreServiceFailure.other).run(),
|
||||
CoreServiceFailure.unexpected,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<CoreServiceFailure, Unit> patchOverrides(ClashConfig overrides) {
|
||||
return exceptionHandler(
|
||||
() async =>
|
||||
clash.patchConfigs(overrides).mapLeft(CoreServiceFailure.other).run(),
|
||||
CoreServiceFailure.unexpected,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<CoreServiceFailure, List<ClashProxy>> getProxies() {
|
||||
return exceptionHandler(
|
||||
() async => clash.getProxies().mapLeft(CoreServiceFailure.other).run(),
|
||||
CoreServiceFailure.unexpected,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<CoreServiceFailure, Unit> changeProxy(
|
||||
String selectorName,
|
||||
String proxyName,
|
||||
) {
|
||||
return exceptionHandler(
|
||||
() async => clash
|
||||
.changeProxy(selectorName, proxyName)
|
||||
.mapLeft(CoreServiceFailure.other)
|
||||
.run(),
|
||||
CoreServiceFailure.unexpected,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<Either<CoreServiceFailure, ClashTraffic>> watchTraffic() {
|
||||
return clash.watchTraffic().handleExceptions(CoreServiceFailure.unexpected);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<CoreServiceFailure, int> testDelay(
|
||||
String proxyName, {
|
||||
String testUrl = Defaults.connectionTestUrl,
|
||||
}) {
|
||||
return exceptionHandler(
|
||||
() async {
|
||||
final result = clash
|
||||
.getProxyDelay(proxyName, testUrl)
|
||||
.mapLeft(CoreServiceFailure.other)
|
||||
.run();
|
||||
return result;
|
||||
},
|
||||
CoreServiceFailure.unexpected,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<ConnectionStatus> watchConnectionStatus() =>
|
||||
singbox.watchConnectionStatus();
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
export 'clash_config.dart';
|
||||
export 'clash_enums.dart';
|
||||
export 'clash_facade.dart';
|
||||
export 'clash_log.dart';
|
||||
export 'clash_proxy.dart';
|
||||
export 'clash_traffic.dart';
|
||||
@@ -1,66 +0,0 @@
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hiddify/domain/clash/clash_enums.dart';
|
||||
|
||||
part 'clash_config.freezed.dart';
|
||||
part 'clash_config.g.dart';
|
||||
|
||||
@freezed
|
||||
class ClashConfig with _$ClashConfig {
|
||||
const ClashConfig._();
|
||||
|
||||
@JsonSerializable(includeIfNull: false, fieldRename: FieldRename.kebab)
|
||||
const factory ClashConfig({
|
||||
@JsonKey(name: 'port') int? httpPort,
|
||||
int? socksPort,
|
||||
int? redirPort,
|
||||
int? tproxyPort,
|
||||
int? mixedPort,
|
||||
List<String>? authentication,
|
||||
bool? allowLan,
|
||||
String? bindAddress,
|
||||
TunnelMode? mode,
|
||||
LogLevel? logLevel,
|
||||
bool? ipv6,
|
||||
}) = _ClashConfig;
|
||||
|
||||
ClashConfig patch(ClashConfigPatch patch) {
|
||||
return copyWith(
|
||||
httpPort: (patch.httpPort ?? optionOf(httpPort)).toNullable(),
|
||||
socksPort: (patch.socksPort ?? optionOf(socksPort)).toNullable(),
|
||||
redirPort: (patch.redirPort ?? optionOf(redirPort)).toNullable(),
|
||||
tproxyPort: (patch.tproxyPort ?? optionOf(tproxyPort)).toNullable(),
|
||||
mixedPort: (patch.mixedPort ?? optionOf(mixedPort)).toNullable(),
|
||||
authentication:
|
||||
(patch.authentication ?? optionOf(authentication)).toNullable(),
|
||||
allowLan: (patch.allowLan ?? optionOf(allowLan)).toNullable(),
|
||||
bindAddress: (patch.bindAddress ?? optionOf(bindAddress)).toNullable(),
|
||||
mode: (patch.mode ?? optionOf(mode)).toNullable(),
|
||||
logLevel: (patch.logLevel ?? optionOf(logLevel)).toNullable(),
|
||||
ipv6: (patch.ipv6 ?? optionOf(ipv6)).toNullable(),
|
||||
);
|
||||
}
|
||||
|
||||
factory ClashConfig.fromJson(Map<String, dynamic> json) =>
|
||||
_$ClashConfigFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ClashConfigPatch with _$ClashConfigPatch {
|
||||
const ClashConfigPatch._();
|
||||
|
||||
@JsonSerializable(includeIfNull: false)
|
||||
const factory ClashConfigPatch({
|
||||
Option<int>? httpPort,
|
||||
Option<int>? socksPort,
|
||||
Option<int>? redirPort,
|
||||
Option<int>? tproxyPort,
|
||||
Option<int>? mixedPort,
|
||||
Option<List<String>>? authentication,
|
||||
Option<bool>? allowLan,
|
||||
Option<String>? bindAddress,
|
||||
Option<TunnelMode>? mode,
|
||||
Option<LogLevel>? logLevel,
|
||||
Option<bool>? ipv6,
|
||||
}) = _ClashConfigPatch;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
enum TunnelMode {
|
||||
rule,
|
||||
global,
|
||||
direct;
|
||||
}
|
||||
|
||||
enum LogLevel {
|
||||
info,
|
||||
warning,
|
||||
error,
|
||||
debug,
|
||||
silent;
|
||||
|
||||
Color get color => switch (this) {
|
||||
info => Colors.lightGreen,
|
||||
warning => Colors.orangeAccent,
|
||||
error => Colors.redAccent,
|
||||
debug => Colors.lightBlue,
|
||||
_ => Colors.white,
|
||||
};
|
||||
}
|
||||
|
||||
enum ProxyType {
|
||||
direct("Direct"),
|
||||
reject("Reject"),
|
||||
compatible("Compatible"),
|
||||
pass("Pass"),
|
||||
shadowSocks("ShadowSocks"),
|
||||
shadowSocksR("ShadowSocksR"),
|
||||
snell("Snell"),
|
||||
socks5("Socks5"),
|
||||
http("Http"),
|
||||
vmess("Vmess"),
|
||||
vless("Vless"),
|
||||
trojan("Trojan"),
|
||||
hysteria("Hysteria"),
|
||||
wireGuard("WireGuard"),
|
||||
tuic("Tuic"),
|
||||
ssh("SSH"),
|
||||
relay("Relay"),
|
||||
selector("Selector"),
|
||||
fallback("Fallback"),
|
||||
urlTest("URLTest", "urltest"),
|
||||
loadBalance("LoadBalance"),
|
||||
unknown("Unknown");
|
||||
|
||||
const ProxyType(this.label, [this._key]);
|
||||
|
||||
final String? _key;
|
||||
final String label;
|
||||
|
||||
String get key => _key ?? name;
|
||||
|
||||
static List<ProxyType> groupValues = [
|
||||
selector,
|
||||
fallback,
|
||||
urlTest,
|
||||
loadBalance,
|
||||
];
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:hiddify/domain/clash/clash.dart';
|
||||
import 'package:hiddify/domain/constants.dart';
|
||||
import 'package:hiddify/domain/core_service_failure.dart';
|
||||
|
||||
abstract class ClashFacade {
|
||||
TaskEither<CoreServiceFailure, ClashConfig> getConfigs();
|
||||
|
||||
TaskEither<CoreServiceFailure, Unit> patchOverrides(ClashConfig overrides);
|
||||
|
||||
TaskEither<CoreServiceFailure, List<ClashProxy>> getProxies();
|
||||
|
||||
TaskEither<CoreServiceFailure, Unit> changeProxy(
|
||||
String selectorName,
|
||||
String proxyName,
|
||||
);
|
||||
|
||||
TaskEither<CoreServiceFailure, int> testDelay(
|
||||
String proxyName, {
|
||||
String testUrl = Defaults.connectionTestUrl,
|
||||
});
|
||||
|
||||
Stream<Either<CoreServiceFailure, ClashTraffic>> watchTraffic();
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hiddify/domain/clash/clash_enums.dart';
|
||||
|
||||
part 'clash_log.freezed.dart';
|
||||
part 'clash_log.g.dart';
|
||||
|
||||
@freezed
|
||||
class ClashLog with _$ClashLog {
|
||||
const ClashLog._();
|
||||
|
||||
const factory ClashLog({
|
||||
@JsonKey(name: 'type') required LogLevel level,
|
||||
@JsonKey(name: 'payload') required String message,
|
||||
@JsonKey(defaultValue: DateTime.now) required DateTime time,
|
||||
}) = _ClashLog;
|
||||
|
||||
String get timeStamp =>
|
||||
"${time.month}-${time.day} ${time.hour}:${time.minute}:${time.second}";
|
||||
|
||||
factory ClashLog.fromJson(Map<String, dynamic> json) =>
|
||||
_$ClashLogFromJson(json);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
import 'package:dartx/dartx.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hiddify/domain/clash/clash_enums.dart';
|
||||
|
||||
part 'clash_proxy.freezed.dart';
|
||||
part 'clash_proxy.g.dart';
|
||||
|
||||
// TODO: test and improve
|
||||
@Freezed(fromJson: true)
|
||||
sealed class ClashProxy with _$ClashProxy {
|
||||
const ClashProxy._();
|
||||
|
||||
const factory ClashProxy.group({
|
||||
required String name,
|
||||
@JsonKey(fromJson: _typeFromJson) required ProxyType type,
|
||||
required List<String> all,
|
||||
required String now,
|
||||
@Default(false) bool udp,
|
||||
List<ClashHistory>? history,
|
||||
@JsonKey(includeFromJson: false, includeToJson: false) int? delay,
|
||||
}) = ClashProxyGroup;
|
||||
|
||||
const factory ClashProxy.item({
|
||||
required String name,
|
||||
@JsonKey(fromJson: _typeFromJson) required ProxyType type,
|
||||
@Default(false) bool udp,
|
||||
List<ClashHistory>? history,
|
||||
@JsonKey(includeFromJson: false, includeToJson: false) int? delay,
|
||||
}) = ClashProxyItem;
|
||||
|
||||
factory ClashProxy.fromJson(Map<String, dynamic> json) {
|
||||
final isGroup = json.containsKey('all') ||
|
||||
json.containsKey('now') ||
|
||||
ProxyType.groupValues.any(
|
||||
(e) => e.label == json.getOrElse('type', () => null),
|
||||
);
|
||||
if (isGroup) {
|
||||
return ClashProxyGroup.fromJson(json);
|
||||
} else {
|
||||
return ClashProxyItem.fromJson(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProxyType _typeFromJson(dynamic type) =>
|
||||
ProxyType.values
|
||||
.firstOrNullWhere((e) => e.key == (type as String?)?.toLowerCase()) ??
|
||||
ProxyType.unknown;
|
||||
|
||||
@freezed
|
||||
class ClashHistory with _$ClashHistory {
|
||||
const ClashHistory._();
|
||||
|
||||
const factory ClashHistory({
|
||||
required String time,
|
||||
required int delay,
|
||||
}) = _ClashHistory;
|
||||
|
||||
factory ClashHistory.fromJson(Map<String, dynamic> json) =>
|
||||
_$ClashHistoryFromJson(json);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'clash_traffic.freezed.dart';
|
||||
part 'clash_traffic.g.dart';
|
||||
|
||||
@freezed
|
||||
class ClashTraffic with _$ClashTraffic {
|
||||
const ClashTraffic._();
|
||||
|
||||
const factory ClashTraffic({
|
||||
@JsonKey(name: 'up') required int upload,
|
||||
@JsonKey(name: 'down') required int download,
|
||||
}) = _ClashTraffic;
|
||||
|
||||
factory ClashTraffic.fromJson(Map<String, dynamic> json) =>
|
||||
_$ClashTrafficFromJson(json);
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:hiddify/domain/clash/clash.dart';
|
||||
import 'package:hiddify/domain/singbox/singbox.dart';
|
||||
|
||||
abstract interface class CoreFacade implements SingboxFacade, ClashFacade {}
|
||||
abstract interface class CoreFacade implements SingboxFacade {}
|
||||
|
||||
Reference in New Issue
Block a user