mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 08:20:32 +05:30
NextPage for Search
This commit is contained in:
parent
9b170c8be2
commit
4ed137c174
@ -22,6 +22,13 @@ interface PipedApi {
|
|||||||
@Query("filter") filter: String
|
@Query("filter") filter: String
|
||||||
): SearchResult
|
): SearchResult
|
||||||
|
|
||||||
|
@GET("nextpage/search")
|
||||||
|
suspend fun getSearchResultsNextPage(
|
||||||
|
@Query("q") searchQuery: String,
|
||||||
|
@Query("filter") filter: String,
|
||||||
|
@Query("nextpage") nextPage: String
|
||||||
|
): SearchResult
|
||||||
|
|
||||||
@GET("suggestions")
|
@GET("suggestions")
|
||||||
suspend fun getSuggestions(@Query("query") query: String): List<String>
|
suspend fun getSuggestions(@Query("query") query: String): List<String>
|
||||||
|
|
||||||
|
@ -12,11 +12,10 @@ import android.view.ViewGroup
|
|||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.*
|
||||||
import android.widget.AutoCompleteTextView
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.TextView.*
|
import android.widget.TextView.*
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.content.ContentProviderCompat.requireContext
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
@ -31,11 +30,13 @@ import kotlinx.coroutines.launch
|
|||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
|
|
||||||
private var selectedFilter = 0
|
|
||||||
|
|
||||||
class SearchFragment : Fragment() {
|
class SearchFragment : Fragment() {
|
||||||
private val TAG = "SearchFragment"
|
private val TAG = "SearchFragment"
|
||||||
|
private var selectedFilter = 0
|
||||||
|
private var nextPage : String? = null
|
||||||
|
private lateinit var searchRecView : RecyclerView
|
||||||
|
private var searchAdapter : SearchAdapter? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
arguments?.let {
|
arguments?.let {
|
||||||
@ -54,7 +55,7 @@ class SearchFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
val recyclerView = view.findViewById<RecyclerView>(R.id.search_recycler)
|
searchRecView = view.findViewById<RecyclerView>(R.id.search_recycler)
|
||||||
|
|
||||||
val autoTextView = view.findViewById<AutoCompleteTextView>(R.id.autoCompleteTextView)
|
val autoTextView = view.findViewById<AutoCompleteTextView>(R.id.autoCompleteTextView)
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ class SearchFragment : Fragment() {
|
|||||||
})
|
})
|
||||||
.setPositiveButton(getString(R.string.okay), DialogInterface.OnClickListener {
|
.setPositiveButton(getString(R.string.okay), DialogInterface.OnClickListener {
|
||||||
_, _ -> selectedFilter = tempSelectedItem
|
_, _ -> selectedFilter = tempSelectedItem
|
||||||
fetchSearch(autoTextView.text.toString(), recyclerView)
|
fetchSearch(autoTextView.text.toString())
|
||||||
})
|
})
|
||||||
.setNegativeButton(getString(R.string.cancel), null)
|
.setNegativeButton(getString(R.string.cancel), null)
|
||||||
.create()
|
.create()
|
||||||
@ -82,7 +83,7 @@ class SearchFragment : Fragment() {
|
|||||||
|
|
||||||
//show search history
|
//show search history
|
||||||
|
|
||||||
recyclerView.visibility = GONE
|
searchRecView.visibility = GONE
|
||||||
historyRecycler.visibility = VISIBLE
|
historyRecycler.visibility = VISIBLE
|
||||||
|
|
||||||
historyRecycler.layoutManager = LinearLayoutManager(view.context)
|
historyRecycler.layoutManager = LinearLayoutManager(view.context)
|
||||||
@ -93,7 +94,7 @@ class SearchFragment : Fragment() {
|
|||||||
SearchHistoryAdapter(requireContext(), historylist, autoTextView)
|
SearchHistoryAdapter(requireContext(), historylist, autoTextView)
|
||||||
}
|
}
|
||||||
|
|
||||||
recyclerView.layoutManager = GridLayoutManager(view.context, 1)
|
searchRecView.layoutManager = GridLayoutManager(view.context, 1)
|
||||||
autoTextView.requestFocus()
|
autoTextView.requestFocus()
|
||||||
val imm =
|
val imm =
|
||||||
requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
@ -110,24 +111,30 @@ class SearchFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||||
if (s!! != "") {
|
if (s!! != "") {
|
||||||
recyclerView.visibility = VISIBLE
|
searchRecView.visibility = VISIBLE
|
||||||
historyRecycler.visibility = GONE
|
historyRecycler.visibility = GONE
|
||||||
recyclerView.adapter = null
|
searchRecView.adapter = null
|
||||||
|
|
||||||
|
searchRecView.viewTreeObserver
|
||||||
|
.addOnScrollChangedListener {
|
||||||
|
if (!searchRecView.canScrollVertically(1)) {
|
||||||
|
fetchNextSearchItems(autoTextView.text.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
fetchSuggestions(s.toString(), autoTextView)
|
fetchSuggestions(s.toString(), autoTextView)
|
||||||
delay(1000)
|
delay(1000)
|
||||||
addtohistory(s.toString())
|
addtohistory(s.toString())
|
||||||
fetchSearch(s.toString(), recyclerView)
|
fetchSearch(s.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun afterTextChanged(s: Editable?) {
|
override fun afterTextChanged(s: Editable?) {
|
||||||
if (s!!.isEmpty()) {
|
if (s!!.isEmpty()) {
|
||||||
recyclerView.visibility = GONE
|
searchRecView.visibility = GONE
|
||||||
historyRecycler.visibility = VISIBLE
|
historyRecycler.visibility = VISIBLE
|
||||||
var historylist = getHistory()
|
var historylist = getHistory()
|
||||||
if (historylist.size != 0) {
|
if (historylist.size != 0) {
|
||||||
@ -167,10 +174,10 @@ class SearchFragment : Fragment() {
|
|||||||
autoTextView.setAdapter(adapter)
|
autoTextView.setAdapter(adapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun fetchSearch(query: String, recyclerView: RecyclerView){
|
private fun fetchSearch(query: String){
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.getSearchResults(query, "all")
|
RetrofitInstance.api.getSearchResults(query, "videos")
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection $e")
|
Log.e(TAG, "IOException, you might not have internet connection $e")
|
||||||
@ -179,15 +186,34 @@ class SearchFragment : Fragment() {
|
|||||||
Log.e(TAG, "HttpException, unexpected response")
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
|
nextPage = response.nextpage
|
||||||
if(response.items!!.isNotEmpty()){
|
if(response.items!!.isNotEmpty()){
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
recyclerView.adapter = SearchAdapter(response.items, selectedFilter)
|
searchAdapter = SearchAdapter(response.items, selectedFilter)
|
||||||
|
searchRecView.adapter = searchAdapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun fetchNextSearchItems(query: String){
|
||||||
|
lifecycleScope.launchWhenCreated {
|
||||||
|
val response = try {
|
||||||
|
RetrofitInstance.api.getSearchResultsNextPage(query!!, "videos", nextPage!!)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
println(e)
|
||||||
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
|
return@launchWhenCreated
|
||||||
|
} catch (e: HttpException) {
|
||||||
|
Log.e(TAG, "HttpException, unexpected response," + e.response())
|
||||||
|
return@launchWhenCreated
|
||||||
|
}
|
||||||
|
nextPage = response.nextpage
|
||||||
|
searchAdapter?.updateItems(response.items!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
||||||
this ?: return
|
this ?: return
|
||||||
if (!isAdded) return // Fragment not attached to an Activity
|
if (!isAdded) return // Fragment not attached to an Activity
|
||||||
|
@ -14,6 +14,7 @@ import com.github.libretube.MainActivity
|
|||||||
import com.github.libretube.PlayerFragment
|
import com.github.libretube.PlayerFragment
|
||||||
import com.github.libretube.R
|
import com.github.libretube.R
|
||||||
import com.github.libretube.formatShort
|
import com.github.libretube.formatShort
|
||||||
|
import com.github.libretube.obj.Comment
|
||||||
import com.github.libretube.obj.SearchItem
|
import com.github.libretube.obj.SearchItem
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import kotlinx.coroutines.NonDisposableHandle.parent
|
import kotlinx.coroutines.NonDisposableHandle.parent
|
||||||
@ -22,7 +23,13 @@ private var showVideos = true
|
|||||||
private var showChannels = true
|
private var showChannels = true
|
||||||
private var showPlaylists = true
|
private var showPlaylists = true
|
||||||
|
|
||||||
class SearchAdapter(private val searchItems: List<SearchItem>, private val selectedFilter : Int): RecyclerView.Adapter<CustomViewHolder1>() {
|
class SearchAdapter(private val searchItems: MutableList<SearchItem>, private val selectedFilter : Int): RecyclerView.Adapter<CustomViewHolder1>() {
|
||||||
|
|
||||||
|
fun updateItems(newItems: List<SearchItem>){
|
||||||
|
var searchItemsSize = searchItems.size
|
||||||
|
searchItems.addAll(newItems)
|
||||||
|
notifyItemRangeInserted(searchItemsSize, newItems.size)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return searchItems.size
|
return searchItems.size
|
||||||
|
@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
|||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
data class SearchResult(
|
data class SearchResult(
|
||||||
val items: List<SearchItem>? = listOf(),
|
val items: MutableList<SearchItem>? = arrayListOf(),
|
||||||
val nextpage: String? ="",
|
val nextpage: String? ="",
|
||||||
val suggestion: String?="",
|
val suggestion: String?="",
|
||||||
val corrected: Boolean? = null
|
val corrected: Boolean? = null
|
||||||
|
Loading…
x
Reference in New Issue
Block a user