Merge pull request #2655 from vitorpamplona/claude/mute-unmute-icons-Lcxuc

feat(nests): use mic icons for talk / stop talking
This commit is contained in:
Vitor Pamplona
2026-04-30 08:49:39 -04:00
committed by GitHub
@@ -31,14 +31,17 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.material3.AssistChip import androidx.compose.material3.AssistChip
import androidx.compose.material3.AssistChipDefaults import androidx.compose.material3.AssistChipDefaults
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.FilledIconButton
import androidx.compose.material3.FilledTonalIconButton import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.FilledTonalIconToggleButton import androidx.compose.material3.FilledTonalIconToggleButton
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
@@ -263,7 +266,11 @@ private fun OnStageControls(
when (val broadcast = ui.broadcast) { when (val broadcast = ui.broadcast) {
BroadcastUiState.Idle -> { BroadcastUiState.Idle -> {
Button(onClick = { // Mic OFF visual: filled primary button signals "tap to go live".
// Sized larger than the surrounding 40.dp icon buttons so the
// mic state is unmistakable at a glance.
FilledIconButton(
onClick = {
val granted = val granted =
ContextCompat.checkSelfPermission( ContextCompat.checkSelfPermission(
context, context,
@@ -274,8 +281,19 @@ private fun OnStageControls(
} else { } else {
permissionLauncher.launch(Manifest.permission.RECORD_AUDIO) permissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
} }
}) { },
Text(stringRes(R.string.nest_talk)) modifier = Modifier.size(56.dp),
colors =
IconButtonDefaults.filledIconButtonColors(
containerColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary,
),
) {
Icon(
symbol = MaterialSymbols.MicOff,
contentDescription = stringRes(R.string.nest_talk),
modifier = Modifier.size(28.dp),
)
} }
OutlinedButton(onClick = { viewModel.setOnStage(false) }) { OutlinedButton(onClick = { viewModel.setOnStage(false) }) {
Text(stringRes(R.string.nest_leave_stage)) Text(stringRes(R.string.nest_leave_stage))
@@ -336,8 +354,23 @@ private fun OnStageControls(
), ),
) )
} }
OutlinedButton(onClick = { viewModel.stopBroadcast() }) { // Mic ON visual: filled error-color button screams "MIC IS LIVE,
Text(stringRes(R.string.nest_stop_talking)) // tap to stop transmitting". Same large footprint as the Idle
// mic button so the state swap is impossible to miss.
FilledIconButton(
onClick = { viewModel.stopBroadcast() },
modifier = Modifier.size(56.dp),
colors =
IconButtonDefaults.filledIconButtonColors(
containerColor = MaterialTheme.colorScheme.error,
contentColor = MaterialTheme.colorScheme.onError,
),
) {
Icon(
symbol = MaterialSymbols.Mic,
contentDescription = stringRes(R.string.nest_stop_talking),
modifier = Modifier.size(28.dp),
)
} }
OutlinedButton(onClick = { OutlinedButton(onClick = {
viewModel.stopBroadcast() viewModel.stopBroadcast()
@@ -348,8 +381,20 @@ private fun OnStageControls(
} }
is BroadcastUiState.Failed -> { is BroadcastUiState.Failed -> {
Button(onClick = { viewModel.startBroadcast(speakerPubkeyHex) }) { FilledIconButton(
Text(stringRes(R.string.nest_talk)) onClick = { viewModel.startBroadcast(speakerPubkeyHex) },
modifier = Modifier.size(56.dp),
colors =
IconButtonDefaults.filledIconButtonColors(
containerColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary,
),
) {
Icon(
symbol = MaterialSymbols.MicOff,
contentDescription = stringRes(R.string.nest_talk),
modifier = Modifier.size(28.dp),
)
} }
} }
} }