Skip to content

Commit 8ae33d1

Browse files
committed
feat: progress
1 parent 54b43b2 commit 8ae33d1

1 file changed

Lines changed: 51 additions & 15 deletions

File tree

‎lib/src/presentation/cubit/home_cubit.dart‎

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import 'package:freezed_annotation/freezed_annotation.dart';
44
import 'package:hydrated_bloc/hydrated_bloc.dart';
55
import 'package:injectable/injectable.dart';
66
import 'package:vpnapp/core/models/v2ray_server.dart';
7+
import 'package:vpnapp/core/network/network_result.dart';
78
import 'package:vpnapp/core/utils/v2ray_service.dart';
89
import 'package:vpnapp/src/data/mappers/ipinfo_mapper.dart';
910
import 'package:vpnapp/src/data/models/ipinfo_model.dart';
1011
import 'package:vpnapp/src/domain/entities/ipinfo_entity.dart';
1112
import 'package:vpnapp/src/domain/use_cases/get_remote_ipinfo_use_case.dart';
13+
import 'package:vpnapp/src/domain/use_cases/get_remote_remnawave_vless_use_case.dart';
1214

1315
part 'home_state.dart';
1416

@@ -18,23 +20,30 @@ part 'home_cubit.freezed.dart';
1820
class HomeCubit extends HydratedCubit<HomeState> {
1921
final V2RayService _service;
2022
final GetRemoteIpinfoUseCase _getRemoteIpinfoUseCase;
23+
final GetRemoteRemnawaveVlessUseCase _getRemoteRemnawaveVlessUseCase;
2124
StreamSubscription? _statusSub;
2225

23-
HomeCubit(this._service, this._getRemoteIpinfoUseCase)
24-
: super(const HomeState()) {
26+
HomeCubit(
27+
this._service,
28+
this._getRemoteIpinfoUseCase,
29+
this._getRemoteRemnawaveVlessUseCase,
30+
) : super(const HomeState()) {
2531
_init();
2632
}
2733

2834
void _init() async {
2935
await _service.init();
3036

37+
// Синхронизируем state с реальным состоянием сервиса
3138
final realStatus = _service.status;
3239
emit(state.copyWith(connectionStatus: realStatus));
3340

41+
// Если уже подключены — сразу запрашиваем IP инфо
3442
if (realStatus == VPNConnectionStatus.connected) {
3543
_fetchIpInfo();
3644
}
3745

46+
// Подписываемся на изменения статуса подключения
3847
_statusSub = _service.statusStream.listen((status) {
3948
emit(state.copyWith(connectionStatus: status));
4049

@@ -48,21 +57,14 @@ class HomeCubit extends HydratedCubit<HomeState> {
4857
});
4958

5059
if (state.servers.isEmpty) {
51-
_loadServers();
60+
// первый запуск
61+
emit(state.copyWith(servers: []));
5262
}
5363
}
5464

55-
void _loadServers() {
56-
final rawLinks = [];
57-
58-
final servers = rawLinks
59-
.map((link) => V2RayServer.fromAnyLink(link))
60-
.toList();
61-
emit(state.copyWith(servers: servers));
62-
}
63-
64-
void add(String link) {
65+
void add(String link) async {
6566
try {
67+
// Пытаемся распарсить как одиночную V2Ray ссылку (vmess/vless)
6668
final newServer = V2RayServer.fromAnyLink(link);
6769
final updatedServers = [...state.servers, newServer];
6870
emit(
@@ -72,19 +74,49 @@ class HomeCubit extends HydratedCubit<HomeState> {
7274
),
7375
);
7476
} catch (e) {
75-
rethrow;
77+
// Если это не ссылка — возможно это подписка (base64 список) Remnawave
78+
final resp = await _getRemoteRemnawaveVlessUseCase(params: link);
79+
if (resp is Success) {
80+
final List<V2RayServer> parsedServers = [];
81+
82+
// Пробегаемся по всем строкам из подписки
83+
for (var item in resp.data ?? []) {
84+
try {
85+
final server = V2RayServer.fromAnyLink(item);
86+
parsedServers.add(server);
87+
} catch (_) {
88+
// Игнорируем мусор
89+
}
90+
}
91+
// Если вообще ничего не распарсилось просто выходим
92+
if (parsedServers.isEmpty) {
93+
return;
94+
}
95+
96+
// Добавляем все новые сервера к текущим
97+
final updatedServers = [...state.servers, ...parsedServers];
98+
emit(
99+
state.copyWith(
100+
servers: updatedServers,
101+
selectedServer: state.selectedServer ?? parsedServers.first,
102+
),
103+
);
104+
}
76105
}
77106
}
78107

79108
Future<void> selectServer(V2RayServer server) async {
109+
// Если этот сервер уже выбран ничего не делаем
80110
if (state.selectedServer?.id == server.id) return;
81111

112+
// Если сейчас есть активное VPN подключение
82113
if (state.connectionStatus == VPNConnectionStatus.connected) {
83114
await _service.disconnect();
84115
emit(state.copyWith(selectedServer: server));
85116
await _service.connect(server);
86117
_fetchIpInfo();
87118
} else {
119+
// Если VPN не подключен просто меняем выбранный сервер
88120
emit(state.copyWith(selectedServer: server));
89121
}
90122
}
@@ -100,12 +132,16 @@ class HomeCubit extends HydratedCubit<HomeState> {
100132
}
101133

102134
Future<void> toggleConnection() async {
135+
// Если сервер не выбран ничего не делаем
103136
if (state.selectedServer == null) return;
104-
105137
try {
138+
// Если уже подключены — отключаемся
106139
if (state.connectionStatus == VPNConnectionStatus.connected) {
107140
await _service.disconnect();
108141
} else {
142+
// Загрузка
143+
emit(state.copyWith(connectionStatus: VPNConnectionStatus.connecting));
144+
// Если не подключены подключаемся к выбранному серверу
109145
await _service.connect(state.selectedServer!);
110146
}
111147
} catch (e) {

0 commit comments

Comments
 (0)