Skip to content

Commit 4c3cfb0

Browse files
committed
#1857 feat: show a tip to use pro mode for volume button screen off remapping
1 parent 340f0e4 commit 4c3cfb0

4 files changed

Lines changed: 99 additions & 43 deletions

File tree

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

Lines changed: 79 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.github.sds100.keymapper.base.onboarding
22

33
import android.os.Build
4+
import android.view.KeyEvent
45
import dagger.hilt.android.scopes.ViewModelScoped
56
import io.github.sds100.keymapper.base.R
67
import io.github.sds100.keymapper.base.actions.Action
@@ -49,6 +50,7 @@ class OnboardingTipDelegateImpl @Inject constructor(
4950
private const val SEQUENCE_TRIGGER_TIP_ID = "sequence_trigger_tip"
5051
private const val TRIGGER_CONSTRAINTS_TIP_ID = "trigger_constraints_tip"
5152
const val CAPS_LOCK_PRO_MODE_COMPATIBILITY_TIP_ID = "caps_lock_pro_mode_compatibility_tip"
53+
const val VOLUME_BUTTONS_PRO_MODE_TIP_ID = "volume_buttons_pro_mode_tip"
5254
const val SCREEN_PINNING_TIP_ID = "screen_pinning_tip"
5355
const val IME_DETECTION_TIP_ID = "ime_detection_tip"
5456
const val RINGER_MODE_TIP_ID = "ringer_mode_tip"
@@ -77,6 +79,11 @@ class OnboardingTipDelegateImpl @Inject constructor(
7779
false,
7880
)
7981

82+
private var shownVolumeButtonsProModeTip: Boolean by PrefDelegate(
83+
Keys.shownVolumeButtonsProModeTip,
84+
false,
85+
)
86+
8087
private var shownScreenPinningTip: Boolean by PrefDelegate(
8188
Keys.shownScreenPinningTip,
8289
false,
@@ -113,33 +120,7 @@ class OnboardingTipDelegateImpl @Inject constructor(
113120
override fun onTriggerTipDismissClick() {
114121
val currentTip = triggerTip.value
115122

116-
when (currentTip?.id) {
117-
PARALLEL_TRIGGER_TIP_ID -> {
118-
shownParallelTriggerOrderExplanation = true
119-
}
120-
121-
SEQUENCE_TRIGGER_TIP_ID -> {
122-
shownSequenceTriggerExplanation = true
123-
}
124-
125-
TRIGGER_CONSTRAINTS_TIP_ID -> {
126-
shownTriggerConstraintsTip = true
127-
}
128-
129-
CAPS_LOCK_PRO_MODE_COMPATIBILITY_TIP_ID -> {
130-
shownCapsLockProModeTip = true
131-
}
132-
133-
SCREEN_PINNING_TIP_ID -> {
134-
shownScreenPinningTip = true
135-
}
136-
137-
IME_DETECTION_TIP_ID -> {
138-
shownImeDetectionTip = true
139-
}
140-
141-
// POWER_BUTTON_EMERGENCY_TIP_ID doesn't need preference setting as it's non-dismissable
142-
}
123+
currentTip?.let { neverShowTipAgain(it.id) }
143124

144125
triggerTip.value = null
145126
}
@@ -163,6 +144,12 @@ class OnboardingTipDelegateImpl @Inject constructor(
163144
navigate("ringer_mode_tip_pro_mode", NavDestination.ProMode)
164145
}
165146
}
147+
148+
VOLUME_BUTTONS_PRO_MODE_TIP_ID -> {
149+
viewModelScope.launch {
150+
navigate("volume_buttons_pro_mode_tip", NavDestination.ProMode)
151+
}
152+
}
166153
}
167154
}
168155

@@ -175,9 +162,14 @@ class OnboardingTipDelegateImpl @Inject constructor(
175162
}
176163

