diff --git a/assets/tones/call_tone.mp3 b/assets/tones/call_tone.mp3 new file mode 100644 index 0000000..d79a046 Binary files /dev/null and b/assets/tones/call_tone.mp3 differ diff --git a/lib/core/api.dart b/lib/core/api.dart index f5de6f1..f13a376 100644 --- a/lib/core/api.dart +++ b/lib/core/api.dart @@ -4,8 +4,8 @@ import 'package:flutter/cupertino.dart'; import 'package:queuing_system/core/base/base_app_client.dart'; import 'package:queuing_system/core/response_model/patient_call.dart'; -const _getCallRequestInfoByClinicInfo = "/GetCallRequestInfoByClinincInfo"; -const _call_UpdateNotIsQueueRecordByIDAsync = "/Call_UpdateNotIsQueueRecordByID"; +const _getCallRequestInfoByClinicInfo = "/GetCallRequestInfoByClinincInfoNew"; +const _call_UpdateNotIsQueueRecordByIDAsync = "/Call_UpdateNotIsQueueRecordByIDNew"; class API { static getCallRequestInfoByClinicInfo(String deviceIp, {@required Function(List, List) onSuccess, @required Function(dynamic) onFailure}) async { @@ -14,11 +14,11 @@ class API { body: body, onSuccess: (response, status) { if (status == 200) { - var calledByNurse = (response["CalledByNurse"] as List).map((j) => Tickets.fromJson(j)).toList(); + var calledByNurse = (response["CalledByNurseNew"] as List).map((j) => Tickets.fromJson(j)).toList(); - final patients = (response["ClinicCurrentPatient"] as List).map((j) => Tickets.fromJson(j)).toList(); + final patients = (response["ClinicCurrentPatientNew"] as List).map((j) => Tickets.fromJson(j)).toList(); calledByNurse.addAll(patients); - log("calledByNurse: ${calledByNurse.toString()} "); + log("CalledByNurseNew: ${calledByNurse.toString()} "); log("patients: ${patients.toString()} "); var isQueuePatients = calledByNurse.where((element) => element.isQueue == false).toList(); diff --git a/lib/core/response_model/patient_call.dart b/lib/core/response_model/patient_call.dart index ca93354..c126cbb 100644 --- a/lib/core/response_model/patient_call.dart +++ b/lib/core/response_model/patient_call.dart @@ -17,10 +17,13 @@ class Tickets { this.callNoStr, this.queueNo, this.queueDuration, + this.isQueue, + this.isVoiceReq, + this.isToneReq, }); int getRandomNum() { - return Random().nextInt(2); + return Random().nextInt(1); } Tickets.fromJson(dynamic json) { @@ -39,6 +42,8 @@ class Tickets { queueDuration = json['QueueDuration']; callNoStr = json['CallNoStr'] ?? json['CallNo'].toString(); isQueue = json["ISQueue"] ?? false; + isToneReq = json["IsToneReq"] ?? true; + isVoiceReq = json["IsVoiceReq"] ?? true; // isQueue = getRandomNum(); } @@ -58,6 +63,8 @@ class Tickets { String callNoStr; bool callUpdated = false; bool isQueue; + bool isToneReq; + bool isVoiceReq; Map toJson() { final map = {}; @@ -76,12 +83,14 @@ class Tickets { map['QueueNo'] = queueNo; map['QueueDuration'] = queueDuration; map['ISQueue'] = isQueue; + map['IsToneReq'] = isToneReq; + map['IsVoiceReq'] = isVoiceReq; return map; } @override String toString() { - return (callNoStr).toString(); + return (queueNo).toString(); } CallType getCallType() { diff --git a/lib/home/home_screen.dart b/lib/home/home_screen.dart index 5f263ad..9b74296 100644 --- a/lib/home/home_screen.dart +++ b/lib/home/home_screen.dart @@ -2,9 +2,9 @@ import 'dart:developer'; import 'package:connectivity/connectivity.dart'; import 'package:flutter/material.dart'; +import 'package:just_audio/just_audio.dart'; import 'package:queuing_system/core/api.dart'; import 'package:queuing_system/core/base/app_scaffold_widget.dart'; -import 'package:queuing_system/core/config/config.dart'; import 'package:queuing_system/core/config/size_config.dart'; import 'package:queuing_system/core/response_model/patient_call.dart'; import 'package:queuing_system/header/app_header.dart'; @@ -22,7 +22,9 @@ var DEVICE_IP = "10.10.15.11"; // Testing IP // var DEVICE_IP = "10.70.249.21"; // (Make sure by Haroon before use it) Production IP class MyHomePage extends StatefulWidget { - String title = "MyHomePage"; + final String title = "MyHomePage"; + + const MyHomePage({Key key}) : super(key: key); @override State createState() => _MyHomePageState(); @@ -82,30 +84,30 @@ class _MyHomePageState extends State { ), ], ), - Row( - children: [ - const SizedBox(width: 60), - SizedBox( - width: 200, - child: TextField( - controller: controller, - )), - const SizedBox(width: 30), - isLoading - ? const CircularProgressIndicator() - : ElevatedButton( - onPressed: onUpdateIPPressed, - child: const Text( - "Update IP", - style: TextStyle(color: Colors.white), - ), - style: ElevatedButton.styleFrom(backgroundColor: AppGlobal.appRedColor), - ), - const SizedBox(width: 30), - Text("IP: $DEVICE_IP", style: const TextStyle(fontWeight: FontWeight.w600)), - const SizedBox(width: 20), - ], - ), + // Row( + // children: [ + // const SizedBox(width: 60), + // SizedBox( + // width: 200, + // child: TextField( + // controller: controller, + // )), + // const SizedBox(width: 30), + // isLoading + // ? const CircularProgressIndicator() + // : ElevatedButton( + // onPressed: onUpdateIPPressed, + // child: const Text( + // "Update IP", + // style: TextStyle(color: Colors.white), + // ), + // style: ElevatedButton.styleFrom(backgroundColor: AppGlobal.appRedColor), + // ), + // const SizedBox(width: 30), + // Text("IP: $DEVICE_IP", style: const TextStyle(fontWeight: FontWeight.w600)), + // const SizedBox(width: 20), + // ], + // ), ], ), ), @@ -168,35 +170,64 @@ class _MyHomePageState extends State { } CallByVoice voiceCaller; + final AudioPlayer audioPlayer = AudioPlayer(); int callFlag = 0; voiceCall() async { - //TODO: After calling this voice call, we should delay for milliseconds that is given by API. After that we will check if there are more patients in isQueuePatients we will remove the patient from waiting list and then update the state + //DONE: After calling this voice call, we should delay for milliseconds that is given by API. After that we will check if there are more patients in isQueuePatients we will remove the patient from waiting list and then update the state - if (waitings.isNotEmpty && voiceCaller == null) { - final postVoice = getCallTypeText(waitings.first); - voiceCaller = CallByVoice(waitings.first.callNoStr.toString(), preVoice: "Ticket Number", postVoice: postVoice, lang: 'en'); - await voiceCaller.startCalling(); - voiceCaller = null; + if (waitings.isNotEmpty) { + if (waitings.first.isToneReq) { + audioPlayer.setAsset("assets/tones/call_tone.mp3"); + await audioPlayer.play(); + await Future.delayed(const Duration(seconds: 2)); + } + if (waitings.first.isVoiceReq && voiceCaller == null) { + final postVoice = getCallTypeText(waitings.first); + voiceCaller = CallByVoice(waitings.first.queueNo.toString(), preVoice: "Ticket Number", postVoice: postVoice, lang: 'en'); + await voiceCaller.startCalling(); + voiceCaller = null; + } } if (isQueuePatients.isNotEmpty) { await Future.delayed(Duration(milliseconds: int.parse(isQueuePatients.first.queueDuration) * 10)).whenComplete(() async { - isQueuePatients.removeAt(0); - Tickets ticket = waitings.elementAt(0); - waitings.removeAt(0); - waitings.add(ticket); if (isQueuePatients.isNotEmpty) { - setState(() {}); + isQueuePatients.removeAt(0); + } + if (waitings.isNotEmpty) { + Tickets ticket = waitings.elementAt(0); + waitings.removeAt(0); + waitings.add(ticket); } - if (isQueuePatients.isEmpty && callFlag == 1) { - callFlag == 0; - await Future.delayed(const Duration(seconds: 3)); + if (isQueuePatients.isNotEmpty) { + setState(() {}); } }); + } else { + // if (isQueuePatients.isEmpty && callFlag == 1) { + // callFlag == 0; + // await Future.delayed(const Duration(seconds: 3)); + // waitings.clear(); + // API.getCallRequestInfoByClinicInfo(DEVICE_IP, onSuccess: (waitingCalls, isQueuePatientsCalls) { + // setState(() { + // waitings = waitingCalls; + // isQueuePatients = isQueuePatientsCalls; + // // currents = currentInClinic; + // }); + // + // log("--------------------"); + // log("waiting: $waitings"); + // log("isQueuePatients: $isQueuePatients"); + // log("--------------------"); + // + // updateTickets(); + // }, onFailure: (error) {}); + // } } } onUpdateAvailable(data) async { + print("here is the data: $data"); if (isQueuePatients.isNotEmpty && callFlag == 0) { callFlag = 1; return; diff --git a/lib/home/home_screen_components.dart b/lib/home/home_screen_components.dart index 3f3408f..4eb11c0 100644 --- a/lib/home/home_screen_components.dart +++ b/lib/home/home_screen_components.dart @@ -44,8 +44,8 @@ Widget priorityTicketsWithSideList(List tickets) { SizedBox( width: SizeConfig.getWidthMultiplier() * 13, child: AppText( - itm.callNoStr.toString(), - letterSpacing: -2.32, + itm.queueNo.toString(), + letterSpacing: -2, fontWeight: FontWeight.bold, fontSize: SizeConfig.getWidthMultiplier() * 4.5, textAlign: TextAlign.end, diff --git a/lib/home/priority_calls.dart b/lib/home/priority_calls.dart index 35ae16b..8bbb4e4 100644 --- a/lib/home/priority_calls.dart +++ b/lib/home/priority_calls.dart @@ -21,7 +21,7 @@ class PriorityTickets extends StatelessWidget { children: [ const SizedBox(height: 20), vTicketItem( - ticketNo: firstTicket.callNoStr ?? '', + ticketNo: firstTicket.queueNo ?? '', callType: firstTicket.getCallType(), scale: 1, blink: true, @@ -34,14 +34,14 @@ class PriorityTickets extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceAround, children: otherTickets .map((ticket) => Padding( - padding: EdgeInsets.only(top: SizeConfig.getHeightMultiplier() * 2), - child: vTicketItem( - ticketNo: ticket.callNoStr ?? '', + padding: EdgeInsets.only(top: SizeConfig.getHeightMultiplier() * 2), + child: vTicketItem( + ticketNo: ticket.queueNo ?? '', callType: ticket.getCallType(), scale: 0.7, roomNo: ticket.roomNo, ), - )) + )) .toList(), ) ] @@ -59,6 +59,11 @@ class vTicketItem extends StatelessWidget { const vTicketItem({@required this.ticketNo, @required this.roomNo, @required this.callType, this.scale, this.blink = false}); + String getFormattedTicket(String ticketNo) { + var formattedString = ticketNo.split(" "); + return formattedString[0] + " " + formattedString[1]; + } + @override Widget build(BuildContext context) { return Transform.scale( @@ -66,8 +71,13 @@ class vTicketItem extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - BlinkText(ticketNo, - style: TextStyle(fontSize: SizeConfig.getWidthMultiplier() * 10, letterSpacing: -9.32, height: 0.5, fontWeight: FontWeight.bold), + BlinkText(getFormattedTicket(ticketNo), + style: TextStyle( + fontSize: SizeConfig.getWidthMultiplier() * 10, + letterSpacing: -9.32, + height: 0.5, + fontWeight: FontWeight.bold, + ), beginColor: Colors.black, endColor: blink ? Colors.black.withOpacity(0.1) : Colors.black, // endColor: blink ? AppGlobal.appRedColor : Colors.black, @@ -95,12 +105,12 @@ class vTicketItem extends StatelessWidget { fontWeight: FontWeight.w600, fontHeight: 0.5, ), - Container( - color: Colors.grey.withOpacity(0.3), - width: 6, - height: SizeConfig.getHeightMultiplier() * 3, - margin: const EdgeInsets.symmetric(horizontal: 10), - ), + Container( + color: Colors.grey.withOpacity(0.3), + width: 6, + height: SizeConfig.getHeightMultiplier() * 3, + margin: const EdgeInsets.symmetric(horizontal: 10), + ), AppText( "Room: $roomNo", color: callType.color(), diff --git a/lib/utils/call_by_voice.dart b/lib/utils/call_by_voice.dart index a23887c..e537020 100644 --- a/lib/utils/call_by_voice.dart +++ b/lib/utils/call_by_voice.dart @@ -1,5 +1,3 @@ -import 'dart:developer'; - import 'package:flutter/cupertino.dart'; import 'package:flutter_tts/flutter_tts.dart'; @@ -21,13 +19,14 @@ class CallByVoice { startCalling() async { textToSpeech.setLanguage("en-US"); - var splitText = ticketNo.split("-"); + var clinic = ticketNo.split(" "); + var splitText = clinic[1].split("-"); // Create Pre Voice Players if (preVoice != null && preVoice.isNotEmpty) { textToSpeech.setSpeechRate(rate); textToSpeech.setPitch(pitch); textToSpeech.setVolume(volume); - await textToSpeech.speak(preVoice + " .. " + splitText[0] + " .. " + splitText[1] + " .. " + postVoice); + await textToSpeech.speak(preVoice + " .. " + clinic[0] + " .. " + splitText[0] + " .. " + splitText[1] + " .. " + postVoice); } // // Create Ticket Number Voice Players diff --git a/lib/utils/signalR_utils.dart b/lib/utils/signalR_utils.dart index 505feb1..fe08ad1 100644 --- a/lib/utils/signalR_utils.dart +++ b/lib/utils/signalR_utils.dart @@ -15,30 +15,33 @@ https://vcallapi.hmg.com/patientcalling.html?IPAddress=10.10.14.20&Clinic=4&Proj --------------------------------------- */ -class SignalRHelper{ +class SignalRHelper { + // String hubBaseURL = "https://vcallapi.hmg.com/PatientCallingHub"; String hubBaseURL = "https://vcallapi.hmg.com/PatientCallingHub"; + // String hubBaseURL = "https://vcallapi.hmg.com/PatientCallingHub?IPAddress=10.10.14.20"; // "https://VCallApi.hmg.com/WebRTCHub?source=mobile&username=2001273"; - String msg ="Awaiting Patients Arrival"; + String msg = "Awaiting Patients Arrival"; HubConnection connection; - startSignalRConnection(String deviceIp, {@required Function(dynamic) onUpdateAvailable, @required VoidCallback onConnect, @required Function(dynamic) onDisconnect, @required VoidCallback onConnecting}) async { - + startSignalRConnection(String deviceIp, + {@required Function(dynamic) onUpdateAvailable, @required VoidCallback onConnect, @required Function(dynamic) onDisconnect, @required VoidCallback onConnecting}) async { // Hardcoded IP For Testing // deviceIp = "10.10.14.11"; print("Connecting Signal R with: $deviceIp"); final url = hubBaseURL+"?IPAddress=$deviceIp"; + // final url = hubBaseURL; connection = HubConnectionBuilder() .withUrl( - url, - HttpConnectionOptions( - client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true), - transport: HttpTransportType.webSockets, - logging: (level, message) => { - print(message) - }, - )) + url, + HttpConnectionOptions( + client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true), + transport: HttpTransportType.webSockets, + logging: (level, message) => { + print(message), + }, + )) .build(); connection.onclose(onDisconnect); @@ -49,33 +52,33 @@ class SignalRHelper{ onUpdateAvailable(message); }); + // try { await connection.start(); - - } + // } catch (e, s) { + // print("Here the error: ${e.toString()}"); + // } + } void sendMessage(List args) async { await connection.invoke('SendMessage', args: args); //['Bob', 'Says hi!'] } bool getConnectionState() { - if(connection == null ) return false; + if (connection == null) return false; if (connection.state == HubConnectionState.connected || connection.state == HubConnectionState.connecting) return true; if (connection.state == HubConnectionState.disconnected || connection.state == HubConnectionState.disconnecting) return false; } - closeConnection(BuildContext context) async { - if(connection.state == HubConnectionState.connected || connection.state == HubConnectionState.connecting) - { + if (connection.state == HubConnectionState.connected || connection.state == HubConnectionState.connecting) { await connection.stop(); } } startConnection(BuildContext context) async { - if(connection.state == HubConnectionState.connected || connection.state == HubConnectionState.connecting) - { + if (connection.state == HubConnectionState.connected || connection.state == HubConnectionState.connecting) { connection.off('addChatMessage'); await connection.start(); } } -} \ No newline at end of file +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index addc988..950f73d 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,7 +9,7 @@ import audio_session import connectivity_macos import flutter_tts import just_audio -import path_provider_macos +import path_provider_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 35bf3c8..4b25199 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -281,49 +281,42 @@ packages: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "2.0.11" + version: "2.0.13" path_provider_android: dependency: transitive description: name: path_provider_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.20" - path_provider_ios: + version: "2.0.24" + path_provider_foundation: dependency: transitive description: - name: path_provider_ios + name: path_provider_foundation url: "https://pub.dartlang.org" source: hosted - version: "2.0.11" + version: "2.1.3" path_provider_linux: dependency: transitive description: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.7" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.6" + version: "2.1.10" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.0.6" path_provider_windows: dependency: transitive description: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "2.1.5" petitparser: dependency: transitive description: @@ -454,7 +447,7 @@ packages: name: uuid url: "https://pub.dartlang.org" source: hosted - version: "3.0.6" + version: "3.0.7" vector_math: dependency: transitive description: @@ -475,14 +468,14 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "3.1.3" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.2.0+2" + version: "1.0.0" xml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c1f5263..c79fd06 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -74,6 +74,7 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - assets/images/ + - assets/tones/ fonts: