11import 'package:flutter/widgets.dart' ;
2- import 'package:shared_preferences/shared_preferences.dart' ;
32import '../models/v2ray_config.dart' ;
43import '../models/subscription.dart' ;
54import '../services/v2ray_service.dart' ;
@@ -8,7 +7,7 @@ import '../services/server_service.dart';
87class V2RayProvider with ChangeNotifier , WidgetsBindingObserver {
98 final V2RayService _v2rayService = V2RayService ();
109 final ServerService _serverService = ServerService ();
11- bool status_ping_only = false ;
10+ bool statusPingOnly = false ;
1211 List <V2RayConfig > _configs = [];
1312 List <Subscription > _subscriptions = [];
1413 V2RayConfig ? _selectedConfig;
@@ -69,7 +68,7 @@ class V2RayProvider with ChangeNotifier, WidgetsBindingObserver {
6968
7069 // If we couldn't find the exact active config in our list,
7170 // try to find a matching one by address and port
72- if (_selectedConfig == null && activeConfig != null ) {
71+ if (_selectedConfig == null ) {
7372 for (var config in _configs) {
7473 if (config.address == activeConfig.address &&
7574 config.port == activeConfig.port) {
@@ -576,7 +575,12 @@ class V2RayProvider with ChangeNotifier, WidgetsBindingObserver {
576575 try {
577576 // Disconnect from current server if connected
578577 if (_v2rayService.activeConfig != null ) {
579- await _v2rayService.disconnect ();
578+ try {
579+ await _v2rayService.disconnect ();
580+ } catch (e) {
581+ debugPrint ('Error disconnecting from current server: $e ' );
582+ // Continue with connection attempt even if disconnect failed
583+ }
580584 }
581585
582586 // Try to connect with automatic retry
@@ -585,26 +589,40 @@ class V2RayProvider with ChangeNotifier, WidgetsBindingObserver {
585589
586590 for (int attempt = 1 ; attempt <= maxAttempts; attempt++ ) {
587591 try {
588- // Connect to server
589- success = await _v2rayService.connect (config, _isProxyMode);
592+ debugPrint ('Connection attempt $attempt /$maxAttempts for ${config .remark }' );
593+
594+ // Connect to server with timeout
595+ success = await _v2rayService.connect (config, _isProxyMode)
596+ .timeout (
597+ const Duration (seconds: 30 ), // Timeout for connection
598+ onTimeout: () {
599+ debugPrint ('Connection timeout for ${config .remark }' );
600+ return false ;
601+ },
602+ );
590603
591604 if (success) {
592- // Connection successful, break the retry loop
605+ debugPrint ( ' Connection successful for ${ config . remark }' );
593606 break ;
594607 } else {
595608 // Connection failed but no exception was thrown
596- lastError = 'Failed to connect to server on attempt $attempt ' ;
597- print (lastError);
609+ lastError = 'Failed to connect to ${ config . remark } on attempt $attempt ' ;
610+ debugPrint (lastError);
598611
599612 // If this is not the last attempt, wait before retrying
600613 if (attempt < maxAttempts) {
601614 await Future .delayed (Duration (seconds: retryDelaySeconds));
602615 }
603616 }
604617 } catch (e) {
605- // Exception during connection attempt
606- lastError = 'Error on connection attempt $attempt : $e ' ;
607- print (lastError);
618+ // Check if this is a timeout-related error
619+ if (e.toString ().contains ('timeout' )) {
620+ lastError = 'Connection timeout on attempt $attempt : $e ' ;
621+ debugPrint (lastError);
622+ } else {
623+ lastError = 'Error on connection attempt $attempt : $e ' ;
624+ debugPrint (lastError);
625+ }
608626
609627 // If this is not the last attempt, wait before retrying
610628 if (attempt < maxAttempts) {
@@ -614,29 +632,48 @@ class V2RayProvider with ChangeNotifier, WidgetsBindingObserver {
614632 }
615633
616634 if (success) {
617- // Wait for 3 seconds as requested
618- await Future .delayed (const Duration (seconds: 3 ));
635+ try {
636+ // Wait for connection to stabilize
637+ await Future .delayed (const Duration (seconds: 2 )); // Reduced from 3 to 2 seconds
619638
620- // Update config status
621- for (int i = 0 ; i < _configs.length; i++ ) {
622- if (_configs[i].id == config.id) {
623- _configs[i].isConnected = true ;
624- } else {
625- _configs[i].isConnected = false ;
639+ // Update config status safely
640+ for (int i = 0 ; i < _configs.length; i++ ) {
641+ if (_configs[i].id == config.id) {
642+ _configs[i].isConnected = true ;
643+ } else {
644+ _configs[i].isConnected = false ;
645+ }
626646 }
627- }
628- _selectedConfig = config;
647+ _selectedConfig = config;
629648
630- // Persist the changes
631- await _v2rayService.saveConfigs (_configs);
649+ // Persist the changes with error handling
650+ try {
651+ await _v2rayService.saveConfigs (_configs);
652+ } catch (e) {
653+ debugPrint ('Error saving configs after connection: $e ' );
654+ // Don't fail the connection for this
655+ }
632656
633- // Reset usage statistics when connecting to a new server
634- await _v2rayService.resetUsageStats ();
657+ // Reset usage statistics when connecting to a new server
658+ try {
659+ await _v2rayService.resetUsageStats ();
660+ } catch (e) {
661+ debugPrint ('Error resetting usage stats: $e ' );
662+ // Don't fail the connection for this
663+ }
664+
665+ debugPrint ('Successfully connected to ${config .remark }' );
666+ } catch (e) {
667+ debugPrint ('Error in post-connection setup: $e ' );
668+ // Connection succeeded but post-setup failed
669+ _setError ('Connected but failed to update settings: $e ' );
670+ }
635671 } else {
636- _setError ('Failed to connect after multiple attempts' );
672+ _setError ('Failed to connect to ${ config . remark } after $ maxAttempts attempts: $ lastError ' );
637673 }
638674 } catch (e) {
639- _setError ('Error in connection process: $e ' );
675+ debugPrint ('Unexpected error in connection process: $e ' );
676+ _setError ('Unexpected error connecting to ${config .remark }: $e ' );
640677 } finally {
641678 _isConnecting = false ;
642679 notifyListeners ();
@@ -649,7 +686,7 @@ class V2RayProvider with ChangeNotifier, WidgetsBindingObserver {
649686
650687 try {
651688 await _v2rayService.disconnect ();
652- status_ping_only = false ;
689+ statusPingOnly = false ;
653690 // Update config status
654691 for (int i = 0 ; i < _configs.length; i++ ) {
655692 _configs[i].isConnected = false ;
0 commit comments