mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-09 19:55:11 +01:00
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:
parent
7043687142
commit
149ecaa592
@ -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())
|
||||
}
|
||||
|
||||
|
@ -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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user