import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'platform_model.dart'; // ignore: depend_on_referenced_packages import 'package:collection/collection.dart'; class Peer { final String id; String hash; String username; String hostname; String platform; String alias; List tags; bool forceAlwaysRelay = false; String rdpPort; String rdpUsername; bool online = false; String getId() { if (alias != '') { return alias; } return id; } Peer.fromJson(Map json) : id = json['id'] ?? '', hash = json['hash'] ?? '', username = json['username'] ?? '', hostname = json['hostname'] ?? '', platform = json['platform'] ?? '', alias = json['alias'] ?? '', tags = json['tags'] ?? [], forceAlwaysRelay = json['forceAlwaysRelay'] == 'true', rdpPort = json['rdpPort'] ?? '', rdpUsername = json['rdpUsername'] ?? ''; Map toJson() { return { "id": id, "hash": hash, "username": username, "hostname": hostname, "platform": platform, "alias": alias, "tags": tags, "forceAlwaysRelay": forceAlwaysRelay.toString(), "rdpPort": rdpPort, "rdpUsername": rdpUsername, }; } Map toAbUploadJson() { return { "id": id, "hash": hash, "username": username, "hostname": hostname, "platform": platform, "alias": alias, "tags": tags, }; } Peer({ required this.id, required this.hash, required this.username, required this.hostname, required this.platform, required this.alias, required this.tags, required this.forceAlwaysRelay, required this.rdpPort, required this.rdpUsername, }); Peer.loading() : this( id: '...', hash: '', username: '...', hostname: '...', platform: '...', alias: '', tags: [], forceAlwaysRelay: false, rdpPort: '', rdpUsername: '', ); bool equal(Peer other) { return id == other.id && hash == other.hash && username == other.username && hostname == other.hostname && platform == other.platform && alias == other.alias && tags.equals(other.tags) && forceAlwaysRelay == other.forceAlwaysRelay && rdpPort == other.rdpPort && rdpUsername == other.rdpUsername; } Peer.copy(Peer other) : this( id: other.id, hash: other.hash, username: other.username, hostname: other.hostname, platform: other.platform, alias: other.alias, tags: other.tags.toList(), forceAlwaysRelay: other.forceAlwaysRelay, rdpPort: other.rdpPort, rdpUsername: other.rdpUsername); } enum UpdateEvent { online, load } class Peers extends ChangeNotifier { final String name; final String loadEvent; List peers; UpdateEvent event = UpdateEvent.load; static const _cbQueryOnlines = 'callback_query_onlines'; Peers({required this.name, required this.peers, required this.loadEvent}) { platformFFI.registerEventHandler(_cbQueryOnlines, name, (evt) async { _updateOnlineState(evt); }); platformFFI.registerEventHandler(loadEvent, name, (evt) async { _updatePeers(evt); }); } @override void dispose() { platformFFI.unregisterEventHandler(_cbQueryOnlines, name); platformFFI.unregisterEventHandler(loadEvent, name); super.dispose(); } Peer getByIndex(int index) { if (index < peers.length) { return peers[index]; } else { return Peer.loading(); } } int getPeersCount() { return peers.length; } void _updateOnlineState(Map evt) { evt['onlines'].split(',').forEach((online) { for (var i = 0; i < peers.length; i++) { if (peers[i].id == online) { peers[i].online = true; } } }); evt['offlines'].split(',').forEach((offline) { for (var i = 0; i < peers.length; i++) { if (peers[i].id == offline) { peers[i].online = false; } } }); event = UpdateEvent.online; notifyListeners(); } void _updatePeers(Map evt) { final onlineStates = _getOnlineStates(); peers = _decodePeers(evt['peers']); for (var peer in peers) { final state = onlineStates[peer.id]; peer.online = state != null && state != false; } event = UpdateEvent.load; notifyListeners(); } Map _getOnlineStates() { var onlineStates = {}; for (var peer in peers) { onlineStates[peer.id] = peer.online; } return onlineStates; } List _decodePeers(String peersStr) { try { if (peersStr == "") return []; List peers = json.decode(peersStr); return peers.map((peer) { return Peer.fromJson(peer as Map); }).toList(); } catch (e) { debugPrint('peers(): $e'); } return []; } }