Fix online status not getting set correctly

Closes #6
This commit is contained in:
Nutcake 2023-10-12 18:01:15 +02:00
parent 023ed9edc1
commit fcd34d4fb1
9 changed files with 41 additions and 16 deletions

View file

@ -31,6 +31,13 @@ class RecordApi {
return body.map((e) => Record.fromMap(e)).toList();
}
static Future<List<Record>> getGroupRecordsAt(ApiClient client, {required String path, required String groupId}) async {
final response = await client.get("/users/$groupId/records?path=$path");
client.checkResponse(response);
final body = jsonDecode(response.body) as List;
return body.map((e) => Record.fromMap(e)).toList();
}
static Future<void> deleteRecord(ApiClient client, {required String recordId}) async {
final response = await client.delete("/users/${client.userId}/records/$recordId");
client.checkResponse(response);

View file

@ -24,6 +24,7 @@ import 'package:package_info_plus/package_info_plus.dart';
class MessagingClient extends ChangeNotifier {
static const Duration _autoRefreshDuration = Duration(seconds: 10);
static const Duration _unreadSafeguardDuration = Duration(seconds: 120);
static const Duration _statusHeartbeatDuration = Duration(seconds: 150);
static const String _messageBoxKey = "message-box";
static const String _lastUpdateKey = "__last-update-time";
@ -38,7 +39,7 @@ class MessagingClient extends ChangeNotifier {
final Set<String> _knownSessionKeys = {};
Friend? selectedFriend;
Timer? _notifyOnlineTimer;
Timer? _statusHeartbeat;
Timer? _autoRefresh;
Timer? _unreadSafeguard;
String? _initStatus;
@ -62,7 +63,7 @@ class MessagingClient extends ChangeNotifier {
void dispose() {
debugPrint("mClient disposed: $hashCode");
_autoRefresh?.cancel();
_notifyOnlineTimer?.cancel();
_statusHeartbeat?.cancel();
_unreadSafeguard?.cancel();
_hubManager.dispose();
super.dispose();
@ -117,6 +118,7 @@ class MessagingClient extends ChangeNotifier {
}
void markMessagesRead(MarkReadBatch batch) {
if (_userStatus.onlineStatus == OnlineStatus.invisible || _userStatus.onlineStatus == OnlineStatus.offline) return;
final msgBody = batch.toMap();
_hubManager.send("MarkMessagesRead", arguments: [msgBody]);
clearUnreadsForUser(batch.senderId);
@ -124,11 +126,14 @@ class MessagingClient extends ChangeNotifier {
Future<void> setOnlineStatus(OnlineStatus status) async {
final pkginfo = await PackageInfo.fromPlatform();
final now = DateTime.now();
_userStatus = _userStatus.copyWith(
userId: _apiClient.userId,
appVersion: "${pkginfo.version} of ${pkginfo.appName}",
lastStatusChange: DateTime.now(),
lastPresenceTimestamp: now,
lastStatusChange: now,
onlineStatus: status,
isPresent: true,
);
_hubManager.send(
@ -258,7 +263,6 @@ class MessagingClient extends ChangeNotifier {
_hubManager.setHandler(EventTarget.removeSession, _onRemoveSession);
await _hubManager.start();
await setOnlineStatus(OnlineStatus.online);
_hubManager.send(
"InitializeStatus",
responseHandler: (Map data) async {
@ -272,6 +276,10 @@ class MessagingClient extends ChangeNotifier {
await _refreshUnreads();
_unreadSafeguard = Timer.periodic(_unreadSafeguardDuration, (timer) => _refreshUnreads());
_hubManager.send("RequestStatus", arguments: [null, false]);
await setOnlineStatus(OnlineStatus.online);
_statusHeartbeat = Timer.periodic(_statusHeartbeatDuration, (timer) {
setOnlineStatus(_userStatus.onlineStatus);
});
},
);
}

View file

@ -107,10 +107,10 @@ class HubManager {
void _handleInvocation(body) async {
final target = EventTarget.parse(body["target"]);
final args = body["arguments"] ?? [];
if (kDebugMode) _logger.info("Invocation target: ${target.name}, args:\n$args");
final handler = _handlers[target];
if (handler == null) {
_logger.info("Unhandled event received");
_logger.warning("Unhandled event received");
if (kDebugMode) _logger.warning("Invocation target: ${target.name}, args:\n$args");
return;
}
handler(args);

View file

@ -36,7 +36,6 @@ class AuthenticationData {
Map<String, String> get authorizationHeader => {
"Authorization": "res $userId:$token",
"UID": uid,
};
Map<String, dynamic> toMap() {

View file

@ -1,3 +1,5 @@
import 'package:intl/intl.dart';
import 'package:recon/config.dart';
import 'package:recon/crypto_helper.dart';
import 'package:recon/models/session.dart';
import 'package:recon/models/session_metadata.dart';
@ -10,7 +12,7 @@ enum UserSessionType
graphicalClient,
chatClient,
headless,
not;
bot;
factory UserSessionType.fromString(String? text) {
return UserSessionType.values.firstWhere((element) => element.name.toLowerCase() == text?.toLowerCase(),
@ -20,6 +22,7 @@ enum UserSessionType
}
class UserStatus {
final String userId;
final OnlineStatus onlineStatus;
final DateTime lastStatusChange;
final DateTime lastPresenceTimestamp;
@ -36,6 +39,7 @@ class UserStatus {
final List<Session> decodedSessions;
const UserStatus({
required this.userId,
required this.onlineStatus,
required this.lastStatusChange,
required this.lastPresenceTimestamp,
@ -54,15 +58,18 @@ class UserStatus {
factory UserStatus.initial() =>
UserStatus.empty().copyWith(
compatibilityHash: Config.latestCompatHash,
onlineStatus: OnlineStatus.online,
hashSalt: CryptoHelper.cryptoToken(),
outputDevice: "Screen",
outputDevice: "Unknown",
userSessionId: const Uuid().v4().toString(),
sessionType: UserSessionType.chatClient,
isPresent: true,
);
factory UserStatus.empty() =>
UserStatus(
userId: "",
onlineStatus: OnlineStatus.offline,
lastStatusChange: DateTime.now(),
lastPresenceTimestamp: DateTime.now(),
@ -82,6 +89,7 @@ class UserStatus {
final statusString = map["onlineStatus"].toString();
final status = OnlineStatus.fromString(statusString);
return UserStatus(
userId: map["userId"] ?? "",
onlineStatus: status,
lastStatusChange: DateTime.tryParse(map["lastStatusChange"] ?? "") ?? DateTime.now(),
lastPresenceTimestamp: DateTime.tryParse(map["lastPresenceTimestamp"] ?? "") ?? DateTime.now(),
@ -92,7 +100,7 @@ class UserStatus {
appVersion: map["appVersion"] ?? "",
outputDevice: map["outputDevice"] ?? "Unknown",
isMobile: map["isMobile"] ?? false,
compatibilityHash: map["compatabilityHash"] ?? "",
compatibilityHash: map["compatibilityHash"] ?? "",
hashSalt: map["hashSalt"] ?? "",
sessionType: UserSessionType.fromString(map["sessionType"])
);
@ -100,6 +108,7 @@ class UserStatus {
Map toMap({bool shallow = false}) {
return {
"userId": userId,
"onlineStatus": onlineStatus.index,
"lastStatusChange": lastStatusChange.toIso8601String(),
"isPresent": isPresent,
@ -117,10 +126,12 @@ class UserStatus {
"outputDevice": outputDevice,
"isMobile": isMobile,
"compatibilityHash": compatibilityHash,
"sessionType": toBeginningOfSentenceCase(sessionType.name)
};
}
UserStatus copyWith({
String? userId,
OnlineStatus? onlineStatus,
DateTime? lastStatusChange,
DateTime? lastPresenceTimestamp,
@ -137,6 +148,7 @@ class UserStatus {
List<Session>? decodedSessions,
}) =>
UserStatus(
userId: userId ?? this.userId,
onlineStatus: onlineStatus ?? this.onlineStatus,
lastStatusChange: lastStatusChange ?? this.lastStatusChange,
lastPresenceTimestamp: lastPresenceTimestamp ?? this.lastPresenceTimestamp,

View file

@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:recon/client_holder.dart';
import 'package:recon/clients/messaging_client.dart';
import 'package:recon/models/users/online_status.dart';
@ -52,7 +53,7 @@ class _FriendsListAppBarState extends State<FriendsListAppBar> with AutomaticKee
}
},
itemBuilder: (BuildContext context) => OnlineStatus.values
.where((element) => element == OnlineStatus.online || element == OnlineStatus.invisible)
.where((element) => element == OnlineStatus.online || element == OnlineStatus.offline).sorted((a, b) => b.index.compareTo(a.index),)
.map(
(item) => PopupMenuItem<OnlineStatus>(
value: item,

View file

@ -5,7 +5,6 @@ import 'package:recon/auxiliary.dart';
import 'package:recon/clients/inventory_client.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path/path.dart';
import 'package:provider/provider.dart';

View file

@ -926,7 +926,7 @@ packages:
source: hosted
version: "3.0.7"
vector_math:
dependency: "direct main"
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"

View file

@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 0.9.0+1
version: 0.9.1+1
environment:
sdk: '>=3.0.1'
@ -63,7 +63,6 @@ dependencies:
permission_handler: ^10.2.0
flutter_downloader: ^1.10.4
flutter_cube: ^0.1.1
vector_math: ^2.1.4
dev_dependencies:
flutter_test: