implemented sorting in every tab except "recent sessions"

This commit is contained in:
NicKoehler 2023-03-03 20:53:42 +01:00
parent 6ae2fbdbc8
commit a04351baf4
No known key found for this signature in database
GPG Key ID: BAE01394EB51AC58
2 changed files with 107 additions and 20 deletions

View File

@ -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/material_mod_popup_menu.dart'
as mod_menu;
import 'package:flutter_hbb/models/file_model.dart';
import 'package:flutter_hbb/models/peer_tab_model.dart';
import 'package:get/get.dart';
import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart';
@ -39,6 +40,8 @@ EdgeInsets? _menuPadding() {
class _PeerTabPageState extends State<PeerTabPage>
with SingleTickerProviderStateMixin {
bool _hideSort = bind.getLocalFlutterConfig(k: 'peer-tab-index') == '0';
final List<_TabEntry> entries = [
_TabEntry(
RecentPeersView(
@ -83,6 +86,7 @@ class _PeerTabPageState extends State<PeerTabPage>
if (tabIndex < entries.length) {
gFFI.peerTabModel.setCurrentTab(tabIndex);
entries[tabIndex].load();
_hideSort = tabIndex == 0;
}
}
@ -95,22 +99,27 @@ class _PeerTabPageState extends State<PeerTabPage>
SizedBox(
height: 28,
child: Container(
padding: isDesktop ? null : EdgeInsets.symmetric(horizontal: 2),
constraints: isDesktop ? null : kMobilePageConstraints,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: visibleContextMenuListener(
_createSwitchBar(context))),
buildScrollJumper(),
const PeerSearchBar(),
Offstage(
offstage: !isDesktop,
child: _createPeerViewTypeSwitch(context)
.marginOnly(left: 13)),
],
)),
padding: isDesktop ? null : EdgeInsets.symmetric(horizontal: 2),
constraints: isDesktop ? null : kMobilePageConstraints,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child:
visibleContextMenuListener(_createSwitchBar(context))),
buildScrollJumper(),
const PeerSearchBar(),
Offstage(
offstage: !isDesktop,
child: _createPeerViewTypeSwitch(context)
.marginOnly(left: 13)),
Offstage(
offstage: _hideSort,
child: PeerSortDropdown(),
)
],
),
),
),
_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(),
);
}
}

View File

@ -18,6 +18,13 @@ typedef PeerCardBuilder = Widget Function(Peer peer);
/// for peer search text, global obs value
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 =
TextEditingController(text: peerSearchText.value);
@ -101,7 +108,7 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
}
Widget _buildPeersView(Peers peers) {
final body = ObxValue<RxString>((searchText) {
final body = ObxValue<RxList>((filters) {
return FutureBuilder<List<Peer>>(
builder: (context, snapshot) {
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;
}
@ -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) {
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();
if (searchText.isEmpty) {
return peers;
@ -197,6 +229,7 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
filteredList.add(peers[i]);
}
}
return filteredList;
}
}