Update error details dialog

This commit is contained in:
Koitharu
2025-03-04 14:05:45 +02:00
parent 93e8e87b03
commit d51790811a
4 changed files with 77 additions and 21 deletions

View File

@@ -43,6 +43,9 @@ class AppUpdateRepository @Inject constructor(
append("/releases?page=1&per_page=10")
}
val isUpdateAvailable: Boolean
get() = availableUpdate.value != null
fun observeAvailableUpdate() = availableUpdate.asStateFlow()
suspend fun getAvailableVersions(): List<AppVersion> {

View File

@@ -2,26 +2,33 @@ package org.koitharu.kotatsu.core.ui.dialog
import android.os.Bundle
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.method.LinkMovementMethodCompat
import androidx.core.text.parseAsHtml
import androidx.core.view.isVisible
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.github.AppUpdateRepository
import org.koitharu.kotatsu.core.nav.AppRouter
import org.koitharu.kotatsu.core.nav.router
import org.koitharu.kotatsu.core.ui.AlertDialogFragment
import org.koitharu.kotatsu.core.util.ext.copyToClipboard
import org.koitharu.kotatsu.core.util.ext.getCauseUrl
import org.koitharu.kotatsu.core.util.ext.isReportable
import org.koitharu.kotatsu.core.util.ext.report
import org.koitharu.kotatsu.core.util.ext.requireSerializable
import org.koitharu.kotatsu.core.util.ext.setTextAndVisible
import org.koitharu.kotatsu.databinding.DialogErrorDetailsBinding
import javax.inject.Inject
class ErrorDetailsDialog : AlertDialogFragment<DialogErrorDetailsBinding>() {
@AndroidEntryPoint
class ErrorDetailsDialog : AlertDialogFragment<DialogErrorDetailsBinding>(), View.OnClickListener {
private lateinit var exception: Throwable
@Inject
lateinit var appUpdateRepository: AppUpdateRepository
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val args = requireArguments()
@@ -34,31 +41,50 @@ class ErrorDetailsDialog : AlertDialogFragment<DialogErrorDetailsBinding>() {
override fun onViewBindingCreated(binding: DialogErrorDetailsBinding, savedInstanceState: Bundle?) {
super.onViewBindingCreated(binding, savedInstanceState)
with(binding.textViewMessage) {
movementMethod = LinkMovementMethodCompat.getInstance()
text = context.getString(
R.string.manga_error_description_pattern,
exception.message?.htmlEncode().orEmpty(),
arguments?.getString(AppRouter.KEY_URL) ?: exception.getCauseUrl(),
).parseAsHtml(HtmlCompat.FROM_HTML_MODE_LEGACY)
}
binding.buttonBrowser.setOnClickListener(this)
binding.textViewSummary.text = exception.message
val isUrlAvailable = !exception.getCauseUrl().isNullOrEmpty()
binding.buttonBrowser.isVisible = isUrlAvailable
binding.textViewBrowser.isVisible = isUrlAvailable
binding.textViewDescription.setTextAndVisible(
if (appUpdateRepository.isUpdateAvailable) {
R.string.error_disclaimer_app_outdated
} else if (exception.isReportable()) {
R.string.error_disclaimer_report
} else {
0
},
)
}
@Suppress("NAME_SHADOWING")
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
val builder = super.onBuildDialog(builder)
.setCancelable(true)
.setNegativeButton(android.R.string.cancel, null)
.setTitle(R.string.error_occurred)
.setNegativeButton(R.string.close, null)
.setTitle(R.string.error_details)
.setNeutralButton(androidx.preference.R.string.copy) { _, _ ->
context?.copyToClipboard(getString(R.string.error), exception.stackTraceToString())
}
if (exception.isReportable()) {
builder.setPositiveButton(R.string.report) { _, _ ->
if (appUpdateRepository.isUpdateAvailable) {
builder.setPositiveButton(R.string.update) { _, _ ->
router.openAppUpdate()
dismiss()
}
} else if (exception.isReportable()) {
builder.setPositiveButton(R.string.report) { _, _ ->
exception.report(silent = true)
dismiss()
}
}
return builder
}
override fun onClick(v: View) {
router.openBrowser(
url = exception.getCauseUrl() ?: return,
source = null,
title = null,
)
}
}

View File

@@ -13,12 +13,35 @@
android:paddingTop="@dimen/margin_normal">
<TextView
android:id="@+id/textView_message"
style="@style/MaterialAlertDialog.Material3.Body.Text"
android:id="@+id/textView_summary"
style="?textAppearanceBodyMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:linksClickable="true"
tools:text="@tools:sample/lorem[20]" />
tools:text="@tools:sample/lorem[14]" />
<TextView
android:id="@+id/textView_browser"
style="?textAppearanceBodySmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/error_disclaimer_manga" />
<Button
android:id="@+id/button_browser"
style="?materialButtonTonalStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/open_in_browser" />
<TextView
android:id="@+id/textView_description"
style="?textAppearanceBodySmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
tools:text="@string/error_disclaimer_report" />
</LinearLayout>

View File

@@ -810,4 +810,8 @@
<string name="chapter_number">Chapter %s</string>
<string name="unnamed_chapter">Unnamed chapter</string>
<string name="search_disabled_sources">Search through disabled sources</string>
<string name="error_details">Error details</string>
<string name="error_disclaimer_manga">Try to open manga in a web browser to ensure it is available on its source.</string>
<string name="error_disclaimer_app_outdated">It looks like your version of Kotatsu is out of date. Please install the latest version to get all available fixes.</string>
<string name="error_disclaimer_report">You can submit a bug report to the developers. This will help us investigate and fix the issue.</string>
</resources>