From 08886f8880356c930b1a4fa24da23809130c1b69 Mon Sep 17 00:00:00 2001 From: Percy Wegmann Date: Fri, 29 Mar 2024 11:05:37 -0500 Subject: [PATCH] Keep peer list search result after hitting search button Signed-off-by: Percy Wegmann --- .../com/tailscale/ipn/ui/util/PeerHelper.kt | 44 +++++-------------- .../ipn/ui/viewModel/MainViewModel.kt | 14 ++++-- 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/android/src/main/java/com/tailscale/ipn/ui/util/PeerHelper.kt b/android/src/main/java/com/tailscale/ipn/ui/util/PeerHelper.kt index 847192b..e4c92f6 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/util/PeerHelper.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/util/PeerHelper.kt @@ -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) -typealias GroupedPeers = MutableMap> - -class PeerCategorizer(scope: CoroutineScope) { +class PeerCategorizer { var peerSets: List = emptyList() var lastSearchResult: List = 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 { - val peers: List = netmap.Peers ?: return emptyList() + fun regenerateGroupedPeers(netmap: Netmap.NetworkMap) { + val peers: List = netmap.Peers ?: return val selfNode = netmap.SelfNode var grouped = mutableMapOf>() @@ -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 { @@ -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 } } diff --git a/android/src/main/java/com/tailscale/ipn/ui/viewModel/MainViewModel.kt b/android/src/main/java/com/tailscale/ipn/ui/viewModel/MainViewModel.kt index 68f1cb4..11f5b0a 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/viewModel/MainViewModel.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/viewModel/MainViewModel.kt @@ -37,7 +37,7 @@ class MainViewModel : IpnViewModel() { // The active search term for filtering peers val searchTerm: StateFlow = 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() {