Android: tap orb to dismiss talk mode with haptic feedback
Makes the talk orb tappable to disable voice mode - much easier to hit than the small button. Includes haptic feedback on tap.
This commit is contained in:
parent
e5198b8f31
commit
32cf8c3290
@ -271,6 +271,7 @@ fun RootScreen(viewModel: MainViewModel) {
|
|||||||
statusText = talkStatusText,
|
statusText = talkStatusText,
|
||||||
isListening = talkIsListening,
|
isListening = talkIsListening,
|
||||||
isSpeaking = talkIsSpeaking,
|
isSpeaking = talkIsSpeaking,
|
||||||
|
onDismiss = { viewModel.setTalkEnabled(false) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import androidx.compose.animation.core.infiniteRepeatable
|
|||||||
import androidx.compose.animation.core.rememberInfiniteTransition
|
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@ -18,11 +20,14 @@ import androidx.compose.material3.Surface
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Brush
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||||
|
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||||
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
@ -33,7 +38,9 @@ fun TalkOrbOverlay(
|
|||||||
isListening: Boolean,
|
isListening: Boolean,
|
||||||
isSpeaking: Boolean,
|
isSpeaking: Boolean,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
onDismiss: (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
|
val haptic = LocalHapticFeedback.current
|
||||||
val transition = rememberInfiniteTransition(label = "talk-orb")
|
val transition = rememberInfiniteTransition(label = "talk-orb")
|
||||||
val t by
|
val t by
|
||||||
transition.animateFloat(
|
transition.animateFloat(
|
||||||
@ -62,7 +69,19 @@ fun TalkOrbOverlay(
|
|||||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
) {
|
) {
|
||||||
Box(contentAlignment = Alignment.Center) {
|
Box(contentAlignment = Alignment.Center) {
|
||||||
Canvas(modifier = Modifier.size(360.dp)) {
|
Canvas(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(360.dp)
|
||||||
|
.clickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = null, // No ripple - the orb itself is the feedback
|
||||||
|
enabled = onDismiss != null,
|
||||||
|
onClick = {
|
||||||
|
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||||
|
onDismiss?.invoke()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
) {
|
||||||
val center = this.center
|
val center = this.center
|
||||||
val baseRadius = size.minDimension * 0.30f
|
val baseRadius = size.minDimension * 0.30f
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user