Skip to content

Commit 11d6a71

Browse files
authored
Merge branch 'develop' into l10n/develop
2 parents a849938 + baf32a0 commit 11d6a71

File tree

13 files changed

+406
-197
lines changed

13 files changed

+406
-197
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Redesign the Settings screen.
1010
- Shortcuts on the trigger screen that guide you how to set up different types of buttons.
1111
- #1788 dismiss lockscreen when launching app action from lockscreen
12+
- Show tips for parallel and sequence triggers, and constraints in the trigger screen
1213

1314
## Removed
1415

app/src/main/java/io/github/sds100/keymapper/trigger/ConfigTriggerViewModel.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package io.github.sds100.keymapper.trigger
33
import dagger.hilt.android.lifecycle.HiltViewModel
44
import io.github.sds100.keymapper.base.keymaps.DisplayKeyMapUseCase
55
import io.github.sds100.keymapper.base.keymaps.FingerprintGesturesSupportedUseCase
6+
import io.github.sds100.keymapper.base.onboarding.OnboardingTipDelegate
67
import io.github.sds100.keymapper.base.onboarding.OnboardingUseCase
78
import io.github.sds100.keymapper.base.shortcuts.CreateKeyMapShortcutUseCase
89
import io.github.sds100.keymapper.base.trigger.BaseConfigTriggerViewModel
@@ -23,6 +24,7 @@ class ConfigTriggerViewModel @Inject constructor(
2324
private val createKeyMapShortcut: CreateKeyMapShortcutUseCase,
2425
private val displayKeyMap: DisplayKeyMapUseCase,
2526
private val fingerprintGesturesSupported: FingerprintGesturesSupportedUseCase,
27+
onboardingTipDelegate: OnboardingTipDelegate,
2628
triggerSetupDelegate: TriggerSetupDelegate,
2729
resourceProvider: ResourceProvider,
2830
navigationProvider: NavigationProvider,
@@ -34,6 +36,7 @@ class ConfigTriggerViewModel @Inject constructor(
3436
createKeyMapShortcut = createKeyMapShortcut,
3537
displayKeyMap = displayKeyMap,
3638
fingerprintGesturesSupported = fingerprintGesturesSupported,
39+
onboardingTipDelegate = onboardingTipDelegate,
3740
triggerSetupDelegate = triggerSetupDelegate,
3841
resourceProvider = resourceProvider,
3942
navigationProvider = navigationProvider,

app/version.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
VERSION_NAME=4.0.0-beta.1
2-
VERSION_CODE=153
2+
VERSION_CODE=154
33
VERSION_NUM=0

base/src/main/java/io/github/sds100/keymapper/base/BaseViewModelHiltModule.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import io.github.sds100.keymapper.base.logging.DisplayLogUseCase
3333
import io.github.sds100.keymapper.base.logging.DisplayLogUseCaseImpl
3434
import io.github.sds100.keymapper.base.logging.ShareLogcatUseCase
3535
import io.github.sds100.keymapper.base.logging.ShareLogcatUseCaseImpl
36+
import io.github.sds100.keymapper.base.onboarding.OnboardingTipDelegate
37+
import io.github.sds100.keymapper.base.onboarding.OnboardingTipDelegateImpl
3638
import io.github.sds100.keymapper.base.promode.SystemBridgeSetupUseCase
3739
import io.github.sds100.keymapper.base.promode.SystemBridgeSetupUseCaseImpl
3840
import io.github.sds100.keymapper.base.settings.ConfigSettingsUseCase
@@ -156,4 +158,8 @@ abstract class BaseViewModelHiltModule {
156158
@Binds
157159
@ViewModelScoped
158160
abstract fun bindShareLogcatUseCase(impl: ShareLogcatUseCaseImpl): ShareLogcatUseCase
161+
162+
@Binds
163+
@ViewModelScoped
164+
abstract fun bindOnboardingTipDelegate(impl: OnboardingTipDelegateImpl): OnboardingTipDelegate
159165
}

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

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -111,22 +111,9 @@ class DisplayKeyMapUseCaseImpl @Inject constructor(
111111
)
112112
}
113113

114-
override val showTriggerKeyboardIconExplanation: Flow<Boolean> =
115-
settingsRepository.get(Keys.neverShowTriggerKeyboardIconExplanation).map { neverShow ->
116-
if (neverShow == null) {
117-
true
118-
} else {
119-
!neverShow
120-
}
121-
}
122-
123114
override val showDeviceDescriptors: Flow<Boolean> =
124115
settingsRepository.get(Keys.showDeviceDescriptors).map { it == true }
125116

126-
override fun neverShowTriggerKeyboardIconExplanation() {
127-
settingsRepository.set(Keys.neverShowTriggerKeyboardIconExplanation, true)
128-
}
129-
130117
override fun neverShowDpadImeSetupError() {
131118
settingsRepository.set(Keys.neverShowDpadImeTriggerError, true)
132119
}
@@ -230,8 +217,6 @@ interface DisplayKeyMapUseCase :
230217
val triggerErrorSnapshot: Flow<TriggerErrorSnapshot>
231218
suspend fun isFloatingButtonsPurchased(): Boolean
232219
suspend fun fixTriggerError(error: TriggerError)
233-
val showTriggerKeyboardIconExplanation: Flow<Boolean>
234-
fun neverShowTriggerKeyboardIconExplanation()
235220
override val showDeviceDescriptors: Flow<Boolean>
236221

237222
fun neverShowDpadImeSetupError()
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
package io.github.sds100.keymapper.base.onboarding
2+
3+
import dagger.hilt.android.scopes.ViewModelScoped
4+
import io.github.sds100.keymapper.base.R
5+
import io.github.sds100.keymapper.base.keymaps.DisplayKeyMapUseCase
6+
import io.github.sds100.keymapper.base.trigger.ConfigTriggerUseCase
7+
import io.github.sds100.keymapper.base.trigger.KeyCodeTriggerKey
8+
import io.github.sds100.keymapper.base.trigger.KeyEventTriggerKey
9+
import io.github.sds100.keymapper.base.trigger.Trigger
10+
import io.github.sds100.keymapper.base.trigger.TriggerMode
11+
import io.github.sds100.keymapper.base.utils.ui.ResourceProvider
12+
import io.github.sds100.keymapper.common.utils.dataOrNull
13+
import io.github.sds100.keymapper.data.Keys
14+
import io.github.sds100.keymapper.data.repositories.PreferenceRepository
15+
import io.github.sds100.keymapper.data.utils.PrefDelegate
16+
import io.github.sds100.keymapper.system.inputevents.KeyEventUtils
17+
import kotlinx.coroutines.CoroutineScope
18+
import kotlinx.coroutines.flow.MutableStateFlow
19+
import kotlinx.coroutines.flow.StateFlow
20+
import kotlinx.coroutines.flow.mapNotNull
21+
import kotlinx.coroutines.launch
22+
import javax.inject.Inject
23+
import javax.inject.Named
24+
25+
@ViewModelScoped
26+
class OnboardingTipDelegateImpl @Inject constructor(
27+
@Named("viewmodel")
28+
private val viewModelScope: CoroutineScope,
29+
private val preferenceRepository: PreferenceRepository,
30+
private val configTriggerUseCase: ConfigTriggerUseCase,
31+
private val displayKeyMap: DisplayKeyMapUseCase,
32+
resourceProvider: ResourceProvider,
33+
) : OnboardingTipDelegate,
34+
PreferenceRepository by preferenceRepository,
35+
ResourceProvider by resourceProvider {
36+
37+
companion object {
38+
private const val POWER_BUTTON_EMERGENCY_TIP_ID = "power_button_emergency_tip"
39+
private const val PARALLEL_TRIGGER_TIP_ID = "parallel_trigger_tip"
40+
private const val SEQUENCE_TRIGGER_TIP_ID = "sequence_trigger_tip"
41+
private const val TRIGGER_CONSTRAINTS_TIP_ID = "trigger_constraints_tip"
42+
const val CAPS_LOCK_TIP_ID = "caps_lock_tip"
43+
const val SCREEN_PINNING_TIP_ID = "screen_pinning_tip"
44+
const val IME_DETECTION_TIP_ID = "ime_detection_tip"
45+
}
46+
47+
override val triggerTip: MutableStateFlow<OnboardingTipModel?> = MutableStateFlow(null)
48+
49+
private var shownParallelTriggerOrderExplanation: Boolean by PrefDelegate(
50+
Keys.shownParallelTriggerOrderExplanation,
51+
false,
52+
)
53+
54+
private var shownSequenceTriggerExplanation: Boolean by PrefDelegate(
55+
Keys.shownSequenceTriggerExplanation,
56+
false,
57+
)
58+
59+
private var shownTriggerConstraintsTip: Boolean by PrefDelegate(
60+
Keys.shownTriggerConstraintsTip,
61+
false,
62+
)
63+
64+
private var shownCapsLockTip: Boolean by PrefDelegate(
65+
Keys.shownCapsLockTip,
66+
false,
67+
)
68+
69+
private var shownScreenPinningTip: Boolean by PrefDelegate(
70+
Keys.shownScreenPinningTip,
71+
false,
72+
)
73+
74+
private var shownImeDetectionTip: Boolean by PrefDelegate(
75+
Keys.shownTriggerKeyboardIconExplanation,
76+
false,
77+
)
78+
79+
init {
80+
viewModelScope.launch {
81+
configTriggerUseCase.keyMap
82+
.mapNotNull { it.dataOrNull()?.trigger }
83+
.collect { trigger ->
84+
onCollectTrigger(trigger)
85+
}
86+
}
87+
}
88+
89+
override fun onDismissClick() {
90+
val currentTip = triggerTip.value
91+
92+
when (currentTip?.id) {
93+
PARALLEL_TRIGGER_TIP_ID -> {
94+
shownParallelTriggerOrderExplanation = true
95+
}
96+
97+
SEQUENCE_TRIGGER_TIP_ID -> {
98+
shownSequenceTriggerExplanation = true
99+
}
100+
101+
TRIGGER_CONSTRAINTS_TIP_ID -> {
102+
shownTriggerConstraintsTip = true
103+
}
104+
105+
CAPS_LOCK_TIP_ID -> {
106+
shownCapsLockTip = true
107+
}
108+
109+
SCREEN_PINNING_TIP_ID -> {
110+
shownScreenPinningTip = true
111+
}
112+
113+
IME_DETECTION_TIP_ID -> {
114+
shownImeDetectionTip = true
115+
}
116+
117+
// POWER_BUTTON_EMERGENCY_TIP_ID doesn't need preference setting as it's non-dismissable
118+
}
119+
120+
triggerTip.value = null
121+
}
122+
123+
private suspend fun onCollectTrigger(trigger: Trigger) {
124+
val showPowerButtonEmergencyTip = trigger.keys.any {
125+
it is KeyCodeTriggerKey && KeyEventUtils.isPowerButtonKey(
126+
it.keyCode,
127+
it.scanCode ?: -1,
128+
)
129+
}
130+
131+
val hasCapsLockKey =
132+
trigger.keys.any { it is KeyEventTriggerKey && it.keyCode == android.view.KeyEvent.KEYCODE_CAPS_LOCK }
133+
val hasBackKey =
134+
trigger.keys.any { it is KeyEventTriggerKey && it.keyCode == android.view.KeyEvent.KEYCODE_BACK }
135+
val hasImeKey = trigger.keys.any { it is KeyEventTriggerKey && it.requiresIme }
136+
137+
when {
138+
showPowerButtonEmergencyTip -> {
139+
val tipModel = OnboardingTipModel(
140+
id = POWER_BUTTON_EMERGENCY_TIP_ID,
141+
title = getString(R.string.pro_mode_emergency_tip_title),
142+
message = getString(R.string.pro_mode_emergency_tip_text),
143+
isDismissable = false,
144+
)
145+
146+
triggerTip.value = tipModel
147+
}
148+
149+
trigger.mode is TriggerMode.Parallel && !shownParallelTriggerOrderExplanation -> {
150+
val tipModel = OnboardingTipModel(
151+
id = PARALLEL_TRIGGER_TIP_ID,
152+
title = getString(R.string.tip_parallel_trigger_title),
153+
message = getString(R.string.dialog_message_parallel_trigger_order),
154+
isDismissable = true,
155+
)
156+
157+
triggerTip.value = tipModel
158+
}
159+
160+
trigger.mode is TriggerMode.Sequence && !shownSequenceTriggerExplanation -> {
161+
val tipModel = OnboardingTipModel(
162+
id = SEQUENCE_TRIGGER_TIP_ID,
163+
title = getString(R.string.tip_sequence_trigger_title),
164+
message = getString(R.string.dialog_message_sequence_trigger_explanation),
165+
isDismissable = true,
166+
)
167+
168+
triggerTip.value = tipModel
169+
}
170+
171+
trigger.keys.isNotEmpty() && !shownTriggerConstraintsTip -> {
172+
val tipModel = OnboardingTipModel(
173+
id = TRIGGER_CONSTRAINTS_TIP_ID,
174+
title = getString(R.string.trigger_constraints_tip_title),
175+
message = getString(R.string.trigger_constraints_tip_text),
176+
isDismissable = true,
177+
)
178+
179+
triggerTip.value = tipModel
180+
}
181+
182+
hasCapsLockKey && !shownCapsLockTip -> {
183+
val tip = OnboardingTipModel(
184+
id = CAPS_LOCK_TIP_ID,
185+
title = getString(R.string.tip_caps_lock_title),
186+
message = getString(R.string.tip_caps_lock_text),
187+
isDismissable = true,
188+
)
189+
triggerTip.value = tip
190+
}
191+
192+
hasBackKey && !shownScreenPinningTip -> {
193+
val tip = OnboardingTipModel(
194+
id = SCREEN_PINNING_TIP_ID,
195+
title = getString(R.string.tip_screen_pinning_title),
196+
message = getString(R.string.tip_screen_pinning_text),
197+
isDismissable = true,
198+
)
199+
triggerTip.value = tip
200+
}
201+
202+
hasImeKey && !shownImeDetectionTip -> {
203+
val tip = OnboardingTipModel(
204+
id = IME_DETECTION_TIP_ID,
205+
title = getString(R.string.tip_ime_detection_title),
206+
message = getString(R.string.tip_ime_detection_text),
207+
isDismissable = true,
208+
)
209+
triggerTip.value = tip
210+
}
211+
212+
else -> {
213+
triggerTip.value = null
214+
}
215+
}
216+
}
217+
}
218+
219+
interface OnboardingTipDelegate {
220+
val triggerTip: StateFlow<OnboardingTipModel?>
221+
222+
fun onDismissClick()
223+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package io.github.sds100.keymapper.base.onboarding
2+
3+
data class OnboardingTipModel(
4+
val id: String,
5+
val title: String,
6+
val message: String,
7+
val isDismissable: Boolean,
8+
)

base/src/main/java/io/github/sds100/keymapper/base/onboarding/OnboardingUseCase.kt

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package io.github.sds100.keymapper.base.onboarding
33
import androidx.datastore.preferences.core.Preferences
44
import io.github.sds100.keymapper.base.actions.ActionData
55
import io.github.sds100.keymapper.base.actions.canUseImeToPerform
6-
import io.github.sds100.keymapper.base.purchasing.PurchasingManager
76
import io.github.sds100.keymapper.base.system.inputmethod.KeyMapperImeHelper
87
import io.github.sds100.keymapper.base.utils.VersionHelper
98
import io.github.sds100.keymapper.common.BuildConfigProvider
@@ -35,7 +34,6 @@ class OnboardingUseCaseImpl @Inject constructor(
3534
private val shizukuAdapter: ShizukuAdapter,
3635
private val permissionAdapter: PermissionAdapter,
3736
private val packageManagerAdapter: PackageManagerAdapter,
38-
private val purchasingManager: PurchasingManager,
3937
private val keyMapRepository: KeyMapRepository,
4038
private val buildConfigProvider: BuildConfigProvider,
4139
) : PreferenceRepository by settingsRepository,
@@ -60,14 +58,6 @@ class OnboardingUseCaseImpl @Inject constructor(
6058
settingsRepository.set(Keys.acknowledgedGuiKeyboard, true)
6159
}
6260

63-
override var shownParallelTriggerOrderExplanation by PrefDelegate(
64-
Keys.shownParallelTriggerOrderExplanation,
65-
false,
66-
)
67-
override var shownSequenceTriggerExplanation by PrefDelegate(
68-
Keys.shownSequenceTriggerExplanation,
69-
false,
70-
)
7161
override val showWhatsNew = get(Keys.lastInstalledVersionCodeHomeScreen)
7262
.map { (it ?: -1) < buildConfigProvider.versionCode }
7363

@@ -194,9 +184,6 @@ interface OnboardingUseCase {
194184
fun isTvDevice(): Boolean
195185
fun neverShowGuiKeyboardPromptsAgain()
196186

197-
var shownParallelTriggerOrderExplanation: Boolean
198-
var shownSequenceTriggerExplanation: Boolean
199-
200187
val showFloatingButtonFeatureNotification: Flow<Boolean>
201188
fun showedFloatingButtonFeatureNotification()
202189
var approvedFloatingButtonFeaturePrompt: Boolean

0 commit comments

Comments
 (0)