import 'dart:math'; import 'package:autocomplete_textfield/autocomplete_textfield.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/model/get_medication_response_model.dart'; import 'package:doctor_app_flutter/core/viewModel/medicine_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/medicine/pharmacies_list_screen.dart'; import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/medicine/medicine_item_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/Text.dart'; import 'package:doctor_app_flutter/widgets/shared/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.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 '../../util/extenstions.dart'; DrAppSharedPreferances sharedPref = DrAppSharedPreferances(); class MedicineSearchScreen extends StatefulWidget with DrAppToastMsg { MedicineSearchScreen({this.changeLoadingStata}); final Function changeLoadingStata; @override _MedicineSearchState createState() => _MedicineSearchState(); } class _MedicineSearchState extends State { var data; final myController = TextEditingController(); Helpers helpers = new Helpers(); bool _hasSpeech = false; String _currentLocaleId = ""; bool _isInit = true; final SpeechToText speech = SpeechToText(); String lastStatus = ''; GetMedicationResponseModel _selectedMedication; GlobalKey key = new GlobalKey>(); // String lastWords; List _localeNames = []; String lastError; double level = 0.0; double minSoundLevel = 50000; double maxSoundLevel = -50000; String reconizedWord; @override void didChangeDependencies() { super.didChangeDependencies(); } void requestPermissions() async { Map statuses = await [ Permission.microphone, ].request(); } Future initSpeechState() async { bool hasSpeech = await speech.initialize( onError: errorListener, onStatus: statusListener); // if (hasSpeech) { // _localeNames = await speech.locales(); // var systemLocale = await speech.systemLocale(); _currentLocaleId = TranslationBase.of(context).locale.languageCode == 'en' ? 'en-GB' : 'ar-SA'; // systemLocale.localeId; // } if (!mounted) return; setState(() { _hasSpeech = hasSpeech; }); } InputDecoration textFieldSelectorDecoration(String hintText, String selectedText, bool isDropDown, {IconData icon}) { return InputDecoration( focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), borderRadius: BorderRadius.circular(8), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), borderRadius: BorderRadius.circular(8), ), disabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), borderRadius: BorderRadius.circular(8), ), hintText: selectedText != null ? selectedText : hintText, suffixIcon: isDropDown ? Icon(icon ?? Icons.arrow_drop_down) : null, hintStyle: TextStyle( fontSize: 14, color: Colors.grey.shade600, ), ); } @override Widget build(BuildContext context) { return BaseView( onModelReady: (model) async { if(model.allMedicationList.length == 0) await model.getMedicationList(); }, builder: (_, model, w) => AppScaffold( baseViewModel: model, appBarTitle: TranslationBase .of(context) .searchMedicine, body: SingleChildScrollView( child: FractionallySizedBox( widthFactor: 0.97, child: SingleChildScrollView( child: Column( children: [ Column( children: [ Container( child: Icon( DoctorApp.medicine_search, size: 100, color: Colors.black, ), margin: EdgeInsets.only(top: 50), ), Padding( padding: const EdgeInsets.only(top: 12.0), child: AppText( TranslationBase.of(context).type.toUpperCase(), fontWeight: FontWeight.bold, fontSize: SizeConfig.heightMultiplier * 2.5, ), ), Padding( padding: const EdgeInsets.only(top: 5.0), child: AppText( TranslationBase.of(context).searchMedicineImageCaption, fontSize: SizeConfig.heightMultiplier * 2, ), ) ], ), SizedBox( height: 15, ), FractionallySizedBox( widthFactor: 0.9, child: Column( children: [ Container( height: MediaQuery .of(context) .size .height * 0.070, child: InkWell( onTap: model.allMedicationList != null ? () { setState(() { _selectedMedication = null; }); } : null, child: _selectedMedication == null ? AutoCompleteTextField< GetMedicationResponseModel>( decoration: textFieldSelectorDecoration( TranslationBase .of(context) .searchMedicineNameHere, _selectedMedication != null ? _selectedMedication.genericName : null, true, icon: EvaIcons.search), itemSubmitted: (item) => setState( () => _selectedMedication = item), key: key, suggestions: model.allMedicationList, itemBuilder: (context, suggestion) => new Padding( child: Texts(suggestion.description + '/' + suggestion.genericName), padding: EdgeInsets.all(8.0)), itemSorter: (a, b) => 1, itemFilter: (suggestion, input) => suggestion.genericName .toLowerCase() .startsWith(input.toLowerCase()) || suggestion.description .toLowerCase() .startsWith(input.toLowerCase()) || suggestion.keywords .toLowerCase() .startsWith(input.toLowerCase()), ) : TextField( minLines: 2, maxLines: 2, decoration: textFieldSelectorDecoration( TranslationBase .of(context) .searchMedicineNameHere, _selectedMedication != null ? _selectedMedication.description + (' (${_selectedMedication.genericName} )') : null, true, icon: EvaIcons.search), enabled: false, ), ), ), SizedBox( height: 15, ), Container( child: Wrap( alignment: WrapAlignment.center, children: [ // TODO change it secondary button and add loading AppButton( title: TranslationBase.of(context).search, onPressed: () async { await searchMedicine(context, model); }, ), ], ), ), ], ), ), ], ), ), ), ),),); } searchMedicine(context, MedicineViewModel model) async { FocusScope.of(context).unfocus(); if (_selectedMedication.isNullOrEmpty()) { helpers.showErrorToast(TranslationBase .of(context) .typeMedicineName); //"Type Medicine Name") return; } else if (_selectedMedication.description.length < 3) { helpers.showErrorToast(TranslationBase .of(context) .moreThan3Letter); return; } // GifLoaderDialogUtils.showMyDialog(context); Navigator.push( context, MaterialPageRoute( builder: (context) => PharmaciesListScreen( itemID:_selectedMedication.itemId, selectedMedication: _selectedMedication, ), ), ); // await model.getMedicineItem(_selectedMedication.description); // GifLoaderDialogUtils.hideDialog(context); } startVoiceSearch() { // lastWords = ""; lastError = ""; speech.listen( onResult: resultListener, listenFor: Duration(seconds: 10), localeId: _currentLocaleId, onSoundLevelChange: soundLevelListener, cancelOnError: true, partialResults: true, onDevice: true, listenMode: ListenMode.confirmation); setState(() {}); } void resultListener(SpeechRecognitionResult result) { setState(() { // lastWords = "${result.recognizedWords} - ${result.finalResult}"; reconizedWord = result.recognizedWords; lastStatus = ''; myController.text = reconizedWord; Future.delayed(const Duration(seconds: 2), () { // searchMedicine(context); }); }); } void errorListener(SpeechRecognitionError error) { // print("Received error status: $error, listening: ${speech.isListening}"); setState(() { lastError = "${error.errorMsg} - ${error.permanent}"; }); } void statusListener(String status) { // print( // "Received listener status: $status, listening: ${speech.isListening}"); setState(() { lastStatus = status; }); } // _switchLang(selectedVal) { // setState(() { // _currentLocaleId = selectedVal; // }); // print(selectedVal); // } void soundLevelListener(double level) { minSoundLevel = min(minSoundLevel, level); maxSoundLevel = max(maxSoundLevel, level); // print("sound level $level: $minSoundLevel - $maxSoundLevel "); setState(() { this.level = level; }); } }