implement refreshing chat screen(This foundation really kills me)

main
htylight 2023-09-20 20:21:27 +08:00
parent dbfb24defc
commit e7d9f02137
2 changed files with 56 additions and 17 deletions

View File

@ -30,7 +30,7 @@ class WebSocketManager extends ChangeNotifier {
Timer? heartBeatTimer;
Timer? serverTimer;
Timer? reconnectTimer;
int reconnectCount = 10;
int reconnectCount = 5;
int reconnectTimes = 0;
Duration heartBeatTimeout = const Duration(seconds: 4);
Duration reconnectTimeout = const Duration(seconds: 3);
@ -38,6 +38,10 @@ class WebSocketManager extends ChangeNotifier {
void connect(String userId, bool isReconnect) {
id = userId;
wsUrl = Uri.parse('ws://10.0.2.2:8000/ws/$id?is_reconnect=$isReconnect');
if (isReconnect) {
socketStatus = SocketStatus.reconnecting;
notifyListeners();
}
// This doesn't blcok the programe whethe it connect the server or not
// So heartBeat will be executre straightly
channel = WebSocketChannel.connect(wsUrl);
@ -97,7 +101,7 @@ class WebSocketManager extends ChangeNotifier {
// for example server is restarting
void onDone() {
print('websocket disconnected <$channel>');
print('22222222222222222222');
if (socketStatus == SocketStatus.closed) {
// Client close the connection
return;
@ -112,6 +116,11 @@ class WebSocketManager extends ChangeNotifier {
}
if (reconnectTimes >= reconnectCount) {
socketStatus = SocketStatus.error;
reconnectTimes = 0;
} else {
socketStatus = SocketStatus.reconnecting;
print('3333333333333333333');
notifyListeners();
}
}
@ -121,12 +130,12 @@ class WebSocketManager extends ChangeNotifier {
// print(st);
if (reconnectTimes >= reconnectCount) {
socketStatus = SocketStatus.error;
notifyListeners();
channel.sink.close();
if (heartBeatTimer != null) {
heartBeatTimer!.cancel();
heartBeatTimer = null;
}
channel.sink.close();
notifyListeners();
} else {
print('${reconnectTimes}th reconnection');
reconnect();

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
@ -150,11 +152,30 @@ class _ChatScreenState extends State<ChatScreen> with GetItStateMixin {
Expanded(
child: RefreshIndicator(
onRefresh: () async {
String userId = getIt.get<UserAccount>().id;
if (socketStatus == SocketStatus.error) {
getIt.get<WebSocketManager>().connect(userId, false);
if (socketStatus == SocketStatus.reconnecting) {
return;
}
String userId = getIt.get<UserAccount>().id;
if (socketStatus != SocketStatus.connected) {
getIt.get<WebSocketManager>().connect(userId, true);
await Future.doWhile(() async {
SocketStatus socketStatus =
get<WebSocketManager>().socketStatus;
await Future.delayed(
const Duration(milliseconds: 500),
);
return socketStatus == SocketStatus.reconnecting;
});
SocketStatus socketStatus =
get<WebSocketManager>().socketStatus;
if (socketStatus == SocketStatus.connected) {
await _getUnreceivedMsg(userId);
}
}
await _getUnreceivedMsg(userId);
},
child: ValueListenableBuilder(
valueListenable:
@ -171,15 +192,24 @@ class _ChatScreenState extends State<ChatScreen> with GetItStateMixin {
);
if (openedChat.isEmpty) {
return const Center(
child: Text(
'没有最新消息',
style: TextStyle(
fontSize: 18,
letterSpacing: 5.0,
),
),
);
return LayoutBuilder(builder: (context, constrains) {
return ListView(
itemExtent: constrains.maxHeight / 3,
children: const [
SizedBox(),
Center(
child: Text(
'没有最新消息',
style: TextStyle(
fontSize: 18,
letterSpacing: 4.0,
),
),
),
SizedBox(),
],
);
});
} else {
return ListView.builder(
physics: const BouncingScrollPhysics(