Show dialog on manga loading error
This commit is contained in:
@@ -21,14 +21,14 @@ abstract class AlertDialogFragment<B : ViewBinding> : DialogFragment() {
|
||||
viewBinding = binding
|
||||
return MaterialAlertDialogBuilder(requireContext(), theme)
|
||||
.setView(binding.root)
|
||||
.also(::onBuildDialog)
|
||||
.run(::onBuildDialog)
|
||||
.create()
|
||||
}
|
||||
|
||||
final override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
savedInstanceState: Bundle?,
|
||||
) = viewBinding?.root
|
||||
|
||||
@CallSuper
|
||||
@@ -37,9 +37,9 @@ abstract class AlertDialogFragment<B : ViewBinding> : DialogFragment() {
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
open fun onBuildDialog(builder: MaterialAlertDialogBuilder) = Unit
|
||||
open fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder = builder
|
||||
|
||||
protected fun bindingOrNull(): B? = viewBinding
|
||||
|
||||
protected abstract fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): B
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ class CloudFlareDialog : AlertDialogFragment<FragmentCloudflareBinding>(), Cloud
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder) {
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
return super.onBuildDialog(builder).setNegativeButton(android.R.string.cancel, null)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.koitharu.kotatsu.core.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.core.text.htmlEncode
|
||||
import androidx.core.text.parseAsHtml
|
||||
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.utils.ext.report
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
class MangaErrorDialog : AlertDialogFragment<DialogMangaErrorBinding>() {
|
||||
|
||||
private lateinit var error: Throwable
|
||||
private lateinit var manga: Manga
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val args = requireArguments()
|
||||
manga = requireNotNull(args.getParcelable<ParcelableManga>(ARG_MANGA)?.manga)
|
||||
error = args.getSerializable(ARG_ERROR) as Throwable
|
||||
}
|
||||
|
||||
override fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): DialogMangaErrorBinding {
|
||||
return DialogMangaErrorBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
with(binding.textViewMessage) {
|
||||
movementMethod = LinkMovementMethod.getInstance()
|
||||
text = context.getString(
|
||||
R.string.manga_error_description_pattern,
|
||||
this@MangaErrorDialog.error.message?.htmlEncode().orEmpty(),
|
||||
manga.publicUrl,
|
||||
).parseAsHtml(HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
return super.onBuildDialog(builder)
|
||||
.setCancelable(true)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(R.string.report) { _, _ ->
|
||||
dismiss()
|
||||
error.report(TAG)
|
||||
}.setTitle(R.string.error_occurred)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
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))
|
||||
putSerializable(ARG_ERROR, error)
|
||||
}.show(fm, TAG)
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import com.google.android.material.badge.BadgeDrawable
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.domain.MangaIntent
|
||||
@@ -27,6 +26,7 @@ import org.koitharu.kotatsu.base.ui.widgets.BottomSheetHeaderBar
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
||||
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.ui.model.HistoryInfo
|
||||
import org.koitharu.kotatsu.download.ui.service.DownloadService
|
||||
@@ -36,6 +36,7 @@ import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.reader.ui.ReaderActivity
|
||||
import org.koitharu.kotatsu.reader.ui.ReaderState
|
||||
import org.koitharu.kotatsu.utils.ext.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class DetailsActivity :
|
||||
@@ -172,11 +173,12 @@ class DetailsActivity :
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
val manga = viewModel.manga.value
|
||||
when {
|
||||
ExceptionResolver.canResolve(e) -> {
|
||||
resolveError(e)
|
||||
}
|
||||
viewModel.manga.value == null -> {
|
||||
manga == null -> {
|
||||
Toast.makeText(this, e.getDisplayMessage(resources), Toast.LENGTH_LONG).show()
|
||||
finishAfterTransition()
|
||||
}
|
||||
@@ -192,8 +194,8 @@ class DetailsActivity :
|
||||
)
|
||||
snackbar.anchorView = binding.headerChapters
|
||||
if (e.isReportable()) {
|
||||
snackbar.setAction(R.string.report) {
|
||||
e.report("DetailsActivity::onError")
|
||||
snackbar.setAction(R.string.details) {
|
||||
MangaErrorDialog.show(supportFragmentManager, manga, e)
|
||||
}
|
||||
}
|
||||
snackbar.show()
|
||||
|
||||
@@ -9,6 +9,7 @@ import androidx.fragment.app.FragmentManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.slider.Slider
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.AlertDialogFragment
|
||||
import org.koitharu.kotatsu.base.ui.widgets.CheckableButtonGroup
|
||||
@@ -17,7 +18,6 @@ import org.koitharu.kotatsu.core.prefs.ListMode
|
||||
import org.koitharu.kotatsu.databinding.DialogListModeBinding
|
||||
import org.koitharu.kotatsu.utils.ext.setValueRounded
|
||||
import org.koitharu.kotatsu.utils.progress.IntPercentLabelFormatter
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ListModeSelectDialog :
|
||||
@@ -33,8 +33,9 @@ class ListModeSelectDialog :
|
||||
container: ViewGroup?,
|
||||
) = DialogListModeBinding.inflate(inflater, container, false)
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder) {
|
||||
builder.setTitle(R.string.list_mode)
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
return super.onBuildDialog(builder)
|
||||
.setTitle(R.string.list_mode)
|
||||
.setPositiveButton(R.string.done, null)
|
||||
.setCancelable(true)
|
||||
}
|
||||
|
||||
@@ -27,8 +27,9 @@ class ImportDialogFragment : AlertDialogFragment<DialogImportBinding>(), View.On
|
||||
return DialogImportBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder) {
|
||||
builder.setTitle(R.string._import)
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
return super.onBuildDialog(builder)
|
||||
.setTitle(R.string._import)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setCancelable(true)
|
||||
}
|
||||
|
||||
@@ -15,14 +15,15 @@ import org.koitharu.kotatsu.databinding.DialogReaderConfigBinding
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
@Deprecated("Not in use")
|
||||
class ReaderConfigDialog : AlertDialogFragment<DialogReaderConfigBinding>(),
|
||||
class ReaderConfigDialog :
|
||||
AlertDialogFragment<DialogReaderConfigBinding>(),
|
||||
CheckableButtonGroup.OnCheckedChangeListener {
|
||||
|
||||
private lateinit var mode: ReaderMode
|
||||
|
||||
override fun onInflateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?
|
||||
container: ViewGroup?,
|
||||
) = DialogReaderConfigBinding.inflate(inflater, container, false)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -32,8 +33,9 @@ class ReaderConfigDialog : AlertDialogFragment<DialogReaderConfigBinding>(),
|
||||
?: ReaderMode.STANDARD
|
||||
}
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder) {
|
||||
builder.setTitle(R.string.read_mode)
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
return super.onBuildDialog(builder)
|
||||
.setTitle(R.string.read_mode)
|
||||
.setPositiveButton(R.string.done, null)
|
||||
.setCancelable(true)
|
||||
}
|
||||
@@ -48,8 +50,10 @@ class ReaderConfigDialog : AlertDialogFragment<DialogReaderConfigBinding>(),
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface) {
|
||||
((parentFragment as? Callback)
|
||||
?: (activity as? Callback))?.onReaderModeChanged(mode)
|
||||
(
|
||||
(parentFragment as? Callback)
|
||||
?: (activity as? Callback)
|
||||
)?.onReaderModeChanged(mode)
|
||||
super.onDismiss(dialog)
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,9 @@ class BackupDialogFragment : AlertDialogFragment<DialogProgressBinding>() {
|
||||
viewModel.onError.observe(viewLifecycleOwner, this::onError)
|
||||
}
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder) {
|
||||
builder.setCancelable(false)
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
return super.onBuildDialog(builder)
|
||||
.setCancelable(false)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,9 @@ class RestoreDialogFragment : AlertDialogFragment<DialogProgressBinding>() {
|
||||
viewModel.onError.observe(viewLifecycleOwner, this::onError)
|
||||
}
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder) {
|
||||
builder.setCancelable(false)
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
return super.onBuildDialog(builder)
|
||||
.setCancelable(false)
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
|
||||
@@ -43,8 +43,8 @@ class NewSourcesDialogFragment :
|
||||
viewModel.sources.observe(viewLifecycleOwner) { adapter.items = it }
|
||||
}
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder) {
|
||||
builder
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
return super.onBuildDialog(builder)
|
||||
.setPositiveButton(R.string.done, this)
|
||||
.setCancelable(true)
|
||||
.setTitle(R.string.remote_sources)
|
||||
|
||||
@@ -39,8 +39,8 @@ class OnboardDialogFragment :
|
||||
container: ViewGroup?,
|
||||
) = DialogOnboardBinding.inflate(inflater, container, false)
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder) {
|
||||
builder
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
super.onBuildDialog(builder)
|
||||
.setPositiveButton(R.string.done, this)
|
||||
.setCancelable(true)
|
||||
if (isWelcome) {
|
||||
@@ -50,6 +50,7 @@ class OnboardDialogFragment :
|
||||
.setTitle(R.string.remote_sources)
|
||||
.setNegativeButton(android.R.string.cancel, this)
|
||||
}
|
||||
return builder
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
||||
25
app/src/main/res/layout/dialog_manga_error.xml
Normal file
25
app/src/main/res/layout/dialog_manga_error.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="@dimen/margin_normal"
|
||||
android:paddingTop="@dimen/margin_normal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_message"
|
||||
style="@style/MaterialAlertDialog.Material3.Body.Text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:linksClickable="true"
|
||||
tools:text="@tools:sample/lorem[20]" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
@@ -376,4 +376,5 @@
|
||||
<string name="import_completed_hint">You can delete the original file from storage to save space</string>
|
||||
<string name="import_will_start_soon">Import will start soon</string>
|
||||
<string name="feed">Feed</string>
|
||||
<string name="manga_error_description_pattern">Error details:<br><tt>%1$s</tt><br><br>1. Try to <a href="%2$s">open manga in a web browser</a> to ensure it is available on its source<br>2. If it is available, send an error report to the developers.</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user