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'; const int groupTabIndex = 4; const String defaultGroupTabname = 'Group'; 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', 'Discovered', 'Address Book', defaultGroupTabname, ]; 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; } } 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.userModel.groupName.isNotEmpty) { tabNames[groupTabIndex] = gFFI.userModel.groupName.value; } else { tabNames[groupTabIndex] = defaultGroupTabname; } sc.itemCount = _visibleOrderedTabs.length; notifyListeners(); } setCurrentTab(int index) { if (_currentTab != index) { _currentTab = index; notifyListeners(); } } 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) { if (index >= 0 && index < tabNames.length) { final name = tabNames[index]; if (index == groupTabIndex) { if (name == defaultGroupTabname) { return translate(name); } else { return name; } } else { return translate(name); } } 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.userModel.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); } } }