Merge pull request #964 from Bnyro/master

improve search
This commit is contained in:
Bnyro 2022-08-04 09:39:32 +02:00 committed by GitHub
commit 8f21fce00d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 26 deletions

View File

@ -3,6 +3,7 @@ import java.time.Instant
plugins { plugins {
id 'com.android.application' id 'com.android.application'
id 'kotlin-android' id 'kotlin-android'
id 'kotlin-android-extensions'
} }
android { android {
@ -12,8 +13,8 @@ android {
applicationId 'com.github.libretube' applicationId 'com.github.libretube'
minSdk 21 minSdk 21
targetSdk 31 targetSdk 31
versionCode 15 versionCode 16
versionName '0.4.1' versionName '0.4.2'
multiDexEnabled true multiDexEnabled true
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
resValue "string", "app_name", "LibreTube" resValue "string", "app_name", "LibreTube"
@ -101,6 +102,10 @@ dependencies {
implementation libs.cronet.embedded implementation libs.cronet.embedded
implementation libs.cronet.okhttp implementation libs.cronet.okhttp
implementation libs.coil implementation libs.coil
implementation libs.lifecycle.viewmodel
implementation libs.lifecycle.runtime
implementation libs.lifecycle.livedata
} }
static def getUnixTime() { static def getUnixTime() {

View File

@ -21,6 +21,7 @@ import androidx.appcompat.widget.SearchView
import androidx.constraintlayout.motion.widget.MotionLayout import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
@ -30,6 +31,7 @@ import com.github.libretube.R
import com.github.libretube.databinding.ActivityMainBinding import com.github.libretube.databinding.ActivityMainBinding
import com.github.libretube.dialogs.ErrorDialog import com.github.libretube.dialogs.ErrorDialog
import com.github.libretube.fragments.PlayerFragment import com.github.libretube.fragments.PlayerFragment
import com.github.libretube.models.SearchViewModel
import com.github.libretube.preferences.PreferenceHelper import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys import com.github.libretube.preferences.PreferenceKeys
import com.github.libretube.services.ClosingService import com.github.libretube.services.ClosingService
@ -48,6 +50,7 @@ class MainActivity : AppCompatActivity() {
lateinit var navController: NavController lateinit var navController: NavController
private var startFragmentId = R.id.homeFragment private var startFragmentId = R.id.homeFragment
var autoRotationEnabled = false var autoRotationEnabled = false
lateinit var searchView: SearchView lateinit var searchView: SearchView
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -174,7 +177,16 @@ class MainActivity : AppCompatActivity() {
// stuff for the search in the topBar // stuff for the search in the topBar
val searchItem = menu.findItem(R.id.action_search) val searchItem = menu.findItem(R.id.action_search)
searchView = searchItem.actionView as SearchView searchView = searchItem.actionView as SearchView
searchView.setMaxWidth(Integer.MAX_VALUE) searchView.maxWidth = Integer.MAX_VALUE
val searchViewModel = ViewModelProvider(this)[SearchViewModel::class.java]
searchView.setOnSearchClickListener {
if (navController.currentDestination?.id != R.id.searchResultFragment) {
searchViewModel.setQuery(null)
navController.navigate(R.id.searchFragment)
}
}
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean { override fun onQueryTextSubmit(query: String?): Boolean {
@ -185,15 +197,20 @@ class MainActivity : AppCompatActivity() {
} }
override fun onQueryTextChange(newText: String?): Boolean { override fun onQueryTextChange(newText: String?): Boolean {
if (navController.currentDestination?.id != R.id.searchFragment) {
val bundle = Bundle() val bundle = Bundle()
bundle.putString("query", newText) bundle.putString("query", newText)
navController.navigate(R.id.searchFragment, bundle) navController.navigate(R.id.searchFragment, bundle)
} else {
searchViewModel.setQuery(newText)
}
return true return true
} }
}) })
searchView.setOnCloseListener { searchView.setOnCloseListener {
if (navController.currentDestination?.id == R.id.searchFragment) { if (navController.currentDestination?.id == R.id.searchFragment) {
searchViewModel.setQuery(null)
onBackPressed() onBackPressed()
} }
false false
@ -206,10 +223,6 @@ class MainActivity : AppCompatActivity() {
// automatically handle clicks on the Home/Up button, so long // automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml. // as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) { return when (item.itemId) {
R.id.action_search -> {
navController.navigate(R.id.searchFragment)
true
}
R.id.action_settings -> { R.id.action_settings -> {
val settingsIntent = Intent(this, SettingsActivity::class.java) val settingsIntent = Intent(this, SettingsActivity::class.java)
startActivity(settingsIntent) startActivity(settingsIntent)
@ -357,6 +370,7 @@ class MainActivity : AppCompatActivity() {
override fun onBackPressed() { override fun onBackPressed() {
// remove focus from search // remove focus from search
removeSearchFocus() removeSearchFocus()
navController.popBackStack(R.id.searchFragment, false)
if (binding.mainMotionLayout.progress == 0F) { if (binding.mainMotionLayout.progress == 0F) {
try { try {

View File

@ -6,14 +6,14 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.github.libretube.R
import com.github.libretube.activities.MainActivity import com.github.libretube.activities.MainActivity
import com.github.libretube.adapters.SearchHistoryAdapter import com.github.libretube.adapters.SearchHistoryAdapter
import com.github.libretube.adapters.SearchSuggestionsAdapter import com.github.libretube.adapters.SearchSuggestionsAdapter
import com.github.libretube.databinding.FragmentSearchBinding import com.github.libretube.databinding.FragmentSearchBinding
import com.github.libretube.models.SearchViewModel
import com.github.libretube.preferences.PreferenceHelper import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import retrofit2.HttpException import retrofit2.HttpException
@ -22,6 +22,7 @@ import java.io.IOException
class SearchFragment() : Fragment() { class SearchFragment() : Fragment() {
private val TAG = "SearchFragment" private val TAG = "SearchFragment"
private lateinit var binding: FragmentSearchBinding private lateinit var binding: FragmentSearchBinding
private val viewModel: SearchViewModel by activityViewModels()
private var query: String? = null private var query: String? = null
@ -43,9 +44,19 @@ class SearchFragment() : Fragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
binding.suggestionsRecycler.layoutManager = LinearLayoutManager(requireContext()) binding.suggestionsRecycler.layoutManager = LinearLayoutManager(requireContext())
// waiting for the query to change
viewModel.searchQuery.observe(viewLifecycleOwner) {
showData(it)
}
}
private fun showData(query: String?) {
// fetch the search or history // fetch the search or history
binding.historyEmpty.visibility = View.GONE
binding.suggestionsRecycler.visibility = View.VISIBLE
if (query == null || query == "") showHistory() if (query == null || query == "") showHistory()
else fetchSuggestions(query!!) else fetchSuggestions(query)
} }
private fun fetchSuggestions(query: String) { private fun fetchSuggestions(query: String) {
@ -68,10 +79,12 @@ class SearchFragment() : Fragment() {
(activity as MainActivity).searchView (activity as MainActivity).searchView
) )
runOnUiThread { runOnUiThread {
if (viewModel.searchQuery.value != "") {
binding.suggestionsRecycler.adapter = suggestionsAdapter binding.suggestionsRecycler.adapter = suggestionsAdapter
} }
} }
} }
}
run() run()
} }
@ -94,10 +107,4 @@ class SearchFragment() : Fragment() {
if (!isAdded) return // Fragment not attached to an Activity if (!isAdded) return // Fragment not attached to an Activity
activity?.runOnUiThread(action) activity?.runOnUiThread(action)
} }
override fun onDestroy() {
// remove the backstack entries
findNavController().popBackStack(R.id.searchFragment, true)
super.onDestroy()
}
} }

View File

@ -0,0 +1,12 @@
package com.github.libretube.models
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class SearchViewModel : ViewModel() {
var searchQuery = MutableLiveData<String>()
fun setQuery(query: String?) {
this.searchQuery.value = query
}
}

View File

@ -15,14 +15,14 @@
android:title="@string/settings" android:title="@string/settings"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/action_about"
android:title="@string/about"
app:showAsAction="never" />
<item <item
android:id="@+id/action_community" android:id="@+id/action_community"
android:title="@string/community" android:title="@string/community"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/action_about"
android:title="@string/about"
app:showAsAction="never" />
</menu> </menu>

View File

@ -1,5 +1,6 @@
[versions] [versions]
appcompat = "1.4.1" appcompat = "1.4.1"
lifecycle = "2.5.1"
constraintlayout = "2.1.3" constraintlayout = "2.1.3"
material = "1.6.0" material = "1.6.0"
navigation = "2.4.2" navigation = "2.4.2"
@ -45,3 +46,6 @@ cronet-embedded = { group = "org.chromium.net", name = "cronet-embedded", versio
cronet-okhttp = { group = "com.google.net.cronet", name = "cronet-okhttp", version.ref = "cronetOkHttp" } cronet-okhttp = { group = "com.google.net.cronet", name = "cronet-okhttp", version.ref = "cronetOkHttp" }
coil = { group = "io.coil-kt", name = "coil", version.ref="coil" } coil = { group = "io.coil-kt", name = "coil", version.ref="coil" }
square-leakcanary = { group = "com.squareup.leakcanary", name = "leakcanary-android", version.ref = "leakcanary" } square-leakcanary = { group = "com.squareup.leakcanary", name = "leakcanary-android", version.ref = "leakcanary" }
lifecycle-viewmodel = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycle" }
lifecycle-runtime = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
lifecycle-livedata = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycle" }