Add basic story search support.
This commit is contained in:
parent
1049f8bd2f
commit
e8c10cd550
6 changed files with 63 additions and 15 deletions
|
@ -120,6 +120,7 @@ import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob;
|
|||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.lock.v2.CreateKbsPinActivity;
|
||||
import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder;
|
||||
import org.thoughtcrime.securesms.main.SearchBinder;
|
||||
import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionActivity;
|
||||
import org.thoughtcrime.securesms.megaphone.Megaphone;
|
||||
import org.thoughtcrime.securesms.megaphone.MegaphoneActionController;
|
||||
|
@ -299,7 +300,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
initializeViewModel();
|
||||
initializeListAdapters();
|
||||
initializeTypingObserver();
|
||||
initializeSearchListener();
|
||||
initializeVoiceNotePlayer();
|
||||
|
||||
RatingManager.showRatingDialogIfNecessary(requireContext());
|
||||
|
@ -362,6 +362,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
initializeSearchListener();
|
||||
updateReminders();
|
||||
EventBus.getDefault().register(this);
|
||||
itemAnimator.disable();
|
||||
|
@ -434,6 +435,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
requireCallback().getSearchAction().setOnClickListener(null);
|
||||
fab.stopPulse();
|
||||
cameraFab.stopPulse();
|
||||
EventBus.getDefault().unregister(this);
|
||||
|
@ -617,8 +619,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
requireCallback().getSearchAction().setOnClickListener(v -> {
|
||||
fadeOutButtonsAndMegaphone(250);
|
||||
requireCallback().onSearchOpened();
|
||||
requireCallback().getSearchToolbar().get().display(requireCallback().getSearchAction().getX() + (requireCallback().getSearchAction().getWidth() / 2.0f),
|
||||
requireCallback().getSearchAction().getY() + (requireCallback().getSearchAction().getHeight() / 2.0f));
|
||||
|
||||
requireCallback().getSearchToolbar().get().setListener(new Material3SearchToolbar.Listener() {
|
||||
@Override
|
||||
|
@ -1670,13 +1670,9 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
}
|
||||
}
|
||||
|
||||
public interface Callback extends Material3OnScrollHelperBinder {
|
||||
public interface Callback extends Material3OnScrollHelperBinder, SearchBinder {
|
||||
@NonNull Toolbar getToolbar();
|
||||
|
||||
@NonNull ImageView getSearchAction();
|
||||
|
||||
@NonNull Stub<Material3SearchToolbar> getSearchToolbar();
|
||||
|
||||
@NonNull View getUnreadPaymentsDot();
|
||||
|
||||
@NonNull Stub<Toolbar> getBasicToolbar();
|
||||
|
@ -1685,10 +1681,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
|
||||
void updateProxyStatus(@NonNull WebSocketConnectionState state);
|
||||
|
||||
void onSearchOpened();
|
||||
|
||||
void onSearchClosed();
|
||||
|
||||
void onMultiSelectStarted();
|
||||
|
||||
void onMultiSelectFinished();
|
||||
|
|
|
@ -172,7 +172,7 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
|||
|
||||
private fun presentToolbarForStoriesLandingFragment() {
|
||||
_toolbar.visible = true
|
||||
_searchAction.visible = false
|
||||
_searchAction.visible = true
|
||||
if (_basicToolbar.resolved()) {
|
||||
_basicToolbar.get().visible = false
|
||||
}
|
||||
|
@ -213,6 +213,7 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
|||
override fun onSearchOpened() {
|
||||
conversationListTabsViewModel.onSearchOpened()
|
||||
_searchToolbar.get().clearText()
|
||||
_searchToolbar.get().display(_searchAction.x + (_searchAction.width / 2.0f), _searchAction.y + (_searchAction.height / 2.0f))
|
||||
}
|
||||
|
||||
override fun onSearchClosed() {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package org.thoughtcrime.securesms.main
|
||||
|
||||
import android.widget.ImageView
|
||||
import org.thoughtcrime.securesms.components.Material3SearchToolbar
|
||||
import org.thoughtcrime.securesms.util.views.Stub
|
||||
|
||||
interface SearchBinder {
|
||||
fun getSearchAction(): ImageView
|
||||
|
||||
fun getSearchToolbar(): Stub<Material3SearchToolbar>
|
||||
|
||||
fun onSearchOpened()
|
||||
|
||||
fun onSearchClosed()
|
||||
}
|
|
@ -23,6 +23,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|||
import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.Material3SearchToolbar
|
||||
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
|
@ -33,6 +34,7 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor
|
|||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder
|
||||
import org.thoughtcrime.securesms.main.SearchBinder
|
||||
import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionActivity
|
||||
import org.thoughtcrime.securesms.permissions.Permissions
|
||||
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
|
||||
|
@ -88,6 +90,30 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
override fun onResume() {
|
||||
super.onResume()
|
||||
viewModel.isTransitioningToAnotherScreen = false
|
||||
initializeSearchAction()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
requireListener<SearchBinder>().getSearchAction().setOnClickListener(null)
|
||||
}
|
||||
|
||||
private fun initializeSearchAction() {
|
||||
val searchBinder = requireListener<SearchBinder>()
|
||||
searchBinder.getSearchAction().setOnClickListener {
|
||||
searchBinder.onSearchOpened()
|
||||
|
||||
searchBinder.getSearchToolbar().get().listener = object : Material3SearchToolbar.Listener {
|
||||
override fun onSearchTextChange(text: String) {
|
||||
viewModel.setSearchQuery(text.trim())
|
||||
}
|
||||
|
||||
override fun onSearchClosed() {
|
||||
viewModel.setSearchQuery("")
|
||||
searchBinder.onSearchClosed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun bindAdapter(adapter: MappingAdapter) {
|
||||
|
@ -160,7 +186,16 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
|
||||
private fun getConfiguration(state: StoriesLandingState): DSLConfiguration {
|
||||
return configure {
|
||||
val (stories, hidden) = state.storiesLandingItems.map {
|
||||
val (stories, hidden) = state.storiesLandingItems.filter {
|
||||
if (state.searchQuery.isNotEmpty()) {
|
||||
val storyRecipientName = it.storyRecipient.getDisplayName(requireContext())
|
||||
val individualRecipientName = it.individualRecipient.getDisplayName(requireContext())
|
||||
|
||||
storyRecipientName.contains(state.searchQuery, ignoreCase = true) || individualRecipientName.contains(state.searchQuery, ignoreCase = true)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}.map {
|
||||
createStoryLandingItem(it)
|
||||
}.partition {
|
||||
!it.data.isHidden
|
||||
|
|
|
@ -4,7 +4,8 @@ data class StoriesLandingState(
|
|||
val storiesLandingItems: List<StoriesLandingItemData> = emptyList(),
|
||||
val displayMyStoryItem: Boolean = false,
|
||||
val isHiddenContentVisible: Boolean = false,
|
||||
val loadingState: LoadingState = LoadingState.INIT
|
||||
val loadingState: LoadingState = LoadingState.INIT,
|
||||
val searchQuery: String = ""
|
||||
) {
|
||||
enum class LoadingState {
|
||||
INIT,
|
||||
|
|
|
@ -54,6 +54,10 @@ class StoriesLandingViewModel(private val storiesLandingRepository: StoriesLandi
|
|||
.map { it.storyRecipient.id }
|
||||
}
|
||||
|
||||
fun setSearchQuery(query: String) {
|
||||
store.update { it.copy(searchQuery = query) }
|
||||
}
|
||||
|
||||
class Factory(private val storiesLandingRepository: StoriesLandingRepository) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return modelClass.cast(StoriesLandingViewModel(storiesLandingRepository)) as T
|
||||
|
|
Loading…
Add table
Reference in a new issue