Skip to content

Commit aedfaa9

Browse files
committed
Update README
1 parent 2106953 commit aedfaa9

File tree

1 file changed

+107
-22
lines changed

1 file changed

+107
-22
lines changed

README.md

Lines changed: 107 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -219,25 +219,56 @@ data class MessageData(
219219
### SpeechToTextButton
220220

221221
`SpeechToTextButton` provides speech-to-text functionality with animated waveform visualization
222-
and automatic permission handling. When not recording, it displays a microphone icon button.
223-
When recording, it transforms into a circular button with animated bars that respond to voice input.
222+
and automatic permission handling. Clicking the button toggles recording on and off. When not recording,
223+
it displays a microphone icon button. When recording, it transforms into a circular button with animated
224+
bars that respond to voice input levels.
224225

225226
**Basic Usage:**
226227

227228
```kotlin
228229
import io.getstream.chat.android.ai.compose.ui.component.SpeechToTextButton
230+
import io.getstream.chat.android.ai.compose.ui.component.rememberSpeechToTextButtonState
229231

230232
@Composable
231233
fun MyComposer() {
232234
var text by remember { mutableStateOf("") }
233235

234-
SpeechToTextButton(
235-
onTextRecognized = { recognizedText ->
236-
// Called with partial results as user speaks
237-
// At the end this callback is invoked with the full recognized text
236+
val speechState = rememberSpeechToTextButtonState(
237+
onFinalResult = { recognizedText ->
238+
// Called with the final result when recording stops
238239
text = recognizedText
239240
}
240241
)
242+
243+
SpeechToTextButton(
244+
state = speechState
245+
)
246+
}
247+
```
248+
249+
**Usage with Real-time Streaming:**
250+
251+
```kotlin
252+
@Composable
253+
fun MyComposer() {
254+
var text by remember { mutableStateOf("") }
255+
256+
val speechState = rememberSpeechToTextButtonState(
257+
onPartialResult = { partialText ->
258+
// Called with partial results as user speaks (real-time streaming)
259+
// This updates continuously as speech is detected
260+
text = partialText
261+
},
262+
onFinalResult = { finalText ->
263+
// Called with the final result when recording stops
264+
// This is the complete, finalized transcription
265+
text = finalText
266+
}
267+
)
268+
269+
SpeechToTextButton(
270+
state = speechState
271+
)
241272
}
242273
```
243274

@@ -249,29 +280,39 @@ import io.getstream.chat.android.ai.compose.ui.component.rememberSpeechToTextBut
249280

250281
@Composable
251282
fun MyComposer() {
252-
val speechState = rememberSpeechToTextButtonState()
253283
var text by remember { mutableStateOf("") }
254284

255285
// Remember the text that existed before starting speech recognition
256-
val textBeforeSpeech = remember { mutableStateOf("") }
286+
var textBeforeSpeech by remember { mutableStateOf("") }
287+
288+
val speechState = rememberSpeechToTextButtonState(
289+
onPartialResult = { partialText ->
290+
// Update with partial results in real-time
291+
text = if (textBeforeSpeech.isBlank()) {
292+
partialText
293+
} else {
294+
"$textBeforeSpeech $partialText"
295+
}
296+
},
297+
onFinalResult = { finalText ->
298+
// Append final recognized text after the text which is already in the composer
299+
text = if (textBeforeSpeech.isBlank()) {
300+
finalText
301+
} else {
302+
"$textBeforeSpeech $finalText"
303+
}
304+
}
305+
)
257306

258307
// Capture text when recording starts
259308
LaunchedEffect(speechState.isRecording()) {
260309
if (speechState.isRecording()) {
261-
textBeforeSpeech.value = text
310+
textBeforeSpeech = text
262311
}
263312
}
264313

265314
SpeechToTextButton(
266-
state = speechState,
267-
onTextRecognized = { recognizedText ->
268-
// Append recognized text after the text which is already in the composer
269-
text = if (textBeforeSpeech.value.isBlank()) {
270-
recognizedText
271-
} else {
272-
"${textBeforeSpeech.value} $recognizedText"
273-
}
274-
}
315+
state = speechState
275316
)
276317

277318
// Check if currently recording
@@ -281,17 +322,61 @@ fun MyComposer() {
281322
}
282323
```
283324

325+
**Customization:**
326+
327+
```kotlin
328+
val speechState = rememberSpeechToTextButtonState(
329+
onPartialResult = { partialText ->
330+
// Handle partial results (optional)
331+
},
332+
onFinalResult = { finalText ->
333+
// Handle final result
334+
}
335+
)
336+
337+
SpeechToTextButton(
338+
state = speechState,
339+
idleContent = { onClick ->
340+
// Custom content when not recording
341+
IconButton(onClick = onClick) {
342+
Icon(Icons.Default.Mic, "Voice input")
343+
}
344+
},
345+
recordingContent = { onClick, rmsdB ->
346+
// Custom content when recording
347+
// rmsdB is the current audio level (0-10) for visualization
348+
IconButton(onClick = onClick) {
349+
// Your custom recording visualization
350+
}
351+
}
352+
)
353+
```
354+
284355
**Features:**
356+
- Click to toggle recording on/off
285357
- Automatic audio permission requests (RECORD_AUDIO)
286-
- Animated waveform visualization during recording
287-
- Real-time streaming of recognized text (partial results)
358+
- Animated waveform visualization during recording that responds to audio levels
359+
- Real-time streaming of recognized text (partial results as speech is detected)
360+
- Final result callback when recording stops
288361
- Automatic UI transformation between idle and recording states
289362
- State tracking for recording status
290363

291364
**Parameters:**
292365
- `modifier`: Modifier to be applied to the root container
293-
- `state`: Optional state holder for tracking recording status (defaults to remembered state)
294-
- `onTextRecognized`: Callback invoked with each partial result as speech is detected
366+
- `state`: Optional state holder for tracking recording status and receiving recognized text.
367+
Defaults to a remembered state with an empty callback. To receive text, create a state using
368+
`rememberSpeechToTextButtonState` with your callbacks and pass it here.
369+
- `idleContent`: The composable content to display when not recording. Receives an onClick callback
370+
that toggles recording. Defaults to a microphone icon button.
371+
- `recordingContent`: The composable content to display when recording. Receives an onClick callback
372+
that stops recording and the current audio level (rmsdB) for visualization. Defaults to animated bars.
373+
374+
**rememberSpeechToTextButtonState Parameters:**
375+
- `onPartialResult`: Optional callback invoked when text chunks are recognized during recording.
376+
Called with each partial result as speech is detected, enabling real-time text streaming.
377+
Use this to update your UI in real-time as the user speaks.
378+
- `onFinalResult`: Required callback invoked when the final result is available after recording stops.
379+
Called with the complete, finalized transcription. This is the definitive result of the speech recognition.
295380

296381
**SpeechToTextButtonState API:**
297382

0 commit comments

Comments
 (0)