You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
4.2 KiB
Dart
134 lines
4.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:fluttertoast/fluttertoast.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:speech_to_text/speech_recognition_error.dart';
|
|
import 'package:speech_to_text/speech_recognition_result.dart';
|
|
import 'package:speech_to_text/speech_to_text.dart';
|
|
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
|
|
import 'package:test_sa/views/app_style/sizing.dart';
|
|
import 'package:test_sa/views/widgets/buttons/app_icon_button2.dart';
|
|
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
|
|
|
|
class SpeechToTextButton extends StatefulWidget {
|
|
final TextEditingController controller;
|
|
final bool mini;
|
|
|
|
const SpeechToTextButton({Key key, this.controller, this.mini = false}) : super(key: key);
|
|
|
|
@override
|
|
_SpeechToTextButtonState createState() => _SpeechToTextButtonState();
|
|
}
|
|
|
|
class _SpeechToTextButtonState extends State<SpeechToTextButton> {
|
|
bool _speechEnabled = false;
|
|
SettingProvider _settingProvider;
|
|
SpeechToText _speechToText = SpeechToText();
|
|
|
|
/// This has to happen only once per app
|
|
void _initSpeech() async {
|
|
_speechEnabled = await _speechToText.initialize(
|
|
onError: (SpeechRecognitionError error) async {
|
|
Fluttertoast.showToast(msg: "failed to convert text to speech");
|
|
setState(() {});
|
|
},
|
|
);
|
|
}
|
|
|
|
/// Each time to start a speech recognition session
|
|
void _startListening() async {
|
|
_speechEnabled = _speechToText.isAvailable;
|
|
if (_speechToText.isListening) {
|
|
Fluttertoast.showToast(msg: "Currently in use");
|
|
return;
|
|
}
|
|
if (!_speechEnabled) return;
|
|
await _speechToText.listen(
|
|
onResult: (SpeechRecognitionResult result) {
|
|
widget.controller.text = result.recognizedWords;
|
|
setState(() {});
|
|
},
|
|
localeId: _settingProvider.speechToText);
|
|
setState(() {});
|
|
}
|
|
|
|
/// Manually stop the active speech recognition session
|
|
/// Note that there are also timeouts that each platform enforces
|
|
/// and the SpeechToText plugin supports setting timeouts on the
|
|
/// listen method.
|
|
void _stopListening() async {
|
|
await _speechToText.stop();
|
|
setState(() {});
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
_initSpeech();
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void setState(VoidCallback fn) {
|
|
if (!this.mounted) return;
|
|
super.setState(fn);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
_settingProvider = Provider.of<SettingProvider>(context);
|
|
return Container(
|
|
padding: EdgeInsets.only(left: 12, right: 12),
|
|
decoration: BoxDecoration(
|
|
color: Color(0xfff5f5f5),
|
|
border: Border.all(
|
|
color: Color(0xffefefef),
|
|
),
|
|
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
widget.mini ? SizedBox.shrink() : ASubTitle("Text To Speech"),
|
|
widget.controller.text.isNotEmpty
|
|
? AIconButton2(
|
|
iconData: Icons.delete,
|
|
onPressed: () {
|
|
widget.controller.clear();
|
|
setState(() {});
|
|
},
|
|
)
|
|
: SizedBox.shrink(),
|
|
Spacer(),
|
|
TextButton(
|
|
onPressed: () {
|
|
if (_speechToText.isListening) return;
|
|
|
|
if (_settingProvider.speechToText == "ar") {
|
|
_settingProvider.setSpeechToText("en");
|
|
} else {
|
|
_settingProvider.setSpeechToText("ar");
|
|
}
|
|
},
|
|
child: Text(_settingProvider.speechToText)),
|
|
GestureDetector(
|
|
child: _speechToText.isListening
|
|
? Icon(
|
|
Icons.fiber_manual_record,
|
|
color: Colors.red,
|
|
)
|
|
: Icon(
|
|
Icons.mic,
|
|
color: Theme.of(context).colorScheme.primary,
|
|
),
|
|
onTap: () async {
|
|
if (!_speechEnabled) {
|
|
Fluttertoast.showToast(msg: "microphone not available");
|
|
return;
|
|
}
|
|
_startListening();
|
|
},
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|