import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_hbb/models/peer_model.dart'; import 'package:flutter_hbb/models/platform_model.dart'; import 'package:get/get.dart'; import '../common.dart'; import 'model.dart'; enum PeerTabIndex { recent, fav, lan, ab, group, } const String defaultGroupTabname = 'Group'; class PeerTabModel with ChangeNotifier { WeakReference parent; int get currentTab => _currentTab; int _currentTab = 0; // index in tabNames List tabNames = [ 'Recent Sessions', 'Favorites', 'Discovered', 'Address Book', //defaultGroupTabname, ]; final List icons = [ Icons.access_time_filled, Icons.star, Icons.explore, IconFont.addressBook, Icons.group, ]; List get indexs => List.generate(tabNames.length, (index) => index); List _selectedPeers = List.empty(growable: true); List get selectedPeers => _selectedPeers; bool get multiSelectionMode => _selectedPeers.isNotEmpty; List _currentTabCachedPeers = List.empty(growable: true); List get currentTabCachedPeers => _currentTabCachedPeers; bool isShiftDown = false; String? _shiftAnchorId; PeerTabModel(this.parent) { // init currentTab _currentTab = int.tryParse(bind.getLocalFlutterConfig(k: 'peer-tab-index')) ?? 0; if (_currentTab < 0 || _currentTab >= tabNames.length) { _currentTab = 0; } } setCurrentTab(int index) { if (_currentTab != index) { _currentTab = index; notifyListeners(); } } String tabTooltip(int index, String groupName) { if (index >= 0 && index < tabNames.length) { if (index == PeerTabIndex.group.index) { if (gFFI.userModel.isAdmin.value || groupName.isEmpty) { return translate(defaultGroupTabname); } else { return '${translate('Group')}: $groupName'; } } else { return translate(tabNames[index]); } } assert(false); return index.toString(); } IconData tabIcon(int index) { if (index >= 0 && index < tabNames.length) { return icons[index]; } assert(false); return Icons.help; } togglePeerSelect(Peer peer) { final cached = _currentTabCachedPeers.map((e) => e.id).toList(); int thisIndex = cached.indexOf(peer.id); int closestIndex = -1; String? closestId; int smallestDiff = -1; for (var i = 0; i < cached.length; i++) { if (isPeerSelected(cached[i])) { int diff = (i - thisIndex).abs(); if (smallestDiff == -1 || diff < smallestDiff) { closestIndex = i; closestId = cached[i]; smallestDiff = diff; } } } if (isShiftDown && thisIndex >= 0 && closestIndex >= 0 && closestId != null) { int shiftAnchorIndex = cached.indexOf(_shiftAnchorId ?? ''); if (shiftAnchorIndex < 0) { // use closest as shift anchor, rather than focused which we don't have shiftAnchorIndex = closestIndex; _shiftAnchorId = closestId; } int start = min(shiftAnchorIndex, thisIndex); int end = max(shiftAnchorIndex, thisIndex); _selectedPeers.clear(); for (var i = start; i <= end; i++) { if (!isPeerSelected(cached[i])) { _selectedPeers.add(_currentTabCachedPeers[i]); } } } else { if (isPeerSelected(peer.id)) { _selectedPeers.removeWhere((p) => p.id == peer.id); } else { _selectedPeers.add(peer); } _shiftAnchorId = null; } notifyListeners(); } closeSelection() { _selectedPeers.clear(); _shiftAnchorId = null; notifyListeners(); } setCurrentTabCachedPeers(List peers) { Future.delayed(Duration.zero, () { _currentTabCachedPeers = peers; notifyListeners(); }); } selectAll() { _selectedPeers = _currentTabCachedPeers.toList(); notifyListeners(); } bool isPeerSelected(String id) { return selectedPeers.firstWhereOrNull((p) => p.id == id) != null; } }