From 4e8e8bc23230b9bbaa90b74ce187aeffa44a5b49 Mon Sep 17 00:00:00 2001 From: Niels van Velzen Date: Tue, 12 Mar 2024 14:55:43 +0100 Subject: [PATCH] Fix search action ignoring received query (cherry picked from commit 2784a1bcbb7d6ce7257767c4aab5dd9528d58fff) --- .../androidtv/ui/home/HomeFragment.kt | 2 +- .../androidtv/ui/navigation/Destinations.kt | 4 ++- .../ui/search/LeanbackSearchFragment.kt | 3 ++ .../androidtv/ui/search/SearchFragment.kt | 16 +++++---- .../androidtv/ui/search/TextSearchFragment.kt | 33 ++++++++++++++----- .../androidtv/ui/startup/StartupActivity.kt | 5 ++- .../main/res/layout/fragment_search_text.xml | 3 +- 7 files changed, 46 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.kt b/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.kt index ca3c5c6beb..384fc75f50 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.kt @@ -44,7 +44,7 @@ class HomeFragment : Fragment() { } binding.search.setOnClickListener { - navigationRepository.navigate(Destinations.search) + navigationRepository.navigate(Destinations.search()) } return binding.root diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/navigation/Destinations.kt b/app/src/main/java/org/jellyfin/androidtv/ui/navigation/Destinations.kt index 83cbd323e0..aa0790c130 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/navigation/Destinations.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/navigation/Destinations.kt @@ -46,7 +46,9 @@ object Destinations { // General val home = fragmentDestination() - val search = fragmentDestination() + fun search(query: String? = null) = fragmentDestination( + SearchFragment.EXTRA_QUERY to query, + ) val userPreferences = preferenceDestination() // Browsing diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/search/LeanbackSearchFragment.kt b/app/src/main/java/org/jellyfin/androidtv/ui/search/LeanbackSearchFragment.kt index 2564423b1a..2d605f3a84 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/search/LeanbackSearchFragment.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/search/LeanbackSearchFragment.kt @@ -31,6 +31,9 @@ class LeanbackSearchFragment : SearchSupportFragment(), SearchSupportFragment.Se viewModel.searchResultsFlow .onEach { searchFragmentDelegate.showResults(it) } .launchIn(lifecycleScope) + + val query = arguments?.getString(SearchFragment.EXTRA_QUERY) + if (!query.isNullOrBlank()) setSearchQuery(query, true) } override fun getResultsAdapter() = searchFragmentDelegate.rowsAdapter diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/search/SearchFragment.kt b/app/src/main/java/org/jellyfin/androidtv/ui/search/SearchFragment.kt index 98d27f34e9..fb44ce38ba 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/search/SearchFragment.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/search/SearchFragment.kt @@ -6,9 +6,14 @@ import android.os.Bundle import android.speech.SpeechRecognizer import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment +import androidx.fragment.app.commit import org.jellyfin.androidtv.R class SearchFragment : Fragment(R.layout.fragment_content_view) { + companion object { + const val EXTRA_QUERY = "query" + } + private val isSpeechEnabled by lazy { SpeechRecognizer.isRecognitionAvailable(requireContext()) && ContextCompat.checkSelfPermission( @@ -22,14 +27,13 @@ class SearchFragment : Fragment(R.layout.fragment_content_view) { // Determine fragment to use val searchFragment = when { - isSpeechEnabled -> LeanbackSearchFragment() - else -> TextSearchFragment() + isSpeechEnabled -> LeanbackSearchFragment::class.java + else -> TextSearchFragment::class.java } // Add fragment - childFragmentManager - .beginTransaction() - .replace(R.id.content_view, searchFragment) - .commit() + childFragmentManager.commit { + replace(R.id.content_view, searchFragment, arguments) + } } } diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/search/TextSearchFragment.kt b/app/src/main/java/org/jellyfin/androidtv/ui/search/TextSearchFragment.kt index 1a6a36afc5..86035292ea 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/search/TextSearchFragment.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/search/TextSearchFragment.kt @@ -11,6 +11,7 @@ import android.view.inputmethod.InputMethodManager import android.widget.EditText import androidx.core.content.getSystemService import androidx.fragment.app.Fragment +import androidx.fragment.app.commit import androidx.leanback.app.RowsSupportFragment import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.flow.launchIn @@ -36,26 +37,40 @@ class TextSearchFragment : Fragment() { savedInstanceState: Bundle? ): View { _binding = FragmentSearchTextBinding.inflate(inflater, container, false) - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) binding.searchBar.apply { onTextChanged { viewModel.searchDebounced(it) } onSubmit { viewModel.searchImmediately(it) } } - binding.resultsFrame.getFragment()?.let { - it.adapter = searchFragmentDelegate.rowsAdapter - it.onItemViewClickedListener = searchFragmentDelegate.onItemViewClickedListener - it.onItemViewSelectedListener = searchFragmentDelegate.onItemViewSelectedListener + val rowsSupportFragment = RowsSupportFragment().apply { + adapter = searchFragmentDelegate.rowsAdapter + onItemViewClickedListener = searchFragmentDelegate.onItemViewClickedListener + onItemViewSelectedListener = searchFragmentDelegate.onItemViewSelectedListener + } + + childFragmentManager.commit { + replace(binding.resultsFrame.id, rowsSupportFragment) } + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewModel.searchResultsFlow .onEach { searchFragmentDelegate.showResults(it) } .launchIn(lifecycleScope) + + val query = arguments?.getString(SearchFragment.EXTRA_QUERY) + if (!query.isNullOrBlank()) { + binding.searchBar.setText(query) + viewModel.searchImmediately(query) + binding.resultsFrame.requestFocus() + } else { + binding.searchBar.requestFocus() + } } override fun onDestroyView() { diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/startup/StartupActivity.kt b/app/src/main/java/org/jellyfin/androidtv/ui/startup/StartupActivity.kt index fec85614dc..766227be25 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/startup/StartupActivity.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/startup/StartupActivity.kt @@ -1,6 +1,7 @@ package org.jellyfin.androidtv.ui.startup import android.Manifest +import android.app.SearchManager import android.content.Intent import android.os.Bundle import android.widget.Toast @@ -137,7 +138,9 @@ class StartupActivity : FragmentActivity() { // Create destination val destination = when { // Search is requested - intent.action === Intent.ACTION_SEARCH -> Destinations.search + intent.action === Intent.ACTION_SEARCH -> Destinations.search( + query = intent.getStringExtra(SearchManager.QUERY) + ) // User view item is requested itemId != null && itemIsUserView -> { val item by api.userLibraryApi.getItem(itemId = itemId) diff --git a/app/src/main/res/layout/fragment_search_text.xml b/app/src/main/res/layout/fragment_search_text.xml index eedc9dd997..f7d450eb8d 100644 --- a/app/src/main/res/layout/fragment_search_text.xml +++ b/app/src/main/res/layout/fragment_search_text.xml @@ -48,9 +48,8 @@ app:layout_constraintTop_toTopOf="@id/logo" /> -