|
|
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/BookAppointment/DoctorProfile.dart';
|
|
|
import 'package:diplomaticquarterapp/pages/BookAppointment/Search.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/balance/my_balance_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/medical_profile_page_new.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/cupertino.dart';
|
|
|
import 'package:flutter/material.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<FloatingSearchButton> 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> offset;
|
|
|
String networkImage;
|
|
|
bool isArabic;
|
|
|
|
|
|
@override
|
|
|
void initState() {
|
|
|
controller = AnimationController(vsync: this, duration: Duration(seconds: 1));
|
|
|
offset = Tween<Offset>(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<ProjectViewModel>(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<AuthenticatedUserObject>();
|
|
|
VitalSignService _vitalSignService = locator<VitalSignService>();
|
|
|
|
|
|
@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: <Widget>[
|
|
|
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;
|
|
|
event.setValue({'isRobotVisible': 'false'});
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
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<Permission, PermissionStatus> statuses = await [
|
|
|
Permission.microphone,
|
|
|
].request();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Future<void> 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: MedicalProfilePageNew()));
|
|
|
}
|
|
|
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<DoctorProfileList> 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<DoctorList> doctorsList = [];
|
|
|
List<String> arr = [];
|
|
|
List<String> 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,
|
|
|
FadePage(
|
|
|
page: DoctorProfile(
|
|
|
doctor: docObject,
|
|
|
docProfileList: docProfile,
|
|
|
isOpenAppt: isAppo,
|
|
|
)));
|
|
|
}
|
|
|
|
|
|
Future navigateToSearchResults(context, docList, arr, arrDistance) async {
|
|
|
var result = LinkedHashSet<String>.from(arr).toList();
|
|
|
var numAll = result.length;
|
|
|
Navigator.push(
|
|
|
context,
|
|
|
FadePage(
|
|
|
page: 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 && isInit == false) {
|
|
|
await flutterTts.setVoice({"name": "en-au-x-aub-network", "locale": "en-AU"});
|
|
|
await flutterTts.speak(results['ReturnMessage']);
|
|
|
} else if (results['ReturnMessage_Ar'] != null && isInit == false) {
|
|
|
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;
|
|
|
Future.delayed(const Duration(seconds: 10), () {
|
|
|
event.setValue({"animationEnable": 'false'});
|
|
|
setState(() {
|
|
|
this.networkImage = null;
|
|
|
this.isAnimationEnable = false;
|
|
|
});
|
|
|
});
|
|
|
} else {
|
|
|
flutterTts.setCompletionHandler(() async {
|
|
|
event.setValue({"animationEnable": 'false'});
|
|
|
setState(() {
|
|
|
this.networkImage = null;
|
|
|
this.isAnimationEnable = false;
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
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<MyStatefulBuilder> {
|
|
|
var event = RobotProvider();
|
|
|
var searchText;
|
|
|
static StreamSubscription<dynamic> 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: Image.asset(
|
|
|
'assets/images/soundWaveAnimation.gif',
|
|
|
height: 75,
|
|
|
))),
|
|
|
Expanded(flex: 1, child: Center(child: AppText(searchText != null && searchText != 'null' ? searchText : TranslationBase.of(context).trySaying))),
|
|
|
searchText == 'null'
|
|
|
? Center(
|
|
|
child: RaisedButton(
|
|
|
child: AppText('Retry'),
|
|
|
onPressed: () {
|
|
|
RoboSearch.closeAlertDialog(context);
|
|
|
event.setValue({'startPopUp': 'true'});
|
|
|
},
|
|
|
))
|
|
|
: SizedBox()
|
|
|
]),
|
|
|
)));
|
|
|
|
|
|
@override
|
|
|
void dispose() {
|
|
|
super.dispose();
|
|
|
widget.dispose();
|
|
|
}
|
|
|
}
|