276 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			276 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
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<FFI> parent;
 | 
						|
  int get currentTab => _currentTab;
 | 
						|
  int _currentTab = 0; // index in tabNames
 | 
						|
  List<int> get visibleOrderedTabs => _visibleOrderedTabs;
 | 
						|
  List<int> _visibleOrderedTabs = List.empty(growable: true);
 | 
						|
  List<int> get tabOrder => _tabOrder;
 | 
						|
  List<int> _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<bool> _fullyVisible = List.filled(5, false);
 | 
						|
  bool get leftFullyVisible => _leftFullyVisible;
 | 
						|
  bool _leftFullyVisible = false;
 | 
						|
  bool get rightFullyVisible => _rightFullyVisible;
 | 
						|
  bool _rightFullyVisible = false;
 | 
						|
  ScrollPosController sc = ScrollPosController();
 | 
						|
  List<String> 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<int> 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<int> orderedNotFilteredTabs() {
 | 
						|
    var list = tabOrder.toList();
 | 
						|
    if (_filterGroupCard()) {
 | 
						|
      list.remove(groupTabIndex);
 | 
						|
    }
 | 
						|
    return list;
 | 
						|
  }
 | 
						|
 | 
						|
  // return index array of tabNames
 | 
						|
  List<int> visibleTabs() {
 | 
						|
    var v = List<int>.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<int> _notHiddenTabs() {
 | 
						|
    var v = List<int>.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<int> 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);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |