From 9816b20bf60d19dd20314bcf25bd5875aeaa940d Mon Sep 17 00:00:00 2001 From: Amine Date: Thu, 1 Nov 2018 21:10:00 +0100 Subject: [PATCH] Only do api calls on network available. --- .../bou/readerforselfoss/HomeActivity.kt | 106 ++++----- .../bou/readerforselfoss/LoginActivity.kt | 78 ++++--- .../bou/readerforselfoss/ReaderActivity.kt | 107 +++++---- .../bou/readerforselfoss/SourcesActivity.kt | 47 ++-- .../adapters/ItemCardAdapter.kt | 81 +++---- .../readerforselfoss/adapters/ItemsAdapter.kt | 144 ++++++------ .../adapters/SourcesListAdapter.kt | 45 ++-- .../fragments/ArticleFragment.kt | 207 +++++++++--------- .../utils/network/NetworkUtils.kt | 4 +- app/src/main/res/layout/activity_reader.xml | 1 + 10 files changed, 434 insertions(+), 386 deletions(-) diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/HomeActivity.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/HomeActivity.kt index 369d569..4506ff8 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/HomeActivity.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/HomeActivity.kt @@ -204,7 +204,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int = - if (elementsShown != UNREAD_SHOWN) { + if (elementsShown != UNREAD_SHOWN || !this@HomeActivity.isNetworkAccessible(null)) { 0 } else { super.getSwipeDirs( @@ -696,36 +696,40 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { var sources: List? fun sourcesApiCall() { - api.sources.enqueue(object : Callback> { - override fun onResponse( - call: Call>?, - response: Response> - ) { - sources = response.body() - val apiDrawerData = DrawerData(tags, sources) - if ((maybeDrawerData != null && maybeDrawerData != apiDrawerData) || maybeDrawerData == null) { - handleDrawerData(apiDrawerData) + if (this@HomeActivity.isNetworkAccessible(null)) { + api.sources.enqueue(object : Callback> { + override fun onResponse( + call: Call>?, + response: Response> + ) { + sources = response.body() + val apiDrawerData = DrawerData(tags, sources) + if ((maybeDrawerData != null && maybeDrawerData != apiDrawerData) || maybeDrawerData == null) { + handleDrawerData(apiDrawerData) + } } + + override fun onFailure(call: Call>?, t: Throwable?) { + } + }) + } + } + + if (this@HomeActivity.isNetworkAccessible(null)) { + api.tags.enqueue(object : Callback> { + override fun onResponse( + call: Call>, + response: Response> + ) { + tags = response.body() + sourcesApiCall() } - override fun onFailure(call: Call>?, t: Throwable?) { + override fun onFailure(call: Call>?, t: Throwable?) { + sourcesApiCall() } }) } - - api.tags.enqueue(object : Callback> { - override fun onResponse( - call: Call>, - response: Response> - ) { - tags = response.body() - sourcesApiCall() - } - - override fun onFailure(call: Call>?, t: Throwable?) { - sourcesApiCall() - } - }) } drawer.addItem( @@ -1128,7 +1132,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { } private fun reloadBadges() { - if (displayUnreadCount || displayAllCount) { + if (this@HomeActivity.isNetworkAccessible(null) && (displayUnreadCount || displayAllCount)) { api.stats.enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { if (response.body() != null) { @@ -1234,33 +1238,37 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.refresh -> { - needsConfirmation(R.string.menu_home_refresh, R.string.refresh_dialog_message) { - api.update().enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - Toast.makeText( - this@HomeActivity, - R.string.refresh_success_response, Toast.LENGTH_LONG - ) - .show() - } + if (this@HomeActivity.isNetworkAccessible(null)) { + needsConfirmation(R.string.menu_home_refresh, R.string.refresh_dialog_message) { + api.update().enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + Toast.makeText( + this@HomeActivity, + R.string.refresh_success_response, Toast.LENGTH_LONG + ) + .show() + } - override fun onFailure(call: Call, t: Throwable) { - Toast.makeText( - this@HomeActivity, - R.string.refresh_failer_message, - Toast.LENGTH_SHORT - ).show() - } - }) - Toast.makeText(this, R.string.refresh_in_progress, Toast.LENGTH_SHORT).show() + override fun onFailure(call: Call, t: Throwable) { + Toast.makeText( + this@HomeActivity, + R.string.refresh_failer_message, + Toast.LENGTH_SHORT + ).show() + } + }) + Toast.makeText(this, R.string.refresh_in_progress, Toast.LENGTH_SHORT).show() + } + return true + } else { + return false } - return true } R.id.readAll -> { - if (elementsShown == UNREAD_SHOWN) { + if (elementsShown == UNREAD_SHOWN && this@HomeActivity.isNetworkAccessible(null)) { needsConfirmation(R.string.readAll, R.string.markall_dialog_message) { swipeRefreshLayout.isRefreshing = false val ids = allItems.map { it.id } diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/LoginActivity.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/LoginActivity.kt index 76693de..c79effa 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/LoginActivity.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/LoginActivity.kt @@ -21,6 +21,7 @@ import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.utils.Config import apps.amine.bou.readerforselfoss.utils.isBaseUrlValid import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException +import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible import com.mikepenz.aboutlibraries.Libs import com.mikepenz.aboutlibraries.LibsBuilder import kotlinx.android.synthetic.main.activity_login.* @@ -196,45 +197,50 @@ class LoginActivity : AppCompatActivity() { isWithSelfSignedCert, isWithSelfSignedCert ) - api.login().enqueue(object : Callback { - private fun preferenceError(t: Throwable) { - editor.remove("url") - editor.remove("login") - editor.remove("httpUserName") - editor.remove("password") - editor.remove("httpPassword") - editor.apply() - urlView.error = getString(R.string.wrong_infos) - loginView.error = getString(R.string.wrong_infos) - passwordView.error = getString(R.string.wrong_infos) - httpLoginView.error = getString(R.string.wrong_infos) - httpPasswordView.error = getString(R.string.wrong_infos) - if (logErrors) { - ACRA.getErrorReporter().maybeHandleSilentException(t, this@LoginActivity) - Toast.makeText( - this@LoginActivity, - t.message, - Toast.LENGTH_LONG - ).show() - } - showProgress(false) - } - override fun onResponse( - call: Call, - response: Response - ) { - if (response.body() != null && response.body()!!.isSuccess) { - goToMain() - } else { - preferenceError(Exception("No response body...")) + if (this@LoginActivity.isNetworkAccessible(this@LoginActivity.findViewById(R.id.loginForm))) { + api.login().enqueue(object : Callback { + private fun preferenceError(t: Throwable) { + editor.remove("url") + editor.remove("login") + editor.remove("httpUserName") + editor.remove("password") + editor.remove("httpPassword") + editor.apply() + urlView.error = getString(R.string.wrong_infos) + loginView.error = getString(R.string.wrong_infos) + passwordView.error = getString(R.string.wrong_infos) + httpLoginView.error = getString(R.string.wrong_infos) + httpPasswordView.error = getString(R.string.wrong_infos) + if (logErrors) { + ACRA.getErrorReporter().maybeHandleSilentException(t, this@LoginActivity) + Toast.makeText( + this@LoginActivity, + t.message, + Toast.LENGTH_LONG + ).show() + } + showProgress(false) } - } - override fun onFailure(call: Call, t: Throwable) { - preferenceError(t) - } - }) + override fun onResponse( + call: Call, + response: Response + ) { + if (response.body() != null && response.body()!!.isSuccess) { + goToMain() + } else { + preferenceError(Exception("No response body...")) + } + } + + override fun onFailure(call: Call, t: Throwable) { + preferenceError(t) + } + }) + } else { + showProgress(false) + } } } diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/ReaderActivity.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/ReaderActivity.kt index 3c55594..ca53e96 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/ReaderActivity.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/ReaderActivity.kt @@ -24,6 +24,7 @@ import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.Toppings import apps.amine.bou.readerforselfoss.transformers.DepthPageTransformer import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException +import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible import apps.amine.bou.readerforselfoss.utils.persistence.toEntity import apps.amine.bou.readerforselfoss.utils.succeeded import apps.amine.bou.readerforselfoss.utils.toggleStar @@ -74,7 +75,7 @@ class ReaderActivity : AppCompatActivity() { val scoop = Scoop.getInstance() scoop.bind(this, Toppings.PRIMARY.value, toolBar) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { scoop.bindStatusBar(this, Toppings.PRIMARY_DARK.value) } @@ -103,7 +104,8 @@ class ReaderActivity : AppCompatActivity() { readItem(allItems[currentItem]) - pager.adapter = ScreenSlidePagerAdapter(supportFragmentManager, AppColors(this@ReaderActivity)) + pager.adapter = + ScreenSlidePagerAdapter(supportFragmentManager, AppColors(this@ReaderActivity)) pager.currentItem = currentItem } @@ -132,7 +134,7 @@ class ReaderActivity : AppCompatActivity() { } fun readItem(item: Item) { - if (markOnScroll) { + if (this@ReaderActivity.isNetworkAccessible(this@ReaderActivity.findViewById(R.id.reader_activity_view)) && markOnScroll) { thread { db.itemsDao().delete(item.toEntity()) } @@ -164,7 +166,8 @@ class ReaderActivity : AppCompatActivity() { db.itemsDao().insertAllItems(item.toEntity()) } if (debugReadingItems) { - ACRA.getErrorReporter().maybeHandleSilentException(t, this@ReaderActivity) + ACRA.getErrorReporter() + .maybeHandleSilentException(t, this@ReaderActivity) } } } @@ -191,7 +194,6 @@ class ReaderActivity : AppCompatActivity() { private inner class ScreenSlidePagerAdapter(fm: FragmentManager, val appColors: AppColors) : FragmentStatePagerAdapter(fm) { - override fun getCount(): Int { return allItems.size } @@ -203,7 +205,12 @@ class ReaderActivity : AppCompatActivity() { override fun startUpdate(container: ViewGroup) { super.startUpdate(container) - container.background = ColorDrawable(ContextCompat.getColor(this@ReaderActivity, appColors.colorBackground)) + container.background = ColorDrawable( + ContextCompat.getColor( + this@ReaderActivity, + appColors.colorBackground + ) + ) } } @@ -228,52 +235,56 @@ class ReaderActivity : AppCompatActivity() { return true } R.id.save -> { - api.starrItem(allItems[pager.currentItem].id) - .enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar() - notifyAdapter() - canRemoveFromFavorite() - } + if (this@ReaderActivity.isNetworkAccessible(null)) { + api.starrItem(allItems[pager.currentItem].id) + .enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar() + notifyAdapter() + canRemoveFromFavorite() + } - override fun onFailure( - call: Call, - t: Throwable - ) { - Toast.makeText( - baseContext, - R.string.cant_mark_favortie, - Toast.LENGTH_SHORT - ).show() - } - }) + override fun onFailure( + call: Call, + t: Throwable + ) { + Toast.makeText( + baseContext, + R.string.cant_mark_favortie, + Toast.LENGTH_SHORT + ).show() + } + }) + } } R.id.unsave -> { - api.unstarrItem(allItems[pager.currentItem].id) - .enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar() - notifyAdapter() - canFavorite() - } + if (this@ReaderActivity.isNetworkAccessible(null)) { + api.unstarrItem(allItems[pager.currentItem].id) + .enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar() + notifyAdapter() + canFavorite() + } - override fun onFailure( - call: Call, - t: Throwable - ) { - Toast.makeText( - baseContext, - R.string.cant_unmark_favortie, - Toast.LENGTH_SHORT - ).show() - } - }) + override fun onFailure( + call: Call, + t: Throwable + ) { + Toast.makeText( + baseContext, + R.string.cant_unmark_favortie, + Toast.LENGTH_SHORT + ).show() + } + }) + } } } return super.onOptionsItemSelected(item) diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/SourcesActivity.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/SourcesActivity.kt index 3321e0b..907f3ab 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/SourcesActivity.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/SourcesActivity.kt @@ -13,6 +13,7 @@ import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi import apps.amine.bou.readerforselfoss.api.selfoss.Source import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.Toppings +import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible import com.ftinc.scoop.Scoop import kotlinx.android.synthetic.main.activity_sources.* import retrofit2.Call @@ -66,34 +67,36 @@ class SourcesActivity : AppCompatActivity() { recyclerView.setHasFixedSize(true) recyclerView.layoutManager = mLayoutManager - api.sources.enqueue(object : Callback> { - override fun onResponse( - call: Call>, - response: Response> - ) { - if (response.body() != null && response.body()!!.isNotEmpty()) { - items = response.body() as ArrayList + if (this@SourcesActivity.isNetworkAccessible(this@SourcesActivity.findViewById(R.id.recyclerView))) { + api.sources.enqueue(object : Callback> { + override fun onResponse( + call: Call>, + response: Response> + ) { + if (response.body() != null && response.body()!!.isNotEmpty()) { + items = response.body() as ArrayList + } + val mAdapter = SourcesListAdapter(this@SourcesActivity, items, api) + recyclerView.adapter = mAdapter + mAdapter.notifyDataSetChanged() + if (items.isEmpty()) { + Toast.makeText( + this@SourcesActivity, + R.string.nothing_here, + Toast.LENGTH_SHORT + ).show() + } } - val mAdapter = SourcesListAdapter(this@SourcesActivity, items, api) - recyclerView.adapter = mAdapter - mAdapter.notifyDataSetChanged() - if (items.isEmpty()) { + + override fun onFailure(call: Call>, t: Throwable) { Toast.makeText( this@SourcesActivity, - R.string.nothing_here, + R.string.cant_get_sources, Toast.LENGTH_SHORT ).show() } - } - - override fun onFailure(call: Call>, t: Throwable) { - Toast.makeText( - this@SourcesActivity, - R.string.cant_get_sources, - Toast.LENGTH_SHORT - ).show() - } - }) + }) + } fab.setOnClickListener { startActivity(Intent(this@SourcesActivity, AddSourceActivity::class.java)) diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/ItemCardAdapter.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/ItemCardAdapter.kt index 6af265e..b53be46 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/ItemCardAdapter.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/ItemCardAdapter.kt @@ -21,6 +21,7 @@ import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper import apps.amine.bou.readerforselfoss.utils.glide.bitmapCenterCrop import apps.amine.bou.readerforselfoss.utils.glide.circularBitmapDrawable +import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible import apps.amine.bou.readerforselfoss.utils.openInBrowserAsNewTask import apps.amine.bou.readerforselfoss.utils.openItemUrl import apps.amine.bou.readerforselfoss.utils.shareLink @@ -117,49 +118,53 @@ class ItemCardAdapter( mView.favButton.setOnLikeListener(object : OnLikeListener { override fun liked(likeButton: LikeButton) { - val (id) = items[adapterPosition] - api.starrItem(id).enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - } + if (c.isNetworkAccessible(null)) { + val (id) = items[adapterPosition] + api.starrItem(id).enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + } - override fun onFailure( - call: Call, - t: Throwable - ) { - mView.favButton.isLiked = false - Toast.makeText( - c, - R.string.cant_mark_favortie, - Toast.LENGTH_SHORT - ).show() - } - }) + override fun onFailure( + call: Call, + t: Throwable + ) { + mView.favButton.isLiked = false + Toast.makeText( + c, + R.string.cant_mark_favortie, + Toast.LENGTH_SHORT + ).show() + } + }) + } } override fun unLiked(likeButton: LikeButton) { - val (id) = items[adapterPosition] - api.unstarrItem(id).enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - } + if (c.isNetworkAccessible(null)) { + val (id) = items[adapterPosition] + api.unstarrItem(id).enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + } - override fun onFailure( - call: Call, - t: Throwable - ) { - mView.favButton.isLiked = true - Toast.makeText( - c, - R.string.cant_unmark_favortie, - Toast.LENGTH_SHORT - ).show() - } - }) + override fun onFailure( + call: Call, + t: Throwable + ) { + mView.favButton.isLiked = true + Toast.makeText( + c, + R.string.cant_unmark_favortie, + Toast.LENGTH_SHORT + ).show() + } + }) + } } }) diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/ItemsAdapter.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/ItemsAdapter.kt index d8831a3..562f096 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/ItemsAdapter.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/ItemsAdapter.kt @@ -13,6 +13,7 @@ import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException +import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible import apps.amine.bou.readerforselfoss.utils.persistence.toEntity import apps.amine.bou.readerforselfoss.utils.succeeded import org.acra.ACRA @@ -45,30 +46,32 @@ abstract class ItemsAdapter : RecyclerView.Adapte Snackbar.LENGTH_LONG ) .setAction(R.string.undo_string) { - items.add(position, i) - thread { - db.itemsDao().insertAllItems(i.toEntity()) - } - notifyItemInserted(position) - updateItems(items) - - api.unmarkItem(i.id).enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { + if (app.isNetworkAccessible(null)) { + items.add(position, i) + thread { + db.itemsDao().insertAllItems(i.toEntity()) } + notifyItemInserted(position) + updateItems(items) - override fun onFailure(call: Call, t: Throwable) { - items.remove(i) - thread { - db.itemsDao().delete(i.toEntity()) + api.unmarkItem(i.id).enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { } - notifyItemRemoved(position) - updateItems(items) - doUnmark(i, position) - } - }) + + override fun onFailure(call: Call, t: Throwable) { + items.remove(i) + thread { + db.itemsDao().delete(i.toEntity()) + } + notifyItemRemoved(position) + updateItems(items) + doUnmark(i, position) + } + }) + } } val view = s.view @@ -78,60 +81,61 @@ abstract class ItemsAdapter : RecyclerView.Adapte } fun removeItemAtIndex(position: Int) { + if (app.isNetworkAccessible(null)) { + val i = items[position] - val i = items[position] + items.remove(i) + notifyItemRemoved(position) + updateItems(items) - items.remove(i) - notifyItemRemoved(position) - updateItems(items) + // TODO: Handle network status. + // IF offline, delete from cached articles, and add to some table that will replay the calls on network activation. - // TODO: Handle network status. - // IF offline, delete from cached articles, and add to some table that will replay the calls on network activation. + thread { + db.itemsDao().delete(i.toEntity()) + } - thread { - db.itemsDao().delete(i.toEntity()) + api.markItem(i.id).enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + 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}" + ACRA.getErrorReporter().maybeHandleSilentException(Exception(message), app) + Toast.makeText(app.baseContext, message, Toast.LENGTH_LONG).show() + } + + doUnmark(i, position) + } + + override fun onFailure(call: Call, t: Throwable) { + if (debugReadingItems) { + ACRA.getErrorReporter().maybeHandleSilentException(t, app) + 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) + updateItems(items) + + thread { + db.itemsDao().insertAllItems(i.toEntity()) + } + } + }) } - - api.markItem(i.id).enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - 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}" - ACRA.getErrorReporter().maybeHandleSilentException(Exception(message), app) - Toast.makeText(app.baseContext, message, Toast.LENGTH_LONG).show() - } - - doUnmark(i, position) - } - - override fun onFailure(call: Call, t: Throwable) { - if (debugReadingItems) { - ACRA.getErrorReporter().maybeHandleSilentException(t, app) - 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) - updateItems(items) - - thread { - db.itemsDao().insertAllItems(i.toEntity()) - } - } - }) } fun addItemAtIndex(item: Item, position: Int) { diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/SourcesListAdapter.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/SourcesListAdapter.kt index 02810e3..18493ad 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/SourcesListAdapter.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/adapters/SourcesListAdapter.kt @@ -13,6 +13,7 @@ import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi import apps.amine.bou.readerforselfoss.api.selfoss.Source import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse import apps.amine.bou.readerforselfoss.utils.glide.circularBitmapDrawable +import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible import apps.amine.bou.readerforselfoss.utils.toTextDrawableString import com.amulyakhare.textdrawable.TextDrawable import com.amulyakhare.textdrawable.util.ColorGenerator @@ -70,33 +71,35 @@ class SourcesListAdapter( val deleteBtn: Button = mView.findViewById(R.id.deleteBtn) deleteBtn.setOnClickListener { - val (id) = items[adapterPosition] - api.deleteSource(id).enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - if (response.body() != null && response.body()!!.isSuccess) { - items.removeAt(adapterPosition) - notifyItemRemoved(adapterPosition) - notifyItemRangeChanged(adapterPosition, itemCount) - } else { + if (c.isNetworkAccessible(null)) { + val (id) = items[adapterPosition] + api.deleteSource(id).enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.body() != null && response.body()!!.isSuccess) { + items.removeAt(adapterPosition) + notifyItemRemoved(adapterPosition) + notifyItemRangeChanged(adapterPosition, itemCount) + } else { + Toast.makeText( + app, + R.string.can_delete_source, + Toast.LENGTH_SHORT + ).show() + } + } + + override fun onFailure(call: Call, t: Throwable) { Toast.makeText( app, R.string.can_delete_source, Toast.LENGTH_SHORT ).show() } - } - - override fun onFailure(call: Call, t: Throwable) { - Toast.makeText( - app, - R.string.can_delete_source, - Toast.LENGTH_SHORT - ).show() - } - }) + }) + } } } } diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/fragments/ArticleFragment.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/fragments/ArticleFragment.kt index e6fff57..0e9c075 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/fragments/ArticleFragment.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/fragments/ArticleFragment.kt @@ -29,6 +29,7 @@ import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper import apps.amine.bou.readerforselfoss.utils.isEmptyOrNullOrNullString import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException +import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible import apps.amine.bou.readerforselfoss.utils.openItemUrl import apps.amine.bou.readerforselfoss.utils.shareLink import apps.amine.bou.readerforselfoss.utils.sourceAndDateText @@ -135,35 +136,37 @@ class ArticleFragment : Fragment() { false, activity!! ) - R.id.unread_action -> api.unmarkItem(allItems[pageNumber.toInt()].id).enqueue( - object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - 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}" - ACRA.getErrorReporter().maybeHandleSilentException(Exception(message), activity!!) + R.id.unread_action -> if ((context != null && context!!.isNetworkAccessible(null)) || context == null) { + api.unmarkItem(allItems[pageNumber.toInt()].id).enqueue( + object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + 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}" + ACRA.getErrorReporter().maybeHandleSilentException(Exception(message), activity!!) + } } - } - override fun onFailure( - call: Call, - t: Throwable - ) { - if (debugReadingItems) { - ACRA.getErrorReporter().maybeHandleSilentException(t, activity!!) + override fun onFailure( + call: Call, + t: Throwable + ) { + if (debugReadingItems) { + ACRA.getErrorReporter().maybeHandleSilentException(t, activity!!) + } } } - } - ) + ) + } else -> Unit } } @@ -212,96 +215,98 @@ class ArticleFragment : Fragment() { customTabsIntent: CustomTabsIntent, prefs: SharedPreferences ) { - rootView.progressBar.visibility = View.VISIBLE - val parser = MercuryApi( - prefs.getBoolean("should_log_everything", false) - ) + if ((context != null && context!!.isNetworkAccessible(null)) || context == null) { + rootView.progressBar.visibility = View.VISIBLE + val parser = MercuryApi( + prefs.getBoolean("should_log_everything", false) + ) - parser.parseUrl(url).enqueue( - object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - // TODO: clean all the following after finding the mercury content issue - try { - if (response.body() != null && response.body()!!.content != null && !response.body()!!.content.isNullOrEmpty()) { - try { - rootView.titleView.text = response.body()!!.title + parser.parseUrl(url).enqueue( + object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + // TODO: clean all the following after finding the mercury content issue + try { + if (response.body() != null && response.body()!!.content != null && !response.body()!!.content.isNullOrEmpty()) { try { - // Note: Mercury may return relative urls... If it does the url val will not be changed. - URL(response.body()!!.url) - url = response.body()!!.url - } catch (e: MalformedURLException) { - ACRA.getErrorReporter().maybeHandleSilentException(e, activity!!) - } - } catch (e: Exception) { - if (context != null) { - ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) - } - } - - try { - htmlToWebview(response.body()!!.content.orEmpty(), prefs) - } catch (e: Exception) { - if (context != null) { - ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) - } - } - - try { - if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isNullOrEmpty() && context != null) { - rootView.imageView.visibility = View.VISIBLE + rootView.titleView.text = response.body()!!.title try { - Glide - .with(context!!) - .asBitmap() - .load(response.body()!!.lead_image_url) - .apply(RequestOptions.fitCenterTransform()) - .into(rootView.imageView) - } catch (e: Exception) { + // Note: Mercury may return relative urls... If it does the url val will not be changed. + URL(response.body()!!.url) + url = response.body()!!.url + } catch (e: MalformedURLException) { + ACRA.getErrorReporter().maybeHandleSilentException(e, activity!!) + } + } catch (e: Exception) { + if (context != null) { ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) } - } else { - rootView.imageView.visibility = View.GONE } - } catch (e: Exception) { - if (context != null) { - ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) - } - } - try { - rootView.nestedScrollView.scrollTo(0, 0) + try { + htmlToWebview(response.body()!!.content.orEmpty(), prefs) + } catch (e: Exception) { + if (context != null) { + ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) + } + } - rootView.progressBar.visibility = View.GONE - } catch (e: Exception) { - if (context != null) { - ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) + try { + if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isNullOrEmpty() && context != null) { + rootView.imageView.visibility = View.VISIBLE + try { + Glide + .with(context!!) + .asBitmap() + .load(response.body()!!.lead_image_url) + .apply(RequestOptions.fitCenterTransform()) + .into(rootView.imageView) + } catch (e: Exception) { + ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) + } + } else { + rootView.imageView.visibility = View.GONE + } + } catch (e: Exception) { + if (context != null) { + ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) + } + } + + try { + rootView.nestedScrollView.scrollTo(0, 0) + + rootView.progressBar.visibility = View.GONE + } catch (e: Exception) { + if (context != null) { + ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) + } + } + } else { + try { + openInBrowserAfterFailing(customTabsIntent) + } catch (e: Exception) { + if (context != null) { + ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) + } } } - } else { - try { - openInBrowserAfterFailing(customTabsIntent) - } catch (e: Exception) { - if (context != null) { - ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) - } + } catch (e: Exception) { + if (context != null) { + ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) } } - } catch (e: Exception) { - if (context != null) { - ACRA.getErrorReporter().maybeHandleSilentException(e, context!!) - } } - } - override fun onFailure( - call: Call, - t: Throwable - ) = openInBrowserAfterFailing(customTabsIntent) - } - ) + override fun onFailure( + call: Call, + t: Throwable + ) = openInBrowserAfterFailing(customTabsIntent) + } + ) + } } private fun htmlToWebview(c: String, prefs: SharedPreferences) { diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/utils/network/NetworkUtils.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/utils/network/NetworkUtils.kt index 1e51f11..b5d4c2e 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/utils/network/NetworkUtils.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/utils/network/NetworkUtils.kt @@ -10,13 +10,15 @@ import apps.amine.bou.readerforselfoss.R import com.google.android.material.snackbar.Snackbar var snackBarShown = false +var view: View? = null fun Context.isNetworkAccessible(v: View?): Boolean { val cm = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val activeNetwork: NetworkInfo? = cm.activeNetworkInfo val networkIsAccessible = activeNetwork != null && activeNetwork.isConnectedOrConnecting - if (v != null && !networkIsAccessible && !snackBarShown) { + if (v != null && !networkIsAccessible && (!snackBarShown || v != view)) { + view = v val s = Snackbar .make( v, diff --git a/app/src/main/res/layout/activity_reader.xml b/app/src/main/res/layout/activity_reader.xml index 7b2fc80..5c7927e 100644 --- a/app/src/main/res/layout/activity_reader.xml +++ b/app/src/main/res/layout/activity_reader.xml @@ -2,6 +2,7 @@