Update error details dialog
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user