Skip to content

Commit 8b4271a

Browse files
committed
#1902 feat: add toggle next to record trigger button to use PRO mode
1 parent 57b9edb commit 8b4271a

File tree

10 files changed

+424
-24
lines changed

10 files changed

+424
-24
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- #1491 action to toggle/enable/disable hotspot.
99
- #1414 constraint for when the keyboard is showing.
1010
- #1900 log to logcat if extra logging is enabled.
11+
- #1902 add toggle next to record trigger button to use PRO mode.
1112

1213
## Bug fixes
1314

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
@@ -16,6 +16,7 @@ import io.github.sds100.keymapper.base.trigger.TriggerSetupShortcut
1616
import io.github.sds100.keymapper.base.utils.navigation.NavigationProvider
1717
import io.github.sds100.keymapper.base.utils.ui.DialogProvider
1818
import io.github.sds100.keymapper.base.utils.ui.ResourceProvider
19+
import io.github.sds100.keymapper.sysbridge.manager.SystemBridgeConnectionManager
1920
import javax.inject.Inject
2021
import kotlinx.coroutines.launch
2122

@@ -27,6 +28,7 @@ class ConfigTriggerViewModel @Inject constructor(
2728
private val createKeyMapShortcut: CreateKeyMapShortcutUseCase,
2829
private val displayKeyMap: DisplayKeyMapUseCase,
2930
private val fingerprintGesturesSupported: FingerprintGesturesSupportedUseCase,
31+
private val systemBridgeConnectionManager: SystemBridgeConnectionManager,
3032
setupAccessibilityServiceDelegate: SetupAccessibilityServiceDelegate,
3133
onboardingTipDelegate: OnboardingTipDelegate,
3234
triggerSetupDelegate: TriggerSetupDelegate,
@@ -41,6 +43,7 @@ class ConfigTriggerViewModel @Inject constructor(
4143
displayKeyMap = displayKeyMap,
4244
fingerprintGesturesSupported = fingerprintGesturesSupported,
4345
setupAccessibilityServiceDelegate = setupAccessibilityServiceDelegate,
46+
systemBridgeConnectionManager = systemBridgeConnectionManager,
4447
onboardingTipDelegate = onboardingTipDelegate,
4548
triggerSetupDelegate = triggerSetupDelegate,
4649
resourceProvider = resourceProvider,

base/src/main/java/io/github/sds100/keymapper/base/promode/ProModeViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import io.github.sds100.keymapper.base.utils.ui.DialogProvider
1313
import io.github.sds100.keymapper.base.utils.ui.ResourceProvider
1414
import io.github.sds100.keymapper.common.utils.State
1515
import io.github.sds100.keymapper.common.utils.valueOrNull
16+
import javax.inject.Inject
1617
import kotlinx.coroutines.ExperimentalCoroutinesApi
1718
import kotlinx.coroutines.delay
1819
import kotlinx.coroutines.flow.Flow
@@ -25,7 +26,6 @@ import kotlinx.coroutines.flow.flow
2526
import kotlinx.coroutines.flow.flowOf
2627
import kotlinx.coroutines.flow.stateIn
2728
import kotlinx.coroutines.launch
28-
import javax.inject.Inject
2929

3030
@HiltViewModel
3131
class ProModeViewModel @Inject constructor(

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

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

3+
import android.os.Build
34
import android.view.KeyEvent
45
import androidx.compose.runtime.getValue
56
import androidx.compose.runtime.mutableStateOf
@@ -36,6 +37,8 @@ import io.github.sds100.keymapper.common.utils.InputDeviceUtils
3637
import io.github.sds100.keymapper.common.utils.KMResult
3738
import io.github.sds100.keymapper.common.utils.State
3839
import io.github.sds100.keymapper.common.utils.mapData
40+
import io.github.sds100.keymapper.sysbridge.manager.SystemBridgeConnectionManager
41+
import io.github.sds100.keymapper.sysbridge.manager.SystemBridgeConnectionState
3942
import kotlinx.coroutines.flow.MutableStateFlow
4043
import kotlinx.coroutines.flow.SharingStarted
4144
import kotlinx.coroutines.flow.StateFlow
@@ -59,6 +62,7 @@ abstract class BaseConfigTriggerViewModel(
5962
private val displayKeyMap: DisplayKeyMapUseCase,
6063
private val fingerprintGesturesSupported: FingerprintGesturesSupportedUseCase,
6164
private val setupAccessibilityServiceDelegate: SetupAccessibilityServiceDelegate,
65+
private val systemBridgeConnectionManager: SystemBridgeConnectionManager,
6266
onboardingTipDelegate: OnboardingTipDelegate,
6367
triggerSetupDelegate: TriggerSetupDelegate,
6468
resourceProvider: ResourceProvider,
@@ -75,6 +79,18 @@ abstract class BaseConfigTriggerViewModel(
7579
companion object {
7680
private const val DEVICE_ID_ANY = "any"
7781
private const val DEVICE_ID_INTERNAL = "internal"
82+
83+
fun buildProModeSwitchState(
84+
recordTriggerState: RecordTriggerState,
85+
isProModeRecordingEnabled: Boolean,
86+
systemBridgeState: SystemBridgeConnectionState,
87+
): ProModeRecordSwitchState {
88+
return ProModeRecordSwitchState(
89+
isVisible = systemBridgeState is SystemBridgeConnectionState.Connected,
90+
isChecked = isProModeRecordingEnabled,
91+
isEnabled = recordTriggerState !is RecordTriggerState.CountingDown,
92+
)
93+
}
7894
}
7995

8096
val optionsViewModel = ConfigKeyMapOptionsViewModel(
@@ -96,6 +112,29 @@ abstract class BaseConfigTriggerViewModel(
96112
RecordTriggerState.Idle,
97113
)
98114

115+
val proModeSwitchState: StateFlow<ProModeRecordSwitchState> =
116+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
117+
combine(
118+
recordTrigger.state,
119+
recordTrigger.isEvdevRecordingEnabled,
120+
systemBridgeConnectionManager.connectionState,
121+
Companion::buildProModeSwitchState,
122+
)
123+
.stateIn(
124+
viewModelScope,
125+
SharingStarted.Eagerly,
126+
ProModeRecordSwitchState(
127+
isVisible = false,
128+
isChecked = false,
129+
isEnabled = false,
130+
),
131+
)
132+
} else {
133+
MutableStateFlow(
134+
ProModeRecordSwitchState(isVisible = false, isChecked = false, isEnabled = false),
135+
)
136+
}
137+
99138
val showFingerprintGesturesShortcut: StateFlow<Boolean> =
100139
fingerprintGesturesSupported.isSupported.map { it ?: false }
101140
.stateIn(viewModelScope, SharingStarted.Lazily, false)
@@ -116,6 +155,10 @@ abstract class BaseConfigTriggerViewModel(
116155
private val midDot = getString(R.string.middot)
117156

118157
init {
158+
// Always disable when launching the trigger screen because recording with PRO mode should
159+
// only be used when necessary.
160+
recordTrigger.setEvdevRecordingEnabled(false)
161+
119162
// IMPORTANT! Do not flow on another thread because this causes the drag and drop
120163
// animations to be more janky.
121164
combine(
@@ -486,14 +529,17 @@ abstract class BaseConfigTriggerViewModel(
486529

487530
is RecordTriggerState.Completed,
488531
RecordTriggerState.Idle,
489-
-> recordTrigger.startRecording(enableEvdevRecording = false)
532+
-> recordTrigger.startRecording()
490533
}
491534

492535
// Show dialog if the accessibility service is disabled or crashed
493536
handleServiceEventResult(result)
494537
}
495538
}
496539

540+
fun onProModeSwitchChange(isChecked: Boolean) =
541+
recordTrigger.setEvdevRecordingEnabled(isChecked)
542+
497543
fun handleServiceEventResult(result: KMResult<*>) {
498544
if (result is AccessibilityServiceError) {
499545
showFixAccessibilityServiceDialog(result)

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

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ fun BaseTriggerScreen(
5959
val scope = rememberCoroutineScope()
6060
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
6161
val recordTriggerState by viewModel.recordTriggerState.collectAsStateWithLifecycle()
62+
val proModeSwitchState by viewModel.proModeSwitchState.collectAsStateWithLifecycle()
6263
val showFingerprintGestures: Boolean by
6364
viewModel.showFingerprintGesturesShortcut.collectAsStateWithLifecycle()
6465

@@ -133,9 +134,11 @@ fun BaseTriggerScreen(
133134
modifier = modifier,
134135
configState = state.data,
135136
recordTriggerState = recordTriggerState,
137+
proModeSwitchState = proModeSwitchState,
136138
onRemoveClick = viewModel::onRemoveKeyClick,
137139
onEditClick = viewModel::onTriggerKeyOptionsClick,
138140
onRecordTriggerClick = viewModel::onRecordTriggerButtonClick,
141+
onProModeSwitchChange = viewModel::onProModeSwitchChange,
139142
onAdvancedTriggersClick = viewModel::onAdvancedTriggersClick,
140143
onSelectClickType = viewModel::onClickTypeRadioButtonChecked,
141144
onSelectParallelMode = viewModel::onParallelRadioButtonChecked,
@@ -153,9 +156,11 @@ fun BaseTriggerScreen(
153156
modifier = modifier,
154157
configState = state.data,
155158
recordTriggerState = recordTriggerState,
159+
proModeSwitchState = proModeSwitchState,
156160
onRemoveClick = viewModel::onRemoveKeyClick,
157161
onEditClick = viewModel::onTriggerKeyOptionsClick,
158162
onRecordTriggerClick = viewModel::onRecordTriggerButtonClick,
163+
onProModeSwitchChange = viewModel::onProModeSwitchChange,
159164
onAdvancedTriggersClick = viewModel::onAdvancedTriggersClick,
160165
onSelectClickType = viewModel::onClickTypeRadioButtonChecked,
161166
onSelectParallelMode = viewModel::onParallelRadioButtonChecked,
@@ -200,12 +205,14 @@ private fun TriggerScreenVertical(
200205
modifier: Modifier = Modifier,
201206
configState: ConfigTriggerState,
202207
recordTriggerState: RecordTriggerState,
208+
proModeSwitchState: ProModeRecordSwitchState,
203209
onRemoveClick: (String) -> Unit = {},
204210
onEditClick: (String) -> Unit = {},
205211
onSelectClickType: (ClickType) -> Unit = {},
206212
onSelectParallelMode: () -> Unit = {},
207213
onSelectSequenceMode: () -> Unit = {},
208214
onRecordTriggerClick: () -> Unit = {},
215+
onProModeSwitchChange: (Boolean) -> Unit = {},
209216
onAdvancedTriggersClick: () -> Unit = {},
210217
onMoveTriggerKey: (fromIndex: Int, toIndex: Int) -> Unit = { _, _ -> },
211218
onFixErrorClick: (TriggerError) -> Unit = {},
@@ -232,6 +239,8 @@ private fun TriggerScreenVertical(
232239
modifier = Modifier.padding(start = 8.dp, end = 8.dp, bottom = 8.dp),
233240
onRecordTriggerClick = onRecordTriggerClick,
234241
recordTriggerState = recordTriggerState,
242+
proModeRecordSwitchState = proModeSwitchState,
243+
onProModeSwitchChange = onProModeSwitchChange,
235244
onAdvancedTriggersClick = onAdvancedTriggersClick,
236245
)
237246
}
@@ -281,21 +290,23 @@ private fun TriggerScreenVertical(
281290
isCompact = isCompact,
282291
)
283292
}
284-
}
285-
}
286293

287-
if (!isCompact) {
288-
Spacer(Modifier.height(8.dp))
289-
}
294+
if (!isCompact) {
295+
Spacer(Modifier.height(8.dp))
296+
}
290297

291-
RecordTriggerButtonRow(
292-
modifier = Modifier
293-
.fillMaxWidth()
294-
.padding(start = 8.dp, end = 8.dp, bottom = 8.dp),
295-
onRecordTriggerClick = onRecordTriggerClick,
296-
recordTriggerState = recordTriggerState,
297-
onAdvancedTriggersClick = onAdvancedTriggersClick,
298-
)
298+
RecordTriggerButtonRow(
299+
modifier = Modifier
300+
.fillMaxWidth()
301+
.padding(start = 8.dp, end = 8.dp, bottom = 8.dp),
302+
onRecordTriggerClick = onRecordTriggerClick,
303+
recordTriggerState = recordTriggerState,
304+
proModeRecordSwitchState = proModeSwitchState,
305+
onProModeSwitchChange = onProModeSwitchChange,
306+
onAdvancedTriggersClick = onAdvancedTriggersClick,
307+
)
308+
}
309+
}
299310
}
300311
}
301312
}
@@ -305,12 +316,14 @@ private fun TriggerScreenHorizontal(
305316
modifier: Modifier = Modifier,
306317
configState: ConfigTriggerState,
307318
recordTriggerState: RecordTriggerState,
319+
proModeSwitchState: ProModeRecordSwitchState,
308320
onRemoveClick: (String) -> Unit = {},
309321
onEditClick: (String) -> Unit = {},
310322
onSelectClickType: (ClickType) -> Unit = {},
311323
onSelectParallelMode: () -> Unit = {},
312324
onSelectSequenceMode: () -> Unit = {},
313325
onRecordTriggerClick: () -> Unit = {},
326+
onProModeSwitchChange: (Boolean) -> Unit = {},
314327
onAdvancedTriggersClick: () -> Unit = {},
315328
onMoveTriggerKey: (fromIndex: Int, toIndex: Int) -> Unit = { _, _ -> },
316329
onFixErrorClick: (TriggerError) -> Unit = {},
@@ -336,6 +349,8 @@ private fun TriggerScreenHorizontal(
336349
.padding(start = 8.dp, end = 8.dp, bottom = 8.dp),
337350
onRecordTriggerClick = onRecordTriggerClick,
338351
recordTriggerState = recordTriggerState,
352+
proModeRecordSwitchState = proModeSwitchState,
353+
onProModeSwitchChange = onProModeSwitchChange,
339354
onAdvancedTriggersClick = onAdvancedTriggersClick,
340355
)
341356
}
@@ -403,6 +418,8 @@ private fun TriggerScreenHorizontal(
403418
modifier = Modifier.padding(start = 8.dp, end = 8.dp, bottom = 8.dp),
404419
onRecordTriggerClick = onRecordTriggerClick,
405420
recordTriggerState = recordTriggerState,
421+
proModeRecordSwitchState = proModeSwitchState,
422+
onProModeSwitchChange = onProModeSwitchChange,
406423
onAdvancedTriggersClick = onAdvancedTriggersClick,
407424
)
408425
}
@@ -608,6 +625,11 @@ private fun VerticalPreview() {
608625
TriggerScreenVertical(
609626
configState = previewState,
610627
recordTriggerState = RecordTriggerState.Idle,
628+
proModeSwitchState = ProModeRecordSwitchState(
629+
isVisible = true,
630+
isChecked = false,
631+
isEnabled = true,
632+
),
611633
discoverScreenContent = {
612634
TriggerDiscoverScreen()
613635
},
@@ -622,6 +644,11 @@ private fun VerticalPreviewTiny() {
622644
TriggerScreenVertical(
623645
configState = previewState,
624646
recordTriggerState = RecordTriggerState.Idle,
647+
proModeSwitchState = ProModeRecordSwitchState(
648+
isVisible = true,
649+
isChecked = true,
650+
isEnabled = true,
651+
),
625652
discoverScreenContent = {
626653
TriggerDiscoverScreen()
627654
},
@@ -636,6 +663,11 @@ private fun VerticalEmptyPreview() {
636663
TriggerScreenVertical(
637664
configState = ConfigTriggerState.Empty,
638665
recordTriggerState = RecordTriggerState.Idle,
666+
proModeSwitchState = ProModeRecordSwitchState(
667+
isVisible = false,
668+
isChecked = false,
669+
isEnabled = true,
670+
),
639671
discoverScreenContent = {
640672
TriggerDiscoverScreen()
641673
},
@@ -650,6 +682,11 @@ private fun VerticalEmptyDarkPreview() {
650682
TriggerScreenVertical(
651683
configState = ConfigTriggerState.Empty,
652684
recordTriggerState = RecordTriggerState.Idle,
685+
proModeSwitchState = ProModeRecordSwitchState(
686+
isVisible = true,
687+
isChecked = true,
688+
isEnabled = false,
689+
),
653690
discoverScreenContent = {
654691
TriggerDiscoverScreen()
655692
},
@@ -664,6 +701,11 @@ private fun HorizontalPreview() {
664701
TriggerScreenHorizontal(
665702
configState = previewState,
666703
recordTriggerState = RecordTriggerState.Idle,
704+
proModeSwitchState = ProModeRecordSwitchState(
705+
isVisible = true,
706+
isChecked = false,
707+
isEnabled = true,
708+
),
667709
discoverScreenContent = {
668710
TriggerDiscoverScreen()
669711
},
@@ -693,6 +735,11 @@ private fun HorizontalEmptyPreview() {
693735
TriggerScreenHorizontal(
694736
configState = ConfigTriggerState.Empty,
695737
recordTriggerState = RecordTriggerState.Idle,
738+
proModeSwitchState = ProModeRecordSwitchState(
739+
isVisible = true,
740+
isChecked = false,
741+
isEnabled = true,
742+
),
696743
discoverScreenContent = {
697744
TriggerDiscoverScreen()
698745
},
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.github.sds100.keymapper.base.trigger
2+
3+
data class ProModeRecordSwitchState(
4+
val isVisible: Boolean,
5+
val isChecked: Boolean,
6+
val isEnabled: Boolean,
7+
)

0 commit comments

Comments
 (0)