fix: mic permissions
This commit is contained in:
@@ -250,6 +250,20 @@ class VoiceInputService {
|
|||||||
return _textStreamController!.stream;
|
return _textStreamController!.stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Centralized entry point to begin voice recognition.
|
||||||
|
/// Ensures initialization and microphone permission before starting.
|
||||||
|
Future<Stream<String>> beginListening() async {
|
||||||
|
// Ensure service is ready
|
||||||
|
await initialize();
|
||||||
|
// Ensure microphone permission (triggers OS prompt if needed)
|
||||||
|
final hasMic = await checkPermissions();
|
||||||
|
if (!hasMic) {
|
||||||
|
throw Exception('Microphone permission not granted');
|
||||||
|
}
|
||||||
|
// Start listening and return the transcript stream
|
||||||
|
return startListening();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> stopListening() async {
|
Future<void> stopListening() async {
|
||||||
await _stopListening();
|
await _stopListening();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1998,16 +1998,11 @@ class _VoiceInputSheetState extends ConsumerState<_VoiceInputSheet> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Ensure service is initialized (local STT will request permissions itself)
|
// Ensure service is initialized
|
||||||
final ok = await _voiceService.initialize();
|
final ok = await _voiceService.initialize();
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
throw Exception('Voice service unavailable');
|
throw Exception('Voice service unavailable');
|
||||||
}
|
}
|
||||||
// Only check mic permission when falling back to recording
|
|
||||||
if (!_voiceService.hasLocalStt) {
|
|
||||||
final mic = await _voiceService.checkPermissions();
|
|
||||||
if (!mic) throw Exception('Microphone permission not granted');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start elapsed timer for UX
|
// Start elapsed timer for UX
|
||||||
_elapsedTimer?.cancel();
|
_elapsedTimer?.cancel();
|
||||||
@@ -2019,7 +2014,8 @@ class _VoiceInputSheetState extends ConsumerState<_VoiceInputSheet> {
|
|||||||
setState(() => _elapsedSeconds += 1);
|
setState(() => _elapsedSeconds += 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
final stream = _voiceService.startListening();
|
// Centralized permission + start
|
||||||
|
final stream = await _voiceService.beginListening();
|
||||||
_intensitySub = _voiceService.intensityStream.listen((value) {
|
_intensitySub = _voiceService.intensityStream.listen((value) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
setState(() => _intensity = value);
|
setState(() => _intensity = value);
|
||||||
|
|||||||
@@ -1150,22 +1150,12 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!_voiceService.hasLocalStt) {
|
// Centralized permission + start
|
||||||
final mic = await _voiceService.checkPermissions();
|
final stream = await _voiceService.beginListening();
|
||||||
if (!mic) {
|
|
||||||
_showVoiceUnavailable(
|
|
||||||
AppLocalizations.of(context)?.errorMessage ??
|
|
||||||
'Microphone permission required',
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_isRecording = true;
|
_isRecording = true;
|
||||||
_baseTextAtStart = _controller.text;
|
_baseTextAtStart = _controller.text;
|
||||||
});
|
});
|
||||||
|
|
||||||
final stream = _voiceService.startListening();
|
|
||||||
_intensitySub?.cancel();
|
_intensitySub?.cancel();
|
||||||
_intensitySub = _voiceService.intensityStream.listen((value) {
|
_intensitySub = _voiceService.intensityStream.listen((value) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user