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.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import android.graphics.pdf.PdfDocument
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -10,6 +11,8 @@ import android.view.ViewGroup
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.paging.DataSource
|
||||||
import androidx.paging.ItemKeyedDataSource
|
import androidx.paging.ItemKeyedDataSource
|
||||||
import androidx.paging.PagedList
|
import androidx.paging.PagedList
|
||||||
import androidx.paging.PagedListAdapter
|
import androidx.paging.PagedListAdapter
|
||||||
@ -31,7 +34,7 @@ import retrofit2.Response
|
|||||||
open class FeedFragment<T: FeedContent, VH: RecyclerView.ViewHolder?>: Fragment() {
|
open class FeedFragment<T: FeedContent, VH: RecyclerView.ViewHolder?>: Fragment() {
|
||||||
|
|
||||||
lateinit var content: LiveData<PagedList<T>>
|
lateinit var content: LiveData<PagedList<T>>
|
||||||
|
lateinit var factory: FeedDataSourceFactory
|
||||||
|
|
||||||
protected var accessToken: String? = null
|
protected var accessToken: String? = null
|
||||||
protected lateinit var pixelfedAPI: PixelfedAPI
|
protected lateinit var pixelfedAPI: PixelfedAPI
|
||||||
@ -66,26 +69,73 @@ open class FeedFragment<T: FeedContent, VH: RecyclerView.ViewHolder?>: Fragment(
|
|||||||
pixelfedAPI = PixelfedAPI.create("${preferences.getString("domain", "")}")
|
pixelfedAPI = PixelfedAPI.create("${preferences.getString("domain", "")}")
|
||||||
accessToken = preferences.getString("accessToken", "")
|
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>){
|
inner class FeedDataSource(private val makeInitialCall: (Int) -> Call<List<T>>,
|
||||||
call.enqueue(object : Callback<List<T>> {
|
private val makeAfterCall: (Int, String) -> Call<List<T>>
|
||||||
override fun onResponse(call: Call<List<T>>, response: Response<List<T>>) {
|
): ItemKeyedDataSource<String, T>() {
|
||||||
if (response.code() == 200) {
|
|
||||||
val notifications = response.body()!! as ArrayList<T>
|
//We use the id as the key
|
||||||
callback.onResult(notifications as List<T>)
|
override fun getKey(item: T): String {
|
||||||
} else{
|
return item.id
|
||||||
Toast.makeText(context,"Something went wrong while loading", Toast.LENGTH_SHORT).show()
|
}
|
||||||
}
|
//This is called to initialize the list, so we want some of the latest statuses
|
||||||
swipeRefreshLayout.isRefreshing = false
|
override fun loadInitial(
|
||||||
progressBar.visibility = View.GONE
|
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())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,3 +153,4 @@ abstract class FeedsRecyclerViewAdapter<T: FeedContent, VH : RecyclerView.ViewHo
|
|||||||
|
|
||||||
protected lateinit var context: Context
|
protected lateinit var context: Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,10 +9,8 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.paging.DataSource
|
|
||||||
import androidx.paging.ItemKeyedDataSource
|
|
||||||
import androidx.paging.LivePagedListBuilder
|
import androidx.paging.LivePagedListBuilder
|
||||||
import androidx.paging.PagedList
|
import androidx.paging.PagedList
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
@ -25,12 +23,12 @@ import com.h.pixeldroid.R
|
|||||||
import com.h.pixeldroid.objects.Status
|
import com.h.pixeldroid.objects.Status
|
||||||
import com.h.pixeldroid.utils.ImageConverter
|
import com.h.pixeldroid.utils.ImageConverter
|
||||||
import kotlinx.android.synthetic.main.fragment_home.*
|
import kotlinx.android.synthetic.main.fragment_home.*
|
||||||
|
import retrofit2.Call
|
||||||
|
|
||||||
|
|
||||||
class HomeFragment : FeedFragment<Status, HomeFragment.HomeRecyclerViewAdapter.ViewHolder>() {
|
class HomeFragment : FeedFragment<Status, HomeFragment.HomeRecyclerViewAdapter.ViewHolder>() {
|
||||||
|
|
||||||
lateinit var picRequest: RequestBuilder<Drawable>
|
lateinit var picRequest: RequestBuilder<Drawable>
|
||||||
lateinit var factory: HomeDataSourceFactory
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
@ -38,9 +36,7 @@ class HomeFragment : FeedFragment<Status, HomeFragment.HomeRecyclerViewAdapter.V
|
|||||||
): View? {
|
): View? {
|
||||||
val view = super.onCreateView(inflater, container, savedInstanceState)
|
val view = super.onCreateView(inflater, container, savedInstanceState)
|
||||||
|
|
||||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
content = makeContent()
|
||||||
factory = HomeDataSourceFactory()
|
|
||||||
content = LivePagedListBuilder(factory, config).build()
|
|
||||||
|
|
||||||
//RequestBuilder that is re-used for every image
|
//RequestBuilder that is re-used for every image
|
||||||
picRequest = Glide.with(this)
|
picRequest = Glide.with(this)
|
||||||
@ -67,13 +63,24 @@ class HomeFragment : FeedFragment<Status, HomeFragment.HomeRecyclerViewAdapter.V
|
|||||||
return view
|
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?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
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())
|
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.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.paging.DataSource
|
|
||||||
import androidx.paging.ItemKeyedDataSource
|
|
||||||
import androidx.paging.LivePagedListBuilder
|
import androidx.paging.LivePagedListBuilder
|
||||||
import androidx.paging.PagedList
|
import androidx.paging.PagedList
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
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.Notification
|
||||||
import com.h.pixeldroid.objects.Status
|
import com.h.pixeldroid.objects.Status
|
||||||
import kotlinx.android.synthetic.main.fragment_feed.*
|
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 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>() {
|
class NotificationsFragment : FeedFragment<Notification, NotificationsFragment.NotificationsRecyclerViewAdapter.ViewHolder>() {
|
||||||
|
|
||||||
lateinit var profilePicRequest: RequestBuilder<Drawable>
|
lateinit var profilePicRequest: RequestBuilder<Drawable>
|
||||||
lateinit var factory: NotificationsDataSourceFactory
|
|
||||||
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
@ -50,9 +45,7 @@ class NotificationsFragment : FeedFragment<Notification, NotificationsFragment.N
|
|||||||
|
|
||||||
val view = super.onCreateView(inflater, container, savedInstanceState)
|
val view = super.onCreateView(inflater, container, savedInstanceState)
|
||||||
|
|
||||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
content = makeContent()
|
||||||
factory = NotificationsDataSourceFactory()
|
|
||||||
content = LivePagedListBuilder(factory, config).build()
|
|
||||||
|
|
||||||
//RequestBuilder that is re-used for every image
|
//RequestBuilder that is re-used for every image
|
||||||
profilePicRequest = Glide.with(this)
|
profilePicRequest = Glide.with(this)
|
||||||
@ -79,13 +72,24 @@ class NotificationsFragment : FeedFragment<Notification, NotificationsFragment.N
|
|||||||
|
|
||||||
return view
|
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?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
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)
|
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…
x
Reference in New Issue
Block a user