mirror of
https://codeberg.org/timelimit/timelimit-android.git
synced 2025-10-03 09:49:25 +02:00
Add error detail option to the purchase screen
This commit is contained in:
parent
cba90b69e3
commit
54833c6da1
5 changed files with 43 additions and 8 deletions
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue