From 366ebc781d9f92bb85d40c862936e9bdfacb4267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Sun, 19 Apr 2020 23:20:55 +0200 Subject: [PATCH] Add error message and bug report button to error dialog (#778) --- .../github/wulkanowy/ui/base/ErrorDialog.kt | 45 ++++++++++++++-- .../github/wulkanowy/ui/base/ErrorHandler.kt | 24 ++------- .../wulkanowy/ui/modules/main/MainModule.kt | 7 ++- .../wulkanowy/utils/ResourcesExtension.kt | 20 +++++++ app/src/main/res/layout/dialog_error.xml | 52 ++++++++++++++++--- app/src/main/res/values-pl/strings.xml | 2 +- 6 files changed, 118 insertions(+), 32 deletions(-) create mode 100644 app/src/main/java/io/github/wulkanowy/utils/ResourcesExtension.kt diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt index 3255ea683..374181130 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt @@ -6,19 +6,32 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.HorizontalScrollView import android.widget.Toast import android.widget.Toast.LENGTH_LONG import androidx.core.content.getSystemService -import androidx.fragment.app.DialogFragment import io.github.wulkanowy.R +import io.github.wulkanowy.sdk.exception.FeatureDisabledException +import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException +import io.github.wulkanowy.sdk.exception.ServiceUnavailableException +import io.github.wulkanowy.utils.AppInfo +import io.github.wulkanowy.utils.getString +import io.github.wulkanowy.utils.openEmailClient +import io.github.wulkanowy.utils.openInternetBrowser import kotlinx.android.synthetic.main.dialog_error.* import java.io.PrintWriter import java.io.StringWriter +import java.net.SocketTimeoutException +import java.net.UnknownHostException +import javax.inject.Inject -class ErrorDialog : DialogFragment() { +class ErrorDialog : BaseDialogFragment() { private lateinit var error: Throwable + @Inject + lateinit var appInfo: AppInfo + companion object { private const val ARGUMENT_KEY = "Data" @@ -49,6 +62,9 @@ class ErrorDialog : DialogFragment() { } errorDialogContent.text = stringWriter.toString() + with(errorDialogHorizontalScroll) { + post { fullScroll(HorizontalScrollView.FOCUS_LEFT) } + } errorDialogCopy.setOnClickListener { val clip = ClipData.newPlainText("wulkanowy", stringWriter.toString()) activity?.getSystemService()?.setPrimaryClip(clip) @@ -56,6 +72,29 @@ class ErrorDialog : DialogFragment() { Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show() } errorDialogCancel.setOnClickListener { dismiss() } + errorDialogReport.setOnClickListener { openEmailClient(stringWriter.toString()) } + errorDialogMessage.text = resources.getString(error) + errorDialogReport.isEnabled = when (error) { + is UnknownHostException, + is SocketTimeoutException, + is ServiceUnavailableException, + is FeatureDisabledException, + is FeatureNotAvailableException -> false + else -> true + } + } + + private fun openEmailClient(content: String) { + requireContext().openEmailClient( + chooserTitle = getString(R.string.about_feedback), + email = "wulkanowyinc@gmail.com", + subject = "Zgłoszenie błędu", + body = requireContext().getString(R.string.about_feedback_template, + "${appInfo.systemManufacturer} ${appInfo.systemModel}", appInfo.systemVersion.toString(), appInfo.versionName + ) + "\n" + content, + onActivityNotFound = { + requireContext().openInternetBrowser("https://github.com/wulkanowy/wulkanowy/issues", ::showMessage) + } + ) } } - diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorHandler.kt b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorHandler.kt index 34dc3418b..f746b36f8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorHandler.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorHandler.kt @@ -2,17 +2,11 @@ package io.github.wulkanowy.ui.base import android.content.res.Resources import com.chuckerteam.chucker.api.ChuckerCollector -import io.github.wulkanowy.R import io.github.wulkanowy.data.exceptions.NoCurrentStudentException import io.github.wulkanowy.sdk.exception.BadCredentialsException -import io.github.wulkanowy.sdk.exception.FeatureDisabledException -import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException -import io.github.wulkanowy.sdk.exception.NotLoggedInException -import io.github.wulkanowy.sdk.exception.ServiceUnavailableException +import io.github.wulkanowy.utils.getString import io.github.wulkanowy.utils.security.ScramblerException import timber.log.Timber -import java.net.SocketTimeoutException -import java.net.UnknownHostException import javax.inject.Inject open class ErrorHandler @Inject constructor(protected val resources: Resources, private val chuckerCollector: ChuckerCollector) { @@ -30,18 +24,10 @@ open class ErrorHandler @Inject constructor(protected val resources: Resources, } protected open fun proceed(error: Throwable) { - resources.run { - when (error) { - is UnknownHostException -> showErrorMessage(getString(R.string.error_no_internet), error) - is SocketTimeoutException -> showErrorMessage(getString(R.string.error_timeout), error) - is NotLoggedInException -> showErrorMessage(getString(R.string.error_login_failed), error) - is ServiceUnavailableException -> showErrorMessage(getString(R.string.error_service_unavailable), error) - is FeatureDisabledException -> showErrorMessage(getString(R.string.error_feature_disabled), error) - is ScramblerException, is BadCredentialsException -> onSessionExpired() - is NoCurrentStudentException -> onNoCurrentStudent() - is FeatureNotAvailableException -> showErrorMessage(getString(R.string.error_feature_not_available), error) - else -> showErrorMessage(getString(R.string.error_unknown), error) - } + when (error) { + is ScramblerException, is BadCredentialsException -> onSessionExpired() + is NoCurrentStudentException -> onNoCurrentStudent() + else -> showErrorMessage(resources.getString(error), error) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt index e87e260f7..b533684de 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt @@ -7,6 +7,7 @@ import dagger.Provides import dagger.android.ContributesAndroidInjector import io.github.wulkanowy.R import io.github.wulkanowy.di.scopes.PerFragment +import io.github.wulkanowy.ui.base.ErrorDialog import io.github.wulkanowy.ui.modules.about.AboutFragment import io.github.wulkanowy.ui.modules.about.contributor.ContributorFragment import io.github.wulkanowy.ui.modules.about.license.LicenseFragment @@ -115,6 +116,10 @@ abstract class MainModule { @ContributesAndroidInjector abstract fun bindAccountDialog(): AccountDialog + @PerFragment + @ContributesAndroidInjector + abstract fun bindErrorDialog(): ErrorDialog + @PerFragment @ContributesAndroidInjector(modules = [MobileDeviceModule::class]) abstract fun bindMobileDevices(): MobileDeviceFragment @@ -132,7 +137,7 @@ abstract class MainModule { abstract fun bindLogViewerFragment(): LogViewerFragment @PerFragment - @ContributesAndroidInjector() + @ContributesAndroidInjector abstract fun bindContributorFragment(): ContributorFragment @PerFragment diff --git a/app/src/main/java/io/github/wulkanowy/utils/ResourcesExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/ResourcesExtension.kt new file mode 100644 index 000000000..9744d3747 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/utils/ResourcesExtension.kt @@ -0,0 +1,20 @@ +package io.github.wulkanowy.utils + +import android.content.res.Resources +import io.github.wulkanowy.R +import io.github.wulkanowy.sdk.exception.FeatureDisabledException +import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException +import io.github.wulkanowy.sdk.exception.NotLoggedInException +import io.github.wulkanowy.sdk.exception.ServiceUnavailableException +import java.net.SocketTimeoutException +import java.net.UnknownHostException + +fun Resources.getString(error: Throwable) = when (error) { + is UnknownHostException -> getString(R.string.error_no_internet) + is SocketTimeoutException -> getString(R.string.error_timeout) + is NotLoggedInException -> getString(R.string.error_login_failed) + is ServiceUnavailableException -> getString(R.string.error_service_unavailable) + is FeatureDisabledException -> getString(R.string.error_feature_disabled) + is FeatureNotAvailableException -> getString(R.string.error_feature_not_available) + else -> getString(R.string.error_unknown) +} diff --git a/app/src/main/res/layout/dialog_error.xml b/app/src/main/res/layout/dialog_error.xml index ec25f6a4f..ac2c542a2 100644 --- a/app/src/main/res/layout/dialog_error.xml +++ b/app/src/main/res/layout/dialog_error.xml @@ -1,26 +1,49 @@ - + + + + + android:overScrollMode="ifContentScrolls" + app:layout_constrainedHeight="true" + app:layout_constraintHeight_max="300dp" + app:layout_constraintHeight_min="200dp" + app:layout_constraintTop_toTopOf="parent"> - + + + + + - \ No newline at end of file + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 9cd652723..d179d9e48 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -421,5 +421,5 @@ Trwa przerwa techniczna dziennika UONET+. Spróbuj ponownie później Wystąpił nieoczekiwany błąd Funkcja wyłączona przez szkołę - Funkcja niedostępna. Zaloguj się w innym trybie niż Mobilne API + Funkcja niedostępna. Zaloguj się w trybie innym niż Mobilne API