177164
val hasCapsLockKey =
178-
trigger.keys.any { it is KeyEventTriggerKey && it.keyCode == android.view.KeyEvent.KEYCODE_CAPS_LOCK }
165+
trigger.keys.any { it is KeyEventTriggerKey && it.keyCode == KeyEvent.KEYCODE_CAPS_LOCK }
166+
trigger.keys.any {
167+
it is KeyEventTriggerKey &&
168+
(it.keyCode == KeyEvent.KEYCODE_VOLUME_UP || it.keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
169+
}
170+
179171
val hasBackKey =
180-
trigger.keys.any { it is KeyEventTriggerKey && it.keyCode == android.view.KeyEvent.KEYCODE_BACK }
172+
trigger.keys.any { it is KeyEventTriggerKey && it.keyCode == KeyEvent.KEYCODE_BACK }
181173
val hasImeKey = trigger.keys.any { it is KeyEventTriggerKey && it.requiresIme }
182174

183175
when {
@@ -214,16 +206,17 @@ class OnboardingTipDelegateImpl @Inject constructor(
214206
triggerTip.value = tipModel
215207
}
216208

217-
trigger.keys.isNotEmpty() && !shownTriggerConstraintsTip -> {
218-
val tipModel = OnboardingTipModel(
219-
id = TRIGGER_CONSTRAINTS_TIP_ID,
220-
title = getString(R.string.trigger_constraints_tip_title),
221-
message = getString(R.string.trigger_constraints_tip_text),
222-
isDismissable = true,
223-
)
224-
225-
triggerTip.value = tipModel
226-
}
209+
// DISABLE UNTIL PRO MODE IS STABLE
210+
// hasVolumeKey && !shownVolumeButtonsProModeTip -> {
211+
// val tip = OnboardingTipModel(
212+
// id = VOLUME_BUTTONS_PRO_MODE_TIP_ID,
213+
// title = getString(R.string.tip_volume_buttons_pro_mode_title),
214+
// message = getString(R.string.tip_volume_buttons_pro_mode_text),
215+
// isDismissable = true,
216+
// buttonText = getString(R.string.tip_volume_buttons_pro_mode_button),
217+
// )
218+
// triggerTip.value = tip
219+
// }
227220

228221
hasCapsLockKey && !shownCapsLockProModeTip -> {
229222
val tip = OnboardingTipModel(
@@ -256,12 +249,58 @@ class OnboardingTipDelegateImpl @Inject constructor(
256249
triggerTip.value = tip
257250
}
258251

252+
// Adding a constraint should be the lowest priority
253+
trigger.keys.isNotEmpty() && !shownTriggerConstraintsTip -> {
254+
val tipModel = OnboardingTipModel(
255+
id = TRIGGER_CONSTRAINTS_TIP_ID,
256+
title = getString(R.string.trigger_constraints_tip_title),
257+
message = getString(R.string.trigger_constraints_tip_text),
258+
isDismissable = true,
259+
)
260+
261+
triggerTip.value = tipModel
262+
}
263+
259264
else -> {
260265
triggerTip.value = null
261266
}
262267
}
263268
}
264269

270+
override fun neverShowTipAgain(tipId: String) {
271+
when (tipId) {
272+
PARALLEL_TRIGGER_TIP_ID -> {
273+
shownParallelTriggerOrderExplanation = true
274+
}
275+
276+
SEQUENCE_TRIGGER_TIP_ID -> {
277+
shownSequenceTriggerExplanation = true
278+
}
279+
280+
TRIGGER_CONSTRAINTS_TIP_ID -> {
281+
shownTriggerConstraintsTip = true
282+
}
283+
284+
CAPS_LOCK_PRO_MODE_COMPATIBILITY_TIP_ID -> {
285+
shownCapsLockProModeTip = true
286+
}
287+
288+
VOLUME_BUTTONS_PRO_MODE_TIP_ID -> {
289+
shownVolumeButtonsProModeTip = true
290+
}
291+
292+
SCREEN_PINNING_TIP_ID -> {
293+
shownScreenPinningTip = true
294+
}
295+
296+
IME_DETECTION_TIP_ID -> {
297+
shownImeDetectionTip = true
298+
}
299+
300+
// POWER_BUTTON_EMERGENCY_TIP_ID doesn't need preference setting as it's non-dismissable
301+
}
302+
}
303+
265304
private fun onCollectActions(actionList: List<Action>) {
266305
val hasRingerModeAction = actionList.any { action ->
267306
when (action.data) {
@@ -294,4 +333,5 @@ interface OnboardingTipDelegate {
294333
fun onTriggerTipDismissClick()
295334
fun onActionTipDismissClick()
296335
fun onTipButtonClick(tipId: String)
336+
fun neverShowTipAgain(tipId: String)
297337
}

base/src/main/java/io/github/sds100/keymapper/base/trigger/BaseConfigTriggerViewModel.kt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.github.sds100.keymapper.base.trigger
22

3+
import android.view.KeyEvent
34
import androidx.compose.runtime.getValue
45
import androidx.compose.runtime.mutableStateOf
56
import androidx.compose.runtime.setValue
@@ -381,6 +382,10 @@ abstract class BaseConfigTriggerViewModel(
381382
product = key.device.product,
382383
),
383384
)
385+
386+
if (key.keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || key.keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
387+
neverShowTipAgain(OnboardingTipDelegateImpl.VOLUME_BUTTONS_PRO_MODE_TIP_ID)
388+
}
384389
}
385390

386391
fun onParallelRadioButtonChecked() {
@@ -488,8 +493,14 @@ abstract class BaseConfigTriggerViewModel(
488493
}
489494

490495
override fun onTipButtonClick(tipId: String) {
491-
if (tipId == OnboardingTipDelegateImpl.CAPS_LOCK_PRO_MODE_COMPATIBILITY_TIP_ID) {
492-
showTriggerSetup(TriggerSetupShortcut.KEYBOARD, forceProMode = true)
496+
when (tipId) {
497+
OnboardingTipDelegateImpl.CAPS_LOCK_PRO_MODE_COMPATIBILITY_TIP_ID -> {
498+
showTriggerSetup(TriggerSetupShortcut.KEYBOARD, forceProMode = true)
499+
}
500+
501+
OnboardingTipDelegateImpl.VOLUME_BUTTONS_PRO_MODE_TIP_ID -> {
502+
showTriggerSetup(TriggerSetupShortcut.VOLUME, forceProMode = true)
503+
}
493504
}
494505
}
495506

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,8 +1349,11 @@
13491349
<string name="floating_button_text_key_map_list_item">Floating button %s (%s)</string>
13501350
<string name="deleted_floating_button_text_key_map_list_item">Deleted floating button</string>
13511351
<string name="tip_caps_lock_pro_mode_title">Better Caps Lock compatibility</string>
1352-
<string name="tip_caps_lock_pro_mode_text">PRO mode provides better compatibility for Caps Lock remapping. Please record the trigger again with PRO mode.</string>
1353-
<string name="tip_caps_lock_pro_mode_button">Record again</string>
1352+
<string name="tip_caps_lock_pro_mode_text">PRO mode provides better compatibility for Caps Lock remapping. Tap \'Use PRO mode\' and record it again.</string>
1353+
<string name="tip_caps_lock_pro_mode_button">Use PRO mode</string>
1354+
<string name="tip_volume_buttons_pro_mode_title">Screen off remapping?</string>
1355+
<string name="tip_volume_buttons_pro_mode_text">Use PRO mode if you want your trigger to work when the screen is off. Tap \'Use PRO mode\' and record it again.</string>
1356+
<string name="tip_volume_buttons_pro_mode_button">Use PRO mode</string>
13541357
<string name="tip_screen_pinning_title">App pinning warning</string>
13551358
<string name="tip_screen_pinning_text">Using the back button as a trigger may conflict with app pinning, causing a black screen on unlock. A reboot will fix it.</string>
13561359
<string name="tip_ime_detection_title">Keyboard icon</string>

data/src/main/java/io/github/sds100/keymapper/data/Keys.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ object Keys {
5757
booleanPreferencesKey("key_shown_trigger_constraints_tip")
5858
val shownCapsLockProModeTip =
5959
booleanPreferencesKey("key_shown_caps_lock_pro_mode_compatibility_tip")
60+
val shownVolumeButtonsProModeTip =
61+
booleanPreferencesKey("key_shown_volume_buttons_pro_mode_tip")
6062
val shownScreenPinningTip =
6163
booleanPreferencesKey("key_shown_screen_pinning_tip")
6264
val shownRingerModeTip =

0 commit comments

Comments
 (0)