Skip to content

Commit 542045f

Browse files
committed
#1649 fix: show verification error if there is a network error when fetching purchases
1 parent 1af0c08 commit 542045f

8 files changed

Lines changed: 57 additions & 30 deletions

File tree

app/src/main/java/io/github/sds100/keymapper/mappings/keymaps/DisplayKeyMapUseCase.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,11 @@ class DisplayKeyMapUseCaseImpl(
7676
* This waits for the purchases to be processed with a timeout so the UI doesn't
7777
* say there are no purchases while it is loading.
7878
*/
79-
private val purchasesFlow: Flow<State<Set<ProductId>>> = callbackFlow {
79+
private val purchasesFlow: Flow<State<Result<Set<ProductId>>>> = callbackFlow {
8080
try {
8181
val value = withTimeout(5000L) {
82-
purchasingManager.purchases.filterIsInstance<State.Data<Set<ProductId>>>().first()
82+
purchasingManager.purchases.filterIsInstance<State.Data<Result<Set<ProductId>>>>()
83+
.first()
8384
}
8485

8586
send(value)
@@ -103,7 +104,7 @@ class DisplayKeyMapUseCaseImpl(
103104
isKeyMapperImeChosen = keyMapperImeHelper.isCompatibleImeChosen(),
104105
isDndAccessGranted = permissionAdapter.isGranted(Permission.ACCESS_NOTIFICATION_POLICY),
105106
isRootGranted = permissionAdapter.isGranted(Permission.ROOT),
106-
purchases = purchases.dataOrNull() ?: emptySet(),
107+
purchases = purchases.dataOrNull() ?: Success(emptySet()),
107108
showDpadImeSetupError = showDpadImeSetupError,
108109
)
109110
}
@@ -150,6 +151,8 @@ class DisplayKeyMapUseCaseImpl(
150151
ProductId.FLOATING_BUTTONS,
151152
),
152153
)
154+
155+
TriggerError.PURCHASE_VERIFICATION_FAILED -> purchasingManager.refresh()
153156
}
154157
}
155158

