Globalize the use of caching for main sections data, improved handling of loading more pages.

This commit is contained in:
Antoine POPINEAU 2020-07-10 20:28:44 +02:00
parent 57692f2e42
commit bc1e911b41
No known key found for this signature in database
GPG Key ID: A78AC64694F84063
6 changed files with 33 additions and 34 deletions

View File

@ -19,6 +19,7 @@ class AlbumsGridFragment : FunkwhaleFragment<Album, AlbumsGridAdapter>() {
override val viewRes = R.layout.fragment_albums_grid
override val recycler: RecyclerView get() = albums
override val layoutManager get() = GridLayoutManager(context, 3)
override val alwaysRefresh = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@ -10,10 +10,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.github.apognu.otter.repositories.HttpUpstream
import com.github.apognu.otter.repositories.Repository
import com.github.apognu.otter.utils.Cache
import com.github.apognu.otter.utils.Event
import com.github.apognu.otter.utils.EventBus
import com.github.apognu.otter.utils.untilNetwork
import com.github.apognu.otter.utils.*
import com.google.gson.Gson
import kotlinx.android.synthetic.main.fragment_artists.*
import kotlinx.coroutines.Dispatchers.IO
@ -28,8 +25,7 @@ abstract class FunkwhaleAdapter<D, VH : RecyclerView.ViewHolder> : RecyclerView.
}
abstract class FunkwhaleFragment<D : Any, A : FunkwhaleAdapter<D, *>> : Fragment() {
val INITIAL_PAGES = 5
val OFFSCREEN_PAGES = 10
val OFFSCREEN_PAGES = 20
abstract val viewRes: Int
abstract val recycler: RecyclerView
@ -39,7 +35,6 @@ abstract class FunkwhaleFragment<D : Any, A : FunkwhaleAdapter<D, *>> : Fragment
lateinit var repository: Repository<D, *>
lateinit var adapter: A
private var initialFetched = false
private var moreLoading = false
private var listener: Job? = null
@ -57,10 +52,10 @@ abstract class FunkwhaleFragment<D : Any, A : FunkwhaleAdapter<D, *>> : Fragment
if (upstream.behavior == HttpUpstream.Behavior.Progressive) {
recycler.setOnScrollChangeListener { _, _, _, _, _ ->
val offset = recycler.computeVerticalScrollOffset()
val left = recycler.computeVerticalScrollRange() - recycler.height - offset
if (initialFetched && !moreLoading && offset > 0 && left < (recycler.height * OFFSCREEN_PAGES)) {
if (!moreLoading && offset > 0 && needsMoreOffscreenPages()) {
moreLoading = true
fetch(Repository.Origin.Network.origin, adapter.data.size)
}
}
@ -106,13 +101,17 @@ abstract class FunkwhaleFragment<D : Any, A : FunkwhaleAdapter<D, *>> : Fragment
}
}
repository.fetch(upstreams, size).untilNetwork(lifecycleScope, IO) { data, isCache, page, hasMore ->
moreLoading = true
repository.fetch(upstreams, size).untilNetwork(lifecycleScope, IO) { data, isCache, _, hasMore ->
if (isCache && data.isEmpty()) {
return@untilNetwork fetch(Repository.Origin.Network.origin)
}
lifecycleScope.launch(Main) {
if (isCache) {
moreLoading = false
adapter.data = data.toMutableList()
adapter.notifyDataSetChanged()
@ -127,14 +126,6 @@ abstract class FunkwhaleFragment<D : Any, A : FunkwhaleAdapter<D, *>> : Fragment
adapter.data.addAll(data)
(repository.upstream as? HttpUpstream<*, *>)?.let { upstream ->
when (upstream.behavior) {
HttpUpstream.Behavior.Progressive -> if (!hasMore || page >= INITIAL_PAGES) swiper?.isRefreshing = false
HttpUpstream.Behavior.AtOnce -> if (!hasMore) swiper?.isRefreshing = false
HttpUpstream.Behavior.Single -> if (!hasMore) swiper?.isRefreshing = false
}
}
withContext(IO) {
if (adapter.data.isNotEmpty()) {
try {
@ -151,20 +142,27 @@ abstract class FunkwhaleFragment<D : Any, A : FunkwhaleAdapter<D, *>> : Fragment
}
if (hasMore) {
moreLoading = false
(repository.upstream as? HttpUpstream<*, *>)?.let { upstream ->
if (!isCache && upstream.behavior == HttpUpstream.Behavior.Progressive) {
if (page < INITIAL_PAGES) {
moreLoading = true
if (first || needsMoreOffscreenPages()) {
fetch(Repository.Origin.Network.origin, adapter.data.size)
} else {
initialFetched = true
moreLoading = false
}
} else {
moreLoading = false
}
}
}
(repository.upstream as? HttpUpstream<*, *>)?.let { upstream ->
when (upstream.behavior) {
HttpUpstream.Behavior.Progressive -> if (!hasMore || !moreLoading) swiper?.isRefreshing = false
HttpUpstream.Behavior.AtOnce -> if (!hasMore) swiper?.isRefreshing = false
HttpUpstream.Behavior.Single -> if (!hasMore) swiper?.isRefreshing = false
}
}
when (first) {
true -> {
adapter.notifyDataSetChanged()
@ -176,4 +174,11 @@ abstract class FunkwhaleFragment<D : Any, A : FunkwhaleAdapter<D, *>> : Fragment
}
}
}
private fun needsMoreOffscreenPages(): Boolean {
val offset = recycler.computeVerticalScrollOffset()
val left = recycler.computeVerticalScrollRange() - recycler.height - offset
return left < (recycler.height * OFFSCREEN_PAGES)
}
}

View File

@ -17,6 +17,7 @@ import kotlinx.android.synthetic.main.fragment_playlists.*
class PlaylistsFragment : FunkwhaleFragment<Playlist, PlaylistsAdapter>() {
override val viewRes = R.layout.fragment_playlists
override val recycler: RecyclerView get() = playlists
override val alwaysRefresh = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@ -16,6 +16,7 @@ import kotlinx.coroutines.launch
class RadiosFragment : FunkwhaleFragment<Radio, RadiosAdapter>() {
override val viewRes = R.layout.fragment_radios
override val recycler: RecyclerView get() = radios
override val alwaysRefresh = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@ -35,11 +35,6 @@ class RadioPlayer(val context: Context, val scope: CoroutineScope) {
private val favoritedRepository = FavoritedRepository(context)
init {
Cache.get(context, "radio_type")?.readLine()?.log()
Cache.get(context, "radio_id")?.readLine()?.log()
Cache.get(context, "radio_session")?.readLine()?.log()
Cache.get(context, "radio_cookie")?.readLine()?.log()
Cache.get(context, "radio_type")?.readLine()?.let { radio_type ->
Cache.get(context, "radio_id")?.readLine()?.toInt()?.let { radio_id ->
Cache.get(context, "radio_session")?.readLine()?.toInt()?.let { radio_session ->

View File

@ -12,12 +12,8 @@ fun Context?.toast(message: String, length: Int = Toast.LENGTH_SHORT) {
}
}
fun Any.log(message: String) {
Log.d("FUNKWHALE", "${this.javaClass.simpleName}: $message")
}
fun Any.log() {
Log.d("FUNKWHALE", this.toString())
fun Any.log(message: Any) {
Log.d("OTTER", "${javaClass.simpleName}: $message")
}
fun maybeNormalizeUrl(rawUrl: String?): String? {