@ -1,7 +1,43 @@
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/robo-search/search.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
@ -10,36 +46,77 @@ class FloatingSearchButton extends StatefulWidget {
class _FloatingSearchButton extends State < FloatingSearchButton >
with TickerProviderStateMixin {
Offset position = Offset ( 30.0 , 40.0 ) ;
AlignmentDirectional _ironManAlignment = AlignmentDirectional ( 0.0 , 0.7 ) ;
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 ( ) {
/ / TODO: implement 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 Positioned (
left: position . dx ,
top: position . dy ,
child: Draggable (
feedback: Container ( child: getStack ( ) ) ,
child: Container (
child: AnimatedContainer (
duration: Duration ( seconds: 2 ) ,
alignment: _ironManAlignment ,
child: getStack ( ) ,
) ) ,
childWhenDragging: Container (
color: Colors . transparent ,
) ,
onDragEnd: ( details ) {
setState ( ( ) {
position = details . offset ;
} ) ;
} ) ) ;
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 ( ) ,
@ -57,42 +134,518 @@ class _FloatingSearchButton extends State<FloatingSearchButton>
return Container (
height: 150 ,
width: 150 ,
child: Stack (
children: < Widget > [
Positioned (
top: 10 ,
right: 0 ,
child: GestureDetector (
onTap: ( ) {
print ( " hi " ) ;
setState ( ( ) {
_ironManAlignment = AlignmentDirectional ( 0.0 , - 0.20 ) ;
} ) ;
} , / / 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 ,
) ) ,
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 ) ,
) ,
) ,
) ,
GestureDetector (
onTap: ( ) {
/ / animationController . forward ( ) ;
} , / / 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: ( ) { } ,
/ / ) ,
] ,
) ) ;
}
roboSearch ( context ) {
var dialog = RoboSearch ( context: context ) ;
dialog . showAlertDialog ( context ) ;
) ,
] )
/ / 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 ( ) ;
}
}