Add error detail option to the purchase screen

This commit is contained in:
Jonas Lochmann 2022-01-03 01:00:00 +01:00
parent cba90b69e3
commit 54833c6da1
No known key found for this signature in database
GPG key ID: 8B8C9AEE10FA5B36
5 changed files with 43 additions and 8 deletions

View file

@ -1,5 +1,5 @@
/* /*
* TimeLimit Copyright <C> 2019 - 2021 Jonas Lochmann * TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,13 +22,14 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import io.timelimit.android.R import io.timelimit.android.R
import io.timelimit.android.databinding.FragmentPurchaseBinding import io.timelimit.android.databinding.FragmentPurchaseBinding
import io.timelimit.android.livedata.liveDataFromNullableValue import io.timelimit.android.livedata.liveDataFromNullableValue
import io.timelimit.android.livedata.mergeLiveData import io.timelimit.android.livedata.mergeLiveData
import io.timelimit.android.ui.MainActivity import io.timelimit.android.ui.MainActivity
import io.timelimit.android.ui.diagnose.DiagnoseExceptionDialogFragment
import io.timelimit.android.ui.main.FragmentWithCustomTitle import io.timelimit.android.ui.main.FragmentWithCustomTitle
import java.lang.RuntimeException
class PurchaseFragment : Fragment(), FragmentWithCustomTitle { class PurchaseFragment : Fragment(), FragmentWithCustomTitle {
private val activityModel: ActivityPurchaseModel by lazy { (activity as MainActivity).purchaseModel } private val activityModel: ActivityPurchaseModel by lazy { (activity as MainActivity).purchaseModel }
@ -87,7 +88,7 @@ class PurchaseFragment : Fragment(), FragmentWithCustomTitle {
binding.errorReason = when (fragmentStatus) { binding.errorReason = when (fragmentStatus) {
PurchaseFragmentErrorBillingNotSupportedByDevice -> getString(R.string.purchase_error_not_supported_by_device) PurchaseFragmentErrorBillingNotSupportedByDevice -> getString(R.string.purchase_error_not_supported_by_device)
PurchaseFragmentErrorBillingNotSupportedByAppVariant -> getString(R.string.purchase_error_not_supported_by_app_variant) PurchaseFragmentErrorBillingNotSupportedByAppVariant -> getString(R.string.purchase_error_not_supported_by_app_variant)
PurchaseFragmentNetworkError -> getString(R.string.error_network) is PurchaseFragmentNetworkError -> getString(R.string.error_network)
PurchaseFragmentExistingPaymentError -> getString(R.string.purchase_error_existing_payment) PurchaseFragmentExistingPaymentError -> getString(R.string.purchase_error_existing_payment)
PurchaseFragmentServerRejectedError -> getString(R.string.purchase_error_server_rejected) PurchaseFragmentServerRejectedError -> getString(R.string.purchase_error_server_rejected)
PurchaseFragmentServerHasDifferentPublicKey -> getString(R.string.purchase_error_server_different_key) PurchaseFragmentServerHasDifferentPublicKey -> getString(R.string.purchase_error_server_different_key)
@ -97,6 +98,12 @@ class PurchaseFragment : Fragment(), FragmentWithCustomTitle {
is PurchaseFragmentRecoverableError -> true is PurchaseFragmentRecoverableError -> true
is PurchaseFragmentUnrecoverableError -> false is PurchaseFragmentUnrecoverableError -> false
} }
binding.showErrorDetailsButton = when (fragmentStatus) {
is PurchaseFragmentNetworkError -> true
else -> false
}
processingPurchaseError = false processingPurchaseError = false
} }
}.let { } }.let { }
@ -114,6 +121,17 @@ class PurchaseFragment : Fragment(), FragmentWithCustomTitle {
} }
} }
override fun showErrorDetails() {
val status = model.status.value
val exception = when (status) {
is PurchaseFragmentNetworkError -> status.exception
else -> RuntimeException("other error")
}
DiagnoseExceptionDialogFragment.newInstance(exception).show(parentFragmentManager)
}
override fun buyForOneMonth() { override fun buyForOneMonth() {
activityModel.startPurchase(PurchaseIds.SKU_MONTH, checkAtBackend = true, activity = requireActivity()) activityModel.startPurchase(PurchaseIds.SKU_MONTH, checkAtBackend = true, activity = requireActivity())
} }
@ -131,6 +149,7 @@ class PurchaseFragment : Fragment(), FragmentWithCustomTitle {
interface PurchaseFragmentHandlers { interface PurchaseFragmentHandlers {
fun retryAtErrorScreenClicked() fun retryAtErrorScreenClicked()
fun showErrorDetails()
fun buyForOneMonth() fun buyForOneMonth()
fun buyForOneYear() fun buyForOneYear()
} }

View file

@ -1,5 +1,5 @@
/* /*
* TimeLimit Copyright <C> 2019 - 2021 Jonas Lochmann * TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -78,7 +78,7 @@ class PurchaseModel(application: Application): AndroidViewModel(application) {
} catch (ex: BillingNotSupportedException) { } catch (ex: BillingNotSupportedException) {
statusInternal.value = PurchaseFragmentErrorBillingNotSupportedByDevice statusInternal.value = PurchaseFragmentErrorBillingNotSupportedByDevice
} catch (ex: Exception) { } catch (ex: Exception) {
statusInternal.value = PurchaseFragmentNetworkError statusInternal.value = PurchaseFragmentNetworkError(ex)
} }
} }
} }
@ -95,7 +95,7 @@ sealed class PurchaseFragmentRecoverableError: PurchaseFragmentError()
object PurchaseFragmentErrorBillingNotSupportedByDevice: PurchaseFragmentUnrecoverableError() object PurchaseFragmentErrorBillingNotSupportedByDevice: PurchaseFragmentUnrecoverableError()
object PurchaseFragmentErrorBillingNotSupportedByAppVariant: PurchaseFragmentUnrecoverableError() object PurchaseFragmentErrorBillingNotSupportedByAppVariant: PurchaseFragmentUnrecoverableError()
object PurchaseFragmentNetworkError: PurchaseFragmentRecoverableError() data class PurchaseFragmentNetworkError(val exception: Exception): PurchaseFragmentRecoverableError()
object PurchaseFragmentExistingPaymentError: PurchaseFragmentUnrecoverableError() object PurchaseFragmentExistingPaymentError: PurchaseFragmentUnrecoverableError()
object PurchaseFragmentServerRejectedError: PurchaseFragmentUnrecoverableError() object PurchaseFragmentServerRejectedError: PurchaseFragmentUnrecoverableError()
object PurchaseFragmentServerHasDifferentPublicKey: PurchaseFragmentUnrecoverableError() object PurchaseFragmentServerHasDifferentPublicKey: PurchaseFragmentUnrecoverableError()

View file

@ -1,5 +1,5 @@
<!-- <!--
TimeLimit Copyright <C> 2019 - 2021 Jonas Lochmann TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License. the Free Software Foundation version 3 of the License.
@ -30,6 +30,10 @@
name="showRetryButton" name="showRetryButton"
type="Boolean" /> type="Boolean" />
<variable
name="showErrorDetailsButton"
type="boolean" />
<variable <variable
name="priceData" name="priceData"
type="io.timelimit.android.ui.payment.PurchaseFragmentReady" /> type="io.timelimit.android.ui.payment.PurchaseFragmentReady" />
@ -149,6 +153,16 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<Button
style="?borderlessButtonStyle"
android:layout_marginTop="4dp"
android:visibility="@{showErrorDetailsButton ? View.VISIBLE : View.GONE}"
android:onClick="@{() -> handlers.showErrorDetails()}"
android:text="@string/generic_show_details"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout> </LinearLayout>
</RelativeLayout> </RelativeLayout>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
TimeLimit Copyright <C> 2019 - 2021 Jonas Lochmann TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License. the Free Software Foundation version 3 of the License.
@ -29,6 +29,7 @@
<string name="generic_no">Nein</string> <string name="generic_no">Nein</string>
<string name="generic_yes">Ja</string> <string name="generic_yes">Ja</string>
<string name="generic_skip">Überspringen</string> <string name="generic_skip">Überspringen</string>
<string name="generic_show_details">Details anzeigen</string>
<string name="generic_swipe_to_dismiss">Sie können diesen Hinweis entfernen, indem Sie ihn zur Seite wischen</string> <string name="generic_swipe_to_dismiss">Sie können diesen Hinweis entfernen, indem Sie ihn zur Seite wischen</string>
<string name="generic_runtime_permission_rejected">Berechtigung abgelehnt; Sie können die Berechtigungen in den Systemeinstellungen verwalten</string> <string name="generic_runtime_permission_rejected">Berechtigung abgelehnt; Sie können die Berechtigungen in den Systemeinstellungen verwalten</string>

View file

@ -32,6 +32,7 @@
<string name="generic_no">No</string> <string name="generic_no">No</string>
<string name="generic_yes">Yes</string> <string name="generic_yes">Yes</string>
<string name="generic_skip">Skip</string> <string name="generic_skip">Skip</string>
<string name="generic_show_details">Show details</string>
<string name="generic_swipe_to_dismiss">Swipe to the side to remove this message</string> <string name="generic_swipe_to_dismiss">Swipe to the side to remove this message</string>
<string name="generic_runtime_permission_rejected">Permission rejected; You can manage permissions in the system settings</string> <string name="generic_runtime_permission_rejected">Permission rejected; You can manage permissions in the system settings</string>