Implement online-status keep-alive

This commit is contained in:
Nutcake 2023-05-06 18:34:14 +02:00
parent ab21717829
commit 59cd6bc07f
5 changed files with 32 additions and 18 deletions

View file

@ -29,6 +29,11 @@ class UserApi {
return UserStatus.fromMap(data);
}
static Future<void> notifyOnlineInstance(ApiClient client) async {
final response = await client.post("/stats/instanceOnline/${client.authenticationData.secretMachineId.hashCode}");
ApiClient.checkResponse(response);
}
static Future<void> setStatus(ApiClient client, {required UserStatus status}) async {
final pkginfo = await PackageInfo.fromPlatform();
status = status.copyWith(

View file

@ -1,8 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'package:contacts_plus_plus/clients/messaging_client.dart';
import 'package:contacts_plus_plus/clients/notification_client.dart';
import 'package:contacts_plus_plus/clients/settings_client.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_phoenix/flutter_phoenix.dart';

View file

@ -1,9 +1,9 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:contacts_plus_plus/apis/friend_api.dart';
import 'package:contacts_plus_plus/apis/message_api.dart';
import 'package:contacts_plus_plus/apis/user_api.dart';
import 'package:contacts_plus_plus/clients/notification_client.dart';
import 'package:contacts_plus_plus/models/authentication_data.dart';
import 'package:contacts_plus_plus/models/friend.dart';
@ -57,6 +57,7 @@ class MessagingClient extends ChangeNotifier {
final Workmanager _workmanager = Workmanager();
final NotificationClient _notificationClient;
Friend? selectedFriend;
Timer? _notifyOnlineTimer;
Timer? _autoRefresh;
Timer? _refreshTimeout;
int _attempts = 0;
@ -66,16 +67,24 @@ class MessagingClient extends ChangeNotifier {
String? get initStatus => _initStatus;
bool get websocketConnected => _wsChannel != null;
MessagingClient({required ApiClient apiClient, required NotificationClient notificationClient})
: _apiClient = apiClient, _notificationClient = notificationClient {
refreshFriendsListWithErrorHandler();
start();
startWebsocket();
_notifyOnlineTimer = Timer.periodic(const Duration(seconds: 60), (timer) async {
// We should probably let the MessagingClient handle the entire state of USerStatus instead of mirroring like this
// but I don't feel like implementing that right now.
UserApi.setStatus(apiClient, status: await UserApi.getUserStatus(apiClient, userId: apiClient.userId));
});
}
@override
void dispose() {
_autoRefresh?.cancel();
_refreshTimeout?.cancel();
_notifyOnlineTimer?.cancel();
_wsChannel?.close();
super.dispose();
}
@ -116,16 +125,21 @@ class MessagingClient extends ChangeNotifier {
_friendsCache[friend.id] = friend;
}
_sortedFriendsCache.clear();
_sortedFriendsCache.addAll(friends.sorted((a, b) {
_sortedFriendsCache.addAll(friends);
_sortFriendsCache();
_initStatus = "";
notifyListeners();
}
void _sortFriendsCache() {
_sortedFriendsCache.sort((a, b) {
var aVal = friendHasUnreads(a) ? -3 : 0;
var bVal = friendHasUnreads(b) ? -3 : 0;
aVal -= a.userStatus.lastStatusChange.compareTo(b.userStatus.lastStatusChange);
aVal += a.userStatus.onlineStatus.compareTo(b.userStatus.onlineStatus) * 2;
return aVal.compareTo(bVal);
}));
_initStatus = "";
notifyListeners();
});
}
void updateAllUnreads(List<Message> messages) {
@ -151,6 +165,7 @@ class MessagingClient extends ChangeNotifier {
messages.add(message);
}
messages.sort();
_sortFriendsCache();
_notificationClient.showUnreadMessagesNotification(messages.reversed);
notifyListeners();
}
@ -205,11 +220,12 @@ class MessagingClient extends ChangeNotifier {
}
void _onDisconnected(error) async {
_wsChannel = null;
_logger.warning("Neos Hub connection died with error '$error', reconnecting...");
await start();
await startWebsocket();
}
Future<void> start() async {
Future<void> startWebsocket() async {
if (!_apiClient.isAuthenticated) {
_logger.info("Tried to connect to Neos Hub without authentication, this is probably fine for now.");
return;
@ -353,8 +369,3 @@ class MessagingClient extends ChangeNotifier {
_sendData(data);
}
}
class MessagesProvider extends ChangeNotifier {
}

View file

@ -72,7 +72,9 @@ class _ContactsPlusPlusState extends State<ContactsPlusPlus> {
ChangeNotifierProvider( // This doesn't need to be a proxy provider since the arguments should never change during it's lifetime.
create: (context) =>
MessagingClient(
apiClient: clientHolder.apiClient, notificationClient: clientHolder.notificationClient),
apiClient: clientHolder.apiClient,
notificationClient: clientHolder.notificationClient,
),
child: const FriendsList(),
) :
LoginScreen(

View file

@ -4,7 +4,6 @@ import 'package:contacts_plus_plus/apis/user_api.dart';
import 'package:contacts_plus_plus/client_holder.dart';
import 'package:contacts_plus_plus/clients/messaging_client.dart';
import 'package:contacts_plus_plus/models/friend.dart';
import 'package:contacts_plus_plus/models/message.dart';
import 'package:contacts_plus_plus/models/personal_profile.dart';
import 'package:contacts_plus_plus/widgets/default_error_widget.dart';
import 'package:contacts_plus_plus/widgets/expanding_input_fab.dart';