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'; import 'package:recon/models/users/online_status.dart'; import 'package:uuid/uuid.dart'; enum UserSessionType { unknown, graphicalClient, chatClient, headless, bot; factory UserSessionType.fromString(String? text) { return UserSessionType.values.firstWhere((element) => element.name.toLowerCase() == text?.toLowerCase(), orElse: () => UserSessionType.unknown, ); } } class UserStatus { final String userId; final OnlineStatus onlineStatus; final DateTime lastStatusChange; final DateTime lastPresenceTimestamp; final String userSessionId; final int currentSessionIndex; final List sessions; final String appVersion; final String outputDevice; final bool isMobile; final bool isPresent; final String compatibilityHash; final String hashSalt; final UserSessionType sessionType; final List decodedSessions; const UserStatus({ required this.userId, required this.onlineStatus, required this.lastStatusChange, required this.lastPresenceTimestamp, required this.userSessionId, required this.currentSessionIndex, required this.sessions, required this.appVersion, required this.outputDevice, required this.isMobile, required this.isPresent, required this.compatibilityHash, required this.hashSalt, required this.sessionType, this.decodedSessions = const [] }); factory UserStatus.initial() => UserStatus.empty().copyWith( compatibilityHash: Config.latestCompatHash, onlineStatus: OnlineStatus.online, hashSalt: CryptoHelper.cryptoToken(), 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(), userSessionId: "", currentSessionIndex: -1, sessions: [], appVersion: "", outputDevice: "Unknown", isMobile: false, isPresent: false, compatibilityHash: "", hashSalt: "", sessionType: UserSessionType.unknown ); factory UserStatus.fromMap(Map map) { 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(), userSessionId: map["userSessionId"] ?? "", isPresent: map["isPresent"] ?? false, currentSessionIndex: map["currentSessionIndex"] ?? -1, sessions: (map["sessions"] as List? ?? []).map((e) => SessionMetadata.fromMap(e)).toList(), appVersion: map["appVersion"] ?? "", outputDevice: map["outputDevice"] ?? "Unknown", isMobile: map["isMobile"] ?? false, compatibilityHash: map["compatibilityHash"] ?? "", hashSalt: map["hashSalt"] ?? "", sessionType: UserSessionType.fromString(map["sessionType"]) ); } Map toMap({bool shallow = false}) { return { "userId": userId, "onlineStatus": onlineStatus.index, "lastStatusChange": lastStatusChange.toIso8601String(), "isPresent": isPresent, "lastPresenceTimestamp": lastPresenceTimestamp.toIso8601String(), "userSessionId": userSessionId, "currentSessionIndex": currentSessionIndex, "sessions": shallow ? [] : sessions .map( (e) => e.toMap(), ) .toList(), "appVersion": appVersion, "outputDevice": outputDevice, "isMobile": isMobile, "compatibilityHash": compatibilityHash, "sessionType": toBeginningOfSentenceCase(sessionType.name) }; } UserStatus copyWith({ String? userId, OnlineStatus? onlineStatus, DateTime? lastStatusChange, DateTime? lastPresenceTimestamp, bool? isPresent, String? userSessionId, int? currentSessionIndex, List? sessions, String? appVersion, String? outputDevice, bool? isMobile, String? compatibilityHash, String? hashSalt, UserSessionType? sessionType, List? decodedSessions, }) => UserStatus( userId: userId ?? this.userId, onlineStatus: onlineStatus ?? this.onlineStatus, lastStatusChange: lastStatusChange ?? this.lastStatusChange, lastPresenceTimestamp: lastPresenceTimestamp ?? this.lastPresenceTimestamp, isPresent: isPresent ?? this.isPresent, userSessionId: userSessionId ?? this.userSessionId, currentSessionIndex: currentSessionIndex ?? this.currentSessionIndex, sessions: sessions ?? this.sessions, appVersion: appVersion ?? this.appVersion, outputDevice: outputDevice ?? this.outputDevice, isMobile: isMobile ?? this.isMobile, compatibilityHash: compatibilityHash ?? this.compatibilityHash, hashSalt: hashSalt ?? this.hashSalt, sessionType: sessionType ?? this.sessionType, decodedSessions: decodedSessions ?? this.decodedSessions, ); }