diff --git a/speech_to_text/example/lib/main.dart b/speech_to_text/example/lib/main.dart index e423428..ba111f3 100644 --- a/speech_to_text/example/lib/main.dart +++ b/speech_to_text/example/lib/main.dart @@ -40,6 +40,7 @@ class _SpeechSampleAppState extends State { "", 3, 30, + false, false); @override @@ -57,7 +58,7 @@ class _SpeechSampleAppState extends State { var hasSpeech = await speech.initialize( onError: errorListener, onStatus: statusListener, - debugLogging: currentOptions.logEvents, + debugLogging: currentOptions.debugLogging, ); if (hasSpeech) { speech.unexpectedPhraseAggregator = _punctAggregator; @@ -339,7 +340,7 @@ class SessionOptionsWidget extends StatelessWidget { children: [ Row( children: [ - const Text('Language: '), + const Text('localeId: '), Expanded( child: DropdownButton( onChanged: (selectedVal) => onChange(options.copyWith( @@ -382,65 +383,75 @@ class SessionOptionsWidget extends StatelessWidget { ), Row( children: [ - const Text('On device: '), + const Text('partialResults: '), Checkbox( - value: options.options.onDevice, + value: options.options.partialResults, onChanged: (value) { onChange(options.copyWith( - options: options.options.copyWith(onDevice: value))); + options: options.options.copyWith(partialResults: value))); }, ), ], ), Row( children: [ - const Text('Auto Punctuation: '), + const Text('onDevice: '), Checkbox( - value: options.options.autoPunctuation, + value: options.options.onDevice, onChanged: (value) { onChange(options.copyWith( - options: options.options.copyWith(autoPunctuation: value))); + options: options.options.copyWith(onDevice: value))); }, ), ], ), Row( children: [ - const Text('Enable Haptics: '), + const Text('cancelOnError: '), Checkbox( - value: options.options.enableHapticFeedback, + value: options.options.cancelOnError, onChanged: (value) { onChange(options.copyWith( - options: - options.options.copyWith(enableHapticFeedback: value))); + options: options.options.copyWith(cancelOnError: value))); }, ), ], ), Row( children: [ - const Text('Partial results: '), + const Text('autoPunctuation: '), Checkbox( - value: options.options.partialResults, + value: options.options.autoPunctuation, onChanged: (value) { onChange(options.copyWith( - options: options.options.copyWith(partialResults: value))); + options: options.options.copyWith(autoPunctuation: value))); }, ), ], ), Row( children: [ - const Text('Cancel on error: '), + const Text('enableHapticFeedback: '), Checkbox( - value: options.options.cancelOnError, + value: options.options.enableHapticFeedback, onChanged: (value) { onChange(options.copyWith( - options: options.options.copyWith(cancelOnError: value))); + options: + options.options.copyWith(enableHapticFeedback: value))); }, ), ], ), + Row( + children: [ + const Text('debugLogging: '), + Checkbox( + value: options.debugLogging, + onChanged: (value) => + onChange(options.copyWith(debugLogging: value)), + ), + ], + ), Row( children: [ const Text('Log events: '), @@ -513,24 +524,27 @@ class SpeechExampleConfig { final SpeechListenOptions options; final String localeId; final bool logEvents; + final bool debugLogging; final int pauseFor; final int listenFor; SpeechExampleConfig(this.options, this.localeId, this.pauseFor, - this.listenFor, this.logEvents); + this.listenFor, this.logEvents, this.debugLogging); SpeechExampleConfig copyWith( {SpeechListenOptions? options, String? localeId, bool? logEvents, int? pauseFor, - int? listenFor}) { + int? listenFor, + bool? debugLogging}) { return SpeechExampleConfig( options ?? this.options, localeId ?? this.localeId, pauseFor ?? this.pauseFor, listenFor ?? this.listenFor, - logEvents ?? this.logEvents); + logEvents ?? this.logEvents, + debugLogging ?? this.debugLogging); } } @@ -543,6 +557,7 @@ Future showSetUp(BuildContext context, ..text = updatedOptions.listenFor.toString(); var pauseController = TextEditingController() ..text = updatedOptions.pauseFor.toString(); + var showHelp = false; await showModalBottomSheet( elevation: 0, context: context, @@ -558,30 +573,45 @@ Future showSetUp(BuildContext context, maxWidth: double.infinity, ), child: StatefulBuilder( - builder: (context, setState) => Column( + builder: (context, setState) => Stack( children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - "Session Options", - style: Theme.of(context).textTheme.titleMedium, + Column(children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + "Session Options", + style: Theme.of(context).textTheme.titleMedium, + ), ), - ), - Expanded( - child: SingleChildScrollView( - padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 16.0), - child: SessionOptionsWidget( - onChange: (newOptions) { - setState(() { - updatedOptions = newOptions; - }); - }, - listenForController: listenController, - pauseForController: pauseController, - options: updatedOptions, - localeNames: localeNames, + Expanded( + child: SingleChildScrollView( + padding: + const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 16.0), + child: showHelp + ? const HelpWidget() + : SessionOptionsWidget( + onChange: (newOptions) { + setState(() { + updatedOptions = newOptions; + }); + }, + listenForController: listenController, + pauseForController: pauseController, + options: updatedOptions, + localeNames: localeNames, + ), ), ), + ]), + Positioned( + right: 0.0, + top: 0.0, + child: IconButton( + onPressed: () => setState( + () => showHelp = !showHelp, + ), + icon: Icon( + showHelp ? Icons.settings : Icons.question_mark)), ), ], ), @@ -596,6 +626,76 @@ Future showSetUp(BuildContext context, return updatedOptions; } +class HelpWidget extends StatelessWidget { + const HelpWidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return const Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'The plugin provides a number of options that can be set to control ' + 'the behavior of the speech recognition. The option names shown ' + 'correspond to the names of the fields in the SpeechListenOptions, ' + 'or parameters of the listen or initialize methods. '), + Text(''), + Text('localeId:', style: TextStyle(fontWeight: FontWeight.bold)), + Text('The language to use for speech recognition. This is ' + 'based on the languages installed on the device. '), + Text(''), + Text('pauseFor:', style: TextStyle(fontWeight: FontWeight.bold)), + Text('The number of seconds to pause after the last speech is ' + 'detected before stopping the recognition. Note that this is ' + 'ignored on Android devices which impose their own quite short ' + 'pause duration. '), + Text(''), + Text('listenFor:', style: TextStyle(fontWeight: FontWeight.bold)), + Text('The maximum number of seconds to listen for speech ' + 'before stopping the recognition. Note that the actual time ' + 'may be less if the device imposes a shorter maximum duration. '), + Text(''), + Text('partialResults:', style: TextStyle(fontWeight: FontWeight.bold)), + Text('When true the plugin will return results as they are recognized. ' + 'When false the plugin will only return the final result. Note ' + 'that recognizers will change the recognized result as more ' + 'speech is received. This means that the final result may be ' + 'different from the last partial result. '), + Text(''), + Text('onDevice:', style: TextStyle(fontWeight: FontWeight.bold)), + Text('When true all recognition will be done on device. ' + 'Recognition will fail if the device does not support on device ' + 'recognition for the selected language. '), + Text(''), + Text('cancelOnError:', style: TextStyle(fontWeight: FontWeight.bold)), + Text('When true the plugin will automatically cancel recognition ' + 'when an error occurs. If false it will attempt to continue ' + 'recognition until the stop or cancel method is called. '), + Text(''), + Text('debugLogging:', style: TextStyle(fontWeight: FontWeight.bold)), + Text('When true the device specific implementation will log ' + 'more detailed information during initialization and recognition. '), + Text(''), + Text('autoPunctuation:', style: TextStyle(fontWeight: FontWeight.bold)), + Text('When true the plugin will attempt to add punctuation to the ' + 'recognized text on supported devices. '), + Text(''), + Text('enableHapticFeedback:', + style: TextStyle(fontWeight: FontWeight.bold)), + Text('When true the plugin will provide haptic feedback during ' + 'recognition. Some platforms disable haptics during recognition ' + 'to improve accuracy. This option allows the user to override ' + 'that behavior. '), + Text(''), + Text('logEvents:', style: TextStyle(fontWeight: FontWeight.bold)), + Text('Logs example app events to the console. ' + 'This is not a plugin feature, purely a part of the example app. '), + ], + ); + } +} + /// A simple widget that displays a microphone icon /// and a circle that changes size based on the sound level. class MicrophoneWidget extends StatelessWidget {