Refactor error handling
This commit is contained in:
@@ -1,14 +1,12 @@
|
||||
package org.koitharu.kotatsu.base.ui.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.view.View
|
||||
import androidx.lifecycle.Observer
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.domain.reverseAsync
|
||||
import org.koitharu.kotatsu.main.ui.owners.BottomNavOwner
|
||||
import org.koitharu.kotatsu.utils.ext.findActivity
|
||||
|
||||
class ReversibleActionObserver(
|
||||
private val snackbarHost: View,
|
||||
@@ -29,10 +27,4 @@ class ReversibleActionObserver(
|
||||
}
|
||||
snackbar.show()
|
||||
}
|
||||
|
||||
private fun Context.findActivity(): Activity? = when (this) {
|
||||
is Activity -> this
|
||||
is ContextWrapper -> baseContext.findActivity()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
package org.koitharu.kotatsu.bookmarks.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updateLayoutParams
|
||||
@@ -10,7 +14,6 @@ import androidx.fragment.app.viewModels
|
||||
import coil.ImageLoader
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.domain.reverseAsync
|
||||
import org.koitharu.kotatsu.base.ui.BaseFragment
|
||||
@@ -24,6 +27,7 @@ import org.koitharu.kotatsu.bookmarks.data.ids
|
||||
import org.koitharu.kotatsu.bookmarks.domain.Bookmark
|
||||
import org.koitharu.kotatsu.bookmarks.ui.adapter.BookmarksGroupAdapter
|
||||
import org.koitharu.kotatsu.bookmarks.ui.model.BookmarksGroup
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.databinding.FragmentListSimpleBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener
|
||||
@@ -32,9 +36,9 @@ import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
|
||||
import org.koitharu.kotatsu.main.ui.owners.SnackbarOwner
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.reader.ui.ReaderActivity
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.invalidateNestedItemDecorations
|
||||
import org.koitharu.kotatsu.utils.ext.scaleUpActivityOptionsOf
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class BookmarksFragment :
|
||||
@@ -76,7 +80,7 @@ class BookmarksFragment :
|
||||
binding.recyclerView.addItemDecoration(spacingDecoration)
|
||||
|
||||
viewModel.content.observe(viewLifecycleOwner, ::onListChanged)
|
||||
viewModel.onError.observe(viewLifecycleOwner, ::onError)
|
||||
viewModel.onError.observe(viewLifecycleOwner, SnackbarErrorObserver(binding.recyclerView, this))
|
||||
viewModel.onActionDone.observe(viewLifecycleOwner, ::onActionDone)
|
||||
}
|
||||
|
||||
@@ -132,6 +136,7 @@ class BookmarksFragment :
|
||||
mode.finish()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@@ -154,14 +159,6 @@ class BookmarksFragment :
|
||||
adapter?.items = list
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
Snackbar.make(
|
||||
binding.recyclerView,
|
||||
e.getDisplayMessage(resources),
|
||||
Snackbar.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
|
||||
private fun onActionDone(action: ReversibleAction) {
|
||||
val handle = action.handle
|
||||
val length = if (handle == null) Snackbar.LENGTH_SHORT else Snackbar.LENGTH_LONG
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package org.koitharu.kotatsu.core.exceptions.resolve
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.view.View
|
||||
import androidx.core.util.Consumer
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.MangaErrorDialog
|
||||
import org.koitharu.kotatsu.parsers.exception.ParseException
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
|
||||
class DialogErrorObserver(
|
||||
host: View,
|
||||
fragment: Fragment?,
|
||||
resolver: ExceptionResolver?,
|
||||
private val onResolved: Consumer<Boolean>?,
|
||||
) : ErrorObserver(host, fragment, resolver, onResolved) {
|
||||
|
||||
constructor(
|
||||
host: View,
|
||||
fragment: Fragment?,
|
||||
) : this(host, fragment, null, null)
|
||||
|
||||
override fun onChanged(error: Throwable?) {
|
||||
if (error == null) {
|
||||
return
|
||||
}
|
||||
val listener = DialogListener(error)
|
||||
val dialogBuilder = MaterialAlertDialogBuilder(activity ?: host.context)
|
||||
.setMessage(error.getDisplayMessage(host.context.resources))
|
||||
.setNegativeButton(R.string.close, listener)
|
||||
.setOnCancelListener(listener)
|
||||
if (canResolve(error)) {
|
||||
dialogBuilder.setPositiveButton(ExceptionResolver.getResolveStringId(error), listener)
|
||||
} else if (error is ParseException) {
|
||||
val fm = fragmentManager
|
||||
if (fm != null) {
|
||||
dialogBuilder.setPositiveButton(R.string.details) { _, _ ->
|
||||
MangaErrorDialog.show(fm, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
val dialog = dialogBuilder.create()
|
||||
if (activity != null) {
|
||||
dialog.setOwnerActivity(activity)
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
private inner class DialogListener(
|
||||
private val error: Throwable,
|
||||
) : DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface?, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_NEGATIVE -> onResolved?.accept(false)
|
||||
DialogInterface.BUTTON_POSITIVE -> resolve(error)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCancel(dialog: DialogInterface?) {
|
||||
onResolved?.accept(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.koitharu.kotatsu.core.exceptions.resolve
|
||||
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.util.Consumer
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.coroutineScope
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koitharu.kotatsu.utils.ext.findActivity
|
||||
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
|
||||
|
||||
abstract class ErrorObserver(
|
||||
protected val host: View,
|
||||
protected val fragment: Fragment?,
|
||||
private val resolver: ExceptionResolver?,
|
||||
private val onResolved: Consumer<Boolean>?,
|
||||
) : Observer<Throwable> {
|
||||
|
||||
protected val activity = host.context.findActivity()
|
||||
|
||||
private val lifecycleScope: LifecycleCoroutineScope
|
||||
get() = checkNotNull(fragment?.viewLifecycleScope ?: (activity as? LifecycleOwner)?.lifecycle?.coroutineScope)
|
||||
|
||||
protected val fragmentManager: FragmentManager?
|
||||
get() = fragment?.childFragmentManager ?: (activity as? AppCompatActivity)?.supportFragmentManager
|
||||
|
||||
protected fun canResolve(error: Throwable): Boolean {
|
||||
return resolver != null && ExceptionResolver.canResolve(error)
|
||||
}
|
||||
|
||||
protected fun resolve(error: Throwable) {
|
||||
lifecycleScope.launch {
|
||||
val isResolved = resolver?.resolve(error) ?: false
|
||||
if (isActive) {
|
||||
onResolved?.accept(isResolved)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.koitharu.kotatsu.core.exceptions.resolve
|
||||
|
||||
import android.view.View
|
||||
import androidx.core.util.Consumer
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.MangaErrorDialog
|
||||
import org.koitharu.kotatsu.main.ui.owners.BottomNavOwner
|
||||
import org.koitharu.kotatsu.parsers.exception.ParseException
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
|
||||
class SnackbarErrorObserver(
|
||||
host: View,
|
||||
fragment: Fragment?,
|
||||
resolver: ExceptionResolver?,
|
||||
onResolved: Consumer<Boolean>?,
|
||||
) : ErrorObserver(host, fragment, resolver, onResolved) {
|
||||
|
||||
constructor(
|
||||
host: View,
|
||||
fragment: Fragment?,
|
||||
) : this(host, fragment, null, null)
|
||||
|
||||
override fun onChanged(error: Throwable?) {
|
||||
if (error == null) {
|
||||
return
|
||||
}
|
||||
val snackbar = Snackbar.make(host, error.getDisplayMessage(host.context.resources), Snackbar.LENGTH_SHORT)
|
||||
if (activity is BottomNavOwner) {
|
||||
snackbar.anchorView = activity.bottomNav
|
||||
}
|
||||
if (canResolve(error)) {
|
||||
snackbar.setAction(ExceptionResolver.getResolveStringId(error)) {
|
||||
resolve(error)
|
||||
}
|
||||
} else if (error is ParseException) {
|
||||
val fm = fragmentManager
|
||||
if (fm != null) {
|
||||
snackbar.setAction(R.string.details) {
|
||||
MangaErrorDialog.show(fm, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
snackbar.show()
|
||||
}
|
||||
}
|
||||
@@ -12,24 +12,20 @@ import androidx.fragment.app.FragmentManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.AlertDialogFragment
|
||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
||||
import org.koitharu.kotatsu.databinding.DialogMangaErrorBinding
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.exception.ParseException
|
||||
import org.koitharu.kotatsu.utils.ext.report
|
||||
import org.koitharu.kotatsu.utils.ext.requireParcelable
|
||||
import org.koitharu.kotatsu.utils.ext.requireSerializable
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
class MangaErrorDialog : AlertDialogFragment<DialogMangaErrorBinding>() {
|
||||
|
||||
private lateinit var error: Throwable
|
||||
private lateinit var manga: Manga
|
||||
private lateinit var exception: ParseException
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val args = requireArguments()
|
||||
manga = args.requireParcelable<ParcelableManga>(ARG_MANGA).manga
|
||||
error = args.requireSerializable(ARG_ERROR)
|
||||
exception = args.requireSerializable(ARG_ERROR)
|
||||
}
|
||||
|
||||
override fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): DialogMangaErrorBinding {
|
||||
@@ -42,8 +38,8 @@ class MangaErrorDialog : AlertDialogFragment<DialogMangaErrorBinding>() {
|
||||
movementMethod = LinkMovementMethod.getInstance()
|
||||
text = context.getString(
|
||||
R.string.manga_error_description_pattern,
|
||||
this@MangaErrorDialog.error.message?.htmlEncode().orEmpty(),
|
||||
manga.publicUrl,
|
||||
exception.message?.htmlEncode().orEmpty(),
|
||||
exception.url,
|
||||
).parseAsHtml(HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
}
|
||||
}
|
||||
@@ -54,7 +50,7 @@ class MangaErrorDialog : AlertDialogFragment<DialogMangaErrorBinding>() {
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(R.string.report) { _, _ ->
|
||||
dismiss()
|
||||
error.report()
|
||||
exception.report()
|
||||
}.setTitle(R.string.error_occurred)
|
||||
}
|
||||
|
||||
@@ -62,10 +58,8 @@ class MangaErrorDialog : AlertDialogFragment<DialogMangaErrorBinding>() {
|
||||
|
||||
private const val TAG = "MangaErrorDialog"
|
||||
private const val ARG_ERROR = "error"
|
||||
private const val ARG_MANGA = "manga"
|
||||
|
||||
fun show(fm: FragmentManager, manga: Manga, error: Throwable) = MangaErrorDialog().withArgs(2) {
|
||||
putParcelable(ARG_MANGA, ParcelableManga(manga, false))
|
||||
fun show(fm: FragmentManager, error: ParseException) = MangaErrorDialog().withArgs(1) {
|
||||
putSerializable(ARG_ERROR, error)
|
||||
}.show(fm, TAG)
|
||||
}
|
||||
|
||||
@@ -29,10 +29,9 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.domain.MangaIntent
|
||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.base.ui.widgets.BottomSheetHeaderBar
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
||||
import org.koitharu.kotatsu.core.os.ShortcutsUpdater
|
||||
import org.koitharu.kotatsu.core.ui.MangaErrorDialog
|
||||
import org.koitharu.kotatsu.databinding.ActivityDetailsBinding
|
||||
import org.koitharu.kotatsu.details.service.MangaPrefetchService
|
||||
import org.koitharu.kotatsu.details.ui.model.ChapterListItem
|
||||
@@ -45,7 +44,6 @@ import org.koitharu.kotatsu.reader.ui.ReaderState
|
||||
import org.koitharu.kotatsu.utils.ViewBadge
|
||||
import org.koitharu.kotatsu.utils.ext.assistedViewModels
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.isReportable
|
||||
import org.koitharu.kotatsu.utils.ext.setNavigationBarTransparentCompat
|
||||
import org.koitharu.kotatsu.utils.ext.textAndVisible
|
||||
import javax.inject.Inject
|
||||
@@ -105,7 +103,19 @@ class DetailsActivity :
|
||||
viewModel.manga.observe(this, ::onMangaUpdated)
|
||||
viewModel.newChaptersCount.observe(this, ::onNewChaptersChanged)
|
||||
viewModel.onMangaRemoved.observe(this, ::onMangaRemoved)
|
||||
viewModel.onError.observe(this, ::onError)
|
||||
viewModel.onError.observe(
|
||||
this,
|
||||
SnackbarErrorObserver(
|
||||
host = binding.containerDetails,
|
||||
fragment = null,
|
||||
resolver = exceptionResolver,
|
||||
onResolved = { isResolved ->
|
||||
if (isResolved) {
|
||||
viewModel.reload()
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
viewModel.onShowToast.observe(this) {
|
||||
makeSnackbar(getString(it), Snackbar.LENGTH_SHORT).show()
|
||||
}
|
||||
@@ -191,37 +201,6 @@ class DetailsActivity :
|
||||
finishAfterTransition()
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
val manga = viewModel.manga.value
|
||||
when {
|
||||
ExceptionResolver.canResolve(e) -> {
|
||||
resolveError(e)
|
||||
}
|
||||
|
||||
manga == null -> {
|
||||
Toast.makeText(this, e.getDisplayMessage(resources), Toast.LENGTH_LONG).show()
|
||||
finishAfterTransition()
|
||||
}
|
||||
|
||||
else -> {
|
||||
val snackbar = makeSnackbar(
|
||||
e.getDisplayMessage(resources),
|
||||
if (viewModel.manga.value?.chapters == null) {
|
||||
Snackbar.LENGTH_INDEFINITE
|
||||
} else {
|
||||
Snackbar.LENGTH_LONG
|
||||
},
|
||||
)
|
||||
if (e.isReportable()) {
|
||||
snackbar.setAction(R.string.details) {
|
||||
MangaErrorDialog.show(supportFragmentManager, manga, e)
|
||||
}
|
||||
}
|
||||
snackbar.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.root.updatePadding(
|
||||
left = insets.left,
|
||||
|
||||
@@ -13,7 +13,6 @@ import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.ImageLoader
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseFragment
|
||||
@@ -22,6 +21,7 @@ import org.koitharu.kotatsu.base.ui.util.RecyclerViewOwner
|
||||
import org.koitharu.kotatsu.base.ui.util.ReversibleActionObserver
|
||||
import org.koitharu.kotatsu.base.ui.util.SpanSizeResolver
|
||||
import org.koitharu.kotatsu.bookmarks.ui.BookmarksActivity
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.databinding.FragmentExploreBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
import org.koitharu.kotatsu.explore.ui.adapter.ExploreAdapter
|
||||
@@ -29,14 +29,12 @@ import org.koitharu.kotatsu.explore.ui.adapter.ExploreListEventListener
|
||||
import org.koitharu.kotatsu.explore.ui.model.ExploreItem
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesActivity
|
||||
import org.koitharu.kotatsu.history.ui.HistoryActivity
|
||||
import org.koitharu.kotatsu.main.ui.owners.BottomNavOwner
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.search.ui.MangaListActivity
|
||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||
import org.koitharu.kotatsu.suggestions.ui.SuggestionsActivity
|
||||
import org.koitharu.kotatsu.utils.ext.addMenuProvider
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -74,7 +72,7 @@ class ExploreFragment :
|
||||
viewModel.content.observe(viewLifecycleOwner) {
|
||||
exploreAdapter?.items = it
|
||||
}
|
||||
viewModel.onError.observe(viewLifecycleOwner, ::onError)
|
||||
viewModel.onError.observe(viewLifecycleOwner, SnackbarErrorObserver(binding.recyclerView, this))
|
||||
viewModel.onOpenManga.observe(viewLifecycleOwner, ::onOpenManga)
|
||||
viewModel.onActionDone.observe(viewLifecycleOwner, ReversibleActionObserver(binding.recyclerView))
|
||||
viewModel.isGrid.observe(viewLifecycleOwner, ::onGridModeChanged)
|
||||
@@ -129,16 +127,6 @@ class ExploreFragment :
|
||||
|
||||
override fun onEmptyActionClick() = onManageClick(requireView())
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
val snackbar = Snackbar.make(
|
||||
binding.recyclerView,
|
||||
e.getDisplayMessage(resources),
|
||||
Snackbar.LENGTH_SHORT,
|
||||
)
|
||||
snackbar.anchorView = (activity as? BottomNavOwner)?.bottomNav
|
||||
snackbar.show()
|
||||
}
|
||||
|
||||
private fun onOpenManga(manga: Manga) {
|
||||
val intent = DetailsActivity.newIntent(context ?: return, manga)
|
||||
startActivity(intent)
|
||||
|
||||
@@ -18,11 +18,11 @@ import androidx.core.view.updatePadding
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.ImageLoader
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.base.ui.list.ListSelectionController
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.databinding.ActivityCategoriesBinding
|
||||
import org.koitharu.kotatsu.favourites.ui.FavouritesActivity
|
||||
@@ -31,7 +31,6 @@ import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEdit
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.scaleUpActivityOptionsOf
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -72,7 +71,7 @@ class FavouriteCategoriesActivity :
|
||||
onBackPressedDispatcher.addCallback(exitReorderModeCallback)
|
||||
|
||||
viewModel.detalizedCategories.observe(this, ::onCategoriesChanged)
|
||||
viewModel.onError.observe(this, ::onError)
|
||||
viewModel.onError.observe(this, SnackbarErrorObserver(binding.recyclerView, null))
|
||||
viewModel.isInReorderMode.observe(this, ::onReorderModeChanged)
|
||||
}
|
||||
|
||||
@@ -146,11 +145,6 @@ class FavouriteCategoriesActivity :
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
Snackbar.make(binding.recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun onReorderModeChanged(isReorderMode: Boolean) {
|
||||
val transition = Fade().apply {
|
||||
duration = resources.getInteger(android.R.integer.config_shortAnimTime).toLong()
|
||||
|
||||
@@ -31,9 +31,8 @@ import org.koitharu.kotatsu.base.ui.list.decor.SpacingItemDecoration
|
||||
import org.koitharu.kotatsu.base.ui.list.decor.TypedSpacingItemDecoration
|
||||
import org.koitharu.kotatsu.base.ui.list.fastscroll.FastScroller
|
||||
import org.koitharu.kotatsu.base.ui.util.ReversibleAction
|
||||
import org.koitharu.kotatsu.browser.cloudflare.CloudFlareDialog
|
||||
import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.prefs.ListMode
|
||||
import org.koitharu.kotatsu.databinding.FragmentListBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
@@ -55,7 +54,6 @@ import org.koitharu.kotatsu.search.ui.MangaListActivity
|
||||
import org.koitharu.kotatsu.utils.ShareHelper
|
||||
import org.koitharu.kotatsu.utils.ext.addMenuProvider
|
||||
import org.koitharu.kotatsu.utils.ext.clearItemDecorations
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.getThemeColor
|
||||
import org.koitharu.kotatsu.utils.ext.measureHeight
|
||||
import org.koitharu.kotatsu.utils.ext.resolveDp
|
||||
@@ -128,7 +126,7 @@ abstract class MangaListFragment :
|
||||
viewModel.gridScale.observe(viewLifecycleOwner, ::onGridScaleChanged)
|
||||
viewModel.isLoading.observe(viewLifecycleOwner, ::onLoadingStateChanged)
|
||||
viewModel.content.observe(viewLifecycleOwner, ::onListChanged)
|
||||
viewModel.onError.observe(viewLifecycleOwner, ::onError)
|
||||
viewModel.onError.observe(viewLifecycleOwner, SnackbarErrorObserver(binding.recyclerView, this))
|
||||
viewModel.onActionDone.observe(viewLifecycleOwner, ::onActionDone)
|
||||
}
|
||||
|
||||
@@ -175,18 +173,6 @@ abstract class MangaListFragment :
|
||||
listAdapter?.setItems(list, listCommitCallback)
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
if (e is CloudFlareProtectedException) {
|
||||
CloudFlareDialog.newInstance(e.url, e.headers).show(childFragmentManager, CloudFlareDialog.TAG)
|
||||
} else {
|
||||
Snackbar.make(
|
||||
binding.recyclerView,
|
||||
e.getDisplayMessage(resources),
|
||||
Snackbar.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun onActionDone(action: ReversibleAction) {
|
||||
val handle = action.handle
|
||||
val length = if (handle == null) Snackbar.LENGTH_SHORT else Snackbar.LENGTH_LONG
|
||||
|
||||
@@ -33,7 +33,6 @@ import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_
|
||||
import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL
|
||||
import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
|
||||
import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -41,6 +40,7 @@ import kotlinx.coroutines.withContext
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.base.ui.widgets.SlidingBottomNavigationView
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.databinding.ActivityMainBinding
|
||||
import org.koitharu.kotatsu.details.service.MangaPrefetchService
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
@@ -62,7 +62,6 @@ import org.koitharu.kotatsu.suggestions.ui.SuggestionsWorker
|
||||
import org.koitharu.kotatsu.tracker.work.TrackWorker
|
||||
import org.koitharu.kotatsu.utils.VoiceInputContract
|
||||
import org.koitharu.kotatsu.utils.ext.drawableEnd
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.hideKeyboard
|
||||
import org.koitharu.kotatsu.utils.ext.resolve
|
||||
import org.koitharu.kotatsu.utils.ext.scaleUpActivityOptionsOf
|
||||
@@ -132,7 +131,7 @@ class MainActivity :
|
||||
}
|
||||
|
||||
viewModel.onOpenReader.observe(this, this::onOpenReader)
|
||||
viewModel.onError.observe(this, this::onError)
|
||||
viewModel.onError.observe(this, SnackbarErrorObserver(binding.container, null))
|
||||
viewModel.isLoading.observe(this, this::onLoadingStateChanged)
|
||||
viewModel.isResumeEnabled.observe(this, this::onResumeEnabledChanged)
|
||||
viewModel.counters.observe(this, ::onCountersChanged)
|
||||
@@ -252,10 +251,6 @@ class MainActivity :
|
||||
startActivity(ReaderActivity.newIntent(this, manga), options)
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
Snackbar.make(binding.container, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
private fun onCountersChanged(counters: SparseIntArray) {
|
||||
repeat(counters.size) { i ->
|
||||
val id = counters.keyAt(i)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.koitharu.kotatsu.reader.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
@@ -23,7 +22,6 @@ import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -34,7 +32,7 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.domain.MangaIntent
|
||||
import org.koitharu.kotatsu.base.ui.BaseFullscreenActivity
|
||||
import org.koitharu.kotatsu.bookmarks.domain.Bookmark
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.DialogErrorObserver
|
||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
||||
import org.koitharu.kotatsu.core.prefs.ReaderMode
|
||||
import org.koitharu.kotatsu.databinding.ActivityReaderBinding
|
||||
@@ -51,13 +49,10 @@ import org.koitharu.kotatsu.utils.GridTouchHelper
|
||||
import org.koitharu.kotatsu.utils.IdlingDetector
|
||||
import org.koitharu.kotatsu.utils.ShareHelper
|
||||
import org.koitharu.kotatsu.utils.ext.assistedViewModels
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.getParcelableExtraCompat
|
||||
import org.koitharu.kotatsu.utils.ext.hasGlobalPoint
|
||||
import org.koitharu.kotatsu.utils.ext.isReportable
|
||||
import org.koitharu.kotatsu.utils.ext.observeWithPrevious
|
||||
import org.koitharu.kotatsu.utils.ext.postDelayed
|
||||
import org.koitharu.kotatsu.utils.ext.report
|
||||
import org.koitharu.kotatsu.utils.ext.setValueRounded
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
@@ -116,7 +111,21 @@ class ReaderActivity :
|
||||
insetsDelegate.interceptingWindowInsetsListener = this
|
||||
idlingDetector.bindToLifecycle(this)
|
||||
|
||||
viewModel.onError.observe(this, this::onError)
|
||||
viewModel.onError.observe(
|
||||
this,
|
||||
DialogErrorObserver(
|
||||
host = binding.container,
|
||||
fragment = null,
|
||||
resolver = exceptionResolver,
|
||||
onResolved = { isResolved ->
|
||||
if (isResolved) {
|
||||
viewModel.reload()
|
||||
} else if (viewModel.content.value?.pages.isNullOrEmpty()) {
|
||||
finishAfterTransition()
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
viewModel.readerMode.observe(this, this::onInitReader)
|
||||
viewModel.onPageSaved.observe(this, this::onPageSaved)
|
||||
viewModel.uiState.observeWithPrevious(this, this::onUiStateChanged)
|
||||
@@ -218,22 +227,6 @@ class ReaderActivity :
|
||||
menu.findItem(R.id.action_pages_thumbs).isVisible = hasPages
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
val listener = ErrorDialogListener(e)
|
||||
val dialog = MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.error_occurred)
|
||||
.setMessage(e.getDisplayMessage(resources))
|
||||
.setNegativeButton(R.string.close, listener)
|
||||
.setOnCancelListener(listener)
|
||||
val resolveTextId = ExceptionResolver.getResolveStringId(e)
|
||||
if (resolveTextId != 0) {
|
||||
dialog.setPositiveButton(resolveTextId, listener)
|
||||
} else if (e.isReportable()) {
|
||||
dialog.setPositiveButton(R.string.report, listener)
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
override fun onGridTouch(area: Int) {
|
||||
controlDelegate.onGridTouch(area, binding.container)
|
||||
}
|
||||
@@ -396,40 +389,6 @@ class ReaderActivity :
|
||||
}
|
||||
}
|
||||
|
||||
private inner class ErrorDialogListener(
|
||||
private val exception: Throwable,
|
||||
) : DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface?, which: Int) {
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
dialog?.dismiss()
|
||||
if (ExceptionResolver.canResolve(exception)) {
|
||||
tryResolve(exception)
|
||||
} else {
|
||||
exception.report()
|
||||
}
|
||||
} else {
|
||||
onCancel(dialog)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCancel(dialog: DialogInterface?) {
|
||||
if (viewModel.content.value?.pages.isNullOrEmpty()) {
|
||||
finishAfterTransition()
|
||||
}
|
||||
}
|
||||
|
||||
private fun tryResolve(e: Throwable) {
|
||||
lifecycleScope.launch {
|
||||
if (exceptionResolver.resolve(e)) {
|
||||
viewModel.reload()
|
||||
} else {
|
||||
onCancel(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val ACTION_MANGA_READ = "${BuildConfig.APPLICATION_ID}.action.READ_MANGA"
|
||||
|
||||
@@ -9,12 +9,12 @@ import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import coil.ImageLoader
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.base.ui.list.decor.TypedSpacingItemDecoration
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.databinding.ActivityScrobblerConfigBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService
|
||||
@@ -25,7 +25,6 @@ import org.koitharu.kotatsu.tracker.ui.feed.adapter.FeedAdapter
|
||||
import org.koitharu.kotatsu.utils.ext.assistedViewModels
|
||||
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
|
||||
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.hideCompat
|
||||
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
||||
import org.koitharu.kotatsu.utils.ext.showCompat
|
||||
@@ -72,7 +71,7 @@ class ScrobblerConfigActivity : BaseActivity<ActivityScrobblerConfigBinding>(),
|
||||
viewModel.content.observe(this, listAdapter::setItems)
|
||||
viewModel.user.observe(this, this::onUserChanged)
|
||||
viewModel.isLoading.observe(this, this::onLoadingStateChanged)
|
||||
viewModel.onError.observe(this, this::onError)
|
||||
viewModel.onError.observe(this, SnackbarErrorObserver(binding.recyclerView, null))
|
||||
viewModel.onLoggedOut.observe(this) {
|
||||
finishAfterTransition()
|
||||
}
|
||||
@@ -139,14 +138,6 @@ class ScrobblerConfigActivity : BaseActivity<ActivityScrobblerConfigBinding>(),
|
||||
}
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
Snackbar.make(
|
||||
binding.recyclerView,
|
||||
e.getDisplayMessage(resources),
|
||||
Snackbar.LENGTH_LONG,
|
||||
).show()
|
||||
}
|
||||
|
||||
private fun showUserDialog() {
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(title)
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.koitharu.kotatsu.base.ui.BaseFragment
|
||||
import org.koitharu.kotatsu.base.ui.list.SectionedSelectionController
|
||||
import org.koitharu.kotatsu.base.ui.util.RecyclerViewOwner
|
||||
import org.koitharu.kotatsu.base.ui.util.ReversibleAction
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.databinding.FragmentShelfBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
@@ -36,7 +37,6 @@ import org.koitharu.kotatsu.shelf.ui.adapter.ShelfListEventListener
|
||||
import org.koitharu.kotatsu.shelf.ui.model.ShelfSectionModel
|
||||
import org.koitharu.kotatsu.tracker.ui.updates.UpdatesActivity
|
||||
import org.koitharu.kotatsu.utils.ext.addMenuProvider
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -82,7 +82,7 @@ class ShelfFragment :
|
||||
addMenuProvider(ShelfMenuProvider(view.context, childFragmentManager, viewModel))
|
||||
|
||||
viewModel.content.observe(viewLifecycleOwner, ::onListChanged)
|
||||
viewModel.onError.observe(viewLifecycleOwner, ::onError)
|
||||
viewModel.onError.observe(viewLifecycleOwner, SnackbarErrorObserver(binding.recyclerView, this))
|
||||
viewModel.onActionDone.observe(viewLifecycleOwner, ::onActionDone)
|
||||
}
|
||||
|
||||
@@ -135,16 +135,6 @@ class ShelfFragment :
|
||||
adapter?.items = list
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
val snackbar = Snackbar.make(
|
||||
binding.recyclerView,
|
||||
e.getDisplayMessage(resources),
|
||||
Snackbar.LENGTH_SHORT,
|
||||
)
|
||||
snackbar.anchorView = (activity as? BottomNavOwner)?.bottomNav
|
||||
snackbar.show()
|
||||
}
|
||||
|
||||
private fun onActionDone(action: ReversibleAction) {
|
||||
val handle = action.handle
|
||||
val length = if (handle == null) Snackbar.LENGTH_SHORT else Snackbar.LENGTH_LONG
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseFragment
|
||||
import org.koitharu.kotatsu.base.ui.list.PaginationScrollListener
|
||||
import org.koitharu.kotatsu.base.ui.list.decor.TypedSpacingItemDecoration
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.databinding.FragmentFeedBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
import org.koitharu.kotatsu.list.ui.adapter.MangaListListener
|
||||
@@ -25,7 +26,6 @@ import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.tracker.ui.feed.adapter.FeedAdapter
|
||||
import org.koitharu.kotatsu.tracker.work.TrackWorker
|
||||
import org.koitharu.kotatsu.utils.ext.addMenuProvider
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.getThemeColor
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -75,7 +75,7 @@ class FeedFragment :
|
||||
)
|
||||
|
||||
viewModel.content.observe(viewLifecycleOwner, this::onListChanged)
|
||||
viewModel.onError.observe(viewLifecycleOwner, this::onError)
|
||||
viewModel.onError.observe(viewLifecycleOwner, SnackbarErrorObserver(binding.recyclerView, this))
|
||||
viewModel.onFeedCleared.observe(viewLifecycleOwner) {
|
||||
onFeedCleared()
|
||||
}
|
||||
@@ -118,16 +118,6 @@ class FeedFragment :
|
||||
snackbar.show()
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
val snackbar = Snackbar.make(
|
||||
binding.recyclerView,
|
||||
e.getDisplayMessage(resources),
|
||||
Snackbar.LENGTH_SHORT,
|
||||
)
|
||||
snackbar.anchorView = (activity as? BottomNavOwner)?.bottomNav
|
||||
snackbar.show()
|
||||
}
|
||||
|
||||
private fun onIsTrackerRunningChanged(isRunning: Boolean) {
|
||||
binding.swipeRefreshLayout.isRefreshing = isRunning
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.koitharu.kotatsu.utils.ext
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.ActivityManager
|
||||
import android.app.ActivityOptions
|
||||
import android.content.Context
|
||||
import android.content.Context.ACTIVITY_SERVICE
|
||||
import android.content.ContextWrapper
|
||||
import android.content.OperationApplicationException
|
||||
import android.content.SharedPreferences
|
||||
import android.content.SyncResult
|
||||
@@ -172,3 +174,9 @@ fun Resources.getLocalesConfig(): LocaleListCompat {
|
||||
}
|
||||
return LocaleListCompat.forLanguageTags(tagsList.complete())
|
||||
}
|
||||
|
||||
fun Context.findActivity(): Activity? = when (this) {
|
||||
is Activity -> this
|
||||
is ContextWrapper -> baseContext.findActivity()
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -11,17 +11,16 @@ import androidx.core.graphics.Insets
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.core.view.updatePadding
|
||||
import com.google.android.material.R as materialR
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.prefs.AppWidgetConfig
|
||||
import org.koitharu.kotatsu.databinding.ActivityCategoriesBinding
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.widget.shelf.adapter.CategorySelectAdapter
|
||||
import org.koitharu.kotatsu.widget.shelf.model.CategoryItem
|
||||
import com.google.android.material.R as materialR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ShelfConfigActivity :
|
||||
@@ -58,7 +57,7 @@ class ShelfConfigActivity :
|
||||
viewModel.checkedId = config.categoryId
|
||||
|
||||
viewModel.content.observe(this, this::onContentChanged)
|
||||
viewModel.onError.observe(this, this::onError)
|
||||
viewModel.onError.observe(this, SnackbarErrorObserver(binding.recyclerView, null))
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
@@ -105,11 +104,6 @@ class ShelfConfigActivity :
|
||||
adapter.items = categories
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
Snackbar.make(binding.recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun updateWidget() {
|
||||
val intent = Intent(this, ShelfWidgetProvider::class.java)
|
||||
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
|
||||
Reference in New Issue
Block a user