From 10508a41b163470d36628bc39a1155ce7e1f1c9b Mon Sep 17 00:00:00 2001 From: fufesou Date: Wed, 21 Jun 2023 16:08:45 +0800 Subject: [PATCH] manage network state for both user info and user group Signed-off-by: fufesou --- flutter/lib/common/widgets/address_book.dart | 24 ++++++++------ flutter/lib/common/widgets/my_group.dart | 24 ++++++++------ .../lib/desktop/pages/connection_page.dart | 31 ++++++++++++++----- flutter/lib/models/ab_model.dart | 13 +++++--- flutter/lib/models/state_model.dart | 3 ++ flutter/lib/models/user_model.dart | 2 -- 6 files changed, 64 insertions(+), 33 deletions(-) diff --git a/flutter/lib/common/widgets/address_book.dart b/flutter/lib/common/widgets/address_book.dart index c37fe9ccb..d5441acfe 100644 --- a/flutter/lib/common/widgets/address_book.dart +++ b/flutter/lib/common/widgets/address_book.dart @@ -3,6 +3,7 @@ import 'package:flutter_hbb/common/formatter/id_formatter.dart'; import 'package:flutter_hbb/common/widgets/peer_card.dart'; import 'package:flutter_hbb/common/widgets/peers_view.dart'; import 'package:flutter_hbb/desktop/widgets/popup_menu.dart'; +import 'package:flutter_hbb/models/state_model.dart'; import '../../consts.dart'; import '../../desktop/widgets/material_mod_popup_menu.dart' as mod_menu; import 'package:get/get.dart'; @@ -29,15 +30,18 @@ class _AddressBookState extends State { } @override - Widget build(BuildContext context) => FutureBuilder( - future: buildBody(context), - builder: (context, snapshot) { - if (snapshot.hasData) { - return snapshot.data!; - } else { - return const Offstage(); - } - }); + Widget build(BuildContext context) => Obx(() => Offstage( + offstage: stateGlobal.svcStatus.value != SvcStatus.ready, + child: FutureBuilder( + future: buildBody(context), + builder: (context, snapshot) { + if (snapshot.hasData) { + return snapshot.data!; + } else { + return const Offstage(); + } + }), + )); Future buildBody(BuildContext context) async { return Obx(() { @@ -54,7 +58,7 @@ class _AddressBookState extends State { if (gFFI.abModel.abError.isNotEmpty) { return _buildShowError(gFFI.abModel.abError.value); } - if (gFFI.userModel.fromServer.isFalse) { + if (gFFI.abModel.fromServer.isFalse) { return Offstage(); } return isDesktop diff --git a/flutter/lib/common/widgets/my_group.dart b/flutter/lib/common/widgets/my_group.dart index 53f789ae1..3642ae85f 100644 --- a/flutter/lib/common/widgets/my_group.dart +++ b/flutter/lib/common/widgets/my_group.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hbb/common/hbbs/hbbs.dart'; import 'package:flutter_hbb/common/widgets/peers_view.dart'; +import 'package:flutter_hbb/models/state_model.dart'; import 'package:get/get.dart'; import '../../common.dart'; @@ -26,15 +27,20 @@ class _MyGroupState extends State { } @override - Widget build(BuildContext context) => FutureBuilder( - future: buildBody(context), - builder: (context, snapshot) { - if (snapshot.hasData) { - return snapshot.data!; - } else { - return const Offstage(); - } - }); + Widget build(BuildContext context) { + return Obx(() => Offstage( + offstage: stateGlobal.svcStatus.value != SvcStatus.ready, + child: FutureBuilder( + future: buildBody(context), + builder: (context, snapshot) { + if (snapshot.hasData) { + return snapshot.data!; + } else { + return const Offstage(); + } + }), + )); + } Future buildBody(BuildContext context) async { return Obx(() { diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 6d3f8994c..5d0addbca 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -42,7 +42,6 @@ class _ConnectionPageState extends State final FocusNode _idFocusNode = FocusNode(); var svcStopped = Get.find(tag: 'stop-service'); - var svcStatusCode = 0.obs; var svcIsUsingPublicServer = true.obs; bool isWindowMinimized = false; @@ -253,9 +252,9 @@ class _ConnectionPageState extends State width: 8, decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), - color: svcStopped.value || svcStatusCode.value == 0 + color: svcStopped.value || stateGlobal.svcStatus.value == SvcStatus.connecting ? kColorWarn - : (svcStatusCode.value == 1 + : (stateGlobal.svcStatus.value == SvcStatus.ready ? Color.fromARGB(255, 50, 190, 166) : Color.fromARGB(255, 224, 79, 95)), ), @@ -263,9 +262,9 @@ class _ConnectionPageState extends State Text( svcStopped.value ? translate("Service is not running") - : svcStatusCode.value == 0 + : stateGlobal.svcStatus.value == SvcStatus.connecting ? translate("connecting_status") - : svcStatusCode.value == -1 + : stateGlobal.svcStatus.value == SvcStatus.notReady ? translate("not_ready_status") : translate('Ready'), style: TextStyle(fontSize: em)), @@ -286,7 +285,7 @@ class _ConnectionPageState extends State Flexible( child: Offstage( offstage: !(!svcStopped.value && - svcStatusCode.value == 1 && + stateGlobal.svcStatus.value == SvcStatus.ready && svcIsUsingPublicServer.value), child: Row( crossAxisAlignment: CrossAxisAlignment.center, @@ -330,7 +329,25 @@ class _ConnectionPageState extends State updateStatus() async { final status = jsonDecode(await bind.mainGetConnectStatus()) as Map; - svcStatusCode.value = status["status_num"]; + final statusNum = status['status_num'] as int; + final preStatus = stateGlobal.svcStatus.value; + if (statusNum == 0) { + stateGlobal.svcStatus.value = SvcStatus.connecting; + } else if (statusNum == -1) { + stateGlobal.svcStatus.value = SvcStatus.notReady; + } else if (statusNum == 1) { + stateGlobal.svcStatus.value = SvcStatus.ready; + if (preStatus != SvcStatus.ready) { + gFFI.userModel.refreshCurrentUser(); + gFFI.groupModel.pull(); + } + } else { + stateGlobal.svcStatus.value = SvcStatus.notReady; + } + if (stateGlobal.svcStatus.value != SvcStatus.ready) { + gFFI.userModel.isAdmin.value = false; + gFFI.groupModel.reset(); + } svcIsUsingPublicServer.value = await bind.mainIsUsingPublicServer(); } } diff --git a/flutter/lib/models/ab_model.dart b/flutter/lib/models/ab_model.dart index 133343297..8bcb3f7a6 100644 --- a/flutter/lib/models/ab_model.dart +++ b/flutter/lib/models/ab_model.dart @@ -10,12 +10,13 @@ import 'package:http/http.dart' as http; import '../common.dart'; class AbModel { - var abLoading = false.obs; - var abError = "".obs; - var tags = [].obs; - var peers = List.empty(growable: true).obs; + final abLoading = false.obs; + final abError = "".obs; + final tags = [].obs; + final RxBool fromServer = false.obs; + final peers = List.empty(growable: true).obs; - var selectedTags = List.empty(growable: true).obs; + final selectedTags = List.empty(growable: true).obs; WeakReference parent; @@ -49,8 +50,10 @@ class AbModel { } } } + fromServer.value = true; return resp.body; } else { + fromServer.value = true; return ""; } } catch (err) { diff --git a/flutter/lib/models/state_model.dart b/flutter/lib/models/state_model.dart index 155700262..f7b4f8cc2 100644 --- a/flutter/lib/models/state_model.dart +++ b/flutter/lib/models/state_model.dart @@ -6,6 +6,8 @@ import 'package:get/get.dart'; import '../consts.dart'; +enum SvcStatus { notReady, connecting, ready } + class StateGlobal { int _windowId = -1; bool _fullscreen = false; @@ -16,6 +18,7 @@ class StateGlobal { final RxDouble _windowBorderWidth = RxDouble(kWindowBorderWidth); final RxBool showRemoteToolBar = false.obs; final RxInt displaysCount = 0.obs; + final svcStatus = SvcStatus.notReady.obs; // Use for desktop -> remote toolbar -> resolution final Map> _lastResolutionGroupValues = {}; diff --git a/flutter/lib/models/user_model.dart b/flutter/lib/models/user_model.dart index ebf89e26c..7835e50b1 100644 --- a/flutter/lib/models/user_model.dart +++ b/flutter/lib/models/user_model.dart @@ -14,7 +14,6 @@ import 'platform_model.dart'; class UserModel { final RxString userName = ''.obs; final RxBool isAdmin = false.obs; - final RxBool fromServer = false.obs; WeakReference parent; UserModel(this.parent); @@ -85,7 +84,6 @@ class UserModel { _parseAndUpdateUser(UserPayload user) { userName.value = user.name; isAdmin.value = user.isAdmin; - fromServer.value = true; } Future _updateOtherModels() async {