feat(voice): integrate one-shot voice capture into Quick Capture bar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-05 14:46:34 -04:00
parent 2231c60bfb
commit 211bf0d658
+30 -1
View File
@@ -29,6 +29,8 @@ import 'screens/settings/settings_screen.dart';
import 'screens/setup/setup_screen.dart';
import 'screens/splash/splash_screen.dart';
import 'screens/tasks/task_edit_screen.dart';
import 'providers/voice_provider.dart';
import 'widgets/voice_mic_button.dart';
// ChangeNotifier that fires when auth or server URL changes,
// used as GoRouter.refreshListenable so the router re-evaluates redirects
@@ -399,6 +401,7 @@ class _QuickCaptureBarState extends ConsumerState<_QuickCaptureBar> {
@override
void dispose() {
_controller.dispose();
ref.read(voiceProvider.notifier).exitVoiceMode();
super.dispose();
}
@@ -440,6 +443,25 @@ class _QuickCaptureBarState extends ConsumerState<_QuickCaptureBar> {
}
}
Future<void> _toggleCaptureMic() async {
final voice = ref.read(voiceProvider);
if (voice.voiceModeActive) {
ref.read(voiceProvider.notifier).exitVoiceMode();
return;
}
await ref.read(voiceProvider.notifier).enterVoiceMode(
onTranscript: (transcript) async {
ref.read(captureWorkQueueProvider.notifier).enqueue(transcript);
},
enableTts: false,
onError: (msg) {
if (!mounted) return;
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(msg)));
},
);
}
String _hintForLocation(String location) {
if (location.startsWith(Routes.knowledge)) return 'Capture a note…';
if (location.startsWith(Routes.projects)) return 'Capture a note…';
@@ -482,7 +504,9 @@ class _QuickCaptureBarState extends ConsumerState<_QuickCaptureBar> {
onSubmitted: (_) => _submit(),
onChanged: (_) => setState(() {}),
decoration: InputDecoration(
hintText: _hintForLocation(location),
hintText: ref.watch(voiceProvider).voiceModeActive
? 'Listening…'
: _hintForLocation(location),
isDense: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 14, vertical: 10),
@@ -512,6 +536,11 @@ class _QuickCaptureBarState extends ConsumerState<_QuickCaptureBar> {
),
),
),
VoiceMicButton(
mode: ref.watch(voiceProvider).mode,
voiceModeActive: ref.watch(voiceProvider).voiceModeActive,
onTap: _toggleCaptureMic,
),
IconButton(
icon: const Icon(Icons.settings_outlined),
tooltip: 'Settings',