From c02a502a7f9eba4c30c38a3e184e85a73694575d Mon Sep 17 00:00:00 2001 From: 21pages Date: Wed, 21 Jun 2023 16:04:52 +0800 Subject: [PATCH] peer tab use icon Signed-off-by: 21pages --- flutter/assets/address_book.ttf | Bin 0 -> 1792 bytes flutter/lib/common.dart | 2 + flutter/lib/common/widgets/address_book.dart | 1 - flutter/lib/common/widgets/my_group.dart | 36 ++- flutter/lib/common/widgets/peer_tab_page.dart | 203 +++----------- .../desktop/pages/desktop_setting_page.dart | 1 + flutter/lib/models/group_model.dart | 48 ++-- flutter/lib/models/peer_tab_model.dart | 247 ++---------------- flutter/lib/models/user_model.dart | 6 +- flutter/pubspec.yaml | 3 + 10 files changed, 101 insertions(+), 446 deletions(-) create mode 100644 flutter/assets/address_book.ttf diff --git a/flutter/assets/address_book.ttf b/flutter/assets/address_book.ttf new file mode 100644 index 0000000000000000000000000000000000000000..509fb63c09da8c63d47908d675ecfca1f703d948 GIT binary patch literal 1792 zcmd^9T~8cU7=F%~VL`wOmV%&JhL2q$g<064lvIR5Es*%ZM-eqK%CI}TP3gpOxr7Zp_lc_06u5-tRJ-hz%z5+^Ssadao+RJ z$v^;TK@|qZ7B9U%Z+(!s4u~nT>&ur?>FKVepQwLGeKS*Z%MXUX`hxmH&T_u6m;3q4 z)lUJVK>NdO&&>|r-guArKIh~%iN?FeP2z7j2e*siwI%|_{!Y`)r!~nVW#jm;FjO{N@sEvF~Z01Zy{{M^(ISQl%FIBk+%q5kvOn zw{C2{`_%LwXsP+$|N53XBWml>JrhQPY7?XmR+%K$&=Bd0ZRP_UMS5+gW{hD5@}-4W z)^VcXh9&fa`Oz}ev~D<<#S&I&9_SzF>pvk* zwRgmY)7SZeNY98f?Gv^T6O(6cab{vhq~qdLN31cDbWS!mRV9Unft zVXrtbQEGHnMh6^c(Q%By_(c5R6O|%yJ}Fbl^NEA&%hhgJ!+yhJ0O)z~24udzuy ztZ@VXQfZB2+6OWRCfH5HExg9 zsYS2k1@$zQtNC;o=B!-c7p(>6^9lvuDhK{$FB96^VOTzwN~wJmZ)f}>E+Bvh7a?U9 z7PhcQxq}RRl#q*L_=vtn?>w%cz{ubc>+$FfdIzY`Pvx{Q4x7Ke<6evODn*{htEu2B zcT2OzkQG^+0W%ee7Ib|cD=83L{D8`KnRznwwy_;Wm2nO!KK1j|{q5+SMfG#64fT(H X+>k;F1Fdd08+et<=$7yAD!0D?EMoMM literal 0 HcmV?d00001 diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 5445bf2f0..2e6a28613 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -94,6 +94,8 @@ class IconFont { static const IconData menu = IconData(0xe628, fontFamily: _family1); static const IconData search = IconData(0xe6a4, fontFamily: _family2); static const IconData roundClose = IconData(0xe6ed, fontFamily: _family2); + static const IconData addressBook = + IconData(0xe602, fontFamily: "AddressBook"); } class ColorThemeExtension extends ThemeExtension { diff --git a/flutter/lib/common/widgets/address_book.dart b/flutter/lib/common/widgets/address_book.dart index 29270a349..949217e4d 100644 --- a/flutter/lib/common/widgets/address_book.dart +++ b/flutter/lib/common/widgets/address_book.dart @@ -3,7 +3,6 @@ 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'; diff --git a/flutter/lib/common/widgets/my_group.dart b/flutter/lib/common/widgets/my_group.dart index 3642ae85f..472f98406 100644 --- a/flutter/lib/common/widgets/my_group.dart +++ b/flutter/lib/common/widgets/my_group.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hbb/common/hbbs/hbbs.dart'; +import 'package:flutter_hbb/common/widgets/login.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'; @@ -28,24 +28,20 @@ class _MyGroupState extends State { @override 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(); - } - }), - )); + return Obx(() { + // use username to be same with ab + if (gFFI.userModel.userName.value.isEmpty) { + return Center( + child: ElevatedButton( + onPressed: loginDialog, child: Text(translate("Login")))); + } + return buildBody(context); + }); } - Future buildBody(BuildContext context) async { + Widget buildBody(BuildContext context) { return Obx(() { - if (gFFI.groupModel.groupLoading.value || - gFFI.groupModel.peerLoading.value) { + if (gFFI.groupModel.groupLoading.value) { return const Center( child: CircularProgressIndicator(), ); @@ -109,9 +105,9 @@ class _MyGroupState extends State { Expanded( child: Align( alignment: Alignment.topLeft, - child: MyGroupPeerView( + child: Obx(() => MyGroupPeerView( menuPadding: widget.menuPadding, - initPeers: gFFI.groupModel.peersShow)), + initPeers: gFFI.groupModel.peersShow.value))), ) ], ); @@ -147,9 +143,9 @@ class _MyGroupState extends State { Expanded( child: Align( alignment: Alignment.topLeft, - child: MyGroupPeerView( + child: Obx(() => MyGroupPeerView( menuPadding: widget.menuPadding, - initPeers: gFFI.groupModel.peersShow)), + initPeers: gFFI.groupModel.peersShow.value))), ) ], ); diff --git a/flutter/lib/common/widgets/peer_tab_page.dart b/flutter/lib/common/widgets/peer_tab_page.dart index f3289b8b3..6d8bc2a94 100644 --- a/flutter/lib/common/widgets/peer_tab_page.dart +++ b/flutter/lib/common/widgets/peer_tab_page.dart @@ -1,7 +1,3 @@ -import 'dart:ui' as ui; - -import 'package:bot_toast/bot_toast.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hbb/common/widgets/address_book.dart'; import 'package:flutter_hbb/common/widgets/my_group.dart'; @@ -10,16 +6,13 @@ import 'package:flutter_hbb/common/widgets/peer_card.dart'; import 'package:flutter_hbb/common/widgets/animated_rotation_widget.dart'; import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/desktop/widgets/popup_menu.dart'; -import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart'; -import 'package:flutter_hbb/desktop/widgets/material_mod_popup_menu.dart' - as mod_menu; + import 'package:flutter_hbb/models/peer_tab_model.dart'; import 'package:get/get.dart'; -import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart'; import 'package:provider/provider.dart'; -import 'package:visibility_detector/visibility_detector.dart'; import '../../common.dart'; +import '../../models/group_model.dart'; import '../../models/platform_model.dart'; class PeerTabPage extends StatefulWidget { @@ -68,7 +61,6 @@ class _PeerTabPageState extends State () => gFFI.groupModel.pull(), ), ]; - final _scrollDebounce = Debouncer(delay: Duration(milliseconds: 50)); @override void initState() { @@ -101,11 +93,8 @@ class _PeerTabPageState extends State child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - Expanded( - child: - visibleContextMenuListener(_createSwitchBar(context))), - buildScrollJumper(), - const PeerSearchBar().marginOnly(right: 13), + Expanded(child: _createSwitchBar(context)), + const PeerSearchBar().marginOnly(right: isMobile ? 0 : 13), _createRefresh(), Offstage( offstage: !isDesktop, @@ -124,121 +113,58 @@ class _PeerTabPageState extends State } Widget _createSwitchBar(BuildContext context) { - getListener({required Key key, required Widget child, required int index}) { - if (isMobile) { - return ReorderableDelayedDragStartListener( - key: key, child: child, index: index); - } else { - return ReorderableDragStartListener( - key: key, child: child, index: index); - } + final model = Provider.of(context); + + getTabChild(int t) { + final color = model.currentTab == t + ? MyTheme.tabbar(context).selectedTextColor + : MyTheme.tabbar(context).unSelectedTextColor + ?..withOpacity(0.5); + return Obx(() => Tooltip( + message: model.tabTooltip(t, gFFI.groupModel.groupName.value), + child: Icon(model.tabIcon(t), color: color), + )); } - final model = Provider.of(context); - int indexCounter = -1; - return ReorderableListView( - buildDefaultDragHandles: false, - onReorder: (oldIndex, newIndex) { - model.onReorder(oldIndex, newIndex); - }, + return ListView( scrollDirection: Axis.horizontal, physics: NeverScrollableScrollPhysics(), - scrollController: model.sc, - children: model.visibleOrderedTabs.map((t) { - indexCounter++; - return getListener( - key: ValueKey(t), - index: indexCounter, - child: VisibilityDetector( - key: ValueKey(t), - onVisibilityChanged: (info) { - final id = (info.key as ValueKey).value; - model.setTabFullyVisible(id, info.visibleFraction > 0.99); - }, - child: Listener( - // handle mouse wheel - onPointerSignal: (e) { - if (e is PointerScrollEvent) { - if (!model.sc.canScroll) return; - _scrollDebounce.call(() { - model.sc.animateTo(model.sc.offset + e.scrollDelta.dy, - duration: Duration(milliseconds: 200), - curve: Curves.ease); - }); - } - }, - child: InkWell( - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration( - color: model.currentTab == t - ? Theme.of(context).colorScheme.background - : null, - borderRadius: BorderRadius.circular(6), - ), - child: Align( - alignment: Alignment.center, - child: Text( - model.translatedTabname(t), - textAlign: TextAlign.center, - style: TextStyle( - height: 1, - fontSize: 14, - color: model.currentTab == t - ? MyTheme.tabbar(context).selectedTextColor - : MyTheme.tabbar(context).unSelectedTextColor - ?..withOpacity(0.5)), - ), - )), - onTap: () async { - await handleTabSelection(t); - await bind.setLocalFlutterConfig( - k: 'peer-tab-index', v: t.toString()); - }, + children: model.indexs.map((t) { + return InkWell( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: model.currentTab == t + ? Theme.of(context).colorScheme.background + : null, + borderRadius: BorderRadius.circular(6), ), - ), - ), + child: Align( + alignment: Alignment.center, + child: getTabChild(t), + )), + onTap: () async { + await handleTabSelection(t); + await bind.setLocalFlutterConfig( + k: 'peer-tab-index', v: t.toString()); + }, ); }).toList()); } - Widget buildScrollJumper() { - final model = Provider.of(context); - return Offstage( - offstage: !model.showScrollBtn, - child: Row( - children: [ - GestureDetector( - child: Icon(Icons.arrow_left, - size: 22, - color: model.leftFullyVisible - ? Theme.of(context).disabledColor - : null), - onTap: model.sc.backward), - GestureDetector( - child: Icon(Icons.arrow_right, - size: 22, - color: model.rightFullyVisible - ? Theme.of(context).disabledColor - : null), - onTap: model.sc.forward) - ], - )); - } - Widget _createPeersView() { final model = Provider.of(context); Widget child; - if (model.visibleOrderedTabs.isEmpty) { - child = visibleContextMenuListener(Center( + if (model.indexs.isEmpty) { + child = Center( child: Text(translate('Right click to select tabs')), - )); + ); } else { - if (model.visibleOrderedTabs.contains(model.currentTab)) { + if (model.indexs.contains(model.currentTab)) { child = entries[model.currentTab].widget; } else { Future.delayed(Duration.zero, () { - model.setCurrentTab(model.visibleOrderedTabs[0]); + model.setCurrentTab(model.indexs[0]); }); child = entries[0].widget; } @@ -300,57 +226,6 @@ class _PeerTabPageState extends State ), ); } - - Widget visibleContextMenuListener(Widget child) { - return Listener( - onPointerDown: (e) { - if (e.kind != ui.PointerDeviceKind.mouse) { - return; - } - if (e.buttons == 2) { - showRightMenu( - (CancelFunc cancelFunc) { - return visibleContextMenu(cancelFunc); - }, - target: e.position, - ); - } - }, - child: child); - } - - Widget visibleContextMenu(CancelFunc cancelFunc) { - final model = Provider.of(context); - final List menu = List.empty(growable: true); - final List menuIndex = List.empty(growable: true); - var list = model.orderedNotFilteredTabs(); - for (int i = 0; i < list.length; i++) { - int tabIndex = list[i]; - int bitMask = 1 << tabIndex; - menuIndex.add(tabIndex); - menu.add(MenuEntrySwitch( - switchType: SwitchType.scheckbox, - text: model.translatedTabname(tabIndex), - getter: () async { - return model.tabHiddenFlag & bitMask == 0; - }, - setter: (show) async { - model.onHideShow(tabIndex, show); - cancelFunc(); - })); - } - return mod_menu.PopupMenu( - items: menu - .map((entry) => entry.build( - context, - const MenuConfig( - commonColor: MyTheme.accent, - height: 20.0, - dividerHeight: 12.0, - ))) - .expand((i) => i) - .toList()); - } } class PeerSearchBar extends StatefulWidget { diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index 578b63b20..1e8c16e91 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -8,6 +8,7 @@ import 'package:flutter_hbb/common.dart'; import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/desktop/pages/desktop_home_page.dart'; import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart'; +import 'package:flutter_hbb/models/group_model.dart'; import 'package:flutter_hbb/models/platform_model.dart'; import 'package:flutter_hbb/models/server_model.dart'; import 'package:flutter_hbb/plugin/manager.dart'; diff --git a/flutter/lib/models/group_model.dart b/flutter/lib/models/group_model.dart index 411703237..cea5d7749 100644 --- a/flutter/lib/models/group_model.dart +++ b/flutter/lib/models/group_model.dart @@ -11,23 +11,17 @@ import 'package:http/http.dart' as http; class GroupModel { final RxBool groupLoading = false.obs; final RxString groupLoadError = "".obs; - final RxBool peerLoading = false.obs; //to-do: not used - final RxString peerLoadError = "".obs; - final RxString groupName = ''.obs; final RxString groupId = ''.obs; + RxString groupName = ''.obs; final RxList users = RxList.empty(growable: true); - final List peersShow = List.empty(growable: true); + final RxList peersShow = RxList.empty(growable: true); final RxString selectedUser = ''.obs; final RxString searchUserText = ''.obs; WeakReference parent; GroupModel(this.parent); - Future reset() async { - groupLoading.value = false; - groupLoadError.value = ""; - peerLoading.value = false; - peerLoadError.value = ""; + reset() { groupName.value = ''; groupId.value = ''; users.clear(); @@ -35,7 +29,14 @@ class GroupModel { } Future pull() async { - await reset(); + groupLoading.value = true; + groupLoadError.value = ""; + await _pull(); + groupLoading.value = false; + } + + Future _pull() async { + reset(); if (bind.mainGetLocalOption(key: 'access_token') == '') { return; } @@ -49,13 +50,6 @@ class GroupModel { reset(); return; } - if (gFFI.userModel.userName.isEmpty || - (gFFI.userModel.isAdmin.isFalse && groupName.isEmpty)) { - gFFI.peerTabModel.check_dynamic_tabs(); - return; - } - groupLoading.value = true; - groupLoadError.value = ""; final api = "${await bind.mainGetApiServer()}/api/users"; try { var uri0 = Uri.parse(api); @@ -101,8 +95,6 @@ class GroupModel { debugPrint('$err'); groupLoadError.value = err.toString(); } finally { - groupLoading.value = false; - gFFI.peerTabModel.check_dynamic_tabs(); _pullUserPeers(); } } @@ -130,6 +122,7 @@ class GroupModel { return groupId.value.isNotEmpty && groupName.isNotEmpty; } catch (e) { debugPrint('$e'); + groupLoadError.value = e.toString(); } finally {} return false; @@ -137,9 +130,6 @@ class GroupModel { Future _pullUserPeers() async { peersShow.clear(); - peerLoading.value = true; - peerLoadError.value = ""; - List peerPayloads = List.empty(growable: true); final api = "${await bind.mainGetApiServer()}/api/peers"; try { var uri0 = Uri.parse(api); @@ -173,9 +163,11 @@ class GroupModel { final data = json['data']; if (data is List) { for (final p in data) { - final peer = PeerPayload.fromJson(p); - peerPayloads.add(peer); - peersShow.add(PeerPayload.toPeer(peer)); + final peerPayload = PeerPayload.fromJson(p); + final peer = PeerPayload.toPeer(peerPayload); + if (!peersShow.any((e) => e.id == peer.id)) { + peersShow.add(peer); + } } } } @@ -185,9 +177,7 @@ class GroupModel { } while (current * pageSize < total); } catch (err) { debugPrint('$err'); - peerLoadError.value = err.toString(); - } finally { - peerLoading.value = false; - } + groupLoadError.value = err.toString(); + } finally {} } } diff --git a/flutter/lib/models/peer_tab_model.dart b/flutter/lib/models/peer_tab_model.dart index 715da0c9c..f7cec5304 100644 --- a/flutter/lib/models/peer_tab_model.dart +++ b/flutter/lib/models/peer_tab_model.dart @@ -1,9 +1,5 @@ -import 'dart:convert'; - import 'package:flutter/material.dart'; import 'package:flutter_hbb/models/platform_model.dart'; -import 'package:get/get.dart'; -import 'package:scroll_pos/scroll_pos.dart'; import '../common.dart'; import 'model.dart'; @@ -15,20 +11,6 @@ class PeerTabModel with ChangeNotifier { WeakReference parent; int get currentTab => _currentTab; int _currentTab = 0; // index in tabNames - List get visibleOrderedTabs => _visibleOrderedTabs; - List _visibleOrderedTabs = List.empty(growable: true); - List get tabOrder => _tabOrder; - List _tabOrder = List.from([0, 1, 2, 3, 4]); // constant length - int get tabHiddenFlag => _tabHiddenFlag; - int _tabHiddenFlag = 0; - bool get showScrollBtn => _showScrollBtn; - bool _showScrollBtn = false; - final List _fullyVisible = List.filled(5, false); - bool get leftFullyVisible => _leftFullyVisible; - bool _leftFullyVisible = false; - bool get rightFullyVisible => _rightFullyVisible; - bool _rightFullyVisible = false; - ScrollPosController sc = ScrollPosController(); List tabNames = [ 'Recent Sessions', 'Favorites', @@ -36,66 +18,22 @@ class PeerTabModel with ChangeNotifier { 'Address Book', defaultGroupTabname, ]; + final List icons = [ + Icons.access_time, + Icons.star, + Icons.explore, + IconFont.addressBook, + Icons.group, + ]; + List get indexs => List.generate(tabNames.length, (index) => index); PeerTabModel(this.parent) { - // init tabHiddenFlag - _tabHiddenFlag = int.tryParse( - bind.getLocalFlutterConfig(k: 'hidden-peer-card'), - radix: 2) ?? - 0; - var tabs = _notHiddenTabs(); - // remove dynamic tabs - tabs.remove(groupTabIndex); - // init tabOrder - try { - final conf = bind.getLocalFlutterConfig(k: 'peer-tab-order'); - if (conf.isNotEmpty) { - final json = jsonDecode(conf); - if (json is List) { - final List list = - json.map((e) => int.tryParse(e.toString()) ?? -1).toList(); - if (list.length == _tabOrder.length && - _tabOrder.every((e) => list.contains(e))) { - _tabOrder = list; - } - } - } - } catch (e) { - debugPrintStack(label: '$e'); - } - // init visibleOrderedTabs - var tempList = _tabOrder.toList(); - tempList.removeWhere((e) => !tabs.contains(e)); - _visibleOrderedTabs = tempList; // init currentTab _currentTab = int.tryParse(bind.getLocalFlutterConfig(k: 'peer-tab-index')) ?? 0; - if (!tabs.contains(_currentTab)) { - if (tabs.isNotEmpty) { - _currentTab = tabs[0]; - } else { - _currentTab = 0; - } + if (_currentTab < 0 || _currentTab >= tabNames.length) { + _currentTab = 0; } - sc.itemCount = _visibleOrderedTabs.length; - } - - check_dynamic_tabs() { - var visible = visibleTabs(); - _visibleOrderedTabs = _tabOrder.where((e) => visible.contains(e)).toList(); - if (_visibleOrderedTabs.contains(groupTabIndex) && - int.tryParse(bind.getLocalFlutterConfig(k: 'peer-tab-index')) == - groupTabIndex) { - _currentTab = groupTabIndex; - } - if (gFFI.userModel.isAdmin.isFalse && - gFFI.groupModel.groupName.isNotEmpty) { - tabNames[groupTabIndex] = gFFI.groupModel.groupName.value; - } else { - tabNames[groupTabIndex] = defaultGroupTabname; - } - sc.itemCount = _visibleOrderedTabs.length; - notifyListeners(); } setCurrentTab(int index) { @@ -105,172 +43,27 @@ class PeerTabModel with ChangeNotifier { } } - setTabFullyVisible(int index, bool visible) { - if (index >= 0 && index < _fullyVisible.length) { - if (visible != _fullyVisible[index]) { - _fullyVisible[index] = visible; - bool changed = false; - bool show = _visibleOrderedTabs.any((e) => !_fullyVisible[e]); - if (show != _showScrollBtn) { - _showScrollBtn = show; - changed = true; - } - if (_visibleOrderedTabs.isNotEmpty && _visibleOrderedTabs[0] == index) { - if (_leftFullyVisible != visible) { - _leftFullyVisible = visible; - changed = true; - } - } - if (_visibleOrderedTabs.isNotEmpty && - _visibleOrderedTabs.last == index) { - if (_rightFullyVisible != visible) { - _rightFullyVisible = visible; - changed = true; - } - } - if (changed) { - notifyListeners(); - } - } - } - } - - onReorder(oldIndex, newIndex) { - if (oldIndex < newIndex) { - newIndex -= 1; - } - var list = _visibleOrderedTabs.toList(); - final int item = list.removeAt(oldIndex); - list.insert(newIndex, item); - _visibleOrderedTabs = list; - - var tmpTabOrder = _visibleOrderedTabs.toList(); - var left = _tabOrder.where((e) => !tmpTabOrder.contains(e)).toList(); - for (var t in left) { - _addTabInOrder(tmpTabOrder, t); - } - _tabOrder = tmpTabOrder; - bind.setLocalFlutterConfig(k: 'peer-tab-order', v: jsonEncode(tmpTabOrder)); - notifyListeners(); - } - - onHideShow(int index, bool show) async { - int bitMask = 1 << index; - if (show) { - _tabHiddenFlag &= ~bitMask; - } else { - _tabHiddenFlag |= bitMask; - } - await bind.setLocalFlutterConfig( - k: 'hidden-peer-card', v: _tabHiddenFlag.toRadixString(2)); - var visible = visibleTabs(); - _visibleOrderedTabs = _tabOrder.where((e) => visible.contains(e)).toList(); - if (_visibleOrderedTabs.isNotEmpty && - !_visibleOrderedTabs.contains(_currentTab)) { - _currentTab = _visibleOrderedTabs[0]; - } - notifyListeners(); - } - - List orderedNotFilteredTabs() { - var list = tabOrder.toList(); - if (_filterGroupCard()) { - list.remove(groupTabIndex); - } - return list; - } - - // return index array of tabNames - List visibleTabs() { - var v = List.empty(growable: true); - for (int i = 0; i < tabNames.length; i++) { - if (!_isTabHidden(i) && !_isTabFilter(i)) { - v.add(i); - } - } - return v; - } - - String translatedTabname(int index) { + String tabTooltip(int index, String groupName) { if (index >= 0 && index < tabNames.length) { - final name = tabNames[index]; if (index == groupTabIndex) { - if (name == defaultGroupTabname) { - return translate(name); + if (gFFI.userModel.isAdmin.value || groupName.isEmpty) { + return translate(defaultGroupTabname); } else { - return name; + return '${translate('Group')}: $groupName'; } } else { - return translate(name); + return translate(tabNames[index]); } } assert(false); return index.toString(); } - bool _isTabHidden(int tabindex) { - return _tabHiddenFlag & (1 << tabindex) != 0; - } - - bool _isTabFilter(int tabIndex) { - if (tabIndex == groupTabIndex) { - return _filterGroupCard(); - } - return false; - } - - // return true if hide group card - bool _filterGroupCard() { - if (gFFI.groupModel.users.isEmpty || - (gFFI.userModel.isAdmin.isFalse && gFFI.groupModel.groupName.isEmpty)) { - return true; - } else { - return false; - } - } - - List _notHiddenTabs() { - var v = List.empty(growable: true); - for (int i = 0; i < tabNames.length; i++) { - if (!_isTabHidden(i)) { - v.add(i); - } - } - return v; - } - - // add tabIndex to list - _addTabInOrder(List list, int tabIndex) { - if (!_tabOrder.contains(tabIndex) || list.contains(tabIndex)) { - return; - } - bool sameOrder = true; - int lastIndex = -1; - for (int i = 0; i < list.length; i++) { - var index = _tabOrder.lastIndexOf(list[i]); - if (index > lastIndex) { - lastIndex = index; - continue; - } else { - sameOrder = false; - break; - } - } - if (sameOrder) { - var indexInTabOrder = _tabOrder.indexOf(tabIndex); - var left = List.empty(growable: true); - for (int i = 0; i < indexInTabOrder; i++) { - left.add(_tabOrder[i]); - } - int insertIndex = list.lastIndexWhere((e) => left.contains(e)); - if (insertIndex < 0) { - insertIndex = 0; - } else { - insertIndex += 1; - } - list.insert(insertIndex, tabIndex); - } else { - list.add(tabIndex); + IconData tabIcon(int index) { + if (index >= 0 && index < tabNames.length) { + return icons[index]; } + assert(false); + return Icons.help; } } diff --git a/flutter/lib/models/user_model.dart b/flutter/lib/models/user_model.dart index a6d2117c0..be736297f 100644 --- a/flutter/lib/models/user_model.dart +++ b/flutter/lib/models/user_model.dart @@ -1,9 +1,7 @@ import 'dart:async'; import 'dart:convert'; -import 'package:flutter/material.dart'; import 'package:flutter_hbb/common/hbbs/hbbs.dart'; -import 'package:flutter_hbb/common/widgets/peer_tab_page.dart'; import 'package:get/get.dart'; import 'package:http/http.dart' as http; @@ -79,7 +77,6 @@ class UserModel { await gFFI.abModel.reset(); await gFFI.groupModel.reset(); userName.value = ''; - gFFI.peerTabModel.check_dynamic_tabs(); } _parseAndUpdateUser(UserPayload user) { @@ -89,8 +86,7 @@ class UserModel { // update ab and group status static Future updateOtherModels() async { - await gFFI.abModel.pullAb(); - await gFFI.groupModel.pull(); + await Future.wait([gFFI.abModel.pullAb(), gFFI.groupModel.pull()]); } Future logOut() async { diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index a1388f067..f8541c12d 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -145,6 +145,9 @@ flutter: - family: PeerSearchbar fonts: - asset: assets/peer_searchbar.ttf + - family: AddressBook + fonts: + - asset: assets/address_book.ttf # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware.