Working on #169.
List isn't reloaded each time. When new articles arrive, the list is still updated, but the list stays at the same (old) position. Not sure if I keep this behavior, or try to keep the old position and scroll to it.
This commit is contained in:
parent
80ad65b196
commit
2c8902d404
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
- Updated the Contribution guide about translations.
|
- Updated the Contribution guide about translations.
|
||||||
|
|
||||||
|
- Better handling for articles update. (See #169)
|
||||||
|
|
||||||
**1.5.5.x (didn't last long) AND 1.5.6.x**
|
**1.5.5.x (didn't last long) AND 1.5.6.x**
|
||||||
|
|
||||||
- Toolbar in reader activity.
|
- Toolbar in reader activity.
|
||||||
|
@ -17,13 +17,13 @@ import android.support.v7.widget.RecyclerView
|
|||||||
import android.support.v7.widget.SearchView
|
import android.support.v7.widget.SearchView
|
||||||
import android.support.v7.widget.StaggeredGridLayoutManager
|
import android.support.v7.widget.StaggeredGridLayoutManager
|
||||||
import android.support.v7.widget.helper.ItemTouchHelper
|
import android.support.v7.widget.helper.ItemTouchHelper
|
||||||
import android.util.Log
|
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter
|
import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter
|
||||||
import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter
|
import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter
|
||||||
|
import apps.amine.bou.readerforselfoss.adapters.ItemsAdapter
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.Item
|
import apps.amine.bou.readerforselfoss.api.selfoss.Item
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
|
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.Sources
|
import apps.amine.bou.readerforselfoss.api.selfoss.Sources
|
||||||
@ -119,6 +119,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
private var recyclerViewScrollListener: RecyclerView.OnScrollListener? = null
|
private var recyclerViewScrollListener: RecyclerView.OnScrollListener? = null
|
||||||
private lateinit var settings: SharedPreferences
|
private lateinit var settings: SharedPreferences
|
||||||
|
|
||||||
|
private var recyclerAdapter: RecyclerView.Adapter<*>? = null
|
||||||
|
|
||||||
private var badgeNew: Int = -1
|
private var badgeNew: Int = -1
|
||||||
private var badgeAll: Int = -1
|
private var badgeAll: Int = -1
|
||||||
private var badgeFavs: Int = -1
|
private var badgeFavs: Int = -1
|
||||||
@ -161,7 +163,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
handleBottomBar()
|
handleBottomBar()
|
||||||
handleDrawer()
|
handleDrawer()
|
||||||
|
|
||||||
reloadLayoutManager()
|
|
||||||
handleSwipeRefreshLayout()
|
handleSwipeRefreshLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,6 +315,16 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
|
|
||||||
handleSharedPrefs()
|
handleSharedPrefs()
|
||||||
|
|
||||||
|
reloadLayoutManager()
|
||||||
|
|
||||||
|
if (!infiniteScroll) {
|
||||||
|
recyclerView.setHasFixedSize(true)
|
||||||
|
} else {
|
||||||
|
handleInfiniteScroll()
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBottomBarActions()
|
||||||
|
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,48 +634,67 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun reloadLayoutManager() {
|
private fun reloadLayoutManager() {
|
||||||
val mLayoutManager: RecyclerView.LayoutManager
|
val currentManager = recyclerView.layoutManager
|
||||||
if (shouldBeCardView) {
|
val layoutManager: RecyclerView.LayoutManager
|
||||||
mLayoutManager = StaggeredGridLayoutManager(
|
|
||||||
calculateNoOfColumns(),
|
// This will only update the layout manager if settings changed
|
||||||
StaggeredGridLayoutManager.VERTICAL
|
when (currentManager) {
|
||||||
)
|
is StaggeredGridLayoutManager ->
|
||||||
mLayoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
|
if (!shouldBeCardView) {
|
||||||
} else {
|
layoutManager = GridLayoutManager(this, calculateNoOfColumns())
|
||||||
mLayoutManager = GridLayoutManager(this, calculateNoOfColumns())
|
recyclerView.layoutManager = layoutManager
|
||||||
|
}
|
||||||
|
is GridLayoutManager ->
|
||||||
|
if (shouldBeCardView) {
|
||||||
|
layoutManager = StaggeredGridLayoutManager(
|
||||||
|
calculateNoOfColumns(),
|
||||||
|
StaggeredGridLayoutManager.VERTICAL
|
||||||
|
)
|
||||||
|
layoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
|
||||||
|
recyclerView.layoutManager = layoutManager
|
||||||
|
}
|
||||||
|
else ->
|
||||||
|
if (currentManager == null) {
|
||||||
|
if (!shouldBeCardView) {
|
||||||
|
layoutManager = GridLayoutManager(this, calculateNoOfColumns())
|
||||||
|
recyclerView.layoutManager = layoutManager
|
||||||
|
} else {
|
||||||
|
layoutManager = StaggeredGridLayoutManager(
|
||||||
|
calculateNoOfColumns(),
|
||||||
|
StaggeredGridLayoutManager.VERTICAL
|
||||||
|
)
|
||||||
|
layoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
|
||||||
|
recyclerView.layoutManager = layoutManager
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Unit
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recyclerView.layoutManager = mLayoutManager
|
|
||||||
|
|
||||||
if (!infiniteScroll) {
|
|
||||||
recyclerView.setHasFixedSize(true)
|
|
||||||
} else {
|
|
||||||
handleInfiniteScroll()
|
|
||||||
}
|
|
||||||
|
|
||||||
handleBottomBarActions(mLayoutManager)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleBottomBarActions(mLayoutManager: RecyclerView.LayoutManager) {
|
private fun handleBottomBarActions() {
|
||||||
bottomBar.setTabSelectedListener(object : BottomNavigationBar.OnTabSelectedListener {
|
bottomBar.setTabSelectedListener(object : BottomNavigationBar.OnTabSelectedListener {
|
||||||
override fun onTabUnselected(position: Int) = Unit
|
override fun onTabUnselected(position: Int) = Unit
|
||||||
|
|
||||||
override fun onTabReselected(position: Int) =
|
override fun onTabReselected(position: Int) {
|
||||||
when (mLayoutManager) {
|
val layoutManager = recyclerView.adapter
|
||||||
is StaggeredGridLayoutManager ->
|
|
||||||
if (mLayoutManager.findFirstCompletelyVisibleItemPositions(null)[0] == 0) {
|
when (layoutManager) {
|
||||||
getElementsAccordingToTab()
|
is StaggeredGridLayoutManager ->
|
||||||
} else {
|
if (layoutManager.findFirstCompletelyVisibleItemPositions(null)[0] == 0) {
|
||||||
mLayoutManager.scrollToPositionWithOffset(0, 0)
|
getElementsAccordingToTab()
|
||||||
}
|
} else {
|
||||||
is GridLayoutManager ->
|
layoutManager.scrollToPositionWithOffset(0, 0)
|
||||||
if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0) {
|
}
|
||||||
getElementsAccordingToTab()
|
is GridLayoutManager ->
|
||||||
} else {
|
if (layoutManager.findFirstCompletelyVisibleItemPosition() == 0) {
|
||||||
mLayoutManager.scrollToPositionWithOffset(0, 0)
|
getElementsAccordingToTab()
|
||||||
}
|
} else {
|
||||||
else -> Unit
|
layoutManager.scrollToPositionWithOffset(0, 0)
|
||||||
}
|
}
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onTabSelected(position: Int) {
|
override fun onTabSelected(position: Int) {
|
||||||
offset = 0
|
offset = 0
|
||||||
@ -739,25 +769,21 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
call: (String?, Long?, String?) -> Call<List<Item>>
|
call: (String?, Long?, String?) -> Call<List<Item>>
|
||||||
) {
|
) {
|
||||||
fun handleItemsResponse(response: Response<List<Item>>) {
|
fun handleItemsResponse(response: Response<List<Item>>) {
|
||||||
val didUpdate = (response.body() != items)
|
val shouldUpdate = (response.body() != items)
|
||||||
if (response.body() != null) {
|
if (response.body() != null) {
|
||||||
if (response.body() != items) {
|
if (shouldUpdate) {
|
||||||
if (appendResults) {
|
items = response.body() as ArrayList<Item>
|
||||||
items.addAll(response.body() as ArrayList<Item>)
|
|
||||||
} else {
|
|
||||||
items = response.body() as ArrayList<Item>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!appendResults) {
|
if (!appendResults) {
|
||||||
items = ArrayList()
|
items = ArrayList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (didUpdate) {
|
if (shouldUpdate) {
|
||||||
handleListResult(appendResults)
|
handleListResult(appendResults)
|
||||||
}
|
}
|
||||||
|
|
||||||
mayBeEmpty()
|
if (!appendResults) mayBeEmpty()
|
||||||
swipeRefreshLayout.isRefreshing = false
|
swipeRefreshLayout.isRefreshing = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,49 +862,49 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadLayoutManager()
|
if (recyclerAdapter == null) {
|
||||||
|
if (shouldBeCardView) {
|
||||||
|
recyclerAdapter =
|
||||||
|
ItemCardAdapter(
|
||||||
|
this,
|
||||||
|
items,
|
||||||
|
api,
|
||||||
|
customTabActivityHelper,
|
||||||
|
internalBrowser,
|
||||||
|
articleViewer,
|
||||||
|
fullHeightCards,
|
||||||
|
appColors,
|
||||||
|
debugReadingItems,
|
||||||
|
userIdentifier
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
recyclerAdapter =
|
||||||
|
ItemListAdapter(
|
||||||
|
this,
|
||||||
|
items,
|
||||||
|
api,
|
||||||
|
customTabActivityHelper,
|
||||||
|
clickBehavior,
|
||||||
|
internalBrowser,
|
||||||
|
articleViewer,
|
||||||
|
debugReadingItems,
|
||||||
|
userIdentifier
|
||||||
|
)
|
||||||
|
|
||||||
val mAdapter: RecyclerView.Adapter<*>
|
recyclerView.addItemDecoration(
|
||||||
if (shouldBeCardView) {
|
DividerItemDecoration(
|
||||||
mAdapter =
|
this@HomeActivity,
|
||||||
ItemCardAdapter(
|
DividerItemDecoration.VERTICAL
|
||||||
this,
|
)
|
||||||
items,
|
)
|
||||||
api,
|
}
|
||||||
customTabActivityHelper,
|
recyclerView.adapter = recyclerAdapter
|
||||||
internalBrowser,
|
|
||||||
articleViewer,
|
|
||||||
fullHeightCards,
|
|
||||||
appColors,
|
|
||||||
debugReadingItems,
|
|
||||||
userIdentifier
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
mAdapter =
|
if (!appendResults) {
|
||||||
ItemListAdapter(
|
(recyclerAdapter as ItemsAdapter<*>).updateAllItems(items)
|
||||||
this,
|
} else {
|
||||||
items,
|
(recyclerAdapter as ItemsAdapter<*>).addItemsAtEnd(items)
|
||||||
api,
|
}
|
||||||
customTabActivityHelper,
|
|
||||||
clickBehavior,
|
|
||||||
internalBrowser,
|
|
||||||
articleViewer,
|
|
||||||
debugReadingItems,
|
|
||||||
userIdentifier
|
|
||||||
)
|
|
||||||
|
|
||||||
recyclerView.addItemDecoration(
|
|
||||||
DividerItemDecoration(
|
|
||||||
this@HomeActivity,
|
|
||||||
DividerItemDecoration.VERTICAL
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
recyclerView.adapter = mAdapter
|
|
||||||
mAdapter.notifyDataSetChanged()
|
|
||||||
|
|
||||||
if (appendResults) {
|
|
||||||
recyclerView.scrollToPosition(firstVisible!!)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadBadges()
|
reloadBadges()
|
||||||
|
@ -40,17 +40,17 @@ import retrofit2.Callback
|
|||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
|
||||||
class ItemCardAdapter(
|
class ItemCardAdapter(
|
||||||
private val app: Activity,
|
override val app: Activity,
|
||||||
private val items: ArrayList<Item>,
|
override var items: ArrayList<Item>,
|
||||||
private val api: SelfossApi,
|
override val api: SelfossApi,
|
||||||
private val helper: CustomTabActivityHelper,
|
private val helper: CustomTabActivityHelper,
|
||||||
private val internalBrowser: Boolean,
|
private val internalBrowser: Boolean,
|
||||||
private val articleViewer: Boolean,
|
private val articleViewer: Boolean,
|
||||||
private val fullHeightCards: Boolean,
|
private val fullHeightCards: Boolean,
|
||||||
private val appColors: AppColors,
|
private val appColors: AppColors,
|
||||||
val debugReadingItems: Boolean,
|
override val debugReadingItems: Boolean,
|
||||||
val userIdentifier: String
|
override val userIdentifier: String
|
||||||
) : RecyclerView.Adapter<ItemCardAdapter.ViewHolder>() {
|
) : ItemsAdapter<ItemCardAdapter.ViewHolder>() {
|
||||||
private val c: Context = app.baseContext
|
private val c: Context = app.baseContext
|
||||||
private val generator: ColorGenerator = ColorGenerator.MATERIAL
|
private val generator: ColorGenerator = ColorGenerator.MATERIAL
|
||||||
private val imageMaxHeight: Int = c.resources.getDimension(R.dimen.card_image_max_height).toInt()
|
private val imageMaxHeight: Int = c.resources.getDimension(R.dimen.card_image_max_height).toInt()
|
||||||
@ -103,86 +103,6 @@ class ItemCardAdapter(
|
|||||||
return items.size
|
return items.size
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doUnmark(i: Item, position: Int) {
|
|
||||||
val s = Snackbar
|
|
||||||
.make(
|
|
||||||
app.findViewById(R.id.coordLayout),
|
|
||||||
R.string.marked_as_read,
|
|
||||||
Snackbar.LENGTH_LONG
|
|
||||||
)
|
|
||||||
.setAction(R.string.undo_string) {
|
|
||||||
items.add(position, i)
|
|
||||||
notifyItemInserted(position)
|
|
||||||
|
|
||||||
api.unmarkItem(i.id).enqueue(object : Callback<SuccessResponse> {
|
|
||||||
override fun onResponse(
|
|
||||||
call: Call<SuccessResponse>,
|
|
||||||
response: Response<SuccessResponse>
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
|
||||||
items.remove(i)
|
|
||||||
notifyItemRemoved(position)
|
|
||||||
doUnmark(i, position)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
val view = s.view
|
|
||||||
val tv: TextView = view.findViewById(android.support.design.R.id.snackbar_text)
|
|
||||||
tv.setTextColor(Color.WHITE)
|
|
||||||
s.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeItemAtIndex(position: Int) {
|
|
||||||
|
|
||||||
val i = items[position]
|
|
||||||
|
|
||||||
items.remove(i)
|
|
||||||
notifyItemRemoved(position)
|
|
||||||
|
|
||||||
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
|
|
||||||
override fun onResponse(
|
|
||||||
call: Call<SuccessResponse>,
|
|
||||||
response: Response<SuccessResponse>
|
|
||||||
) {
|
|
||||||
if (!response.succeeded() && debugReadingItems) {
|
|
||||||
val message =
|
|
||||||
"message: ${response.message()} " +
|
|
||||||
"response isSuccess: ${response.isSuccessful} " +
|
|
||||||
"response code: ${response.code()} " +
|
|
||||||
"response message: ${response.message()} " +
|
|
||||||
"response errorBody: ${response.errorBody()?.string()} " +
|
|
||||||
"body success: ${response.body()?.success} " +
|
|
||||||
"body isSuccess: ${response.body()?.isSuccess}"
|
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
|
||||||
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
|
|
||||||
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
|
||||||
|
|
||||||
Toast.makeText(c, message, Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
doUnmark(i, position)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
|
||||||
if (debugReadingItems) {
|
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
|
||||||
Crashlytics.log(100, "READ_DEBUG_ERROR", t.message)
|
|
||||||
Crashlytics.logException(t)
|
|
||||||
Toast.makeText(c, t.message, Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
Toast.makeText(
|
|
||||||
app,
|
|
||||||
app.getString(R.string.cant_mark_read),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
items.add(i)
|
|
||||||
notifyItemInserted(position)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class ViewHolder(val mView: CardView) : RecyclerView.ViewHolder(mView) {
|
inner class ViewHolder(val mView: CardView) : RecyclerView.ViewHolder(mView) {
|
||||||
init {
|
init {
|
||||||
mView.setCardBackgroundColor(appColors.cardBackground)
|
mView.setCardBackgroundColor(appColors.cardBackground)
|
||||||
|
@ -39,16 +39,16 @@ import java.util.*
|
|||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class ItemListAdapter(
|
class ItemListAdapter(
|
||||||
private val app: Activity,
|
override val app: Activity,
|
||||||
private val items: ArrayList<Item>,
|
override var items: ArrayList<Item>,
|
||||||
private val api: SelfossApi,
|
override val api: SelfossApi,
|
||||||
private val helper: CustomTabActivityHelper,
|
private val helper: CustomTabActivityHelper,
|
||||||
private val clickBehavior: Boolean,
|
private val clickBehavior: Boolean,
|
||||||
private val internalBrowser: Boolean,
|
private val internalBrowser: Boolean,
|
||||||
private val articleViewer: Boolean,
|
private val articleViewer: Boolean,
|
||||||
val debugReadingItems: Boolean,
|
override val debugReadingItems: Boolean,
|
||||||
val userIdentifier: String
|
override val userIdentifier: String
|
||||||
) : RecyclerView.Adapter<ItemListAdapter.ViewHolder>() {
|
) : ItemsAdapter<ItemListAdapter.ViewHolder>() {
|
||||||
private val generator: ColorGenerator = ColorGenerator.MATERIAL
|
private val generator: ColorGenerator = ColorGenerator.MATERIAL
|
||||||
private val c: Context = app.baseContext
|
private val c: Context = app.baseContext
|
||||||
private val bars: ArrayList<Boolean> = ArrayList(Collections.nCopies(items.size + 1, false))
|
private val bars: ArrayList<Boolean> = ArrayList(Collections.nCopies(items.size + 1, false))
|
||||||
@ -119,84 +119,7 @@ class ItemListAdapter(
|
|||||||
|
|
||||||
override fun getItemCount(): Int = items.size
|
override fun getItemCount(): Int = items.size
|
||||||
|
|
||||||
private fun doUnmark(i: Item, position: Int) {
|
|
||||||
val s = Snackbar
|
|
||||||
.make(
|
|
||||||
app.findViewById(R.id.coordLayout),
|
|
||||||
R.string.marked_as_read,
|
|
||||||
Snackbar.LENGTH_LONG
|
|
||||||
)
|
|
||||||
.setAction(R.string.undo_string) {
|
|
||||||
items.add(position, i)
|
|
||||||
notifyItemInserted(position)
|
|
||||||
|
|
||||||
api.unmarkItem(i.id).enqueue(object : Callback<SuccessResponse> {
|
|
||||||
override fun onResponse(
|
|
||||||
call: Call<SuccessResponse>,
|
|
||||||
response: Response<SuccessResponse>
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
|
||||||
items.remove(i)
|
|
||||||
notifyItemRemoved(position)
|
|
||||||
doUnmark(i, position)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
val view = s.view
|
|
||||||
val tv: TextView = view.findViewById(android.support.design.R.id.snackbar_text)
|
|
||||||
tv.setTextColor(Color.WHITE)
|
|
||||||
s.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeItemAtIndex(position: Int) {
|
|
||||||
|
|
||||||
val i = items[position]
|
|
||||||
|
|
||||||
items.remove(i)
|
|
||||||
notifyItemRemoved(position)
|
|
||||||
|
|
||||||
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
|
|
||||||
override fun onResponse(
|
|
||||||
call: Call<SuccessResponse>,
|
|
||||||
response: Response<SuccessResponse>
|
|
||||||
) {
|
|
||||||
if (!response.succeeded() && debugReadingItems) {
|
|
||||||
val message =
|
|
||||||
"message: ${response.message()} " +
|
|
||||||
"response isSuccess: ${response.isSuccessful} " +
|
|
||||||
"response code: ${response.code()} " +
|
|
||||||
"response message: ${response.message()} " +
|
|
||||||
"response errorBody: ${response.errorBody()?.string()} " +
|
|
||||||
"body success: ${response.body()?.success} " +
|
|
||||||
"body isSuccess: ${response.body()?.isSuccess}"
|
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
|
||||||
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
|
|
||||||
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
|
||||||
Toast.makeText(c, message, Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
doUnmark(i, position)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
|
||||||
if (debugReadingItems) {
|
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
|
||||||
Crashlytics.log(100, "READ_DEBUG_ERROR", t.message)
|
|
||||||
Crashlytics.logException(t)
|
|
||||||
Toast.makeText(c, t.message, Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
Toast.makeText(
|
|
||||||
app,
|
|
||||||
app.getString(R.string.cant_mark_read),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
items.add(i)
|
|
||||||
notifyItemInserted(position)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class ViewHolder(val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
|
inner class ViewHolder(val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
|
||||||
|
|
||||||
@ -312,4 +235,6 @@ class ItemListAdapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,121 @@
|
|||||||
|
package apps.amine.bou.readerforselfoss.adapters
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.support.design.widget.Snackbar
|
||||||
|
import android.support.v7.widget.RecyclerView
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import apps.amine.bou.readerforselfoss.R
|
||||||
|
import apps.amine.bou.readerforselfoss.api.selfoss.Item
|
||||||
|
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
|
||||||
|
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
|
||||||
|
import apps.amine.bou.readerforselfoss.utils.succeeded
|
||||||
|
import com.crashlytics.android.Crashlytics
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.Callback
|
||||||
|
import retrofit2.Response
|
||||||
|
|
||||||
|
abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapter<VH>() {
|
||||||
|
abstract var items: ArrayList<Item>
|
||||||
|
abstract val api: SelfossApi
|
||||||
|
abstract val debugReadingItems: Boolean
|
||||||
|
abstract val userIdentifier: String
|
||||||
|
abstract val app: Activity
|
||||||
|
|
||||||
|
fun updateAllItems(newItems: ArrayList<Item>) {
|
||||||
|
items = newItems
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doUnmark(i: Item, position: Int) {
|
||||||
|
val s = Snackbar
|
||||||
|
.make(
|
||||||
|
app.findViewById(R.id.coordLayout),
|
||||||
|
R.string.marked_as_read,
|
||||||
|
Snackbar.LENGTH_LONG
|
||||||
|
)
|
||||||
|
.setAction(R.string.undo_string) {
|
||||||
|
items.add(position, i)
|
||||||
|
notifyItemInserted(position)
|
||||||
|
|
||||||
|
api.unmarkItem(i.id).enqueue(object : Callback<SuccessResponse> {
|
||||||
|
override fun onResponse(
|
||||||
|
call: Call<SuccessResponse>,
|
||||||
|
response: Response<SuccessResponse>
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
||||||
|
items.remove(i)
|
||||||
|
notifyItemRemoved(position)
|
||||||
|
doUnmark(i, position)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
val view = s.view
|
||||||
|
val tv: TextView = view.findViewById(android.support.design.R.id.snackbar_text)
|
||||||
|
tv.setTextColor(Color.WHITE)
|
||||||
|
s.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeItemAtIndex(position: Int) {
|
||||||
|
|
||||||
|
val i = items[position]
|
||||||
|
|
||||||
|
items.remove(i)
|
||||||
|
notifyItemRemoved(position)
|
||||||
|
|
||||||
|
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
|
||||||
|
override fun onResponse(
|
||||||
|
call: Call<SuccessResponse>,
|
||||||
|
response: Response<SuccessResponse>
|
||||||
|
) {
|
||||||
|
if (!response.succeeded() && debugReadingItems) {
|
||||||
|
val message =
|
||||||
|
"message: ${response.message()} " +
|
||||||
|
"response isSuccess: ${response.isSuccessful} " +
|
||||||
|
"response code: ${response.code()} " +
|
||||||
|
"response message: ${response.message()} " +
|
||||||
|
"response errorBody: ${response.errorBody()?.string()} " +
|
||||||
|
"body success: ${response.body()?.success} " +
|
||||||
|
"body isSuccess: ${response.body()?.isSuccess}"
|
||||||
|
Crashlytics.setUserIdentifier(userIdentifier)
|
||||||
|
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
|
||||||
|
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
||||||
|
|
||||||
|
Toast.makeText(app.baseContext, message, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
doUnmark(i, position)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
||||||
|
if (debugReadingItems) {
|
||||||
|
Crashlytics.setUserIdentifier(userIdentifier)
|
||||||
|
Crashlytics.log(100, "READ_DEBUG_ERROR", t.message)
|
||||||
|
Crashlytics.logException(t)
|
||||||
|
Toast.makeText(app.baseContext, t.message, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
Toast.makeText(
|
||||||
|
app,
|
||||||
|
app.getString(R.string.cant_mark_read),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
items.add(i)
|
||||||
|
notifyItemInserted(position)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addItemAtIndex(item: Item, position: Int) {
|
||||||
|
items.add(position, item)
|
||||||
|
notifyItemInserted(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addItemsAtEnd(newItems: List<Item>) {
|
||||||
|
val oldSize = items.size
|
||||||
|
items.addAll(newItems)
|
||||||
|
notifyItemRangeInserted(oldSize, newItems.size)
|
||||||
|
}
|
||||||
|
}
|
@ -6,9 +6,9 @@ import com.google.gson.annotations.SerializedName
|
|||||||
|
|
||||||
class ParsedContent(
|
class ParsedContent(
|
||||||
@SerializedName("title") val title: String,
|
@SerializedName("title") val title: String,
|
||||||
@SerializedName("content") val content: String,
|
@SerializedName("content") val content: String?,
|
||||||
@SerializedName("date_published") val date_published: String,
|
@SerializedName("date_published") val date_published: String,
|
||||||
@SerializedName("lead_image_url") val lead_image_url: String,
|
@SerializedName("lead_image_url") val lead_image_url: String?,
|
||||||
@SerializedName("dek") val dek: String,
|
@SerializedName("dek") val dek: String,
|
||||||
@SerializedName("url") val url: String,
|
@SerializedName("url") val url: String,
|
||||||
@SerializedName("domain") val domain: String,
|
@SerializedName("domain") val domain: String,
|
||||||
|
@ -164,14 +164,14 @@ class ArticleFragment : Fragment() {
|
|||||||
response: Response<ParsedContent>
|
response: Response<ParsedContent>
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
if (response.body() != null && response.body()!!.content != null && response.body()!!.content.isNotEmpty()) {
|
if (response.body() != null && response.body()!!.content != null && !response.body()!!.content.isNullOrEmpty()) {
|
||||||
rootView.source.text = response.body()!!.domain
|
rootView.source.text = response.body()!!.domain
|
||||||
rootView.titleView.text = response.body()!!.title
|
rootView.titleView.text = response.body()!!.title
|
||||||
url = response.body()!!.url
|
url = response.body()!!.url
|
||||||
|
|
||||||
htmlToWebview(response.body()!!.content, prefs)
|
htmlToWebview(response.body()!!.content.orEmpty(), prefs)
|
||||||
|
|
||||||
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isEmpty()) {
|
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isNullOrEmpty()) {
|
||||||
rootView.imageView.visibility = View.VISIBLE
|
rootView.imageView.visibility = View.VISIBLE
|
||||||
Glide
|
Glide
|
||||||
.with(activity!!.baseContext)
|
.with(activity!!.baseContext)
|
||||||
|
Loading…
Reference in New Issue
Block a user