123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- import 'package:flutter/widgets.dart';
- import 'package:flutter_hbb/common.dart';
- import 'package:flutter_hbb/common/hbbs/hbbs.dart';
- import 'package:flutter_hbb/common/widgets/peers_view.dart';
- import 'package:flutter_hbb/models/model.dart';
- import 'package:flutter_hbb/models/peer_model.dart';
- import 'package:flutter_hbb/models/platform_model.dart';
- import 'package:get/get.dart';
- import 'dart:convert';
- import '../utils/http_service.dart' as http;
- class GroupModel {
- final RxBool groupLoading = false.obs;
- final RxString groupLoadError = "".obs;
- final RxList<UserPayload> users = RxList.empty(growable: true);
- final RxList<Peer> peers = RxList.empty(growable: true);
- final RxString selectedUser = ''.obs;
- final RxString searchUserText = ''.obs;
- WeakReference<FFI> parent;
- var initialized = false;
- var _cacheLoadOnceFlag = false;
- var _statusCode = 200;
- bool get emtpy => users.isEmpty && peers.isEmpty;
- late final Peers peersModel;
- GroupModel(this.parent) {
- peersModel = Peers(
- name: PeersModelName.group,
- getInitPeers: () => peers,
- loadEvent: LoadEvent.group);
- }
- Future<void> pull({force = true, quiet = false}) async {
- if (bind.isDisableGroupPanel()) return;
- if (!gFFI.userModel.isLogin || groupLoading.value) return;
- if (gFFI.userModel.networkError.isNotEmpty) return;
- if (!force && initialized) return;
- if (!quiet) {
- groupLoading.value = true;
- groupLoadError.value = "";
- }
- try {
- await _pull();
- } catch (_) {}
- groupLoading.value = false;
- initialized = true;
- platformFFI.tryHandle({'name': LoadEvent.group});
- if (_statusCode == 401) {
- gFFI.userModel.reset(resetOther: true);
- } else {
- _saveCache();
- }
- }
- Future<void> _pull() async {
- List<UserPayload> tmpUsers = List.empty(growable: true);
- if (!await _getUsers(tmpUsers)) {
- return;
- }
- List<Peer> tmpPeers = List.empty(growable: true);
- if (!await _getPeers(tmpPeers)) {
- return;
- }
- // me first
- var index = tmpUsers
- .indexWhere((user) => user.name == gFFI.userModel.userName.value);
- if (index != -1) {
- var user = tmpUsers.removeAt(index);
- tmpUsers.insert(0, user);
- }
- users.value = tmpUsers;
- if (!users.any((u) => u.name == selectedUser.value)) {
- selectedUser.value = '';
- }
- // recover online
- final oldOnlineIDs = peers.where((e) => e.online).map((e) => e.id).toList();
- peers.value = tmpPeers;
- peers
- .where((e) => oldOnlineIDs.contains(e.id))
- .map((e) => e.online = true)
- .toList();
- groupLoadError.value = '';
- }
- Future<bool> _getUsers(List<UserPayload> tmpUsers) async {
- final api = "${await bind.mainGetApiServer()}/api/users";
- try {
- var uri0 = Uri.parse(api);
- final pageSize = 100;
- var total = 0;
- int current = 0;
- do {
- current += 1;
- var uri = Uri(
- scheme: uri0.scheme,
- host: uri0.host,
- path: uri0.path,
- port: uri0.port,
- queryParameters: {
- 'current': current.toString(),
- 'pageSize': pageSize.toString(),
- 'accessible': '',
- 'status': '1',
- });
- final resp = await http.get(uri, headers: getHttpHeaders());
- _statusCode = resp.statusCode;
- Map<String, dynamic> json =
- _jsonDecodeResp(utf8.decode(resp.bodyBytes), resp.statusCode);
- if (json.containsKey('error')) {
- if (json['error'] == 'Admin required!' ||
- json['error']
- .toString()
- .contains('ambiguous column name: status')) {
- throw translate('upgrade_rustdesk_server_pro_to_{1.1.10}_tip');
- } else {
- throw json['error'];
- }
- }
- if (resp.statusCode != 200) {
- throw 'HTTP ${resp.statusCode}';
- }
- if (json.containsKey('total')) {
- if (total == 0) total = json['total'];
- if (json.containsKey('data')) {
- final data = json['data'];
- if (data is List) {
- for (final user in data) {
- final u = UserPayload.fromJson(user);
- int index = tmpUsers.indexWhere((e) => e.name == u.name);
- if (index < 0) {
- tmpUsers.add(u);
- } else {
- tmpUsers[index] = u;
- }
- }
- }
- }
- }
- } while (current * pageSize < total);
- return true;
- } catch (err) {
- debugPrint('get accessible users: $err');
- groupLoadError.value =
- '${translate('pull_group_failed_tip')}: ${translate(err.toString())}';
- }
- return false;
- }
- Future<bool> _getPeers(List<Peer> tmpPeers) async {
- try {
- final api = "${await bind.mainGetApiServer()}/api/peers";
- var uri0 = Uri.parse(api);
- final pageSize = 100;
- var total = 0;
- int current = 0;
- do {
- current += 1;
- var queryParameters = {
- 'current': current.toString(),
- 'pageSize': pageSize.toString(),
- 'accessible': '',
- 'status': '1',
- };
- var uri = Uri(
- scheme: uri0.scheme,
- host: uri0.host,
- path: uri0.path,
- port: uri0.port,
- queryParameters: queryParameters);
- final resp = await http.get(uri, headers: getHttpHeaders());
- _statusCode = resp.statusCode;
- Map<String, dynamic> json =
- _jsonDecodeResp(utf8.decode(resp.bodyBytes), resp.statusCode);
- if (json.containsKey('error')) {
- throw json['error'];
- }
- if (resp.statusCode != 200) {
- throw 'HTTP ${resp.statusCode}';
- }
- if (json.containsKey('total')) {
- if (total == 0) total = json['total'];
- if (json.containsKey('data')) {
- final data = json['data'];
- if (data is List) {
- for (final p in data) {
- final peerPayload = PeerPayload.fromJson(p);
- final peer = PeerPayload.toPeer(peerPayload);
- int index = tmpPeers.indexWhere((e) => e.id == peer.id);
- if (index < 0) {
- tmpPeers.add(peer);
- } else {
- tmpPeers[index] = peer;
- }
- }
- }
- }
- }
- } while (current * pageSize < total);
- return true;
- } catch (err) {
- debugPrint('get accessible peers: $err');
- groupLoadError.value =
- '${translate('pull_group_failed_tip')}: ${translate(err.toString())}';
- }
- return false;
- }
- Map<String, dynamic> _jsonDecodeResp(String body, int statusCode) {
- try {
- Map<String, dynamic> json = jsonDecode(body);
- return json;
- } catch (e) {
- final err = body.isNotEmpty && body.length < 128 ? body : e.toString();
- if (statusCode != 200) {
- throw 'HTTP $statusCode, $err';
- }
- throw err;
- }
- }
- void _saveCache() {
- try {
- final map = (<String, dynamic>{
- "access_token": bind.mainGetLocalOption(key: 'access_token'),
- "users": users.map((e) => e.toGroupCacheJson()).toList(),
- 'peers': peers.map((e) => e.toGroupCacheJson()).toList()
- });
- bind.mainSaveGroup(json: jsonEncode(map));
- } catch (e) {
- debugPrint('group save:$e');
- }
- }
- Future<void> loadCache() async {
- try {
- if (_cacheLoadOnceFlag || groupLoading.value || initialized) return;
- _cacheLoadOnceFlag = true;
- final access_token = bind.mainGetLocalOption(key: 'access_token');
- if (access_token.isEmpty) return;
- final cache = await bind.mainLoadGroup();
- if (groupLoading.value) return;
- final data = jsonDecode(cache);
- if (data == null || data['access_token'] != access_token) return;
- users.clear();
- peers.clear();
- if (data['users'] is List) {
- for (var u in data['users']) {
- users.add(UserPayload.fromJson(u));
- }
- }
- if (data['peers'] is List) {
- for (final peer in data['peers']) {
- peers.add(Peer.fromJson(peer));
- }
- }
- } catch (e) {
- debugPrint("load group cache: $e");
- }
- }
- reset() async {
- groupLoadError.value = '';
- users.clear();
- peers.clear();
- selectedUser.value = '';
- await bind.mainClearGroup();
- }
- }
|