2021-02-06 19:02:12 +01:00
package org.mosad.teapod.ui.activity.main.fragments
2020-10-08 22:20:20 +02:00
2022-12-26 16:10:38 +01:00
import android.annotation.SuppressLint
2020-10-08 22:20:20 +02:00
import android.os.Bundle
2022-12-26 16:10:38 +01:00
import android.util.Log
2020-10-08 22:20:20 +02:00
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
2022-12-26 16:10:38 +01:00
import androidx.appcompat.widget.SearchView
2020-10-08 22:20:20 +02:00
import androidx.fragment.app.Fragment
2022-12-26 16:10:38 +01:00
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
2021-06-06 17:54:19 +02:00
import androidx.lifecycle.lifecycleScope
2022-12-26 16:10:38 +01:00
import androidx.lifecycle.repeatOnLifecycle
2021-12-27 21:14:35 +01:00
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
2020-11-15 13:39:33 +01:00
import kotlinx.coroutines.launch
2020-11-25 22:35:55 +01:00
import org.mosad.teapod.databinding.FragmentLibraryBinding
2022-12-26 16:10:38 +01:00
import org.mosad.teapod.ui.activity.main.viewmodel.LibraryFragmentViewModel
2022-12-03 00:05:57 +01:00
import org.mosad.teapod.util.adapter.MediaItemListAdapter
2021-01-20 16:10:41 +01:00
import org.mosad.teapod.util.showFragment
2020-10-08 22:20:20 +02:00
class LibraryFragment : Fragment ( ) {
2020-11-25 22:35:55 +01:00
private lateinit var binding : FragmentLibraryBinding
2022-12-03 00:05:57 +01:00
private lateinit var adapter : MediaItemListAdapter
2022-12-26 16:10:38 +01:00
private val model : LibraryFragmentViewModel by viewModels ( )
2021-12-27 21:14:35 +01:00
2020-11-25 22:35:55 +01:00
override fun onCreateView ( inflater : LayoutInflater , container : ViewGroup ? , savedInstanceState : Bundle ? ) : View {
binding = FragmentLibraryBinding . inflate ( inflater , container , false )
return binding . root
2020-10-08 22:20:20 +02:00
}
override fun onViewCreated ( view : View , savedInstanceState : Bundle ? ) {
super . onViewCreated ( view , savedInstanceState )
2022-12-03 00:05:57 +01:00
// TODO replace with pagination3
// https://medium.com/swlh/paging3-recyclerview-pagination-made-easy-333c7dfa8797
2022-12-26 16:10:38 +01:00
binding . recyclerMediaSearch . addOnScrollListener ( PaginationScrollListener ( ) )
adapter = MediaItemListAdapter ( MediaItemListAdapter . OnClickListener {
binding . searchText . clearFocus ( )
activity ?. showFragment ( MediaFragment ( it . id ) )
} )
binding . recyclerMediaSearch . adapter = adapter
binding . searchText . setOnQueryTextListener ( object : SearchView . OnQueryTextListener {
override fun onQueryTextSubmit ( query : String ? ) : Boolean {
println ( " onQueryTextSubmit: $query " )
query ?. let { model . search ( it ) }
return false // return false to dismiss the keyboard
}
override fun onQueryTextChange ( newText : String ? ) : Boolean {
println ( " onQueryTextChange: $newText " )
newText ?. let { model . search ( it ) }
return false // return false to dismiss the keyboard
2020-10-09 13:02:58 +02:00
}
2022-12-26 16:10:38 +01:00
} )
2020-10-08 22:20:20 +02:00
2022-12-26 16:10:38 +01:00
viewLifecycleOwner . lifecycleScope . launch {
viewLifecycleOwner . repeatOnLifecycle ( Lifecycle . State . STARTED ) {
model . onUiState ( viewLifecycleOwner . lifecycleScope ) { uiState ->
when ( uiState ) {
is LibraryFragmentViewModel . UiState . Browse -> bindUiStateBrowse ( uiState )
is LibraryFragmentViewModel . UiState . Search -> bindUiStateSearch ( uiState )
is LibraryFragmentViewModel . UiState . Loading -> bindUiStateLoading ( )
is LibraryFragmentViewModel . UiState . Error -> bindUiStateError ( uiState )
}
}
}
2020-10-08 22:20:20 +02:00
}
}
2021-12-27 21:14:35 +01:00
2022-12-26 16:10:38 +01:00
private fun bindUiStateBrowse ( uiState : LibraryFragmentViewModel . UiState . Browse ) {
adapter . submitList ( uiState . itemList )
}
@SuppressLint ( " NotifyDataSetChanged " )
private fun bindUiStateSearch ( uiState : LibraryFragmentViewModel . UiState . Search ) {
adapter . submitList ( uiState . itemList )
adapter . notifyDataSetChanged ( ) // this is needed, else the adapter will not update
}
private fun bindUiStateLoading ( ) {
// currently not used
}
private fun bindUiStateError ( uiState : LibraryFragmentViewModel . UiState . Error ) {
// currently not used
Log . e ( javaClass . name , " A error occurred while loading a UiState: ${uiState.message} " )
}
2021-12-27 21:14:35 +01:00
inner class PaginationScrollListener : RecyclerView . OnScrollListener ( ) {
override fun onScrolled ( recyclerView : RecyclerView , dx : Int , dy : Int ) {
super . onScrolled ( recyclerView , dx , dy )
2022-12-26 16:10:38 +01:00
if ( ! model . isLazyLoading ) {
val layoutManager = recyclerView . layoutManager as ? GridLayoutManager
layoutManager ?. let {
// adapter.itemCount - 10 to start loading a bit earlier than the actual end
if ( layoutManager . findLastCompletelyVisibleItemPosition ( ) >= ( adapter . itemCount - 10 ) ) {
model . onLazyLoad ( ) . invokeOnCompletion {
adapter . notifyItemRangeInserted ( adapter . itemCount , model . PAGESIZE )
}
2021-12-27 21:14:35 +01:00
}
}
}
}
2022-12-26 16:10:38 +01:00
2021-12-27 21:14:35 +01:00
}
2022-12-26 16:10:38 +01:00
}