Wrap stuff in manga details with an online check to improve user experience (#344)

* wrap details stuff in network checks so app doesn't reach out when it knows it cant

* wrap some more clean up a little

* remove online check for chapter click/resume in mangadetail

* code review fixes
This commit is contained in:
Carlos 2020-05-06 20:21:14 -04:00 committed by GitHub
parent 7043687142
commit 149ecaa592
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 34 deletions

View File

@ -97,6 +97,7 @@ import eu.kanade.tachiyomi.util.system.ThemeUtil
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.isInNightMode
import eu.kanade.tachiyomi.util.system.isOnline
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.getText
@ -515,6 +516,14 @@ class MangaDetailsController : BaseController,
}
//endregion
fun isNotOnline(showSnackbar: Boolean = true): Boolean {
if (activity == null || !activity!!.isOnline()) {
if (showSnackbar) view?.snack(R.string.no_network_connection)
return true
}
return false
}
fun showError(message: String) {
swipe_refresh?.isRefreshing = presenter.isLoading
view?.snack(message)
@ -599,7 +608,8 @@ class MangaDetailsController : BaseController,
fun refreshAdapter() = adapter?.notifyDataSetChanged()
override fun onItemClick(view: View?, position: Int): Boolean {
val chapter = (adapter?.getItem(position) as? ChapterItem)?.chapter ?: return false
val chapterItem = (adapter?.getItem(position) as? ChapterItem) ?: return false
val chapter = chapterItem.chapter
if (actionMode != null) {
if (startingDLChapterPos == null) {
adapter?.addSelection(position)
@ -629,6 +639,7 @@ class MangaDetailsController : BaseController,
return false
}
openChapter(chapter)
return false
}
@ -828,13 +839,15 @@ class MangaDetailsController : BaseController,
}
}
R.id.action_open_in_web_view -> openInWebView()
R.id.action_refresh_tracking -> presenter.refreshTrackers()
R.id.action_refresh_tracking -> presenter.refreshTrackers(true)
R.id.action_migrate ->
PreMigrationController.navigateToMigration(
presenter.preferences.skipPreMigration().getOrDefault(),
router,
listOf(manga!!.id!!)
)
if (!isNotOnline()) {
PreMigrationController.navigateToMigration(
presenter.preferences.skipPreMigration().getOrDefault(),
router,
listOf(manga!!.id!!)
)
}
R.id.action_mark_all_as_read -> {
MaterialDialog(view!!.context).message(R.string.mark_all_chapters_as_read)
.positiveButton(R.string.mark_as_read) {
@ -892,8 +905,8 @@ class MangaDetailsController : BaseController,
}
override fun openInWebView() {
if (isNotOnline()) return
val source = presenter.source as? HttpSource ?: return
val url = try {
source.mangaDetailsRequest(presenter.manga).url.toString()
} catch (e: Exception) {
@ -1053,6 +1066,7 @@ class MangaDetailsController : BaseController,
}
override fun globalSearch(text: String) {
if (isNotOnline()) return
router.pushController(SourceSearchController(text).withFadeTransaction())
}

View File

@ -93,7 +93,7 @@ class MangaDetailsPresenter(
controller.updateChapters(this.chapters)
}
fetchTrackings()
refreshTrackers()
refreshTrackers(false)
}
fun onDestroy() {
@ -372,6 +372,7 @@ class MangaDetailsPresenter(
/** Refresh Manga Info and Chapter List (not tracking) */
fun refreshAll() {
if (controller.isNotOnline()) return
scope.launch {
isLoading = true
var mangaError: java.lang.Exception? = null
@ -763,36 +764,40 @@ class MangaDetailsPresenter(
withContext(Dispatchers.Main) { controller.refreshTracking(trackList) }
}
fun refreshTrackers() {
scope.launch {
trackList.filter { it.track != null }.map { item ->
withContext(Dispatchers.IO) {
val trackItem = try {
item.service.refresh(item.track!!)
} catch (e: Exception) {
trackError(e)
null
fun refreshTrackers(showOfflineSnack: Boolean = false) {
if (controller.isNotOnline(showOfflineSnack)) {
scope.launch {
trackList.filter { it.track != null }.map { item ->
withContext(Dispatchers.IO) {
val trackItem = try {
item.service.refresh(item.track!!)
} catch (e: Exception) {
trackError(e)
null
}
if (trackItem != null) {
db.insertTrack(trackItem).executeAsBlocking()
trackItem
} else item.track
}
if (trackItem != null) {
db.insertTrack(trackItem).executeAsBlocking()
trackItem
} else item.track
}
refreshTracking()
}
refreshTracking()
}
}
fun trackSearch(query: String, service: TrackService) {
scope.launch(Dispatchers.IO) {
val results = try {
service.search(query)
} catch (e: Exception) {
withContext(Dispatchers.Main) { controller.trackSearchError(e) }
null
}
if (!results.isNullOrEmpty()) {
withContext(Dispatchers.Main) { controller.onTrackSearchResults(results) }
if (controller.isNotOnline()) {
scope.launch(Dispatchers.IO) {
val results = try {
service.search(query)
} catch (e: Exception) {
withContext(Dispatchers.Main) { controller.trackSearchError(e) }
null
}
if (!results.isNullOrEmpty()) {
withContext(Dispatchers.Main) { controller.onTrackSearchResults(results) }
}
}
}
}

View File

@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.hide
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
import kotlinx.android.synthetic.main.tracking_bottom_sheet.*
import timber.log.Timber
@ -106,8 +107,12 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) : Bott
activity.toast(error.message)
}
override fun onLogoClick(position: Int) {
override fun onLogoClick(position: Int) {
val track = adapter?.getItem(position)?.track ?: return
if (controller.isNotOnline()) {
sheetBehavior.hide()
return
}
if (track.tracking_url.isBlank()) {
activity.toast(R.string.url_not_set_click_again)
@ -119,6 +124,11 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) : Bott
override fun onSetClick(position: Int) {
val item = adapter?.getItem(position) ?: return
if (controller.isNotOnline()) {
sheetBehavior.hide()
return
}
TrackSearchDialog(this, item.service, item.track != null).showDialog(
controller.router,
TAG_SEARCH_CONTROLLER
@ -128,6 +138,10 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) : Bott
override fun onStatusClick(position: Int) {
val item = adapter?.getItem(position) ?: return
if (item.track == null) return
if (controller.isNotOnline()) {
dismiss()
return
}
SetTrackStatusDialog(this, item).showDialog(controller.router)
}
@ -135,13 +149,20 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) : Bott
override fun onChaptersClick(position: Int) {
val item = adapter?.getItem(position) ?: return
if (item.track == null) return
if (controller.isNotOnline()) {
dismiss()
return
}
SetTrackChaptersDialog(this, item).showDialog(controller.router)
}
override fun onScoreClick(position: Int) {
val item = adapter?.getItem(position) ?: return
if (item.track == null) return
if (controller.isNotOnline()) {
dismiss()
return
}
SetTrackScoreDialog(this, item).showDialog(controller.router)
}

View File

@ -12,6 +12,7 @@ import android.content.res.Configuration
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.Uri
import android.os.PowerManager
import android.view.View
@ -219,3 +220,22 @@ fun Context.isInNightMode(): Boolean {
val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
return currentNightMode == Configuration.UI_MODE_NIGHT_YES
}
fun Context.isOnline(): Boolean {
val connectivityManager = this
.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
var result = false
connectivityManager?.let {
val networkCapabilities = connectivityManager.activeNetwork ?: return false
val actNw =
connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
result = when {
actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
else -> false
}
}
return result
}