mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
Add one-pod mode for reactions
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package eu.darken.capod.pods.core
|
||||
|
||||
interface HasDualEarDetection : HasEarDetection {
|
||||
|
||||
val isLeftPodInEar: Boolean
|
||||
|
||||
val isRightPodInEar: Boolean
|
||||
|
||||
val isEitherPodInEar: Boolean
|
||||
get() = isLeftPodInEar || isRightPodInEar
|
||||
|
||||
override val isBeingWorn: Boolean
|
||||
get() = isLeftPodInEar && isRightPodInEar
|
||||
|
||||
}
|
||||
@@ -8,11 +8,11 @@ import eu.darken.capod.common.isBitSet
|
||||
import eu.darken.capod.common.lowerNibble
|
||||
import eu.darken.capod.common.upperNibble
|
||||
import eu.darken.capod.pods.core.HasCase
|
||||
import eu.darken.capod.pods.core.HasDualEarDetection
|
||||
import eu.darken.capod.pods.core.HasDualPods
|
||||
import eu.darken.capod.pods.core.HasDualPods.Pod
|
||||
import eu.darken.capod.pods.core.HasEarDetection
|
||||
|
||||
interface DualApplePods : ApplePods, HasDualPods, HasEarDetection, HasCase {
|
||||
interface DualApplePods : ApplePods, HasDualPods, HasDualEarDetection, HasCase {
|
||||
|
||||
val microPhonePod: Pod
|
||||
get() = when (rawStatus.isBitSet(5)) {
|
||||
@@ -53,22 +53,18 @@ interface DualApplePods : ApplePods, HasDualPods, HasEarDetection, HasCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val isLeftPodInEar: Boolean
|
||||
override val isLeftPodInEar: Boolean
|
||||
get() = when (microPhonePod) {
|
||||
Pod.LEFT -> rawStatus.isBitSet(1)
|
||||
Pod.RIGHT -> rawStatus.isBitSet(3)
|
||||
}
|
||||
|
||||
val isRightPodInEar: Boolean
|
||||
override val isRightPodInEar: Boolean
|
||||
get() = when (microPhonePod) {
|
||||
Pod.LEFT -> rawStatus.isBitSet(3)
|
||||
Pod.RIGHT -> rawStatus.isBitSet(1)
|
||||
}
|
||||
|
||||
override val isBeingWorn: Boolean
|
||||
get() = isLeftPodInEar && isRightPodInEar
|
||||
|
||||
val isLeftPodCharging: Boolean
|
||||
get() = when (microPhonePod) {
|
||||
Pod.LEFT -> rawCaseBattery.upperNibble.isBitSet(0)
|
||||
|
||||
@@ -8,6 +8,7 @@ import eu.darken.capod.common.debug.logging.logTag
|
||||
import eu.darken.capod.common.flow.setupCommonEventHandlers
|
||||
import eu.darken.capod.main.core.GeneralSettings
|
||||
import eu.darken.capod.monitor.core.PodMonitor
|
||||
import eu.darken.capod.pods.core.HasDualEarDetection
|
||||
import eu.darken.capod.pods.core.HasEarDetection
|
||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||
import eu.darken.capod.reaction.settings.ReactionSettings
|
||||
@@ -71,7 +72,13 @@ class AutoConnect @Inject constructor(
|
||||
else -> true
|
||||
}
|
||||
AutoConnectCondition.IN_EAR -> when (mainDevice) {
|
||||
is HasEarDetection -> mainDevice.isBeingWorn
|
||||
is HasEarDetection -> {
|
||||
if (mainDevice is HasDualEarDetection && reactionSettings.onePodMode.value) {
|
||||
mainDevice.isEitherPodInEar
|
||||
} else {
|
||||
mainDevice.isBeingWorn
|
||||
}
|
||||
}
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import eu.darken.capod.common.debug.logging.logTag
|
||||
import eu.darken.capod.common.flow.setupCommonEventHandlers
|
||||
import eu.darken.capod.common.flow.withPrevious
|
||||
import eu.darken.capod.monitor.core.PodMonitor
|
||||
import eu.darken.capod.pods.core.HasDualEarDetection
|
||||
import eu.darken.capod.pods.core.HasEarDetection
|
||||
import eu.darken.capod.reaction.settings.ReactionSettings
|
||||
import kotlinx.coroutines.flow.*
|
||||
@@ -25,7 +26,8 @@ class PlayPause @Inject constructor(
|
||||
fun monitor() = combine(
|
||||
reactionSettings.autoPlay.flow,
|
||||
reactionSettings.autoPause.flow,
|
||||
) { play, pause -> play || pause }
|
||||
reactionSettings.onePodMode.flow,
|
||||
) { play, pause, _ -> play || pause }
|
||||
.flatMapLatest { if (it) bluetoothManager.connectedDevices() else emptyFlow() }
|
||||
.flatMapLatest {
|
||||
if (it.isEmpty()) {
|
||||
@@ -42,7 +44,28 @@ class PlayPause @Inject constructor(
|
||||
if (previous is HasEarDetection && current is HasEarDetection) {
|
||||
log(TAG, VERBOSE) { "previous=${previous.isBeingWorn}, current=${current.isBeingWorn}" }
|
||||
log(TAG, VERBOSE) { "previous-id=${previous.identifier}, current-id=${current.identifier}" }
|
||||
if (previous.identifier == current.identifier && previous.isBeingWorn != current.isBeingWorn) {
|
||||
if (previous.identifier != current.identifier) {
|
||||
return@onEach
|
||||
}
|
||||
|
||||
if (previous is HasDualEarDetection && current is HasDualEarDetection && reactionSettings.onePodMode.value) {
|
||||
log(TAG) { "Ear status changed for dual pod device in single pod mode." }
|
||||
val previousWorn = previous.isEitherPodInEar
|
||||
val currentWorn = current.isEitherPodInEar
|
||||
if (!previousWorn && currentWorn && !mediaControl.isPlaying) {
|
||||
if (reactionSettings.autoPlay.value) {
|
||||
mediaControl.sendPlay()
|
||||
} else {
|
||||
log(TAG) { "autoPlay is disabled" }
|
||||
}
|
||||
} else if (!currentWorn && previousWorn && mediaControl.isPlaying) {
|
||||
if (reactionSettings.autoPause.value) {
|
||||
mediaControl.sendPause()
|
||||
} else {
|
||||
log(TAG) { "autoPause is disabled" }
|
||||
}
|
||||
}
|
||||
} else if (previous.isBeingWorn != current.isBeingWorn) {
|
||||
log(TAG) { "Ear status changed for monitored device." }
|
||||
if (current.isBeingWorn && !mediaControl.isPlaying) {
|
||||
if (reactionSettings.autoPlay.value) {
|
||||
|
||||
@@ -47,11 +47,17 @@ class ReactionSettings @Inject constructor(
|
||||
false
|
||||
)
|
||||
|
||||
val onePodMode = preferences.createFlowPreference(
|
||||
"reaction.onepod.enabled",
|
||||
false
|
||||
)
|
||||
|
||||
override val preferenceDataStore: PreferenceDataStore = PreferenceStoreMapper(
|
||||
autoPause,
|
||||
autoPlay,
|
||||
autoConnect,
|
||||
autoConnectCondition,
|
||||
showPopUpOnCaseOpen,
|
||||
onePodMode,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM14,17h-2L12,9h-2L10,7h4v10z" />
|
||||
</vector>
|
||||
@@ -132,4 +132,6 @@
|
||||
<string name="overview_bluetooth_disabled_description">Bluetooth is disabled, enable it ;).</string>
|
||||
<string name="help_translate_label">Translation</string>
|
||||
<string name="help_translate_description">Help translate this into your favorite language.</string>
|
||||
<string name="settings_onepod_mode_label">One pod mode</string>
|
||||
<string name="settings_onepod_mode_description">Wearing both pods is not required, wearing a single pod is sufficient to trigger reactions.</string>
|
||||
</resources>
|
||||
@@ -1,6 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<CheckBoxPreference
|
||||
android:icon="@drawable/ic_baseline_looks_one_24"
|
||||
android:key="reaction.onepod.enabled"
|
||||
android:summary="@string/settings_onepod_mode_description"
|
||||
android:title="@string/settings_onepod_mode_label" />
|
||||
|
||||
|
||||
<CheckBoxPreference
|
||||
android:icon="@drawable/ic_baseline_play_circle_24"
|
||||
android:key="reaction.autoplay.enabled"
|
||||
|
||||
Reference in New Issue
Block a user