Otter-App-Android-Funkwhale/app/src/main/java/com/github/apognu/otter/fragments/FunkwhaleFragment.kt

117 lines
3.2 KiB
Kotlin
Raw Normal View History

2019-08-19 16:50:33 +02:00
package com.github.apognu.otter.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.github.apognu.otter.repositories.HttpUpstream
2019-08-19 16:50:33 +02:00
import com.github.apognu.otter.repositories.Repository
import com.github.apognu.otter.utils.Cache
2019-10-31 16:17:37 +01:00
import com.github.apognu.otter.utils.log
2019-08-19 16:50:33 +02:00
import com.github.apognu.otter.utils.untilNetwork
import com.google.gson.Gson
2019-08-19 16:50:33 +02:00
import kotlinx.android.synthetic.main.fragment_artists.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
2019-08-19 16:50:33 +02:00
abstract class FunkwhaleAdapter<D, VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>() {
var data: MutableList<D> = mutableListOf()
}
abstract class FunkwhaleFragment<D : Any, A : FunkwhaleAdapter<D, *>> : Fragment() {
abstract val viewRes: Int
abstract val recycler: RecyclerView
open val layoutManager: RecyclerView.LayoutManager get() = LinearLayoutManager(context)
lateinit var repository: Repository<D, *>
lateinit var adapter: A
private var initialFetched = false
2019-08-19 16:50:33 +02:00
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(viewRes, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recycler.layoutManager = layoutManager
recycler.adapter = adapter
(repository.upstream as? HttpUpstream<*, *>)?.let { upstream ->
if (upstream.behavior == HttpUpstream.Behavior.Progressive) {
2019-10-31 16:17:37 +01:00
recycler.setOnScrollChangeListener { _, _, y, _, _ ->
if (y > 0 && !recycler.canScrollVertically(1)) {
fetch(Repository.Origin.Network.origin, adapter.data.size)
}
2019-08-19 16:50:33 +02:00
}
}
}
fetch()
2019-08-19 16:50:33 +02:00
}
override fun onResume() {
super.onResume()
swiper?.setOnRefreshListener {
fetch(Repository.Origin.Network.origin)
2019-08-19 16:50:33 +02:00
}
}
open fun onDataFetched(data: List<D>) {}
private fun fetch(upstreams: Int = (Repository.Origin.Network.origin and Repository.Origin.Cache.origin), size: Int = 0) {
2019-10-31 16:17:37 +01:00
var first = true
swiper?.isRefreshing = true
repository.fetch(upstreams, size).untilNetwork(IO) { data, isCache, hasMore ->
if (isCache) {
adapter.data = data.toMutableList()
2019-10-31 16:17:37 +01:00
adapter.notifyDataSetChanged()
return@untilNetwork
}
2019-10-31 16:17:37 +01:00
if (first) {
first = false
adapter.data.clear()
}
onDataFetched(data)
2019-10-31 16:17:37 +01:00
adapter.data.addAll(data)
if (!hasMore) {
swiper?.isRefreshing = false
repository.cacheId?.let { cacheId ->
Cache.set(
context,
cacheId,
Gson().toJson(repository.cache(adapter.data)).toByteArray()
)
}
}
GlobalScope.launch(Main) {
2019-10-31 16:17:37 +01:00
when (first) {
true -> {
adapter.notifyDataSetChanged()
2019-10-31 16:17:37 +01:00
first = false
}
2019-10-31 16:17:37 +01:00
false -> adapter.notifyItemRangeInserted(adapter.data.size, data.size)
}
}
}
}
2019-08-19 16:50:33 +02:00
}