mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
fix(settings): Show passive info when device is connected but AAP unavailable
This commit is contained in:
@@ -273,12 +273,20 @@ fun DeviceSettingsScreen(
|
||||
|
||||
// Not connected info — BLE live but no AAP connection
|
||||
if (device != null && device.ble != null && !device.isAapConnected && device.address != null) {
|
||||
item("not_connected_info") {
|
||||
NotConnectedCard(
|
||||
isNudgeAvailable = state.isNudgeAvailable,
|
||||
isForceConnecting = state.isForceConnecting,
|
||||
onConnect = onForceConnect,
|
||||
)
|
||||
if (state.isClassicallyConnected) {
|
||||
// Device is connected for audio but AAP isn't available — show passive info
|
||||
item("aap_unavailable_info") {
|
||||
AapUnavailableCard()
|
||||
}
|
||||
} else {
|
||||
// Device is nearby but not connected — prompt user to connect
|
||||
item("not_connected_info") {
|
||||
NotConnectedCard(
|
||||
isNudgeAvailable = state.isNudgeAvailable,
|
||||
isForceConnecting = state.isForceConnecting,
|
||||
onConnect = onForceConnect,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -827,6 +835,29 @@ private fun NotConnectedCard(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AapUnavailableCard() {
|
||||
ElevatedCard(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
elevation = CardDefaults.elevatedCardElevation(defaultElevation = 1.dp),
|
||||
) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text(
|
||||
text = stringResource(R.string.device_settings_aap_unavailable_label),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = stringResource(R.string.device_settings_aap_unavailable_description),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun InfoRow(label: String, value: String, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
|
||||
@@ -80,13 +80,16 @@ class DeviceSettingsViewModel @Inject constructor(
|
||||
deviceForProfile(profileId),
|
||||
upgradeRepo.upgradeInfo,
|
||||
isForceConnecting,
|
||||
) { _, device, upgrade, forcing ->
|
||||
bluetoothManager.connectedDevices,
|
||||
) { _, device, upgrade, forcing, connectedDevices ->
|
||||
val connectedAddresses = connectedDevices.map { it.address }.toSet()
|
||||
State(
|
||||
device = device,
|
||||
now = Instant.now(),
|
||||
isPro = upgrade.isPro,
|
||||
isNudgeAvailable = bluetoothManager.isNudgeAvailable,
|
||||
isForceConnecting = forcing,
|
||||
isClassicallyConnected = device?.address?.let { it in connectedAddresses } == true,
|
||||
)
|
||||
}
|
||||
}.asLiveState()
|
||||
@@ -108,6 +111,7 @@ class DeviceSettingsViewModel @Inject constructor(
|
||||
val isPro: Boolean = false,
|
||||
val isNudgeAvailable: Boolean = true,
|
||||
val isForceConnecting: Boolean = false,
|
||||
val isClassicallyConnected: Boolean = false,
|
||||
) {
|
||||
val reactions: ReactionConfig get() = device?.reactions ?: ReactionConfig()
|
||||
}
|
||||
|
||||
@@ -437,6 +437,8 @@
|
||||
<string name="device_settings_not_connected_description">This device is nearby but not connected to this phone. Connect to access settings and controls.</string>
|
||||
<string name="device_settings_not_connected_connect_action">Connect</string>
|
||||
<string name="device_settings_not_connected_open_settings_action">Open Bluetooth Settings</string>
|
||||
<string name="device_settings_aap_unavailable_label">Advanced settings unavailable</string>
|
||||
<string name="device_settings_aap_unavailable_description">This phone\'s Bluetooth does not support the connection required for advanced AirPods settings.</string>
|
||||
<string name="device_settings_category_sound_label">Sound</string>
|
||||
<string name="device_settings_category_controls_label">Controls</string>
|
||||
<string name="device_settings_nc_one_airpod_label">Noise Cancellation with One AirPod</string>
|
||||
|
||||
+23
@@ -53,6 +53,7 @@ class DeviceSettingsViewModelTest : BaseTest() {
|
||||
|
||||
private lateinit var devicesFlow: MutableStateFlow<List<PodDevice>>
|
||||
private lateinit var upgradeInfoFlow: MutableStateFlow<UpgradeRepo.Info>
|
||||
private lateinit var connectedDevicesFlow: MutableStateFlow<List<BluetoothDevice2>>
|
||||
|
||||
private fun mockBondedDevice(address: BluetoothAddress): BluetoothDevice2 = mockk {
|
||||
every { this@mockk.address } returns address
|
||||
@@ -80,9 +81,11 @@ class DeviceSettingsViewModelTest : BaseTest() {
|
||||
upgradeRepo = mockk<UpgradeRepo>().also {
|
||||
every { it.upgradeInfo } returns upgradeInfoFlow
|
||||
}
|
||||
connectedDevicesFlow = MutableStateFlow(emptyList())
|
||||
bluetoothManager = mockk(relaxed = true) {
|
||||
every { isNudgeAvailable } returns true
|
||||
every { bondedDevices() } returns flowOf(emptySet())
|
||||
every { connectedDevices } returns connectedDevicesFlow
|
||||
}
|
||||
profilesRepo = mockk(relaxed = true)
|
||||
generalSettings = mockk(relaxed = true)
|
||||
@@ -275,4 +278,24 @@ class DeviceSettingsViewModelTest : BaseTest() {
|
||||
sendFailed.command shouldBe AapCommand.SetDeviceName("NewName")
|
||||
sendFailed.message shouldBe "socket closed"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isClassicallyConnected is true when device address is in connected devices`() = runTest(testDispatcher) {
|
||||
connectedDevicesFlow.value = listOf(mockBondedDevice(testAddress))
|
||||
|
||||
val vm = createViewModel()
|
||||
vm.initialize(testAddress)
|
||||
|
||||
vm.state.first().isClassicallyConnected shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isClassicallyConnected is false when device address is not in connected devices`() = runTest(testDispatcher) {
|
||||
connectedDevicesFlow.value = listOf(mockBondedDevice("XX:XX:XX:XX:XX:XX"))
|
||||
|
||||
val vm = createViewModel()
|
||||
vm.initialize(testAddress)
|
||||
|
||||
vm.state.first().isClassicallyConnected shouldBe false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ class AutoConnectLogicTest : BaseTest() {
|
||||
autoConnect = AutoConnect(
|
||||
bluetoothManager = mockk(relaxed = true),
|
||||
deviceMonitor = mockk(relaxed = true),
|
||||
generalSettings = mockk(relaxed = true),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user