implemented sorting in every tab except "recent sessions"
This commit is contained in:
parent
6ae2fbdbc8
commit
a04351baf4
@ -12,6 +12,7 @@ import 'package:flutter_hbb/desktop/widgets/popup_menu.dart';
|
|||||||
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
|
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
|
||||||
import 'package:flutter_hbb/desktop/widgets/material_mod_popup_menu.dart'
|
import 'package:flutter_hbb/desktop/widgets/material_mod_popup_menu.dart'
|
||||||
as mod_menu;
|
as mod_menu;
|
||||||
|
import 'package:flutter_hbb/models/file_model.dart';
|
||||||
import 'package:flutter_hbb/models/peer_tab_model.dart';
|
import 'package:flutter_hbb/models/peer_tab_model.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart';
|
import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart';
|
||||||
@ -39,6 +40,8 @@ EdgeInsets? _menuPadding() {
|
|||||||
|
|
||||||
class _PeerTabPageState extends State<PeerTabPage>
|
class _PeerTabPageState extends State<PeerTabPage>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
|
bool _hideSort = bind.getLocalFlutterConfig(k: 'peer-tab-index') == '0';
|
||||||
|
|
||||||
final List<_TabEntry> entries = [
|
final List<_TabEntry> entries = [
|
||||||
_TabEntry(
|
_TabEntry(
|
||||||
RecentPeersView(
|
RecentPeersView(
|
||||||
@ -83,6 +86,7 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
if (tabIndex < entries.length) {
|
if (tabIndex < entries.length) {
|
||||||
gFFI.peerTabModel.setCurrentTab(tabIndex);
|
gFFI.peerTabModel.setCurrentTab(tabIndex);
|
||||||
entries[tabIndex].load();
|
entries[tabIndex].load();
|
||||||
|
_hideSort = tabIndex == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,16 +105,21 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: visibleContextMenuListener(
|
child:
|
||||||
_createSwitchBar(context))),
|
visibleContextMenuListener(_createSwitchBar(context))),
|
||||||
buildScrollJumper(),
|
buildScrollJumper(),
|
||||||
const PeerSearchBar(),
|
const PeerSearchBar(),
|
||||||
Offstage(
|
Offstage(
|
||||||
offstage: !isDesktop,
|
offstage: !isDesktop,
|
||||||
child: _createPeerViewTypeSwitch(context)
|
child: _createPeerViewTypeSwitch(context)
|
||||||
.marginOnly(left: 13)),
|
.marginOnly(left: 13)),
|
||||||
|
Offstage(
|
||||||
|
offstage: _hideSort,
|
||||||
|
child: PeerSortDropdown(),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
_createPeersView(),
|
_createPeersView(),
|
||||||
],
|
],
|
||||||
@ -417,3 +426,48 @@ class _PeerSearchBarState extends State<PeerSearchBar> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PeerSortDropdown extends StatefulWidget {
|
||||||
|
const PeerSortDropdown({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<PeerSortDropdown> createState() => _PeerSortDropdownState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PeerSortDropdownState extends State<PeerSortDropdown> {
|
||||||
|
final List<String> sort_names = ['id', 'username', "status"];
|
||||||
|
String _sortType = peerSort.value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DropdownButton<String>(
|
||||||
|
value: _sortType,
|
||||||
|
elevation: 16,
|
||||||
|
underline: SizedBox(),
|
||||||
|
onChanged: (v) {
|
||||||
|
if (v != null) {
|
||||||
|
setState(() {
|
||||||
|
_sortType = v;
|
||||||
|
bind.setLocalFlutterConfig(
|
||||||
|
k: "peer-sorting",
|
||||||
|
v: _sortType,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
peerSort.value = _sortType;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dropdownColor: Theme.of(context).cardColor,
|
||||||
|
items: sort_names
|
||||||
|
.map<DropdownMenuItem<String>>(
|
||||||
|
(String value) => DropdownMenuItem<String>(
|
||||||
|
value: value,
|
||||||
|
child: Text(
|
||||||
|
value,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,6 +18,13 @@ typedef PeerCardBuilder = Widget Function(Peer peer);
|
|||||||
|
|
||||||
/// for peer search text, global obs value
|
/// for peer search text, global obs value
|
||||||
final peerSearchText = "".obs;
|
final peerSearchText = "".obs;
|
||||||
|
|
||||||
|
/// for peer sort, global obs value
|
||||||
|
final peerSort = bind.getLocalFlutterConfig(k: 'peer-sorting').obs;
|
||||||
|
|
||||||
|
// list for listener
|
||||||
|
final obslist = [peerSearchText, peerSort].obs;
|
||||||
|
|
||||||
final peerSearchTextController =
|
final peerSearchTextController =
|
||||||
TextEditingController(text: peerSearchText.value);
|
TextEditingController(text: peerSearchText.value);
|
||||||
|
|
||||||
@ -101,7 +108,7 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPeersView(Peers peers) {
|
Widget _buildPeersView(Peers peers) {
|
||||||
final body = ObxValue<RxString>((searchText) {
|
final body = ObxValue<RxList>((filters) {
|
||||||
return FutureBuilder<List<Peer>>(
|
return FutureBuilder<List<Peer>>(
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
@ -139,9 +146,9 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
future: matchPeers(searchText.value, peers.peers),
|
future: matchPeers(filters[0].value, filters[1].value, peers.peers),
|
||||||
);
|
);
|
||||||
}, peerSearchText);
|
}, obslist);
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
@ -179,11 +186,36 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
|
|||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Peer>>? matchPeers(String searchText, List<Peer> peers) async {
|
Future<List<Peer>>? matchPeers(
|
||||||
|
String searchText, String sortedBy, List<Peer> peers) async {
|
||||||
if (widget.peerFilter != null) {
|
if (widget.peerFilter != null) {
|
||||||
peers = peers.where((peer) => widget.peerFilter!(peer)).toList();
|
peers = peers.where((peer) => widget.peerFilter!(peer)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fallback to id sorting
|
||||||
|
if (sortedBy.isEmpty) {
|
||||||
|
sortedBy = 'id';
|
||||||
|
bind.setLocalFlutterConfig(
|
||||||
|
k: "peer-sorting",
|
||||||
|
v: sortedBy,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widget.peers.loadEvent != 'load_recent_peers') {
|
||||||
|
switch (sortedBy) {
|
||||||
|
case 'id':
|
||||||
|
peers.sort((p1, p2) => p1.id.compareTo(p2.id));
|
||||||
|
break;
|
||||||
|
case 'username':
|
||||||
|
peers.sort((p1, p2) =>
|
||||||
|
p1.username.toLowerCase().compareTo(p2.username.toLowerCase()));
|
||||||
|
break;
|
||||||
|
case 'status':
|
||||||
|
peers.sort((p1, p2) => p1.online ? 1 : -1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
searchText = searchText.trim();
|
searchText = searchText.trim();
|
||||||
if (searchText.isEmpty) {
|
if (searchText.isEmpty) {
|
||||||
return peers;
|
return peers;
|
||||||
@ -197,6 +229,7 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
|
|||||||
filteredList.add(peers[i]);
|
filteredList.add(peers[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return filteredList;
|
return filteredList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user