Refactor into superclass
This commit is contained in:
parent
aedd697759
commit
0d6a5b6c86
|
@ -2,6 +2,7 @@ package com.h.pixeldroid.fragments.feeds
|
|||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.graphics.pdf.PdfDocument
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
|
@ -10,6 +11,8 @@ import android.view.ViewGroup
|
|||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.paging.DataSource
|
||||
import androidx.paging.ItemKeyedDataSource
|
||||
import androidx.paging.PagedList
|
||||
import androidx.paging.PagedListAdapter
|
||||
|
@ -31,7 +34,7 @@ import retrofit2.Response
|
|||
open class FeedFragment<T: FeedContent, VH: RecyclerView.ViewHolder?>: Fragment() {
|
||||
|
||||
lateinit var content: LiveData<PagedList<T>>
|
||||
|
||||
lateinit var factory: FeedDataSourceFactory
|
||||
|
||||
protected var accessToken: String? = null
|
||||
protected lateinit var pixelfedAPI: PixelfedAPI
|
||||
|
@ -66,26 +69,73 @@ open class FeedFragment<T: FeedContent, VH: RecyclerView.ViewHolder?>: Fragment(
|
|||
pixelfedAPI = PixelfedAPI.create("${preferences.getString("domain", "")}")
|
||||
accessToken = preferences.getString("accessToken", "")
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener {
|
||||
//by invalidating data, loadInitial will be called again
|
||||
factory.liveData.value!!.invalidate()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal fun enqueueCall(call: Call<List<T>>, callback: ItemKeyedDataSource.LoadCallback<T>){
|
||||
call.enqueue(object : Callback<List<T>> {
|
||||
override fun onResponse(call: Call<List<T>>, response: Response<List<T>>) {
|
||||
if (response.code() == 200) {
|
||||
val notifications = response.body()!! as ArrayList<T>
|
||||
callback.onResult(notifications as List<T>)
|
||||
} else{
|
||||
Toast.makeText(context,"Something went wrong while loading", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
progressBar.visibility = View.GONE
|
||||
}
|
||||
inner class FeedDataSource(private val makeInitialCall: (Int) -> Call<List<T>>,
|
||||
private val makeAfterCall: (Int, String) -> Call<List<T>>
|
||||
): ItemKeyedDataSource<String, T>() {
|
||||
|
||||
//We use the id as the key
|
||||
override fun getKey(item: T): String {
|
||||
return item.id
|
||||
}
|
||||
//This is called to initialize the list, so we want some of the latest statuses
|
||||
override fun loadInitial(
|
||||
params: LoadInitialParams<String>,
|
||||
callback: LoadInitialCallback<T>
|
||||
) {
|
||||
enqueueCall(makeInitialCall(params.requestedLoadSize), callback)
|
||||
}
|
||||
|
||||
//This is called to when we get to the bottom of the loaded content, so we want statuses
|
||||
//older than the given key (params.key)
|
||||
override fun loadAfter(params: LoadParams<String>, callback: LoadCallback<T>) {
|
||||
enqueueCall(makeAfterCall(params.requestedLoadSize, params.key), callback)
|
||||
}
|
||||
|
||||
override fun loadBefore(params: LoadParams<String>, callback: LoadCallback<T>) {
|
||||
//do nothing here, it is expected to pull to refresh to load newer notifications
|
||||
}
|
||||
|
||||
private fun enqueueCall(call: Call<List<T>>, callback: LoadCallback<T>){
|
||||
call.enqueue(object : Callback<List<T>> {
|
||||
override fun onResponse(call: Call<List<T>>, response: Response<List<T>>) {
|
||||
if (response.code() == 200) {
|
||||
val notifications = response.body()!! as ArrayList<T>
|
||||
callback.onResult(notifications as List<T>)
|
||||
} else{
|
||||
Toast.makeText(context,"Something went wrong while loading", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
progressBar.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<List<T>>, t: Throwable) {
|
||||
Toast.makeText(context,"Could not get feed", Toast.LENGTH_SHORT).show()
|
||||
Log.e("FeedFragment", t.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
inner class FeedDataSourceFactory(
|
||||
private val makeInitialCall: (Int) -> Call<List<T>>,
|
||||
private val makeAfterCall: (Int, String) -> Call<List<T>>
|
||||
): DataSource.Factory<String, T>() {
|
||||
lateinit var liveData: MutableLiveData<FeedDataSource>
|
||||
|
||||
override fun create(): DataSource<String, T> {
|
||||
val dataSource = FeedDataSource(::makeInitialCall.get(), ::makeAfterCall.get())
|
||||
liveData = MutableLiveData()
|
||||
liveData.postValue(dataSource)
|
||||
return dataSource
|
||||
}
|
||||
|
||||
|
||||
override fun onFailure(call: Call<List<T>>, t: Throwable) {
|
||||
Toast.makeText(context,"Could not get feed", Toast.LENGTH_SHORT).show()
|
||||
Log.e("FeedFragment", t.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,4 +152,5 @@ abstract class FeedsRecyclerViewAdapter<T: FeedContent, VH : RecyclerView.ViewHo
|
|||
), PreloadModelProvider<T> {
|
||||
|
||||
protected lateinit var context: Context
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,10 +9,8 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.paging.DataSource
|
||||
import androidx.paging.ItemKeyedDataSource
|
||||
import androidx.paging.LivePagedListBuilder
|
||||
import androidx.paging.PagedList
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
@ -25,12 +23,12 @@ import com.h.pixeldroid.R
|
|||
import com.h.pixeldroid.objects.Status
|
||||
import com.h.pixeldroid.utils.ImageConverter
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
import retrofit2.Call
|
||||
|
||||
|
||||
class HomeFragment : FeedFragment<Status, HomeFragment.HomeRecyclerViewAdapter.ViewHolder>() {
|
||||
|
||||
lateinit var picRequest: RequestBuilder<Drawable>
|
||||
lateinit var factory: HomeDataSourceFactory
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
|
@ -38,9 +36,7 @@ class HomeFragment : FeedFragment<Status, HomeFragment.HomeRecyclerViewAdapter.V
|
|||
): View? {
|
||||
val view = super.onCreateView(inflater, container, savedInstanceState)
|
||||
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
factory = HomeDataSourceFactory()
|
||||
content = LivePagedListBuilder(factory, config).build()
|
||||
content = makeContent()
|
||||
|
||||
//RequestBuilder that is re-used for every image
|
||||
picRequest = Glide.with(this)
|
||||
|
@ -67,13 +63,24 @@ class HomeFragment : FeedFragment<Status, HomeFragment.HomeRecyclerViewAdapter.V
|
|||
return view
|
||||
}
|
||||
|
||||
private fun makeContent(): LiveData<PagedList<Status>> {
|
||||
fun makeInitialCall(requestedLoadSize: Int): Call<List<Status>> {
|
||||
return pixelfedAPI
|
||||
.timelineHome("Bearer $accessToken", limit="$requestedLoadSize")
|
||||
}
|
||||
fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Status>> {
|
||||
return pixelfedAPI
|
||||
.timelineHome("Bearer $accessToken", max_id=key,
|
||||
limit="$requestedLoadSize")
|
||||
}
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
factory = FeedDataSourceFactory(::makeInitialCall, ::makeAfterCall)
|
||||
return LivePagedListBuilder(factory, config).build()
|
||||
}
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener {
|
||||
//by invalidating data, loadInitial will be called again
|
||||
factory.postLiveData.value!!.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,47 +145,4 @@ class HomeFragment : FeedFragment<Status, HomeFragment.HomeRecyclerViewAdapter.V
|
|||
return picRequest.load(item.getPostUrl())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inner class HomeDataSource: ItemKeyedDataSource<String, Status>() {
|
||||
|
||||
//We use the id as the key
|
||||
override fun getKey(item: Status): String {
|
||||
return item.id
|
||||
}
|
||||
//This is called to initialize the list, so we want some of the latest statuses
|
||||
override fun loadInitial(
|
||||
params: LoadInitialParams<String>,
|
||||
callback: LoadInitialCallback<Status>
|
||||
) {
|
||||
val call = pixelfedAPI
|
||||
.timelineHome("Bearer $accessToken", limit="${params.requestedLoadSize}")
|
||||
enqueueCall(call, callback)
|
||||
}
|
||||
|
||||
//This is called to when we get to the bottom of the loaded content, so we want statuses
|
||||
//older than the given key (params.key)
|
||||
override fun loadAfter(params: LoadParams<String>, callback: LoadCallback<Status>) {
|
||||
val call = pixelfedAPI
|
||||
.timelineHome("Bearer $accessToken", max_id=params.key,
|
||||
limit="${params.requestedLoadSize}")
|
||||
enqueueCall(call, callback)
|
||||
}
|
||||
|
||||
override fun loadBefore(params: LoadParams<String>, callback: LoadCallback<Status>) {
|
||||
//do nothing here, it is expected to pull to refresh to load newer content
|
||||
}
|
||||
|
||||
}
|
||||
inner class HomeDataSourceFactory: DataSource.Factory<String, Status>() {
|
||||
|
||||
lateinit var postLiveData: MutableLiveData<HomeDataSource>
|
||||
|
||||
override fun create(): DataSource<String, Status> {
|
||||
val dataSource = HomeDataSource()
|
||||
postLiveData = MutableLiveData()
|
||||
postLiveData.postValue(dataSource)
|
||||
return dataSource
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,8 @@ import android.view.ViewGroup
|
|||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.paging.DataSource
|
||||
import androidx.paging.ItemKeyedDataSource
|
||||
import androidx.paging.LivePagedListBuilder
|
||||
import androidx.paging.PagedList
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
@ -29,9 +27,8 @@ import com.h.pixeldroid.R
|
|||
import com.h.pixeldroid.objects.Notification
|
||||
import com.h.pixeldroid.objects.Status
|
||||
import kotlinx.android.synthetic.main.fragment_feed.*
|
||||
import kotlinx.android.synthetic.main.fragment_feed.swipeRefreshLayout
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
import kotlinx.android.synthetic.main.fragment_notifications.view.*
|
||||
import retrofit2.Call
|
||||
|
||||
|
||||
/**
|
||||
|
@ -40,8 +37,6 @@ import kotlinx.android.synthetic.main.fragment_notifications.view.*
|
|||
class NotificationsFragment : FeedFragment<Notification, NotificationsFragment.NotificationsRecyclerViewAdapter.ViewHolder>() {
|
||||
|
||||
lateinit var profilePicRequest: RequestBuilder<Drawable>
|
||||
lateinit var factory: NotificationsDataSourceFactory
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
|
@ -50,9 +45,7 @@ class NotificationsFragment : FeedFragment<Notification, NotificationsFragment.N
|
|||
|
||||
val view = super.onCreateView(inflater, container, savedInstanceState)
|
||||
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
factory = NotificationsDataSourceFactory()
|
||||
content = LivePagedListBuilder(factory, config).build()
|
||||
content = makeContent()
|
||||
|
||||
//RequestBuilder that is re-used for every image
|
||||
profilePicRequest = Glide.with(this)
|
||||
|
@ -79,13 +72,24 @@ class NotificationsFragment : FeedFragment<Notification, NotificationsFragment.N
|
|||
|
||||
return view
|
||||
}
|
||||
|
||||
private fun makeContent(): LiveData<PagedList<Notification>> {
|
||||
fun makeInitialCall(requestedLoadSize: Int): Call<List<Notification>> {
|
||||
return pixelfedAPI
|
||||
.notifications("Bearer $accessToken", min_id="1", limit="$requestedLoadSize")
|
||||
}
|
||||
fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Notification>> {
|
||||
return pixelfedAPI
|
||||
.notifications("Bearer $accessToken", max_id=key, limit="$requestedLoadSize")
|
||||
}
|
||||
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
factory = FeedDataSourceFactory(::makeInitialCall, ::makeAfterCall)
|
||||
return LivePagedListBuilder(factory, config).build()
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener {
|
||||
factory.notificationsLiveData.value!!.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -196,47 +200,4 @@ class NotificationsFragment : FeedFragment<Notification, NotificationsFragment.N
|
|||
return profilePicRequest.load(item.account.avatar_static)
|
||||
}
|
||||
}
|
||||
|
||||
inner class NotificationsDataSource: ItemKeyedDataSource<String, Notification>() {
|
||||
|
||||
//We use the id as the key
|
||||
override fun getKey(item: Notification): String {
|
||||
return item.id
|
||||
}
|
||||
//This is called to initialize the list, so we want some of the latest statuses
|
||||
override fun loadInitial(
|
||||
params: LoadInitialParams<String>,
|
||||
callback: LoadInitialCallback<Notification>
|
||||
) {
|
||||
val call = pixelfedAPI
|
||||
.notifications("Bearer $accessToken", min_id="1", limit="${params.requestedLoadSize}")
|
||||
enqueueCall(call, callback)
|
||||
}
|
||||
//This is called to when we get to the bottom of the loaded content, so we want statuses
|
||||
//older than the given key (params.key)
|
||||
override fun loadAfter(params: LoadParams<String>, callback: LoadCallback<Notification>) {
|
||||
val call = pixelfedAPI
|
||||
.notifications("Bearer $accessToken", max_id=params.key, limit="${params.requestedLoadSize}")
|
||||
enqueueCall(call, callback)
|
||||
}
|
||||
|
||||
override fun loadBefore(params: LoadParams<String>, callback: LoadCallback<Notification>) {
|
||||
//do nothing here, it is expected to pull to refresh to load newer notifications
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
inner class NotificationsDataSourceFactory: DataSource.Factory<String, Notification>() {
|
||||
lateinit var notificationsLiveData: MutableLiveData<NotificationsDataSource>
|
||||
|
||||
override fun create(): DataSource<String, Notification> {
|
||||
val dataSource = NotificationsDataSource()
|
||||
notificationsLiveData = MutableLiveData()
|
||||
notificationsLiveData.postValue(dataSource)
|
||||
return dataSource
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue