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.
228 lines
7.9 KiB
Dart
228 lines
7.9 KiB
Dart
import 'dart:async';
|
|
import 'dart:developer';
|
|
import 'dart:io';
|
|
|
|
import 'package:connectivity/connectivity.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:just_audio/just_audio.dart';
|
|
import 'package:queuing_system/core/api.dart';
|
|
import 'package:queuing_system/core/response_models/call_config.dart';
|
|
import 'package:queuing_system/core/response_models/patient_call.dart';
|
|
import 'package:queuing_system/utils/call_by_voice.dart';
|
|
import 'package:queuing_system/utils/call_type.dart';
|
|
import 'package:queuing_system/utils/signalR_utils.dart';
|
|
|
|
class AppProvider extends ChangeNotifier {
|
|
AppProvider() {
|
|
startSignalHubConnection();
|
|
listenNetworkConnectivity();
|
|
}
|
|
|
|
SignalRHelper signalRHelper = SignalRHelper();
|
|
|
|
final AudioPlayer audioPlayer = AudioPlayer();
|
|
|
|
CallConfig patientCallConfigurations = CallConfig();
|
|
List<Tickets> patientTickets = [];
|
|
List<Tickets> isQueuePatients = [];
|
|
|
|
String currentDeviceIp = "";
|
|
bool isCallingInProgress = false;
|
|
bool isInternetConnectionAvailable = true;
|
|
|
|
updateInternetConnection(bool value) {
|
|
isInternetConnectionAvailable = value;
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> getCurrentIP() async {
|
|
final ips = await NetworkInterface.list(type: InternetAddressType.IPv4);
|
|
for (var interface in ips) {
|
|
if (interface.name == "eth0") {
|
|
for (var address in interface.addresses) {
|
|
currentDeviceIp = address.address;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
if (interface.name == "wlan0") {
|
|
for (var address in interface.addresses) {
|
|
currentDeviceIp = address.address;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> startSignalHubConnection() async {
|
|
if (!signalRHelper.getConnectionState()) {
|
|
signalRHelper.startSignalRConnection(currentDeviceIp, onUpdateAvailable: onPingReceived, onConnect: onConnect, onConnecting: onConnecting, onDisconnect: onDisconnect);
|
|
}
|
|
}
|
|
|
|
Future<void> callPatientsAPI() async {
|
|
patientTickets.clear();
|
|
API.getCallRequestInfoByClinicInfo(currentDeviceIp, onSuccess: (waitingCalls, isQueuePatientsCalls, callConfigs) {
|
|
patientCallConfigurations = callConfigs;
|
|
if (waitingCalls.length > patientCallConfigurations.screenMaxDisplayPatients) {
|
|
patientTickets = waitingCalls.sublist(0, patientCallConfigurations.screenMaxDisplayPatients);
|
|
} else {
|
|
patientTickets = waitingCalls;
|
|
}
|
|
isQueuePatients = isQueuePatientsCalls;
|
|
notifyListeners();
|
|
}, onFailure: (error) {
|
|
log("Api call failed with this error: ${error.toString()}");
|
|
});
|
|
}
|
|
|
|
onPingReceived(data) async {
|
|
if (patientTickets.isNotEmpty) {
|
|
if ((patientTickets.first.isToneReq && isCallingInProgress) || (patientTickets.first.isVoiceReq && voiceCaller != null)) {
|
|
Timer(Duration(seconds: patientCallConfigurations.concurrentCallDelaySec), () async {
|
|
await callPatientsAPI();
|
|
});
|
|
} else {
|
|
await callPatientsAPI();
|
|
}
|
|
} else {
|
|
await callPatientsAPI();
|
|
}
|
|
}
|
|
|
|
String getCallTypeText(Tickets ticket, CallConfig callConfig) {
|
|
final callType = ticket.getCallType();
|
|
switch (callType) {
|
|
case CallType.vitalSign:
|
|
return callConfig.vitalSignText;
|
|
case CallType.doctor:
|
|
return callConfig.doctorText;
|
|
case CallType.procedure:
|
|
return callConfig.procedureText;
|
|
case CallType.vaccination:
|
|
return callConfig.vaccinationText;
|
|
case CallType.nebulization:
|
|
return callConfig.nebulizationText;
|
|
default:
|
|
return callConfig.vitalSignText;
|
|
}
|
|
}
|
|
|
|
CallByVoice? voiceCaller;
|
|
|
|
callPatientTicket(AudioPlayer audioPlayer) async {
|
|
isCallingInProgress = true;
|
|
if (patientTickets.isNotEmpty) {
|
|
if (patientTickets.first.isToneReq && !patientTickets.first.isQueue) {
|
|
audioPlayer.setAsset("assets/tones/call_tone.mp3");
|
|
await audioPlayer.play();
|
|
await Future.delayed(const Duration(seconds: 2));
|
|
isCallingInProgress = false;
|
|
}
|
|
if (patientTickets.first.isVoiceReq && voiceCaller == null && !patientTickets.first.isQueue) {
|
|
final postVoice = getCallTypeText(patientTickets.first, patientCallConfigurations);
|
|
voiceCaller = CallByVoice(preVoice: "Ticket Number", ticketNo: patientTickets.first.queueNo.trim().toString(), postVoice: postVoice, lang: 'en');
|
|
await voiceCaller!.startCalling(patientTickets.first.queueNo.trim().toString() != patientTickets.first.callNoStr.trim().toString());
|
|
voiceCaller = null;
|
|
isCallingInProgress = false;
|
|
}
|
|
}
|
|
if (isQueuePatients.isNotEmpty) {
|
|
await Future.delayed(Duration(seconds: isQueuePatients.first.concurrentCallDelaySec)).whenComplete(() async {
|
|
if (isQueuePatients.isNotEmpty) {
|
|
isQueuePatients.removeAt(0);
|
|
}
|
|
if (patientTickets.isNotEmpty) {
|
|
// Tickets ticket = patientTickets.elementAt(0);
|
|
// patientTickets.removeAt(0);
|
|
// patientTickets.add(ticket);
|
|
}
|
|
if (isQueuePatients.isNotEmpty) {
|
|
// setState(() {});
|
|
}
|
|
});
|
|
} else {
|
|
// if (isQueuePatients.isEmpty && callFlag == 1) {
|
|
// callFlag == 0;
|
|
// await Future.delayed(const Duration(seconds: 3));
|
|
// patientTickets.clear();
|
|
// API.getCallRequestInfoByClinicInfo(DEVICE_IP, onSuccess: (waitingCalls, isQueuePatientsCalls) {
|
|
// setState(() {
|
|
// patientTickets = waitingCalls;
|
|
// isQueuePatients = isQueuePatientsCalls;
|
|
// // currents = currentInClinic;
|
|
// });
|
|
//
|
|
// log("--------------------");
|
|
// log("waiting: $patientTickets");
|
|
// log("isQueuePatients: $isQueuePatients");
|
|
// log("--------------------");
|
|
//
|
|
// updateTickets();
|
|
// }, onFailure: (error) {});
|
|
// }
|
|
}
|
|
}
|
|
|
|
Future<void> listenAudioPlayerEvents() async {
|
|
audioPlayer.playerStateStream.listen((playerState) {
|
|
if (playerState.processingState == ProcessingState.completed) {
|
|
isCallingInProgress = false;
|
|
}
|
|
});
|
|
}
|
|
|
|
updatePatientTickets() {
|
|
if (patientTickets.isNotEmpty) {
|
|
List<Tickets> _ticketsToUpdate = patientTickets.where((t) => t.callUpdated == false).toList();
|
|
API.callUpdateNotIsQueueRecordByIDAsync(currentDeviceIp, ticket: _ticketsToUpdate.first, onSuccess: (ticketsUpdated) {
|
|
log("[${ticketsUpdated.length}] Tickets Updated: $ticketsUpdated");
|
|
}, onFailure: (e) {
|
|
log(" Tickets Update Failed with : ${e.toString()}");
|
|
});
|
|
}
|
|
}
|
|
|
|
updatePatientTicketByIndex(int index) {
|
|
if (patientTickets.isNotEmpty) {
|
|
API.callUpdateNotIsQueueRecordByIDAsync(currentDeviceIp, ticket: patientTickets.elementAt(index), onSuccess: (ticketsUpdated) {
|
|
log("[${patientTickets.elementAt(index).callNoStr}] Ticket Updated: $ticketsUpdated");
|
|
}, onFailure: (e) {
|
|
log(" Tickets Update ${patientTickets.elementAt(index).callNoStr} Failed with Error : ${e.toString()}");
|
|
});
|
|
}
|
|
}
|
|
|
|
onConnect() {
|
|
log("SignalR: onConnect");
|
|
}
|
|
|
|
onDisconnect(exception) {
|
|
log("SignalR: onDisconnect");
|
|
signalRHelper.startSignalRConnection(currentDeviceIp, onUpdateAvailable: onPingReceived, onConnect: onConnect, onConnecting: onConnecting, onDisconnect: onDisconnect);
|
|
}
|
|
|
|
onConnecting() {
|
|
log("SignalR: onConnecting");
|
|
}
|
|
|
|
listenNetworkConnectivity() async {
|
|
Connectivity().onConnectivityChanged.listen((event) async {
|
|
switch (event) {
|
|
case ConnectivityResult.wifi:
|
|
updateInternetConnection(true);
|
|
await getCurrentIP();
|
|
if (signalRHelper.connection == null || signalRHelper.connection!.state != ConnectionState.active) {
|
|
signalRHelper.connection!.start();
|
|
}
|
|
break;
|
|
case ConnectivityResult.none:
|
|
updateInternetConnection(false);
|
|
signalRHelper.closeConnection();
|
|
break;
|
|
case ConnectivityResult.mobile:
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
}
|