переподключение, рабочий логаут
This commit is contained in:
@@ -661,6 +661,18 @@ extension ApiServiceConnection on ApiService {
|
|||||||
|
|
||||||
_pingTimer?.cancel();
|
_pingTimer?.cancel();
|
||||||
_reconnectTimer?.cancel();
|
_reconnectTimer?.cancel();
|
||||||
|
_streamSubscription?.cancel();
|
||||||
|
|
||||||
|
if (_channel != null) {
|
||||||
|
print("Закрываем старое WebSocket соединение перед переподключением...");
|
||||||
|
try {
|
||||||
|
_channel!.sink.close(status.goingAway);
|
||||||
|
} catch (e) {
|
||||||
|
print("Ошибка при закрытии старого соединения: $e");
|
||||||
|
}
|
||||||
|
_channel = null;
|
||||||
|
}
|
||||||
|
|
||||||
_isSessionOnline = false;
|
_isSessionOnline = false;
|
||||||
_isSessionReady = false;
|
_isSessionReady = false;
|
||||||
_handshakeSent = false;
|
_handshakeSent = false;
|
||||||
@@ -730,10 +742,17 @@ extension ApiServiceConnection on ApiService {
|
|||||||
try {
|
try {
|
||||||
_pingTimer?.cancel();
|
_pingTimer?.cancel();
|
||||||
_reconnectTimer?.cancel();
|
_reconnectTimer?.cancel();
|
||||||
|
|
||||||
_streamSubscription?.cancel();
|
_streamSubscription?.cancel();
|
||||||
|
_streamSubscription = null;
|
||||||
|
|
||||||
if (_channel != null) {
|
if (_channel != null) {
|
||||||
_channel!.sink.close();
|
print("🔄 Закрываем старое WebSocket соединение...");
|
||||||
|
try {
|
||||||
|
_channel!.sink.close(status.goingAway);
|
||||||
|
} catch (e) {
|
||||||
|
print("Ошибка при закрытии старого соединения: $e");
|
||||||
|
}
|
||||||
_channel = null;
|
_channel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -752,23 +771,23 @@ extension ApiServiceConnection on ApiService {
|
|||||||
_lastChatsAt = null;
|
_lastChatsAt = null;
|
||||||
|
|
||||||
print(
|
print(
|
||||||
" Кэш чатов очищен: _lastChatsPayload = $_lastChatsPayload, _chatsFetchedInThisSession = $_chatsFetchedInThisSession",
|
"🔄 Кэш чатов очищен: _lastChatsPayload = $_lastChatsPayload, _chatsFetchedInThisSession = $_chatsFetchedInThisSession",
|
||||||
);
|
);
|
||||||
|
|
||||||
_connectionStatusController.add("disconnected");
|
_connectionStatusController.add("disconnected");
|
||||||
|
|
||||||
await connect();
|
await connect();
|
||||||
|
|
||||||
print(" Полное переподключение завершено");
|
print("✅ Полное переподключение завершено");
|
||||||
|
|
||||||
await Future.delayed(const Duration(milliseconds: 1500));
|
await Future.delayed(const Duration(milliseconds: 1500));
|
||||||
|
|
||||||
if (!_reconnectionCompleteController.isClosed) {
|
if (!_reconnectionCompleteController.isClosed) {
|
||||||
print(" Отправляем уведомление о завершении переподключения");
|
print("✅ Отправляем уведомление о завершении переподключения");
|
||||||
_reconnectionCompleteController.add(null);
|
_reconnectionCompleteController.add(null);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("Ошибка полного переподключения: $e");
|
print("❌ Ошибка полного переподключения: $e");
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ class _ChatsScreenState extends State<ChatsScreen>
|
|||||||
StreamSubscription<void>? _connectionStatusSubscription;
|
StreamSubscription<void>? _connectionStatusSubscription;
|
||||||
StreamSubscription<String>? _connectionStateSubscription;
|
StreamSubscription<String>? _connectionStateSubscription;
|
||||||
bool _isAccountsExpanded = false;
|
bool _isAccountsExpanded = false;
|
||||||
|
bool _isReconnecting = false;
|
||||||
|
|
||||||
SharedPreferences? _prefs;
|
SharedPreferences? _prefs;
|
||||||
|
|
||||||
@@ -2328,6 +2329,61 @@ class _ChatsScreenState extends State<ChatsScreen>
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: _isReconnecting
|
||||||
|
? SizedBox(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
valueColor: AlwaysStoppedAnimation<Color>(
|
||||||
|
colors.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const Icon(Icons.refresh),
|
||||||
|
title: const Text('Переподключиться'),
|
||||||
|
enabled: !_isReconnecting,
|
||||||
|
onTap: () async {
|
||||||
|
if (_isReconnecting) return;
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_isReconnecting = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ApiService.instance.performFullReconnection();
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: const Text(
|
||||||
|
'Переподключение выполнено успешно',
|
||||||
|
),
|
||||||
|
backgroundColor: colors.primaryContainer,
|
||||||
|
duration: const Duration(seconds: 2),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('Ошибка переподключения: $e'),
|
||||||
|
backgroundColor: colors.error,
|
||||||
|
duration: const Duration(seconds: 3),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_isReconnecting = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.settings_outlined),
|
leading: const Icon(Icons.settings_outlined),
|
||||||
title: const Text('Настройки'),
|
title: const Text('Настройки'),
|
||||||
@@ -3892,6 +3948,39 @@ class _ChatsScreenState extends State<ChatsScreen>
|
|||||||
|
|
||||||
Future<void> _logout() async {
|
Future<void> _logout() async {
|
||||||
try {
|
try {
|
||||||
|
ApiService.instance.disconnect();
|
||||||
|
|
||||||
|
final accountManager = AccountManager();
|
||||||
|
await accountManager.initialize();
|
||||||
|
final currentAccount = accountManager.currentAccount;
|
||||||
|
|
||||||
|
if (currentAccount != null) {
|
||||||
|
try {
|
||||||
|
if (accountManager.accounts.length > 1) {
|
||||||
|
await accountManager.removeAccount(currentAccount.id);
|
||||||
|
} else {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.remove('authToken');
|
||||||
|
await prefs.remove('userId');
|
||||||
|
await prefs.remove('multi_accounts');
|
||||||
|
await prefs.remove('current_account_id');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print('Ошибка при удалении аккаунта: $e');
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.remove('authToken');
|
||||||
|
await prefs.remove('userId');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.remove('authToken');
|
||||||
|
await prefs.remove('userId');
|
||||||
|
}
|
||||||
|
|
||||||
|
await ApiService.instance.logout();
|
||||||
|
|
||||||
|
ApiService.instance.clearAllCaches();
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
Navigator.of(context).pushAndRemoveUntil(
|
Navigator.of(context).pushAndRemoveUntil(
|
||||||
MaterialPageRoute(builder: (context) => const PhoneEntryScreen()),
|
MaterialPageRoute(builder: (context) => const PhoneEntryScreen()),
|
||||||
|
|||||||
Reference in New Issue
Block a user