переподключение, рабочий логаут
This commit is contained in:
@@ -661,6 +661,18 @@ extension ApiServiceConnection on ApiService {
|
||||
|
||||
_pingTimer?.cancel();
|
||||
_reconnectTimer?.cancel();
|
||||
_streamSubscription?.cancel();
|
||||
|
||||
if (_channel != null) {
|
||||
print("Закрываем старое WebSocket соединение перед переподключением...");
|
||||
try {
|
||||
_channel!.sink.close(status.goingAway);
|
||||
} catch (e) {
|
||||
print("Ошибка при закрытии старого соединения: $e");
|
||||
}
|
||||
_channel = null;
|
||||
}
|
||||
|
||||
_isSessionOnline = false;
|
||||
_isSessionReady = false;
|
||||
_handshakeSent = false;
|
||||
@@ -730,10 +742,17 @@ extension ApiServiceConnection on ApiService {
|
||||
try {
|
||||
_pingTimer?.cancel();
|
||||
_reconnectTimer?.cancel();
|
||||
|
||||
_streamSubscription?.cancel();
|
||||
_streamSubscription = null;
|
||||
|
||||
if (_channel != null) {
|
||||
_channel!.sink.close();
|
||||
print("🔄 Закрываем старое WebSocket соединение...");
|
||||
try {
|
||||
_channel!.sink.close(status.goingAway);
|
||||
} catch (e) {
|
||||
print("Ошибка при закрытии старого соединения: $e");
|
||||
}
|
||||
_channel = null;
|
||||
}
|
||||
|
||||
@@ -752,23 +771,23 @@ extension ApiServiceConnection on ApiService {
|
||||
_lastChatsAt = null;
|
||||
|
||||
print(
|
||||
" Кэш чатов очищен: _lastChatsPayload = $_lastChatsPayload, _chatsFetchedInThisSession = $_chatsFetchedInThisSession",
|
||||
"🔄 Кэш чатов очищен: _lastChatsPayload = $_lastChatsPayload, _chatsFetchedInThisSession = $_chatsFetchedInThisSession",
|
||||
);
|
||||
|
||||
_connectionStatusController.add("disconnected");
|
||||
|
||||
await connect();
|
||||
|
||||
print(" Полное переподключение завершено");
|
||||
print("✅ Полное переподключение завершено");
|
||||
|
||||
await Future.delayed(const Duration(milliseconds: 1500));
|
||||
|
||||
if (!_reconnectionCompleteController.isClosed) {
|
||||
print(" Отправляем уведомление о завершении переподключения");
|
||||
print("✅ Отправляем уведомление о завершении переподключения");
|
||||
_reconnectionCompleteController.add(null);
|
||||
}
|
||||
} catch (e) {
|
||||
print("Ошибка полного переподключения: $e");
|
||||
print("❌ Ошибка полного переподключения: $e");
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ class _ChatsScreenState extends State<ChatsScreen>
|
||||
StreamSubscription<void>? _connectionStatusSubscription;
|
||||
StreamSubscription<String>? _connectionStateSubscription;
|
||||
bool _isAccountsExpanded = false;
|
||||
bool _isReconnecting = false;
|
||||
|
||||
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(
|
||||
leading: const Icon(Icons.settings_outlined),
|
||||
title: const Text('Настройки'),
|
||||
@@ -3892,6 +3948,39 @@ class _ChatsScreenState extends State<ChatsScreen>
|
||||
|
||||
Future<void> _logout() async {
|
||||
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) {
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(builder: (context) => const PhoneEntryScreen()),
|
||||
|
||||
Reference in New Issue
Block a user