@@ -4,11 +4,13 @@ import 'package:freezed_annotation/freezed_annotation.dart';
44import 'package:hydrated_bloc/hydrated_bloc.dart' ;
55import 'package:injectable/injectable.dart' ;
66import 'package:vpnapp/core/models/v2ray_server.dart' ;
7+ import 'package:vpnapp/core/network/network_result.dart' ;
78import 'package:vpnapp/core/utils/v2ray_service.dart' ;
89import 'package:vpnapp/src/data/mappers/ipinfo_mapper.dart' ;
910import 'package:vpnapp/src/data/models/ipinfo_model.dart' ;
1011import 'package:vpnapp/src/domain/entities/ipinfo_entity.dart' ;
1112import '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
1315part 'home_state.dart' ;
1416
@@ -18,23 +20,30 @@ part 'home_cubit.freezed.dart';
1820class 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