2021-02-06 19:02:12 +01:00
package org.mosad.teapod.ui.activity.main.fragments
2020-10-08 22:20:20 +02:00
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
2020-10-11 18:07:00 +02:00
import android.widget.SearchView
2020-10-08 22:20:20 +02:00
import androidx.fragment.app.Fragment
2021-06-06 17:54:19 +02:00
import androidx.lifecycle.lifecycleScope
2021-12-27 22:50:29 +01:00
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
2021-06-06 17:54:19 +02:00
import kotlinx.coroutines.launch
2020-11-25 22:35:55 +01:00
import org.mosad.teapod.databinding.FragmentSearchBinding
2021-12-27 22:50:29 +01:00
import org.mosad.teapod.parser.crunchyroll.Crunchyroll
import org.mosad.teapod.util.ItemMedia
2020-10-14 20:22:20 +02:00
import org.mosad.teapod.util.adapter.MediaItemAdapter
2021-12-27 22:50:29 +01:00
import org.mosad.teapod.util.decoration.MediaItemDecoration
2021-01-20 16:10:41 +01:00
import org.mosad.teapod.util.showFragment
2020-10-08 22:20:20 +02:00
class SearchFragment : Fragment ( ) {
2020-11-25 22:35:55 +01:00
private lateinit var binding : FragmentSearchBinding
2021-12-27 22:50:29 +01:00
private lateinit var adapter : MediaItemAdapter
private val itemList = arrayListOf < ItemMedia > ( )
private var searchJob : Job ? = null
private var oldSearchQuery = " "
2020-10-11 18:07:00 +02:00
2020-11-25 22:35:55 +01:00
override fun onCreateView ( inflater : LayoutInflater , container : ViewGroup ? , savedInstanceState : Bundle ? ) : View {
binding = FragmentSearchBinding . inflate ( inflater , container , false )
return binding . root
2020-10-11 14:25:47 +02:00
}
2020-10-08 22:20:20 +02:00
2020-10-11 14:25:47 +02:00
override fun onViewCreated ( view : View , savedInstanceState : Bundle ? ) {
super . onViewCreated ( view , savedInstanceState )
2020-10-11 18:07:00 +02:00
2021-06-06 17:54:19 +02:00
lifecycleScope . launch {
2020-10-11 18:07:00 +02:00
// create and set the adapter, needs context
2020-10-12 20:30:45 +02:00
context ?. let {
2021-12-27 22:50:29 +01:00
adapter = MediaItemAdapter ( itemList )
adapter . onItemClick = { mediaIdStr , _ ->
2020-11-25 22:35:55 +01:00
binding . searchText . clearFocus ( )
2021-12-27 22:50:29 +01:00
activity ?. showFragment ( MediaFragment ( mediaIdStr ) )
2020-10-15 13:00:44 +02:00
}
2020-11-25 22:35:55 +01:00
binding . recyclerMediaSearch . adapter = adapter
binding . recyclerMediaSearch . addItemDecoration ( MediaItemDecoration ( 9 ) )
2020-10-12 20:30:45 +02:00
}
2020-10-11 18:07:00 +02:00
}
2020-10-12 20:30:45 +02:00
initActions ( )
2020-10-11 18:07:00 +02:00
}
private fun initActions ( ) {
2020-11-25 22:35:55 +01:00
binding . searchText . setOnQueryTextListener ( object : SearchView . OnQueryTextListener {
2020-10-11 18:07:00 +02:00
override fun onQueryTextSubmit ( query : String ? ) : Boolean {
2021-12-27 22:50:29 +01:00
query ?. let { search ( it ) }
2020-10-11 18:07:00 +02:00
return false
}
override fun onQueryTextChange ( newText : String ? ) : Boolean {
2021-12-27 22:50:29 +01:00
newText ?. let { search ( it ) }
2020-10-11 18:07:00 +02:00
return false
}
} )
2020-10-08 22:20:20 +02:00
}
2021-12-27 22:50:29 +01:00
private fun search ( query : String ) {
// if the query hasn't changed since the last successful search, return
if ( query == oldSearchQuery ) return
// cancel search job if one is already running
if ( searchJob ?. isActive == true ) searchJob ?. cancel ( )
searchJob = lifecycleScope . async {
// TODO maybe wait a few ms (500ms?) before searching, if the user inputs any other chars
val results = Crunchyroll . search ( query , 50 )
itemList . clear ( ) // TODO needs clean up
// TODO add top results first heading
itemList . addAll ( results . items [ 0 ] . items . map { item ->
ItemMedia ( item . id , item . title , item . images . poster _wide [ 0 ] [ 0 ] . source )
} )
// TODO currently only tv shows are supported, hence only the first items array
// should be always present
// // TODO add tv shows heading
// if (results.items.size >= 2) {
// itemList.addAll(results.items[1].items.map { item ->
// ItemMedia(item.id, item.title, item.images.poster_wide[0][0].source)
// })
// }
//
// // TODO add movies heading
// if (results.items.size >= 3) {
// itemList.addAll(results.items[2].items.map { item ->
// ItemMedia(item.id, item.title, item.images.poster_wide[0][0].source)
// })
// }
//
// // TODO add episodes heading
// if (results.items.size >= 4) {
// itemList.addAll(results.items[3].items.map { item ->
// ItemMedia(item.id, item.title, item.images.poster_wide[0][0].source)
// })
// }
adapter . notifyDataSetChanged ( )
//adapter.notifyItemRangeInserted(0, itemList.size)
// after successfully searching the query term, add it as old query, to make sure we
// don't search again if the query hasn't changed
oldSearchQuery = query
}
}
2020-10-08 22:20:20 +02:00
}