2023-09-14 16:30:45 +08:00
import ' dart:convert ' ;
2023-08-04 13:11:24 +08:00
import ' dart:math ' ;
2023-02-03 15:07:45 +08:00
import ' package:flutter/material.dart ' ;
2023-08-03 16:48:14 +08:00
import ' package:flutter_hbb/models/peer_model.dart ' ;
2023-02-03 15:07:45 +08:00
import ' package:flutter_hbb/models/platform_model.dart ' ;
2023-08-03 16:48:14 +08:00
import ' package:get/get.dart ' ;
2023-02-03 15:07:45 +08:00
import ' ../common.dart ' ;
import ' model.dart ' ;
2023-08-03 16:48:14 +08:00
enum PeerTabIndex {
recent ,
fav ,
lan ,
ab ,
group ,
}
2023-02-03 15:07:45 +08:00
class PeerTabModel with ChangeNotifier {
WeakReference < FFI > parent ;
int get currentTab = > _currentTab ;
int _currentTab = 0 ; // index in tabNames
List < String > tabNames = [
' Recent Sessions ' ,
' Favorites ' ,
' Discovered ' ,
' Address Book ' ,
2023-09-14 10:17:03 +08:00
' Group ' ,
2023-02-03 15:07:45 +08:00
] ;
2023-06-21 16:04:52 +08:00
final List < IconData > icons = [
2023-06-23 12:58:27 +08:00
Icons . access_time_filled ,
2023-06-21 16:04:52 +08:00
Icons . star ,
Icons . explore ,
IconFont . addressBook ,
Icons . group ,
] ;
2023-09-14 10:17:03 +08:00
final List < bool > _isVisible = List . filled ( 5 , true , growable: false ) ;
2023-09-14 16:30:45 +08:00
List < bool > get isVisible = > _isVisible ;
2023-06-21 16:04:52 +08:00
List < int > get indexs = > List . generate ( tabNames . length , ( index ) = > index ) ;
2023-09-14 16:30:45 +08:00
List < int > get visibleIndexs = > indexs . where ( ( e ) = > _isVisible [ e ] ) . toList ( ) ;
2023-08-03 16:48:14 +08:00
List < Peer > _selectedPeers = List . empty ( growable: true ) ;
List < Peer > get selectedPeers = > _selectedPeers ;
2023-08-09 22:00:15 +08:00
bool _multiSelectionMode = false ;
bool get multiSelectionMode = > _multiSelectionMode ;
2023-08-03 16:48:14 +08:00
List < Peer > _currentTabCachedPeers = List . empty ( growable: true ) ;
List < Peer > get currentTabCachedPeers = > _currentTabCachedPeers ;
2023-08-09 22:00:15 +08:00
bool _isShiftDown = false ;
bool get isShiftDown = > _isShiftDown ;
String _lastId = ' ' ;
String get lastId = > _lastId ;
2023-02-03 15:07:45 +08:00
PeerTabModel ( this . parent ) {
2023-09-14 16:30:45 +08:00
// visible
try {
final option = bind . getLocalFlutterOption ( k: ' peer-tab-visible ' ) ;
if ( option . isNotEmpty ) {
List < dynamic > decodeList = jsonDecode ( option ) ;
if ( decodeList . length = = _isVisible . length ) {
for ( int i = 0 ; i < _isVisible . length ; i + + ) {
if ( decodeList [ i ] is bool ) {
_isVisible [ i ] = decodeList [ i ] ;
}
}
}
}
} catch ( e ) {
debugPrint ( " failed to get peer tab visible list: $ e " ) ;
}
2023-02-03 15:07:45 +08:00
// init currentTab
_currentTab =
2023-08-10 22:27:35 +08:00
int . tryParse ( bind . getLocalFlutterOption ( k: ' peer-tab-index ' ) ) ? ? 0 ;
2023-06-21 16:04:52 +08:00
if ( _currentTab < 0 | | _currentTab > = tabNames . length ) {
_currentTab = 0 ;
2023-02-03 15:07:45 +08:00
}
2023-09-14 16:30:45 +08:00
_trySetCurrentTabToFirstVisible ( ) ;
2023-02-03 15:07:45 +08:00
}
setCurrentTab ( int index ) {
if ( _currentTab ! = index ) {
_currentTab = index ;
notifyListeners ( ) ;
}
}
2023-09-14 10:17:03 +08:00
String tabTooltip ( int index ) {
2023-02-03 15:07:45 +08:00
if ( index > = 0 & & index < tabNames . length ) {
2023-09-14 10:17:03 +08:00
return translate ( tabNames [ index ] ) ;
2023-02-03 15:07:45 +08:00
}
assert ( false ) ;
return index . toString ( ) ;
}
2023-06-21 16:04:52 +08:00
IconData tabIcon ( int index ) {
if ( index > = 0 & & index < tabNames . length ) {
return icons [ index ] ;
2023-02-03 15:07:45 +08:00
}
2023-06-21 16:04:52 +08:00
assert ( false ) ;
return Icons . help ;
2023-02-03 15:07:45 +08:00
}
2023-08-03 16:48:14 +08:00
2023-08-09 22:00:15 +08:00
setMultiSelectionMode ( bool mode ) {
_multiSelectionMode = mode ;
if ( ! mode ) {
_selectedPeers . clear ( ) ;
_lastId = ' ' ;
}
notifyListeners ( ) ;
}
select ( Peer peer ) {
if ( ! _multiSelectionMode ) {
// https://github.com/flutter/flutter/issues/101275#issuecomment-1604541700
// After onTap, the shift key should be pressed for a while when not in multiselection mode,
// because onTap is delayed when onDoubleTap is not null
if ( isDesktop & & ! _isShiftDown ) return ;
_multiSelectionMode = true ;
}
2023-08-04 13:11:24 +08:00
final cached = _currentTabCachedPeers . map ( ( e ) = > e . id ) . toList ( ) ;
int thisIndex = cached . indexOf ( peer . id ) ;
2023-08-09 22:00:15 +08:00
int lastIndex = cached . indexOf ( _lastId ) ;
if ( _isShiftDown & & thisIndex > = 0 & & lastIndex > = 0 ) {
int start = min ( thisIndex , lastIndex ) ;
int end = max ( thisIndex , lastIndex ) ;
bool remove = isPeerSelected ( peer . id ) ;
2023-08-04 13:11:24 +08:00
for ( var i = start ; i < = end ; i + + ) {
2023-08-09 22:00:15 +08:00
if ( remove ) {
if ( isPeerSelected ( cached [ i ] ) ) {
_selectedPeers . removeWhere ( ( p ) = > p . id = = cached [ i ] ) ;
}
} else {
if ( ! isPeerSelected ( cached [ i ] ) ) {
_selectedPeers . add ( _currentTabCachedPeers [ i ] ) ;
}
2023-08-04 13:11:24 +08:00
}
}
2023-08-03 16:48:14 +08:00
} else {
2023-08-04 13:11:24 +08:00
if ( isPeerSelected ( peer . id ) ) {
_selectedPeers . removeWhere ( ( p ) = > p . id = = peer . id ) ;
} else {
_selectedPeers . add ( peer ) ;
}
2023-08-03 16:48:14 +08:00
}
2023-08-09 22:00:15 +08:00
_lastId = peer . id ;
2023-08-03 16:48:14 +08:00
notifyListeners ( ) ;
}
setCurrentTabCachedPeers ( List < Peer > 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 ;
}
2023-08-09 22:00:15 +08:00
setShiftDown ( bool v ) {
if ( _isShiftDown ! = v ) {
_isShiftDown = v ;
if ( _multiSelectionMode ) {
notifyListeners ( ) ;
}
}
}
2023-09-14 16:30:45 +08:00
setTabVisible ( int index , bool visible ) {
if ( index > = 0 & & index < _isVisible . length ) {
if ( _isVisible [ index ] ! = visible ) {
_isVisible [ index ] = visible ;
if ( index = = _currentTab & & ! visible ) {
_trySetCurrentTabToFirstVisible ( ) ;
} else if ( visible & & visibleIndexs . length = = 1 ) {
_currentTab = index ;
}
try {
bind . setLocalFlutterOption (
k: ' peer-tab-visible ' , v: jsonEncode ( _isVisible ) ) ;
} catch ( _ ) { }
notifyListeners ( ) ;
}
}
}
_trySetCurrentTabToFirstVisible ( ) {
if ( ! _isVisible [ _currentTab ] ) {
int firstVisible = _isVisible . indexWhere ( ( e ) = > e ) ;
if ( firstVisible > = 0 ) {
_currentTab = firstVisible ;
}
}
}
2023-02-03 15:07:45 +08:00
}