parent
023ed9edc1
commit
fcd34d4fb1
9 changed files with 41 additions and 16 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -36,7 +36,6 @@ class AuthenticationData {
|
|||
|
||||
Map<String, String> get authorizationHeader => {
|
||||
"Authorization": "res $userId:$token",
|
||||
"UID": uid,
|
||||
};
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -926,7 +926,7 @@ packages:
|
|||
source: hosted
|
||||
version: "3.0.7"
|
||||
vector_math:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue