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
import androidx.fragment.app.Fragment
2021-06-06 17:54:19 +02:00
import androidx.lifecycle.lifecycleScope
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
2021-12-05 00:42:56 +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
2020-11-15 13:39:33 +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 LibraryFragment : Fragment ( ) {
2020-11-25 22:35:55 +01:00
private lateinit var binding : FragmentLibraryBinding
2020-10-15 13:00:44 +02:00
private lateinit var adapter : MediaItemAdapter
2020-10-08 22:20:20 +02:00
2021-12-27 21:14:35 +01:00
private val itemList = arrayListOf < ItemMedia > ( )
private val pageSize = 30
private var nextItemIndex = 0
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 )
2020-10-15 13:00:44 +02:00
// init async
2021-06-06 17:54:19 +02:00
lifecycleScope . launch {
2020-10-09 13:25:12 +02:00
// create and set the adapter, needs context
2021-06-06 17:54:19 +02:00
context ?. let {
2021-12-27 21:14:35 +01:00
val initialResults = Crunchyroll . browse ( n = pageSize )
itemList . addAll ( initialResults . items . map { item ->
ItemMedia ( item . id , item . title , item . images . poster _wide [ 0 ] [ 0 ] . source )
} )
nextItemIndex += pageSize
2021-12-05 00:42:56 +01:00
2021-12-27 21:14:35 +01:00
adapter = MediaItemAdapter ( itemList )
2021-12-20 22:14:58 +01:00
adapter . onItemClick = { mediaIdStr , _ ->
2021-12-27 22:50:29 +01:00
activity ?. showFragment ( MediaFragment ( mediaIdStr ) )
2020-10-12 20:30:45 +02:00
}
2021-06-06 17:54:19 +02:00
binding . recyclerMediaLibrary . adapter = adapter
binding . recyclerMediaLibrary . addItemDecoration ( MediaItemDecoration ( 9 ) )
2021-12-27 21:14:35 +01:00
// TODO replace with pagination3
// https://medium.com/swlh/paging3-recyclerview-pagination-made-easy-333c7dfa8797
binding . recyclerMediaLibrary . addOnScrollListener ( PaginationScrollListener ( ) )
2020-10-09 13:02:58 +02:00
}
2020-10-08 22:20:20 +02:00
}
}
2021-12-27 21:14:35 +01:00
inner class PaginationScrollListener : RecyclerView . OnScrollListener ( ) {
private var isLoading = false
override fun onScrolled ( recyclerView : RecyclerView , dx : Int , dy : Int ) {
super . onScrolled ( recyclerView , dx , dy )
val layoutManager = recyclerView . layoutManager as GridLayoutManager ?
if ( !is Loading ) layoutManager ?. let {
// itemList.size - 5 to start loading a bit earlier than the actual end
if ( layoutManager . findLastCompletelyVisibleItemPosition ( ) >= ( itemList . size - 5 ) ) {
// load new browse results async
isLoading = true
lifecycleScope . launch {
val firstNewItemIndex = itemList . lastIndex + 1
val results = Crunchyroll . browse ( start = nextItemIndex , n = pageSize )
itemList . addAll ( results . items . map { item ->
ItemMedia ( item . id , item . title , item . images . poster _wide [ 0 ] [ 0 ] . source )
} )
nextItemIndex += pageSize
adapter . notifyItemRangeInserted ( firstNewItemIndex , pageSize )
isLoading = false
}
}
}
}
}
2020-10-08 22:20:20 +02:00
}