import 'dart:async'; import 'dart:collection'; import 'dart:io'; import 'dart:math'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/service/medical/vital_sign_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/my_web_view.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/parking_page.dart'; import 'package:diplomaticquarterapp/pages/Blood/blood_donation.dart'; import 'package:diplomaticquarterapp/pages/Blood/my_balance_page.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/BranchView.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/LiveChat/livechat_page.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/findus/findus_page.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart'; import 'package:diplomaticquarterapp/pages/ErService/AmbulanceReq.dart'; import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart'; import 'package:diplomaticquarterapp/pages/ErService/NearestEr.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/MyAppointments.dart'; import 'package:diplomaticquarterapp/pages/feedback/feedback_home_page.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_approval_screen.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; import 'package:diplomaticquarterapp/pages/login/welcome.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/advance_payment_page.dart'; import 'package:diplomaticquarterapp/pages/medical/doctor/doctor_home_page.dart'; import 'package:diplomaticquarterapp/pages/medical/labs/labs_home_page.dart'; import 'package:diplomaticquarterapp/pages/medical/medical_profile_page.dart'; import 'package:diplomaticquarterapp/pages/medical/patient_sick_leave_page.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; import 'package:diplomaticquarterapp/pages/medical/radiology/radiology_home_page.dart'; import 'package:diplomaticquarterapp/pages/medical/reports/report_home_page.dart'; import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart'; import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart'; import 'package:diplomaticquarterapp/pages/vaccine/my_vaccines_screen.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; import 'package:diplomaticquarterapp/services/robo_search/search_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_tts/flutter_tts.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; import 'package:diplomaticquarterapp/pages/BookAppointment/DoctorProfile.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart'; import 'package:flutter/cupertino.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy_module_page.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/%E2%80%8B%20health_calculators.dart'; class FloatingSearchButton extends StatefulWidget { @override _FloatingSearchButton createState() => _FloatingSearchButton(); } class _FloatingSearchButton extends State with TickerProviderStateMixin { Offset position = Offset(250, 400); bool activeAnimation = false; bool isShow = true; SearchProvider searchProvider = new SearchProvider(); RobotProvider eventProvider = RobotProvider(); bool isLoading = false; bool isError = false; stt.SpeechToText speech = stt.SpeechToText(); String error = ''; String _currentLocaleId = ""; String lastError; double level = 0.0; var searchText; double minSoundLevel = 50000; double maxSoundLevel = -50000; String reconizedWord = ''; FlutterTts flutterTts = FlutterTts(); var selectedLang; bool isSearching = false; Map results = {}; String lastStatus; AuthenticatedUser user; bool _isInit = true; var event = RobotProvider(); var sharedPref = new AppSharedPreferences(); bool _hasSpeech = false; ProjectViewModel projectProvider; bool isAnimationEnable = true; AnimationController controller; Animation offset; String networkImage; bool isArabic; @override void initState() { controller = AnimationController(vsync: this, duration: Duration(seconds: 1)); offset = Tween(begin: Offset(0.0, 1.0), end: Offset(0.0, 0.0)) .animate(controller); if (IS_VOICE_COMMAND_CLOSED == true) { controller.reverse(from: -1); } if (mounted) { //Future.delayed(const Duration(seconds: 2), () { isArabic = Provider.of(context, listen: false).isArabic; requestPermissions(); getUserData(); initialSpeak(); setState(() { if (IS_TEXT_COMPLETED) { isAnimationEnable = false; } }); } event.controller.stream.listen((p) { if (p['isRobotVisible'] == 'true') { if (this.mounted) { setState(() { if (IS_VOICE_COMMAND_CLOSED == false) { controller.forward(); } }); } } }); event.controller.stream.listen((p) { if (p['startPopUp'] == 'true') { if (this.mounted) { new RoboSearch(context: context).showAlertDialog(context); initSpeechState().then((value) => {startVoiceSearch()}); } } }); super.initState(); } @override void dispose() { controller.dispose(); super.dispose(); } // @override // void didUpdateWidget(FloatingSearchButton oldWidget) { // // super.didUpdateWidget(oldWidget); // // event.controller.stream.listen((p) { // // if (p['animationEnable'] != 'false') { // // initialSpeak(); // // } // // }); // } AuthenticatedUserObject authenticatedUserObject = locator(); VitalSignService _vitalSignService = locator(); @override Widget build(BuildContext context) { return Container( child: SlideTransition(position: offset, child: getStack())); } Widget getStack() { return Container( height: 150, width: 150, margin: EdgeInsets.only(left: 20.0), child: Stack(children: [ GestureDetector( child: Container( child: networkImage != null ? CachedNetworkImage( imageUrl: networkImage, placeholder: (context, url) => Image.asset('assets/images/gif/robot-idle.gif'), errorWidget: (context, url, error) => Icon(Icons.error), ) : Image.asset(isAnimationEnable == true ? 'assets/images/gif/robot-speaking.gif' : 'assets/images/gif/robot-idle.gif'), ), onTap: () { new RoboSearch(context: context).showAlertDialog(context); initSpeechState().then((value) => {startVoiceSearch()}); }, ), Positioned( left: 15.0, top: 10, child: GestureDetector( onTap: () { setState(() { if (this.mounted) { controller.reverse(); IS_VOICE_COMMAND_CLOSED = true; } }); }, child: Align( alignment: Alignment.topRight, child: CircleAvatar( radius: 14.0, backgroundColor: Colors.red, child: Icon(Icons.close, color: Colors.white), ), ), ), ), ])); } startVoiceSearch() async { _currentLocaleId = TranslationBase.of(AppGlobal.context).locale.languageCode; bool available = await speech.initialize( onStatus: statusListener, onError: errorListener); if (available) { speech.listen( onResult: resultListener, // listenMode: ListenMode.confirmation, localeId: _currentLocaleId == 'en' ? 'en-US' : 'ar-SA', ); } else { print("The user has denied the use of speech recognition."); } // some time later... //speech.stop(); // speech.listen( // onResult: resultListener, // listenFor: Duration(seconds: 10), // localeId: _currentLocaleId == 'en' ? 'en-US' : 'ar-SA', // onSoundLevelChange: soundLevelListener, // cancelOnError: true, // partialResults: true, // onDevice: true, // listenMode: ListenMode.deviceDefault); } void resultListener(result) { reconizedWord = result.recognizedWords; event.setValue({"searchText": reconizedWord}); if (result.finalResult == true) { Future.delayed(const Duration(seconds: 1), () { _speak(reconizedWord); RoboSearch.closeAlertDialog(context); //Navigator.of(context).pop(); }); } } Future _speak(reconizedWord) async { getPages(reconizedWord); } void soundLevelListener(double level) { minSoundLevel = min(minSoundLevel, level); maxSoundLevel = max(maxSoundLevel, level); // print("sound level $level: $minSoundLevel - $maxSoundLevel "); //setState(() { this.level = level; // }); } void requestPermissions() async { if (await Permission.microphone.isDenied || await Permission.microphone.isUndetermined) { Map statuses = await [ Permission.microphone, ].request(); } } Future initSpeechState() async { bool hasSpeech = await speech.initialize( onError: errorListener, onStatus: statusListener); //if (hasSpeech) { // _currentLocaleId = // _currentLocaleId == 'en' // ? 'en-US' // : 'ar-SA'; // systemLocale.localeId; // } if (!mounted) return; // setState(() { // _hasSpeech = hasSpeech; // }); } void errorListener(SpeechRecognitionError error) { event.setValue({"searchText": 'null'}); RoboSearch.closeAlertDialog(context); } void statusListener(String status) { //setState(() { reconizedWord = status == 'listening' ? 'Lisening...' : 'Sorry....'; //}); } getPages(text) { var request = { 'VoiceMessage': text, 'Lang': _currentLocaleId == 'en' ? 'En' : 'Ar' }; searchProvider .getBotPages(request) .then((value) => {getCommands(value['Understand'])}); } getCommands(result) async { results = result; switch (result["CommandNumber"]) { case '100': { getDoctorsList( result['ProjectId'], result['ClinicId'].length > 0 ? result['ClinicId'][0] : 0, context, doctorId: result['DoctorId'], doctorName: null, ); } break; case '102': { getDoctorsList( 0, 0, context, doctorId: result['DoctorId'], doctorName: null, ); } break; case '103': { List clnicID = unique(result['ClinicId']); if (clnicID.length == 1) { getDoctorsList( 0, clnicID[0], context, doctorId: null, doctorName: null, ); } else { goToClinic(clnicID); } } break; case '104': { List clnicID = unique(result['ClinicId']); //= result['ProjectId'] ? result['ProjectId'] : 0; //result['ProjectId']; if (clnicID.length == 1) { getDoctorsList(result['ProjectId'], clnicID[0], context, doctorId: null, doctorName: null, isNearest: true); } else { goToClinic(clnicID); } } break; case '4': { Navigator.push(context, FadePage(page: LabsHomePage())); } break; case '6': { Navigator.push(context, FadePage(page: RadiologyHomePage())); } break; case '7': { Navigator.push( context, FadePage( page: MyAppointments(), ), ); } break; case '8': { Navigator.push( context, FadePage( page: HomePrescriptionsPage(), ), ); } break; case '9': { Navigator.push( context, FadePage( page: DoctorHomePage(), ), ); } break; case '10': { Navigator.push( context, FadePage( page: VitalSignDetailsScreen(), ), ); } break; case '11': { Navigator.push(context, FadePage(page: InsuranceUpdate())); } break; case '12': { Navigator.push(context, FadePage(page: InsuranceApproval())); } break; case '13': { Navigator.push(context, FadePage(page: MyVaccines())); } break; case '14': { Navigator.push(context, FadePage(page: HomeReportPage())); } break; case '5': { Navigator.push(context, FadePage(page: NearestEr())); } break; case '15': { Navigator.push(context, FadePage(page: PatientSickLeavePage())); } break; case '16': { Navigator.push(context, FadePage(page: MyBalancePage())); } break; case '17': { Navigator.push(context, FadePage(page: MedicalProfilePage())); } break; case '18': { //Drivethrough need to be implemeted here. } break; case '19': { Navigator.push(context, FadePage(page: LiveCareHome())); } break; case '20': { //CMC service need to be implemeted } break; case '21': { Navigator.push(context, FadePage(page: MyFamily())); } break; case '22': { Navigator.push(context, FadePage(page: BloodDonationPage())); } break; case '23': { //health calculator need to be implemeted } break; case '24': { Navigator.of(context).push(MaterialPageRoute( builder: (BuildContext context) => MyWebView( title: "HMG News", selectedUrl: "https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live", ))); } break; case '25': { if (user == null) { Navigator.push(context, FadePage(page: WelcomeLogin())); } } break; case '26': { Navigator.push(context, FadePage(page: ParkingPage())); } break; case '27': { Navigator.push( context, FadePage( page: ErOptions( isAppbar: true, ))); } break; case '28': { Navigator.push(context, FadePage(page: AmbulanceReq())); } break; case '29': { Navigator.push(context, FadePage(page: FindUsPage())); } break; case '30': { launch("tel://" + result['PhoneNumbers'][0]); } break; case '31': { Navigator.of(context).popUntil(ModalRoute.withName('/')); } break; case '32': { Navigator.push(context, FadePage(page: AdvancePaymentPage())); } break; case '33': { if (result['LanguageCode'] != '0') { if (projectProvider.isArabic) { projectProvider.changeLanguage('en'); } else { projectProvider.changeLanguage('ar'); } } } break; case '34': { //settings page need to be implemented here } break; case '35': { if (Platform.isIOS) { launch( "https://apps.apple.com/sa/app/dr-suliaman-alhabib/id733503978"); } else { launch( "https://play.google.com/store/apps/details?id=com.ejada.hmg&hl=en"); } } break; case '36': { Navigator.of(context).pushNamed( REGISTER, ); } break; case '37': { Navigator.of(context).pushNamed( SYMPTOM_CHECKER, ); } break; case '38': { await this.sharedPref.setInt(IS_SEARCH_APPO, 1); Navigator.push(context, FadePage(page: MyAppointments())); } break; case '39': { await this.sharedPref.setInt(IS_SEARCH_APPO, 2); Navigator.push(context, FadePage(page: MyAppointments())); } break; case '40': { //Home health care service need to be implemeted here } break; case '41': { Navigator.push(context, FadePage(page: PaymentService())); } break; case '42': { //weather indicator need to be implemented here } break; case '43': { await this.sharedPref.setInt(IS_SEARCH_APPO, 3); Navigator.push(context, FadePage(page: MyAppointments())); } break; case '44': { //chat need be implmented here. Navigator.push(context, FadePage(page: LiveChatPage())); } break; case '45': { launch('https://hmg.com/ir/ar/Pages/ShareInformation/home.aspx'); } break; case '46': { launch('https://hmg.com/ir/ar/pages/home.aspx'); } break; case '200': { Navigator.push(context, FadePage(page: FeedbackHomePage())); } break; case '45': { launch('https://hmg.com/ir/ar/Pages/ShareInformation/home.aspx'); break; } case '46': { launch('https://hmg.com/ir/ar/pages/home.aspx'); break; } case '47': { //this.cs.sharedService.setSharedData(true, "isComingFromVoiceCommand"); //this.cs.openFeedback(); Navigator.push(context, FadePage(page: FeedbackHomePage())); break; } case '48': { Navigator.push(context, FadePage(page: PharmacyPage())); break; } case '50': { this.signOut(); break; } case '51': { // Women health calculator //this.cs.sharedService.setSharedData(true, "isOpenWomenHealthCalculator"); //this.cs.navigateForward('/calculators/calculator'); Navigator.push(context, FadePage(page: HealthCalculators())); break; } case '52': { //this.bridge.openMyInvoices(); break; } case '53': { launch("tel://920066666"); break; } default: { speak(); } break; } } getDoctorProfile(projectId, clinicId, doctorId, context, doctorData) { List docProfileList = []; DoctorsListService service = new DoctorsListService(); service .getDoctorsProfile(doctorId, clinicId, projectId, context) .then((res) { if (res['MessageStatus'] == 1) { if (res['DoctorProfileList'].length != 0) { res['DoctorProfileList'].forEach((v) { docProfileList.add(new DoctorProfileList.fromJson(v)); }); } navigateToDoctorProfile(context, doctorData[0], docProfileList[0], isAppo: true); //speak(); } }).catchError((err) { print(err); }); } getDoctorsList(projectId, clinicId, context, {doctorId, doctorName, isNearest = false}) { List doctorsList = []; List arr = []; List arrDistance = []; DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); service .getDoctorsList(clinicId, projectId, isNearest, context, doctorId: doctorId, doctorName: doctorName) .then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { setState(() { if (res['SearchDoctorsByTime_IsVoiceCommandList'] != null && res['SearchDoctorsByTime_IsVoiceCommandList'].length != 0) { doctorsList.clear(); res['SearchDoctorsByTime_IsVoiceCommandList'].forEach((v1) { v1['DoctorList'].forEach((v) { doctorsList.add(new DoctorList.fromJson(v)); arr.add(new DoctorList.fromJson(v).projectName); arrDistance.add(new DoctorList.fromJson(v) .projectDistanceInKiloMeters .toString()); }); }); if (doctorsList.length == 1) { getDoctorProfile( projectId, clinicId, doctorId[0], context, doctorsList); //speak(); } else { navigateToSearchResults(context, doctorsList, arr, arrDistance); } } else if (res['DoctorList'].length != 0) { doctorsList.clear(); res['DoctorList'].forEach((v) { doctorsList.add(new DoctorList.fromJson(v)); arr.add(new DoctorList.fromJson(v).projectName); arrDistance.add(new DoctorList.fromJson(v) .projectDistanceInKiloMeters .toString()); }); if (doctorsList.length == 1) { getDoctorProfile( projectId, clinicId, doctorId[0], context, doctorsList); //speak(); } else { navigateToSearchResults(context, doctorsList, arr, arrDistance); } } }); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); print(err); }); } Future navigateToDoctorProfile(context, docObject, docProfile, {isAppo}) async { Navigator.push( context, MaterialPageRoute( builder: (context) => DoctorProfile( doctor: docObject, docProfileList: docProfile, isOpenAppt: isAppo, ))); } Future navigateToSearchResults(context, docList, arr, arrDistance) async { var result = LinkedHashSet.from(arr).toList(); var numAll = result.length; Navigator.push( context, MaterialPageRoute( builder: (context) => BranchView( doctorsList: docList, result: result, num: numAll, resultDistance: arrDistance), ), ); } speak({isInit}) async { //if (mounted) { setState(() { this.networkImage = results['AnimationURL']; this.isAnimationEnable = true; }); //} if (isInit == true) { event.setValue({"animationEnable": 'true'}); } if (isArabic == false && results['ReturnMessage'] != null) { await flutterTts .setVoice({"name": "en-au-x-aub-network", "locale": "en-AU"}); await flutterTts.speak(results['ReturnMessage']); } else if (results['ReturnMessage_Ar'] != null) { await flutterTts .setVoice({"name": "ar-xa-x-ard-network", "locale": "ar"}); await flutterTts.speak(results['ReturnMessage_Ar']); } stopAnimation(isInit: isInit); } goToClinic(List ids) { Navigator.push( AppGlobal.context, MaterialPageRoute( builder: (context) => Search( type: 0, clnicIds: ids, ))); speak(); } List unique(List list) { return list.toSet().toList(); } getUserData() async { if (await this.sharedPref.getObject(USER_PROFILE) != null) { user = AuthenticatedUser.fromJson( await this.sharedPref.getObject(USER_PROFILE)); } } initialSpeak() async { await flutterTts.awaitSpeakCompletion(true); results = { 'ReturnMessage_Ar': "هذه الخدمة تم تصميمها لتتمكن من ربط الملفات الطبية للعائلة بملفك الطبي حتى تتمكن من إدارة سجلاتهم عن طريق تسجيل الدخول إلى ملفك الطبي.", 'ReturnMessage': "Through this service, you will be able to link your family medical files to your medical file so that you can manage their records by login to your medical file." }; if (IS_VOICE_COMMAND_CLOSED == false) { if (IS_TEXT_COMPLETED == false) { this.speak(isInit: true); } controller.forward(); } } stopAnimation({isInit}) async { if (isInit == true) { IS_TEXT_COMPLETED = true; } flutterTts.setCompletionHandler(() async { event.setValue({"animationEnable": 'false'}); setState(() { this.networkImage = null; this.isAnimationEnable = false; }); }); } signOut() async { authenticatedUserObject.logout(); projectProvider.isLogin = false; await authenticatedUserObject.getUser(); _vitalSignService.heightCm = ""; _vitalSignService.weightKg = ""; await sharedPref.clear(); this.user = null; Navigator.of(context).pushNamed(HOME); } } class RoboSearch { final BuildContext context; static var dialog; RoboSearch({ @required this.context, }); showAlertDialog(BuildContext context) { //AlertDialog alert = AlertDialog // AlertDialog alert = AlertDialog(content: MyStatefulBuilder(dispose: () { // print('dispose!!!!!!!!!!!!'); // }) // isClosed = true; // streamSubscription.cancel(); // }, builder: (BuildContext context, StateSetter setState) { // //print(streamSubscription); // }), // ); // show the dialog showDialog( context: context, barrierDismissible: true, builder: (BuildContext context) { dialog = context; return MyStatefulBuilder( dispose: () {}, ); }, ); print(dialog); } static closeAlertDialog(BuildContext context) { Navigator.of(dialog).pop(); } } typedef Disposer = void Function(); class MyStatefulBuilder extends StatefulWidget { const MyStatefulBuilder({ // @required this.builder, @required this.dispose, }); //final StatefulWidgetBuilder builder; final Disposer dispose; @override _MyStatefulBuilderState createState() => _MyStatefulBuilderState(); } class _MyStatefulBuilderState extends State { var event = RobotProvider(); var searchText; static StreamSubscription streamSubscription; static var isClosed = false; @override void initState() { streamSubscription = event.controller.stream.listen((p) { if ((p['searchText'] != 'null' && p['searchText'] != null && p['searchText'] != "" && isClosed == false) && mounted) { setState(() { searchText = p['searchText']; }); } }); super.initState(); } @override Widget build(BuildContext context) => AlertDialog( content: Container( color: Colors.white, height: SizeConfig.realScreenHeight * 0.5, width: SizeConfig.realScreenWidth * 0.8, child: Container( child: Column(children: [ Expanded( flex: 1, child: Center( child: Image.asset( 'assets/images/habib-logo.png', height: 75, width: 75, ))), Expanded( flex: 3, child: Center( child: Container( margin: EdgeInsets.all(20), padding: EdgeInsets.all(10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(100), border: Border.all(width: 2, color: Colors.red)), child: Icon( Icons.mic, color: Colors.blue, size: 48, ), ))), Expanded( flex: 1, child: Center( child: Text(searchText != null && searchText != 'null' ? searchText : TranslationBase.of(context).trySaying))), searchText == 'null' ? Center( child: RaisedButton( child: Text('Retry'), onPressed: () { RoboSearch.closeAlertDialog(context); event.setValue({'startPopUp': 'true'}); }, )) : SizedBox() ]), ))); @override void dispose() { super.dispose(); widget.dispose(); } }