diff --git a/app/lib/presentation/widgets/speech_to_text_button.dart b/app/lib/presentation/widgets/speech_to_text_button.dart
index 0ba0e3a5..79baea8d 100644
--- a/app/lib/presentation/widgets/speech_to_text_button.dart
+++ b/app/lib/presentation/widgets/speech_to_text_button.dart
@@ -17,31 +17,60 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
+import 'dart:async';
+
import 'package:flutter/material.dart';
-import 'package:speech_to_text_google_dialog/speech_to_text_google_dialog.dart';
+import 'package:speech_to_text_dialog/speech_to_text_dialog.dart';
import 'package:weblibre/utils/ui_helper.dart' as ui_helper;
-class SpeechToTextButton extends StatelessWidget {
- final Function(dynamic data) onTextReceived;
+class SpeechToTextButton extends StatefulWidget {
+ final Function(String text) onTextReceived;
const SpeechToTextButton({required this.onTextReceived, super.key});
+ @override
+ State createState() => _SpeechToTextButtonState();
+}
+
+class _SpeechToTextButtonState extends State {
+ final _speechDialog = SpeechToTextDialog();
+ StreamSubscription? _textSubscription;
+
+ @override
+ void dispose() {
+ _textSubscription?.cancel().ignore();
+ _speechDialog.dispose();
+ super.dispose();
+ }
+
+ Future _showSpeechDialog(BuildContext context) async {
+ // Cancel any existing subscription
+ await _textSubscription?.cancel();
+
+ // Listen for the next text result
+ _textSubscription = _speechDialog.textStream.take(1).listen((text) {
+ if (text.isNotEmpty) {
+ widget.onTextReceived(text);
+ }
+ });
+
+ // Show the dialog
+ final isServiceAvailable = await _speechDialog.showDialog(
+ // locale: "en-US",
+ );
+
+ if (!isServiceAvailable) {
+ if (context.mounted) {
+ ui_helper.showErrorMessage(context, 'Service is not available');
+ }
+ await _textSubscription?.cancel();
+ }
+ }
+
@override
Widget build(BuildContext context) {
return IconButton(
- onPressed: () async {
- final isServiceAvailable = await SpeechToTextGoogleDialog.getInstance()
- .showGoogleDialog(
- onTextReceived: onTextReceived,
- // locale: "en-US",
- );
-
- if (!isServiceAvailable) {
- if (context.mounted) {
- ui_helper.showErrorMessage(context, 'Service is not available');
- }
- }
- },
+ onPressed: () => _showSpeechDialog(context),
icon: const Icon(Icons.mic),
);
}
diff --git a/app/pubspec.yaml b/app/pubspec.yaml
index d4c54f8b..118a4d22 100644
--- a/app/pubspec.yaml
+++ b/app/pubspec.yaml
@@ -77,9 +77,8 @@ dependencies:
sliver_tools: ^0.2.12
smooth_page_indicator: ^2.0.1
socks5_proxy: ^2.1.1
- speech_to_text_google_dialog:
- git:
- url: https://github.com/FaFre/speech_to_text_google_dialog.git
+ speech_to_text_dialog:
+ path: ../packages/speech_to_text_dialog
sqlite3: ^2.9.4
sqlite3_flutter_libs: ^0.5.41
synchronized: ^3.4.0
diff --git a/lib/src/pigeons/speech_to_text.g.dart b/lib/src/pigeons/speech_to_text.g.dart
new file mode 100644
index 00000000..124a8aee
--- /dev/null
+++ b/lib/src/pigeons/speech_to_text.g.dart
@@ -0,0 +1,137 @@
+// Autogenerated from Pigeon (v26.1.5), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, omit_obvious_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
+
+import 'dart:async';
+import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
+
+import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
+import 'package:flutter/services.dart';
+
+PlatformException _createConnectionError(String channelName) {
+ return PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel: "$channelName".',
+ );
+}
+
+List