Update error details dialog

master
Koitharu 1 year ago
parent 93e8e87b03
commit d51790811a
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

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

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

@ -13,12 +13,35 @@
android:paddingTop="@dimen/margin_normal"> android:paddingTop="@dimen/margin_normal">
<TextView <TextView
android:id="@+id/textView_message" android:id="@+id/textView_summary"
style="@style/MaterialAlertDialog.Material3.Body.Text" style="?textAppearanceBodyMedium"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:linksClickable="true" tools:text="@tools:sample/lorem[14]" />
tools:text="@tools:sample/lorem[20]" />
<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> </LinearLayout>

@ -810,4 +810,8 @@
<string name="chapter_number">Chapter %s</string> <string name="chapter_number">Chapter %s</string>
<string name="unnamed_chapter">Unnamed chapter</string> <string name="unnamed_chapter">Unnamed chapter</string>
<string name="search_disabled_sources">Search through disabled sources</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> </resources>

Loading…
Cancel
Save