mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-25 05:27:42 +00:00
Save search query to savedinstancestate.
This commit is contained in:
committed by
Cody Henthorne
parent
46ca979e59
commit
524ffd9d79
@@ -252,16 +252,23 @@ class MainActivity : PassphraseRequiredActivity(), VoiceNoteMediaControllerOwner
|
||||
)
|
||||
)
|
||||
|
||||
if (SignalStore.internal.largeScreenUi) {
|
||||
LaunchedEffect(scaffoldNavigator.currentDestination) {
|
||||
if (scaffoldNavigator.currentDestination?.pane == ThreePaneScaffoldRole.Secondary) {
|
||||
mainNavigationViewModel.goTo(MainNavigationDetailLocation.Empty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(detailLocation) {
|
||||
if (detailLocation is MainNavigationDetailLocation.Conversation) {
|
||||
if (SignalStore.internal.largeScreenUi) {
|
||||
scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Primary, detailLocation)
|
||||
} else {
|
||||
startActivity((detailLocation as MainNavigationDetailLocation.Conversation).intent)
|
||||
mainNavigationViewModel.goTo(MainNavigationDetailLocation.Empty)
|
||||
}
|
||||
}
|
||||
|
||||
mainNavigationViewModel.goTo(MainNavigationDetailLocation.Empty)
|
||||
}
|
||||
|
||||
AppScaffold(
|
||||
|
||||
@@ -126,6 +126,8 @@ class ContactSearchMediator(
|
||||
}
|
||||
}
|
||||
|
||||
fun getFilter(): String? = viewModel.getQuery()
|
||||
|
||||
fun onConversationFilterRequestChanged(conversationFilterRequest: ConversationFilterRequest) {
|
||||
viewModel.setConversationFilterRequest(conversationFilterRequest)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package org.thoughtcrime.securesms.contacts.paged
|
||||
|
||||
import androidx.lifecycle.AbstractSavedStateViewModelFactory
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.map
|
||||
import androidx.lifecycle.switchMap
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
@@ -26,6 +27,7 @@ import org.whispersystems.signalservice.api.util.Preconditions
|
||||
* Simple, reusable view model that manages a ContactSearchPagedDataSource as well as filter and expansion state.
|
||||
*/
|
||||
class ContactSearchViewModel(
|
||||
private val savedStateHandle: SavedStateHandle,
|
||||
private val selectionLimits: SelectionLimits,
|
||||
private val contactSearchRepository: ContactSearchRepository,
|
||||
private val performSafetyNumberChecks: Boolean,
|
||||
@@ -34,6 +36,10 @@ class ContactSearchViewModel(
|
||||
private val contactSearchPagedDataSourceRepository: ContactSearchPagedDataSourceRepository
|
||||
) : ViewModel() {
|
||||
|
||||
companion object {
|
||||
private const val QUERY = "query"
|
||||
}
|
||||
|
||||
private val safetyNumberRepository: SafetyNumberRepository by lazy { SafetyNumberRepository() }
|
||||
|
||||
private val disposables = CompositeDisposable()
|
||||
@@ -45,7 +51,7 @@ class ContactSearchViewModel(
|
||||
.build()
|
||||
|
||||
private val pagedData = MutableLiveData<LivePagedData<ContactSearchKey, ContactSearchData>>()
|
||||
private val configurationStore = Store(ContactSearchState())
|
||||
private val configurationStore = Store(ContactSearchState(query = savedStateHandle[QUERY]))
|
||||
private val selectionStore = Store<Set<ContactSearchKey>>(emptySet())
|
||||
private val errorEvents = PublishSubject.create<ContactSearchError>()
|
||||
|
||||
@@ -73,7 +79,10 @@ class ContactSearchViewModel(
|
||||
pagedData.value = PagedData.createForLiveData(pagedDataSource, pagingConfig)
|
||||
}
|
||||
|
||||
fun getQuery(): String? = savedStateHandle[QUERY]
|
||||
|
||||
fun setQuery(query: String?) {
|
||||
savedStateHandle[QUERY] = query
|
||||
configurationStore.update { it.copy(query = query) }
|
||||
}
|
||||
|
||||
@@ -169,10 +178,11 @@ class ContactSearchViewModel(
|
||||
private val arbitraryRepository: ArbitraryRepository?,
|
||||
private val searchRepository: SearchRepository,
|
||||
private val contactSearchPagedDataSourceRepository: ContactSearchPagedDataSourceRepository
|
||||
) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
) : AbstractSavedStateViewModelFactory() {
|
||||
override fun <T : ViewModel> create(key: String, modelClass: Class<T>, handle: SavedStateHandle): T {
|
||||
return modelClass.cast(
|
||||
ContactSearchViewModel(
|
||||
savedStateHandle = handle,
|
||||
selectionLimits = selectionLimits,
|
||||
contactSearchRepository = repository,
|
||||
performSafetyNumberChecks = performSafetyNumberChecks,
|
||||
|
||||
@@ -389,6 +389,12 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||
initializeVoiceNotePlayer();
|
||||
initializeBanners();
|
||||
maybeScheduleRefreshProfileJob();
|
||||
ConversationListFragmentExtensionsKt.listenToEventBusWhileResumed(this, mainNavigationViewModel.getDetailLocation());
|
||||
|
||||
String query = contactSearchMediator.getFilter();
|
||||
if (query != null) {
|
||||
onSearchQueryUpdated(query);
|
||||
}
|
||||
|
||||
RatingManager.showRatingDialogIfNecessary(requireContext());
|
||||
|
||||
@@ -473,7 +479,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||
|
||||
initializeSearchListener();
|
||||
initializeFilterListener();
|
||||
EventBus.getDefault().register(this);
|
||||
itemAnimator.disable();
|
||||
SpoilerAnnotation.resetRevealedSpoilers();
|
||||
|
||||
@@ -539,13 +544,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||
itemAnimator.disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
EventBus.getDefault().unregister(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.conversationlist
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.eventFlow
|
||||
import androidx.lifecycle.flowWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.launch
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.thoughtcrime.securesms.main.MainNavigationDetailLocation
|
||||
import org.thoughtcrime.securesms.window.WindowSizeClass.Companion.getWindowSizeClass
|
||||
|
||||
/**
|
||||
* When the user searches for a conversation and then enters a message, we should clear
|
||||
* the search. This is driven by an event bus, which we want to subscribe to only when
|
||||
* the screen has been resumed.
|
||||
*
|
||||
* On COMPACT form factor specifically, we also need to wait until we are in the EMPTY
|
||||
* detail location, to avoid weird predictive back animation issues.
|
||||
*
|
||||
* On other screen types, since we are in a multi-pane mode, we can subscribe immediately.
|
||||
*/
|
||||
fun Fragment.listenToEventBusWhileResumed(
|
||||
detailLocation: Flow<MainNavigationDetailLocation>
|
||||
) {
|
||||
lifecycleScope.launch {
|
||||
detailLocation
|
||||
.flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.RESUMED)
|
||||
.collectLatest {
|
||||
if (resources.getWindowSizeClass().isCompact()) {
|
||||
when (it) {
|
||||
is MainNavigationDetailLocation.Conversation -> unsubscribe()
|
||||
MainNavigationDetailLocation.Empty -> subscribe()
|
||||
}
|
||||
} else {
|
||||
subscribe()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
lifecycle.eventFlow.filter { it == Lifecycle.Event.ON_PAUSE }
|
||||
.collectLatest { unsubscribe() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun Fragment.subscribe() {
|
||||
if (!EventBus.getDefault().isRegistered(this)) {
|
||||
EventBus.getDefault().register(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Fragment.unsubscribe() {
|
||||
if (EventBus.getDefault().isRegistered(this)) {
|
||||
EventBus.getDefault().unregister(this)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user