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.
652 lines
20 KiB
Dart
652 lines
20 KiB
Dart
import 'dart:collection';
|
|
import 'dart:math';
|
|
import 'package:diplomaticquarterapp/config/config.dart';
|
|
import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart';
|
|
import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart';
|
|
import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/BranchView.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/livecare/livecare_home.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/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/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_toast.dart';
|
|
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
|
|
import 'package:diplomaticquarterapp/widgets/robo-search/robosearch.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: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:diplomaticquarterapp/pages/BookAppointment/DoctorProfile.dart';
|
|
import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
import 'package:smart_progress_bar/smart_progress_bar.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;
|
|
final SpeechToText speech = 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;
|
|
|
|
bool _isInit = true;
|
|
var event = RobotProvider();
|
|
|
|
bool _hasSpeech = false;
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
event.controller.stream.listen((p) {
|
|
if (p['isRobot'] == 'true') {
|
|
setState(() {
|
|
position = Offset(250, 400);
|
|
activeAnimation = false;
|
|
});
|
|
}
|
|
});
|
|
requestPermissions();
|
|
// Future.delayed(const Duration(seconds: 10), () {
|
|
initSpeechState().then((value) => {});
|
|
// });
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AnimatedPositioned(
|
|
onEnd: () {
|
|
// setState(() {
|
|
// this.isShow = false;
|
|
// position = Offset(250, 400);
|
|
// });
|
|
},
|
|
left: activeAnimation ? 300 : position.dx,
|
|
top: activeAnimation ? -150 : position.dy,
|
|
duration: activeAnimation
|
|
? const Duration(seconds: 1)
|
|
: const Duration(seconds: 0),
|
|
// curve: Curves.bounceOut,
|
|
child: isShow
|
|
? Draggable(
|
|
feedback: Container(child: getStack()),
|
|
child: getStack(),
|
|
childWhenDragging: Container(
|
|
color: Colors.transparent,
|
|
),
|
|
onDragEnd: (details) {
|
|
setState(() {
|
|
position = details.offset;
|
|
});
|
|
})
|
|
: Container());
|
|
|
|
// Draggable(
|
|
// feedback: getStack(),
|
|
// childWhenDragging: Container(),
|
|
// child: getStack(),
|
|
// onDragEnd: (drag) {
|
|
// setState(() {
|
|
// top = top + drag.offset.dy < 0 ? 0 : top + drag.offset.dy;
|
|
// left = left + drag.offset.dx < 0 ? 0 : left + drag.offset.dx;
|
|
// });
|
|
// });
|
|
}
|
|
|
|
Widget getStack() {
|
|
return Container(
|
|
height: 150,
|
|
width: 150,
|
|
child: Stack(children: <Widget>[
|
|
// Column(
|
|
// mainAxisSize: MainAxisSize.min,
|
|
// crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
// children: <Widget>[
|
|
GestureDetector(
|
|
child: Container(
|
|
child: SvgPicture.asset('assets/images/robort_svg.svg'),
|
|
),
|
|
onTap: () {
|
|
new RoboSearch(context: context).showAlertDialog(context);
|
|
startVoiceSearch();
|
|
},
|
|
),
|
|
// ],
|
|
// ),
|
|
Positioned(
|
|
right: 0.0,
|
|
top: 10,
|
|
child: GestureDetector(
|
|
onTap: () {
|
|
setState(() {
|
|
activeAnimation = true;
|
|
});
|
|
},
|
|
child: Align(
|
|
alignment: Alignment.topRight,
|
|
child: CircleAvatar(
|
|
radius: 14.0,
|
|
backgroundColor: Colors.red,
|
|
child: Icon(Icons.close, color: Colors.white),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
])
|
|
|
|
// Stack(
|
|
// fit: StackFit.loose,
|
|
// overflow: Overflow.visible,
|
|
// children: <Widget>[
|
|
// Container(),
|
|
// Positioned(
|
|
// child: GestureDetector(
|
|
// behavior: HitTestBehavior.translucent,
|
|
// onTapDown: (TapDownDetails details) => {
|
|
// setState(() {
|
|
// activeAnimation = true;
|
|
// })
|
|
// }, // handle your image tap here
|
|
// child: Image.asset(
|
|
// 'assets/images/CloseIcon.png',
|
|
// fit: BoxFit.cover, // this is the solution for border
|
|
// width: 30.0,
|
|
// height: 30.0,
|
|
// ),
|
|
// )),
|
|
// Positioned(
|
|
// child: GestureDetector(
|
|
// onTap: () {
|
|
// this.roboSearch(context);
|
|
// }, // handle your image tap here
|
|
// child: SvgPicture.asset('assets/images/robort_svg.svg')))
|
|
|
|
// // new RawMaterialButton(
|
|
// // // shape: new CircleBorder(),
|
|
// // elevation: 1.0,
|
|
// // child: SvgPicture.asset('assets/images/robort_svg.svg'),
|
|
// // onPressed: () {},
|
|
// // ),
|
|
// ],
|
|
// )
|
|
|
|
);
|
|
}
|
|
|
|
startVoiceSearch() async {
|
|
_currentLocaleId =
|
|
TranslationBase.of(AppGlobal.context).locale.languageCode == 'en'
|
|
? 'en-US'
|
|
: 'ar-SA';
|
|
speech.listen(
|
|
onResult: resultListener,
|
|
listenFor: Duration(seconds: 10),
|
|
localeId: _currentLocaleId,
|
|
onSoundLevelChange: soundLevelListener,
|
|
cancelOnError: true,
|
|
partialResults: true,
|
|
onDevice: true,
|
|
listenMode: ListenMode.deviceDefault);
|
|
}
|
|
|
|
void resultListener(SpeechRecognitionResult result) {
|
|
// lastWords = "${result.recognizedWords} - ${result.finalResult}";
|
|
|
|
if (result.finalResult == true) {
|
|
// setState(() {
|
|
|
|
|
|
reconizedWord = result.recognizedWords;
|
|
event.setValue({"searchText": reconizedWord});
|
|
setState(() {
|
|
searchText = reconizedWord;
|
|
});
|
|
Future.delayed(const Duration(seconds: 1), () {
|
|
_speak(reconizedWord);
|
|
});
|
|
}
|
|
//});
|
|
}
|
|
|
|
Future _speak(reconizedWord) async {
|
|
//await flutterTts.speak(reconizedWord);
|
|
RoboSearch.closeAlertDialog(context);
|
|
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 {
|
|
Map<Permission, PermissionStatus> statuses = await [
|
|
Permission.microphone,
|
|
].request();
|
|
}
|
|
|
|
Future<void> initSpeechState() async {
|
|
bool hasSpeech = await speech.initialize(
|
|
onError: errorListener, onStatus: statusListener);
|
|
if (hasSpeech) {
|
|
_currentLocaleId =
|
|
TranslationBase.of(AppGlobal.context).locale.languageCode == 'en'
|
|
? 'en-US'
|
|
: 'ar-SA'; // systemLocale.localeId;
|
|
|
|
}
|
|
if (!mounted) return;
|
|
|
|
setState(() {
|
|
_hasSpeech = hasSpeech;
|
|
});
|
|
}
|
|
|
|
void errorListener(SpeechRecognitionError error) {
|
|
//setState(() {
|
|
// reconizedWord = "${error.errorMsg} - ${error.permanent}";
|
|
//});
|
|
}
|
|
|
|
void statusListener(String status) {
|
|
//setState(() {
|
|
reconizedWord = status == 'listening' ? 'Lisening...' : 'Sorry....';
|
|
|
|
//});
|
|
}
|
|
|
|
getPages(text) {
|
|
var request = {
|
|
'VoiceMessage': text,
|
|
'Lang': TranslationBase.of(AppGlobal.context).locale.languageCode == 'en'
|
|
? 'En'
|
|
: 'Ar'
|
|
};
|
|
|
|
searchProvider
|
|
.getBotPages(request)
|
|
.then((value) => {getCommands(value['Understand'])});
|
|
}
|
|
|
|
getCommands(result) async {
|
|
print(result);
|
|
results = result;
|
|
|
|
switch (result["CommandNumber"]) {
|
|
case '100':
|
|
{
|
|
List clnicID = unique(result['ClinicId']);
|
|
if (result['ProjectId'] != 0 &&
|
|
clnicID.length > 0 &&
|
|
result['DoctorId'].length > 0) {
|
|
if (clnicID.length == 1) {
|
|
getDoctorsList(
|
|
result['ProjectId'],
|
|
clnicID[0],
|
|
context,
|
|
doctorId: result['DoctorId'],
|
|
doctorName: null,
|
|
);
|
|
} else {
|
|
goToClinic(clnicID);
|
|
}
|
|
} else if (result['ProjectId'] != 0 &&
|
|
clnicID.length > 0 &&
|
|
result['DoctorId'].length == 0) {
|
|
if (clnicID.length == 1) {
|
|
getDoctorsList(
|
|
result['ProjectId'],
|
|
clnicID[0],
|
|
context,
|
|
);
|
|
} else {
|
|
goToClinic(clnicID);
|
|
}
|
|
} else if (result['ProjectId'] == 0 &&
|
|
clnicID.length > 0 &&
|
|
result['DoctorId'].length == 0) {
|
|
if (clnicID.length == 1) {
|
|
getDoctorsList(
|
|
result['ProjectId'],
|
|
clnicID[0],
|
|
context,
|
|
);
|
|
} else {
|
|
goToClinic(clnicID);
|
|
}
|
|
} else if (result['ProjectId'] == 0 &&
|
|
clnicID.length > 0 &&
|
|
result['DoctorId'].length > 0) {
|
|
if (clnicID.length == 1) {
|
|
getDoctorsList(
|
|
result['ProjectId'],
|
|
clnicID[0],
|
|
context,
|
|
doctorId: result['DoctorId'],
|
|
doctorName: null,
|
|
);
|
|
} else {
|
|
goToClinic(clnicID);
|
|
}
|
|
} else {
|
|
goToClinic(clnicID);
|
|
}
|
|
// speak();
|
|
}
|
|
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 '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: LiveCareHome()));
|
|
}
|
|
break;
|
|
|
|
case '200':
|
|
{
|
|
Navigator.push(context, FadePage(page: FeedbackHomePage()));
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Navigator.of(context).pushNamed(HOME);
|
|
speak();
|
|
break;
|
|
}
|
|
|
|
//searchProvider.setLisener(result);
|
|
}
|
|
|
|
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}) {
|
|
List<DoctorList> doctorsList = [];
|
|
List<String> arr = [];
|
|
List<String> arrDistance = [];
|
|
DoctorsListService service = new DoctorsListService();
|
|
service
|
|
.getDoctorsList(clinicId, projectId, false, context,
|
|
doctorId: doctorId, doctorName: doctorName)
|
|
.then((res) {
|
|
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) {
|
|
print(err);
|
|
}).showProgressBar(
|
|
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
|
|
}
|
|
|
|
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 {
|
|
// Navigator.push(
|
|
// context,
|
|
// MaterialPageRoute(
|
|
// builder: (context) => SearchResults(doctorsList: docList)));
|
|
var result = LinkedHashSet<String>.from(arr).toList();
|
|
var numAll = result.length;
|
|
Navigator.push(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (context) => BranchView(
|
|
doctorsList: docList,
|
|
result: result,
|
|
num: numAll,
|
|
resultDistance: arrDistance),
|
|
),
|
|
);
|
|
}
|
|
|
|
speak() async {
|
|
if (_currentLocaleId == 'en-US' && results['ReturnMessage'] != null) {
|
|
await flutterTts.setVoice("en-us-x-sfg#male_2-local");
|
|
await flutterTts.setLanguage(_currentLocaleId);
|
|
await flutterTts.speak(results['ReturnMessage']);
|
|
} else if (results['ReturnMessage_Ar'] != null) {
|
|
await flutterTts.setLanguage(_currentLocaleId);
|
|
|
|
await flutterTts.setVoice("ar-sa-x-sfg#male_1-local");
|
|
await flutterTts.speak(results['ReturnMessage_Ar']);
|
|
}
|
|
// Future.delayed(const Duration(seconds: 10), () {
|
|
// initSpeechState().then((value) => startVoiceSearch());
|
|
// });
|
|
}
|
|
|
|
goToClinic(List ids) {
|
|
Navigator.push(
|
|
AppGlobal.context,
|
|
MaterialPageRoute(
|
|
builder: (context) => Search(
|
|
type: 0,
|
|
clnicIds: ids,
|
|
)));
|
|
speak();
|
|
}
|
|
|
|
List unique(List list) {
|
|
return list.toSet().toList();
|
|
}
|
|
}
|