Keep peer list search result after hitting search button

Signed-off-by: Percy Wegmann <percy@tailscale.com>
ox/styling_bak
Percy Wegmann 2 years ago
parent 89b3a04c0a
commit 08886f8880
No known key found for this signature in database
GPG Key ID: 29D8CDEB4C13D48B

@ -6,37 +6,16 @@ package com.tailscale.ipn.ui.util
import com.tailscale.ipn.ui.model.Netmap
import com.tailscale.ipn.ui.model.Tailcfg
import com.tailscale.ipn.ui.model.UserID
import com.tailscale.ipn.ui.notifier.Notifier
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
data class PeerSet(val user: Tailcfg.UserProfile?, val peers: List<Tailcfg.Node>)
typealias GroupedPeers = MutableMap<UserID, MutableList<Tailcfg.Node>>
class PeerCategorizer(scope: CoroutineScope) {
class PeerCategorizer {
var peerSets: List<PeerSet> = emptyList()
var lastSearchResult: List<PeerSet> = emptyList()
var searchTerm: String = ""
var lastSearchTerm: String = ""
// Keep the peer sets current while the model is active
init {
scope.launch {
Notifier.netmap.collect { netmap ->
netmap?.let {
peerSets = regenerateGroupedPeers(netmap)
lastSearchResult = peerSets
}
?: run {
peerSets = emptyList()
lastSearchResult = emptyList()
}
}
}
}
private fun regenerateGroupedPeers(netmap: Netmap.NetworkMap): List<PeerSet> {
val peers: List<Tailcfg.Node> = netmap.Peers ?: return emptyList()
fun regenerateGroupedPeers(netmap: Netmap.NetworkMap) {
val peers: List<Tailcfg.Node> = netmap.Peers ?: return
val selfNode = netmap.SelfNode
var grouped = mutableMapOf<UserID, MutableList<Tailcfg.Node>>()
@ -56,7 +35,7 @@ class PeerCategorizer(scope: CoroutineScope) {
val me = netmap.currentUserProfile()
val peerSets =
peerSets =
grouped
.map { (userId, peers) ->
val profile = netmap.userProfile(userId)
@ -69,8 +48,6 @@ class PeerCategorizer(scope: CoroutineScope) {
it.user?.DisplayName ?: "Unknown User"
}
}
return peerSets
}
fun groupedAndFilteredPeers(searchTerm: String = ""): List<PeerSet> {
@ -78,14 +55,17 @@ class PeerCategorizer(scope: CoroutineScope) {
return peerSets
}
if (searchTerm == this.searchTerm) {
if (searchTerm == this.lastSearchTerm) {
return lastSearchResult
}
// We can optimize out typing... If the search term starts with the last search term, we can
// just search the last result
val setsToSearch = if (searchTerm.startsWith(this.searchTerm)) lastSearchResult else peerSets
this.searchTerm = searchTerm
val setsToSearch =
if (this.lastSearchTerm.isNotEmpty() && searchTerm.startsWith(this.lastSearchTerm))
lastSearchResult
else peerSets
this.lastSearchTerm = searchTerm
val matchingSets =
setsToSearch
@ -107,7 +87,7 @@ class PeerCategorizer(scope: CoroutineScope) {
}
}
.filterNotNull()
lastSearchResult = matchingSets
return matchingSets
}
}

@ -37,7 +37,7 @@ class MainViewModel : IpnViewModel() {
// The active search term for filtering peers
val searchTerm: StateFlow<String> = MutableStateFlow("")
private val peerCategorizer = PeerCategorizer(viewModelScope)
private val peerCategorizer = PeerCategorizer()
val userName: String
get() {
@ -53,15 +53,21 @@ class MainViewModel : IpnViewModel() {
}
viewModelScope.launch {
Notifier.netmap.collect { netmap ->
peers.set(peerCategorizer.groupedAndFilteredPeers(searchTerm.value))
Notifier.netmap.collect { it ->
it?.let { netmap ->
peerCategorizer.regenerateGroupedPeers(netmap)
peers.set(peerCategorizer.groupedAndFilteredPeers(searchTerm.value))
}
}
}
viewModelScope.launch {
searchTerm.collect { term -> peers.set(peerCategorizer.groupedAndFilteredPeers(term)) }
}
}
fun searchPeers(searchTerm: String) {
this.searchTerm.set(searchTerm)
viewModelScope.launch { peers.set(peerCategorizer.groupedAndFilteredPeers(searchTerm)) }
}
fun disableExitNode() {

Loading…
Cancel
Save