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.
queuing_system/lib/home/home_screen.dart

348 lines
11 KiB
Dart

import 'dart:async';
import 'dart:developer';
import 'dart:io';
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/size_config.dart';
import 'package:queuing_system/core/response_model/patient_call.dart';
import 'package:queuing_system/header/app_header.dart';
import 'package:queuing_system/home/home_screen_components.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';
import 'package:queuing_system/utils/utils.dart';
import 'package:queuing_system/widget/data_display/app_texts_widget.dart';
var deviceIPGlobal = "10.10.15.11";
bool isDevMode = true; // Testing IP
// var DEVICE_IP = "10.10.14.11"; // Testing IP
// var DEVICE_IP = "10.10.15.11";
// var DEVICE_IP = "10.70.249.21"; // (Make sure by Haroon before use it) Production IP
class MyHomePage extends StatefulWidget {
final String title = "MyHomePage";
const MyHomePage({Key key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
SignalRHelper signalRHelper = SignalRHelper();
List<Tickets> waitings = [];
List<Tickets> isQueuePatients = [];
bool isLoading = false;
@override
void dispose() {
super.dispose();
}
Future<String> getCurrentIP() async {
for (var interface in await NetworkInterface.list(type: InternetAddressType.IPv4)) {
log("interfaces: ${interface.name}");
//TODO: WE WILL UPDATE THIS WHEN TESTING ON SCREEN
if (interface.name == "wlan0") {
// if (interface.name == "eth0") {
for (var address in interface.addresses) {
deviceIPGlobal = address.address;
return deviceIPGlobal;
}
}
return "";
}
return "";
}
final AudioPlayer audioPlayer = AudioPlayer();
@override
void initState() {
listenNetworkConnectivity();
scheduleMicrotask(() async {
if (!signalRHelper.getConnectionState()) {
signalRHelper.startSignalRConnection(await getCurrentIP(), onUpdateAvailable: onUpdateAvailable, onConnect: onConnect, onConnecting: onConnecting, onDisconnect: onDisconnect);
}
});
super.initState();
}
TextEditingController controller = TextEditingController();
@override
Widget build(BuildContext context) {
audioPlayer.playerStateStream.listen((playerState) {
if (playerState.processingState == ProcessingState.completed) {
isCallingInProgress = false;
}
});
return AppScaffold(
appBar: AppHeader(),
body: dataContent(audioPlayer),
bottomNavigationBar: Container(
color: Colors.grey.withOpacity(0.1),
height: Utils.getHeight(),
width: double.infinity,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
const SizedBox(width: 20),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
onUpdateAvailable("");
},
child: AppText(
"Powered By",
fontSize: SizeConfig.getWidthMultiplier() * 2.6,
fontFamily: 'Poppins-Medium.ttf',
),
),
Text(deviceIPGlobal, style: TextStyle(fontWeight: FontWeight.w500, fontSize: SizeConfig.getWidthMultiplier() * 2.2)),
],
),
const SizedBox(width: 10),
Image.asset(
"assets/images/cloud_logo.png",
height: SizeConfig.getHeightMultiplier() * 4,
),
],
),
],
),
),
);
}
onUpdateIPPressed() async {
// if (controller.text.isNotEmpty) {
// isLoading = true;
// setState(() {});
// DEVICE_IP = controller.text;
//
// await signalRHelper.connection.stop();
// if (!signalRHelper.getConnectionState()) {
// await signalRHelper.startSignalRConnection(DEVICE_IP, onUpdateAvailable: onUpdateAvailable, onConnect: onConnect, onConnecting: onConnecting, onDisconnect: onDisconnect);
// }
//
// controller.clear();
// waitings.clear();
// isLoading = false;
// setState(() {});
// }
}
Widget dataContent(AudioPlayer audioPlayer) {
voiceCall(audioPlayer);
if (waitings.isEmpty) {
// No Patient in Queue
return noPatientInQueue();
} else if (waitings.length > 3) {
// Return Content With Side List
return priorityTicketsWithSideList(waitings);
} else {
// Return Content In Center Aligned
return priorityTickets(waitings);
}
}
String getCallTypeText(Tickets ticket) {
final callType = ticket.getCallType();
switch (callType) {
case CallType.vitalSign:
return "Please Visit Nurse";
case CallType.doctor:
return "Please Visit Doctor";
case CallType.procedure:
return "Please Visit Procedure";
case CallType.vaccination:
return "Please Visit Vaccination";
case CallType.nebulization:
return "Please Visit Nebulization";
break;
default:
return "";
}
}
CallByVoice voiceCaller;
int callFlag = 0;
// bool isRequiredVoice({CallType callType, bool isQueue}) {
// if (callType == CallType.DOCTOR && !isQueue) {
// return true;
// }
// if (callType == CallType.NURSE && !isQueue) {
// return true;
// }
// return false;
// }
bool isCallingInProgress = false;
voiceCall(AudioPlayer audioPlayer) async {
isCallingInProgress = true;
//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) {
if (waitings.first.isToneReq && waitings.first.isQueue) {
audioPlayer.setAsset("assets/tones/call_tone.mp3");
await audioPlayer.play();
await Future.delayed(const Duration(seconds: 2));
}
if (waitings.first.isVoiceReq && voiceCaller == null && waitings.first.isQueue) {
final postVoice = getCallTypeText(waitings.first);
voiceCaller = CallByVoice(waitings.first.queueNo.trim().toString(), preVoice: "Ticket Number", postVoice: postVoice, lang: 'en');
await voiceCaller.startCalling(waitings.first.queueNo.trim().toString() != waitings.first.callNoStr.trim().toString());
voiceCaller = null;
}
}
if (isQueuePatients.isNotEmpty) {
await Future.delayed(Duration(seconds: isQueuePatients.first.concurrentCallDelaySec)).whenComplete(() async {
if (isQueuePatients.isNotEmpty) {
isQueuePatients.removeAt(0);
}
if (waitings.isNotEmpty) {
// Tickets ticket = waitings.elementAt(0);
// waitings.removeAt(0);
// waitings.add(ticket);
}
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) {});
// }
}
}
Future<void> callPatientsAPI() async {
waitings.clear();
API.getCallRequestInfoByClinicInfo(deviceIPGlobal, onSuccess: (waitingCalls, isQueuePatientsCalls) {
setState(() {
waitings = waitingCalls;
isQueuePatients = isQueuePatientsCalls;
// currents = currentInClinic;
});
log("--------------------");
log("waiting: $waitings");
log("isQueuePatients: $isQueuePatients");
log("--------------------");
updateTickets();
}, onFailure: (error) {});
}
onUpdateAvailable(data) async {
// if (isQueuePatients.isNotEmpty && callFlag == 0) {
// callFlag = 1;
// return;
// }
if (waitings.isNotEmpty) {
if ((waitings.first.isToneReq && isCallingInProgress) || (waitings.first.isVoiceReq && voiceCaller != null)) {
// if (true) {
Timer(Duration(seconds: isQueuePatients.first.concurrentCallDelaySec), () async {
await callPatientsAPI();
});
} else {
await callPatientsAPI();
}
} else {
await callPatientsAPI();
}
}
updateTickets() {
if (waitings != null && waitings.isNotEmpty) {
List<Tickets> _ticketsToUpdate = waitings.where((t) => t.callUpdated == false).toList();
API.callUpdateNotIsQueueRecordByIDAsync(deviceIPGlobal, ticket: _ticketsToUpdate.first, onSuccess: (ticketsUpdated) {
log("[${ticketsUpdated.length}] Tickets Updated: $ticketsUpdated");
}, onFailure: (e) {
log("API UPDate Tickets Failed with : ${e.toString()}");
});
}
}
onConnect() {
log("SignalR: onConnect");
}
onDisconnect(exception) {
log("SignalR: onDisconnect");
signalRHelper.startSignalRConnection(deviceIPGlobal, onUpdateAvailable: onUpdateAvailable, onConnect: onConnect, onConnecting: onConnecting, onDisconnect: onDisconnect);
}
onConnecting() {
log("SignalR: onConnecting");
}
listenNetworkConnectivity() async {
Connectivity().onConnectivityChanged.listen((event) {
switch (event) {
case ConnectivityResult.wifi:
signalRHelper.connection.start();
break;
case ConnectivityResult.none:
signalRHelper.closeConnection(context);
break;
case ConnectivityResult.mobile:
break;
}
});
}
}
// if (isQueuePatients.length > 1) {
// Timer(Duration(milliseconds: int.parse(waitings.first.queueDuration)), () {
// Tickets calledTicket = Tickets();
// if (isQueuePatients.isNotEmpty) {
// calledTicket = isQueuePatients.elementAt(0);
// isQueuePatients.removeAt(0);
// }
// if (waitings.isNotEmpty) {
// // Tickets ticket = waitings.elementAt(0);
// // waitings.removeAt(0);
// // waitings.add(ticket);
// }
// if (isQueuePatients.isNotEmpty) {
// // setState(() {});
// }
// });
// }