app/src/main/java/io/github/sds100/keymapper/mappings/keymaps/KeyMapListScreen.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ fun KeyMapList(
9191
Surface(modifier = modifier) {
9292
if (listItems.data.isEmpty()) {
9393
EmptyKeyMapList(
94-
modifier = Modifier.fillMaxSize().padding(bottom = bottomListPadding),
94+
modifier = Modifier
95+
.fillMaxSize()
96+
.padding(bottom = bottomListPadding),
9597
)
9698
} else {
9799
LoadedKeyMapList(
@@ -487,6 +489,7 @@ private fun getTriggerErrorMessage(error: TriggerError): String {
487489
TriggerError.DPAD_IME_NOT_SELECTED -> stringResource(R.string.trigger_error_dpad_ime_not_selected)
488490
TriggerError.FLOATING_BUTTON_DELETED -> stringResource(R.string.trigger_error_floating_button_deleted)
489491
TriggerError.FLOATING_BUTTONS_NOT_PURCHASED -> stringResource(R.string.trigger_error_floating_buttons_not_purchased)
492+
TriggerError.PURCHASE_VERIFICATION_FAILED -> stringResource(R.string.trigger_error_product_verification_failed)
490493
}
491494
}
492495

app/src/main/java/io/github/sds100/keymapper/mappings/keymaps/trigger/BaseConfigTriggerViewModel.kt

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ import io.github.sds100.keymapper.util.Error
2727
import io.github.sds100.keymapper.util.Result
2828
import io.github.sds100.keymapper.util.State
2929
import io.github.sds100.keymapper.util.dataOrNull
30+
import io.github.sds100.keymapper.util.ifIsData
3031
import io.github.sds100.keymapper.util.mapData
32+
import io.github.sds100.keymapper.util.onSuccess
3133
import io.github.sds100.keymapper.util.ui.CheckBoxListItem
3234
import io.github.sds100.keymapper.util.ui.DialogResponse
3335
import io.github.sds100.keymapper.util.ui.LinkType
@@ -93,7 +95,7 @@ abstract class BaseConfigTriggerViewModel(
9395
private val triggerKeyShortcuts = combine(
9496
fingerprintGesturesSupported.isSupported,
9597
purchasingManager.purchases,
96-
) { isFingerprintGesturesSupported, purchases ->
98+
) { isFingerprintGesturesSupported, purchasesState ->
9799
val newShortcuts = mutableSetOf<ShortcutModel<TriggerKeyShortcut>>()
98100

99101
if (isFingerprintGesturesSupported == true) {
@@ -106,25 +108,27 @@ abstract class BaseConfigTriggerViewModel(
106108
)
107109
}
108110

109-
if (purchases is State.Data) {
110-
if (purchases.data.contains(ProductId.ASSISTANT_TRIGGER)) {
111-
newShortcuts.add(
112-
ShortcutModel(
113-
icon = ComposeIconInfo.Vector(Icons.Rounded.Assistant),
114-
text = getString(R.string.trigger_key_shortcut_add_assistant),
115-
data = TriggerKeyShortcut.ASSISTANT,
116-
),
117-
)
118-
}
111+
purchasesState.ifIsData { result ->
112+
result.onSuccess { purchases ->
113+
if (purchases.contains(ProductId.ASSISTANT_TRIGGER)) {
114+
newShortcuts.add(
115+
ShortcutModel(
116+
icon = ComposeIconInfo.Vector(Icons.Rounded.Assistant),
117+
text = getString(R.string.trigger_key_shortcut_add_assistant),
118+
data = TriggerKeyShortcut.ASSISTANT,
119+
),
120+
)
121+
}
119122

120-
if (purchases.data.contains(ProductId.FLOATING_BUTTONS)) {
121-
newShortcuts.add(
122-
ShortcutModel(
123-
icon = ComposeIconInfo.Vector(Icons.Rounded.BubbleChart),
124-
text = getString(R.string.trigger_key_shortcut_add_floating_button),
125-
data = TriggerKeyShortcut.FLOATING_BUTTON,
126-
),
127-
)
123+
if (purchases.contains(ProductId.FLOATING_BUTTONS)) {
124+
newShortcuts.add(
125+
ShortcutModel(
126+
icon = ComposeIconInfo.Vector(Icons.Rounded.BubbleChart),
127+
text = getString(R.string.trigger_key_shortcut_add_floating_button),
128+
data = TriggerKeyShortcut.FLOATING_BUTTON,
129+
),
130+
)
131+
}
128132
}
129133
}
130134

app/src/main/java/io/github/sds100/keymapper/mappings/keymaps/trigger/TriggerError.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ enum class TriggerError(val isFixable: Boolean) {
2020
FLOATING_BUTTON_DELETED(isFixable = false),
2121

2222
FLOATING_BUTTONS_NOT_PURCHASED(isFixable = true),
23+
24+
PURCHASE_VERIFICATION_FAILED(isFixable = true),
2325
}

app/src/main/java/io/github/sds100/keymapper/mappings/keymaps/trigger/TriggerErrorSnapshot.kt

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import io.github.sds100.keymapper.mappings.keymaps.KeyMap
66
import io.github.sds100.keymapper.mappings.keymaps.requiresImeKeyEventForwardingInPhoneCall
77
import io.github.sds100.keymapper.purchasing.ProductId
88
import io.github.sds100.keymapper.system.inputevents.InputEventUtils
9+
import io.github.sds100.keymapper.util.Error
10+
import io.github.sds100.keymapper.util.Result
11+
import io.github.sds100.keymapper.util.onFailure
12+
import io.github.sds100.keymapper.util.onSuccess
913

1014
/**
1115
* Store the data required for determining trigger errors to reduce the number of calls with
@@ -15,7 +19,7 @@ data class TriggerErrorSnapshot(
1519
val isKeyMapperImeChosen: Boolean,
1620
val isDndAccessGranted: Boolean,
1721
val isRootGranted: Boolean,
18-
val purchases: Set<ProductId>,
22+
val purchases: Result<Set<ProductId>>,
1923
val showDpadImeSetupError: Boolean,
2024
) {
2125
companion object {
@@ -26,13 +30,21 @@ data class TriggerErrorSnapshot(
2630
}
2731

2832
fun getTriggerError(keyMap: KeyMap, key: TriggerKey): TriggerError? {
29-
if (key is AssistantTriggerKey && !purchases.contains(ProductId.ASSISTANT_TRIGGER)) {
30-
return TriggerError.ASSISTANT_TRIGGER_NOT_PURCHASED
33+
purchases.onSuccess { purchases ->
34+
if (key is AssistantTriggerKey && !purchases.contains(ProductId.ASSISTANT_TRIGGER)) {
35+
return TriggerError.ASSISTANT_TRIGGER_NOT_PURCHASED
36+
}
37+
38+
if (key is FloatingButtonKey && !purchases.contains(ProductId.FLOATING_BUTTONS)) {
39+
return TriggerError.FLOATING_BUTTONS_NOT_PURCHASED
40+
}
41+
}.onFailure { error ->
42+
if ((key is AssistantTriggerKey || key is FloatingButtonKey) && error == Error.PurchasingError.NetworkError) {
43+
return TriggerError.PURCHASE_VERIFICATION_FAILED
44+
}
3145
}
3246

33-
if (key is FloatingButtonKey && !purchases.contains(ProductId.FLOATING_BUTTONS)) {
34-
return TriggerError.FLOATING_BUTTONS_NOT_PURCHASED
35-
} else if (key is FloatingButtonKey && key.button == null) {
47+
if (key is FloatingButtonKey && key.button == null) {
3648
return TriggerError.FLOATING_BUTTON_DELETED
3749
}
3850

app/src/main/java/io/github/sds100/keymapper/mappings/keymaps/trigger/TriggerKeyListItem.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ private fun getErrorMessage(error: TriggerError): String {
259259
TriggerError.DPAD_IME_NOT_SELECTED -> stringResource(R.string.trigger_error_dpad_ime_not_selected)
260260
TriggerError.FLOATING_BUTTON_DELETED -> stringResource(R.string.trigger_error_floating_button_deleted)
261261
TriggerError.FLOATING_BUTTONS_NOT_PURCHASED -> stringResource(R.string.trigger_error_floating_buttons_not_purchased)
262+
TriggerError.PURCHASE_VERIFICATION_FAILED -> stringResource(R.string.trigger_error_product_verification_failed)
262263
}
263264
}
264265

app/src/main/java/io/github/sds100/keymapper/purchasing/PurchasingManager.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import kotlinx.coroutines.flow.MutableSharedFlow
77

88
interface PurchasingManager {
99
val onCompleteProductPurchase: MutableSharedFlow<ProductId>
10-
val purchases: Flow<State<Set<ProductId>>>
10+
val purchases: Flow<State<Result<Set<ProductId>>>>
1111
suspend fun launchPurchasingFlow(product: ProductId): Result<Unit>
1212
suspend fun getProductPrice(product: ProductId): Result<String>
1313
suspend fun isPurchased(product: ProductId): Result<Boolean>
14+
fun refresh()
1415
}

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,7 @@
12121212
<string name="setup_assistant_trigger_text">You must read the instructions on our website that describe how to set up this trigger. Key Mapper will not guide you.</string>
12131213
<string name="setup_assistant_trigger_read_instructions_button">Read instructions</string>
12141214
<string name="setup_assistant_trigger_select_type_button">Select trigger type</string>
1215+
<string name="trigger_error_product_verification_failed">Purchase can not be verified. Do you have an internet connection?</string>
12151216

12161217
<!-- Purchasing -->
12171218
<string name="unlock_product_button">Unlock (%s)</string>

0 commit comments

Comments
 (0)