diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/HomeScreen.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/HomeScreen.kt
index a35639e..a3caa3b 100644
--- a/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/HomeScreen.kt
+++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/HomeScreen.kt
@@ -109,8 +109,6 @@ fun HomeScreen(
) {
Spacer(Modifier.height(16.dp))
StatusCard(status)
- Spacer(Modifier.height(16.dp))
- AudioSwitch()
if (live) BluetoothMissingCard()
if (live) BackgroundLocationCard()
BluetoothAddressCard()
@@ -315,34 +313,6 @@ private fun Arrow() = Icon(
tint = MaterialTheme.colorScheme.onSurfaceVariant,
)
-/**
- * Where the car's sound comes from, switchable in one tap from Home: Bluetooth, or through
- * Gearslip over the car link. It takes effect at once when a car is connected.
- */
-@Composable
-private fun AudioSwitch() {
- val pipe by app.seb3thehacker.gearslip.car.CarSettings.pipeAudio.collectAsState()
- val thisCar by app.seb3thehacker.gearslip.car.CarSettings.thisCarPipes.collectAsState()
- val through = pipe || thisCar
- Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
- Text(
- stringResource(R.string.car_audio),
- style = MaterialTheme.typography.labelLarge,
- color = MaterialTheme.colorScheme.primary,
- modifier = Modifier.padding(start = 4.dp),
- )
- androidx.compose.material3.SingleChoiceSegmentedButtonRow(Modifier.fillMaxWidth()) {
- listOf(false to R.string.guide_audio_bluetooth, true to R.string.guide_audio_usb).forEachIndexed { i, (value, label) ->
- SegmentedButton(
- selected = through == value,
- onClick = { app.seb3thehacker.gearslip.car.CarSettings.setPipeAudio(value) },
- shape = androidx.compose.material3.SegmentedButtonDefaults.itemShape(i, 2),
- ) { Text(stringResource(label), maxLines = 1) }
- }
- }
- }
-}
-
@Composable
private fun StatusCard(status: SessionStatus.Snapshot) {
val scheme = MaterialTheme.colorScheme
diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/SettingsScreen.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/SettingsScreen.kt
index 0f6222f..4daf347 100644
--- a/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/SettingsScreen.kt
+++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/SettingsScreen.kt
@@ -1,5 +1,8 @@
package app.seb3thehacker.gearslip.ui
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.selected
import androidx.compose.material.icons.filled.Create
import androidx.compose.ui.res.stringResource
@@ -250,6 +253,7 @@ private fun ConnectionSection() {
icon = Icons.Filled.Home,
trailing = { Switch(checked = launcher, onCheckedChange = null) },
)
+ CarAudioSetting()
var address by remember { mutableStateOf(CarBluetooth.typedAddress(context)) }
var editing by remember { mutableStateOf(false) }
SettingsRow(
@@ -275,6 +279,42 @@ private fun ConnectionSection() {
}
}
+/**
+ * Where the car's sound comes from: Bluetooth, or through Gearslip over the car link. Takes
+ * effect at once when a car is connected. The chosen pill is filled in the main colour, the
+ * other tonal, like the buttons on Home.
+ */
+@Composable
+private fun CarAudioSetting() {
+ val pipe by app.seb3thehacker.gearslip.car.CarSettings.pipeAudio.collectAsState()
+ val thisCar by app.seb3thehacker.gearslip.car.CarSettings.thisCarPipes.collectAsState()
+ val through = pipe || thisCar
+ val scheme = MaterialTheme.colorScheme
+ // Android won't let Gearslip capture navigation voices, only media, so they stay on the phone.
+ SettingsRow(
+ stringResource(R.string.car_audio),
+ subtitle = if (through) stringResource(R.string.home_audio_usb_warning) else null,
+ icon = app.seb3thehacker.gearslip.car.MediaIcons.MusicNote,
+ )
+ androidx.compose.foundation.layout.Row(
+ Modifier.fillMaxWidth().padding(start = 56.dp, end = 16.dp, bottom = 12.dp),
+ horizontalArrangement = androidx.compose.foundation.layout.Arrangement.spacedBy(8.dp),
+ ) {
+ listOf(false to R.string.guide_audio_bluetooth, true to R.string.guide_audio_usb).forEach { (value, label) ->
+ val chosen = through == value
+ androidx.compose.material3.Button(
+ onClick = { app.seb3thehacker.gearslip.car.CarSettings.setPipeAudio(value) },
+ colors = androidx.compose.material3.ButtonDefaults.buttonColors(
+ containerColor = if (chosen) scheme.primary else scheme.secondaryContainer,
+ contentColor = if (chosen) scheme.onPrimary else scheme.onSecondaryContainer,
+ ),
+ contentPadding = androidx.compose.foundation.layout.PaddingValues(horizontal = 12.dp),
+ modifier = Modifier.weight(1f).height(48.dp).semantics { selected = chosen },
+ ) { Text(stringResource(label), maxLines = 1) }
+ }
+ }
+}
+
/** The phone's Bluetooth address, typed in by hand: Android doesn't let apps read it. */
@Composable
internal fun AddressDialog(initial: String, onDismiss: () -> Unit, onSave: (String) -> Boolean) {
diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/UsageStatsChoices.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/UsageStatsChoices.kt
index 5c1df74..94b3728 100644
--- a/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/UsageStatsChoices.kt
+++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/UsageStatsChoices.kt
@@ -129,12 +129,15 @@ internal fun ColumnScope.UsageStatsRows() {
shape = MaterialTheme.shapes.medium,
modifier = Modifier.fillMaxWidth().padding(start = 16.dp, end = 16.dp, bottom = 16.dp),
) {
- Text(
- note,
- style = MaterialTheme.typography.bodySmall,
- fontFamily = FontFamily.Monospace,
- modifier = Modifier.padding(12.dp),
- )
+ // Selectable, so the phone's "id" can be copied into a request to see or delete its notes.
+ androidx.compose.foundation.text.selection.SelectionContainer {
+ Text(
+ note,
+ style = MaterialTheme.typography.bodySmall,
+ fontFamily = FontFamily.Monospace,
+ modifier = Modifier.padding(12.dp),
+ )
+ }
}
}
}
diff --git a/gearslip/src/main/res/values/strings.xml b/gearslip/src/main/res/values/strings.xml
index ac1f627..6a4225c 100644
--- a/gearslip/src/main/res/values/strings.xml
+++ b/gearslip/src/main/res/values/strings.xml
@@ -48,7 +48,8 @@
Recommended
No prompt each drive, and your map app\'s voice reaches the car.
Through Gearslip
- Clearer sound with no delay. Each drive, Android asks you to share your screen, which lets Gearslip send the sound.
+ Clearer sound with no delay, but your map app\'s spoken directions play on the phone, not in the car. Each drive, Android asks you to share your screen, which lets Gearslip send the sound.
+ Spoken directions from map apps play on the phone, not in the car. Choose Bluetooth to hear them in the car.
OPTIONAL
Already allowed.
Scroll for more ↓
@@ -239,7 +240,7 @@
Car audio
Bluetooth (Recommended)
No prompt each drive, and your map app\'s voice reaches the car
- Clearer sound with no delay. Each drive, Android asks you to share your screen, which lets Gearslip send the sound
+ Clearer sound with no delay, but map apps\' spoken directions play on the phone, not in the car. Each drive, Android asks you to share your screen, which lets Gearslip send the sound
Run the command in Help once, and Android stops asking.
Calls go over Bluetooth either way.