Conflicts:
	lib/config/localized_values.dart
	lib/locator.dart
	lib/pages/landing/home_page.dart
	lib/pages/landing/landing_page.dart
	lib/uitl/translations_delegate_base.dart
merge-requests/34/head
Mohammad Aljammal 5 years ago
commit 30c0963063

Binary file not shown.

@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICkDCCAXgCAQAwSzEjMCEGCSqGSIb3DQEJARYUaGFyb29uNjEzOEBnbWFpbC5j
b20xFzAVBgNVBAMMDk1vaGFtZWQgTWVrYXd5MQswCQYDVQQGEwJBRTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnHqsyE7WfiVcE1Lpa4t4OVO6qlll2q
1djs0XG06R/dlDtIqv4940/XLj+hU93mzAcVvFW4DSIEdD3InM3+T6oMTjPu6meU
69h9ryaVkluQRrT/tdGI1EKO4MWGMe4MDIt7DqMhMfAcxTwekwdxdKaCEhaw3qnA
l/64AelY6URW1pHHJMA0VV7j+pE3jVNai+muMXPrhQ1VrOrV8FftpY3bEeRJR2Cl
T0tv0LhEMu4SfLnVWCzGQQC82hilDw3rH3ZDs8DFxF9agNVdwKlYamarh1dQXwRq
Yx2+sjY1/51r9L4VS+GAh9ECxz0e+43NpzfZ/N+mTeDYKDepaBwPQ6kCAwEAAaAA
MA0GCSqGSIb3DQEBCwUAA4IBAQB89OyLfywKT7ftmpEqCmgsmaJexb580q9w8wOk
1JhJkNV5ec+p1dnge2NZeJ4LGII/5wmPj1vANNW0GZdmJDgnC+2gg9toq1QLCAsF
rW7/LMpgAoEH+P5bhrHV9RRv6BQi0ZmN0apBHjp/pqZfm2Cl5jQPEWjUEf2tIF4l
LSKdok6IPO9n4Fgyk0XdUNSEhgVhsLtZkGiXnkI1YovKDnupTFYPXMLp103bc9zP
xDxwscvOysNDijlzZAkJPg2z8NrJIRDrKvLRHzxQwZ/1LHVB/51bp/1iyks3vOjh
qw5XVsrtGAjCjU9md7q3XkPSyKzhK9UqPdOxdvl1OY0KKIIY
-----END CERTIFICATE REQUEST-----

@ -0,0 +1,8 @@
{\rtf1\ansi\ansicpg1252\cocoartf2513
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh8400\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
\f0\fs24 \cf0 Hmg54321}

Binary file not shown.

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r</string>
<key>API_KEY</key>
<string>AIzaSyA_6ayGCk4fly7o7eTVBrj9kuHBYHMAOfs</string>
<key>GCM_SENDER_ID</key>
<string>864393916058</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.cloud.diplomaticquarterapp</string>
<key>PROJECT_ID</key>
<string>diplomaticquarter-d2385</string>
<key>STORAGE_BUCKET</key>
<string>diplomaticquarter-d2385.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:864393916058:ios:13f787bbfe6051f8b97923</string>
<key>DATABASE_URL</key>
<string>https://diplomaticquarter-d2385.firebaseio.com</string>
</dict>
</plist>

@ -0,0 +1,40 @@
{
"project_info": {
"project_number": "864393916058",
"firebase_url": "https://diplomaticquarter-d2385.firebaseio.com",
"project_id": "diplomaticquarter-d2385",
"storage_bucket": "diplomaticquarter-d2385.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:864393916058:android:5b5a65cd6d8c18b4b97923",
"android_client_info": {
"package_name": "com.cloud.diplomaticquarterapp"
}
},
"oauth_client": [
{
"client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyBdV3mos1BPhUzNKCj2KANJtiO3o2zh9IM"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,40 @@
{
"project_info": {
"project_number": "864393916058",
"firebase_url": "https://diplomaticquarter-d2385.firebaseio.com",
"project_id": "diplomaticquarter-d2385",
"storage_bucket": "diplomaticquarter-d2385.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:864393916058:android:5b5a65cd6d8c18b4b97923",
"android_client_info": {
"package_name": "com.cloud.diplomaticquarterapp"
}
},
"oauth_client": [
{
"client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyBdV3mos1BPhUzNKCj2KANJtiO3o2zh9IM"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r</string>
<key>API_KEY</key>
<string>AIzaSyA_6ayGCk4fly7o7eTVBrj9kuHBYHMAOfs</string>
<key>GCM_SENDER_ID</key>
<string>864393916058</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.cloud.diplomaticquarterapp</string>
<key>PROJECT_ID</key>
<string>diplomaticquarter-d2385</string>
<key>STORAGE_BUCKET</key>
<string>diplomaticquarter-d2385.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:864393916058:ios:13f787bbfe6051f8b97923</string>
<key>DATABASE_URL</key>
<string>https://diplomaticquarter-d2385.firebaseio.com</string>
</dict>
</plist>

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r</string>
<key>API_KEY</key>
<string>AIzaSyA_6ayGCk4fly7o7eTVBrj9kuHBYHMAOfs</string>
<key>GCM_SENDER_ID</key>
<string>864393916058</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.cloud.diplomaticquarterapp</string>
<key>PROJECT_ID</key>
<string>diplomaticquarter-d2385</string>
<key>STORAGE_BUCKET</key>
<string>diplomaticquarter-d2385.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:864393916058:ios:13f787bbfe6051f8b97923</string>
<key>DATABASE_URL</key>
<string>https://diplomaticquarter-d2385.firebaseio.com</string>
</dict>
</plist>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

@ -107,6 +107,19 @@ const IS_ALLOW_ASK_DOCTOR = '/Doctors.svc/REST/GetPatientDoctorAppointmentResult
const GET_CALL_REQUEST_TYPE = '/Doctors.svc/REST/GetCallRequestType_LOV';
const SEND_CALL_REQUEST = '/Doctors.svc/REST/InsertCallInfo';
const GET_LIVECARE_CLINICS = '/ER_VirtualCall.svc/REST/PatientER_GetClinics';
const GET_LIVECARE_CLINIC_TIMING = '/ER_VirtualCall.svc/REST/PatientER_GetClinicsServiceTimingsSchedule';
const GET_ER_APPOINTMENT_FEES = '/DoctorApplication.svc/REST/GetERAppointmentFees';
const GET_ER_APPOINTMENT_TIME = '/ER_VirtualCall.svc/REST/GetRestTime';
const ADD_NEW_CALL_FOR_PATIENT_ER = '/DoctorApplication.svc/REST/NewCallForPatientER';
const GET_LIVECARE_HISTORY = '/ER_VirtualCall.svc/REST/GetPatientErVirtualHistory';
const CANCEL_LIVECARE_REQUEST = '/ER_VirtualCall.svc/REST/DeleteErRequest';
const SEND_LIVECARE_INVOICE_EMAIL = '/Notifications.svc/REST/SendInvoiceForLiveCare';
//URL to get medicine and pharmacies list
const CHANNEL = 3;
const GENERAL_ID = 'Cs2020@2016\$2958';

@ -334,4 +334,8 @@ const Map<String, Map<String, String>> localizedValues = {
"ContactUs": {"en": "Contact Us", 'ar': 'الوصول إلينا'},
"ViewAllWaysReachUs": {"en": "View All Ways Reach Us", 'ar': 'جميع طرق الاتصال بنا'},
"medicalProfile": {"en": "Medical Profile", 'ar': 'الملف الطبي'},
"requestType": {"en": "Request Type", "ar": "نوع الاستفسار"},
"consultation": {"en": "Consultation", "ar": "استشارة"},
"logs": {"en": "Logs", "ar": "السجلات"}
};

@ -7,8 +7,14 @@ class VitalSignService extends BaseService {
List<VitalSignResModel> vitalSignResModelList = List();
Map<String, dynamic> body = Map();
Future getPatientRadOrders() async {
Future getPatientRadOrders({int appointmentNo, int projectID}) async {
hasError = false;
if (appointmentNo != null && projectID != null) {
body['TransNo'] = appointmentNo;
body['ProjectID'] = projectID;
}
await baseAppClient.post(GET_PATIENT_VITAL_SIGN,
onSuccess: (dynamic response, int statusCode) {
vitalSignResModelList.clear();
@ -18,6 +24,6 @@ class VitalSignService extends BaseService {
}, onFailure: (String error, int statusCode) {
hasError = true;
super.error = error;
}, body: Map());
}, body: body);
}
}

@ -8,12 +8,18 @@ import '../../../locator.dart';
class VitalSignViewModel extends BaseViewModel {
VitalSignService _vitalSignService = locator<VitalSignService>();
List<VitalSignResModel> get vitalSignResModelList => _vitalSignService.vitalSignResModelList;
List<VitalSignResModel> get vitalSignResModelList =>
_vitalSignService.vitalSignResModelList;
getPatientRadOrders() async {
getPatientRadOrders({int appointmentNo, int projectID}) async {
setState(ViewState.Busy);
await _vitalSignService.getPatientRadOrders();
if (appointmentNo != null && projectID != null) {
await _vitalSignService.getPatientRadOrders(
appointmentNo: appointmentNo, projectID: projectID);
} else {
await _vitalSignService.getPatientRadOrders();
}
if (_vitalSignService.hasError) {
error = _vitalSignService.error;
setState(ViewState.Error);

@ -1,6 +1,5 @@
import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart';
import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/uitl/navigation_service.dart';
import 'package:get_it/get_it.dart';
import 'core/service/appointment_rate_service.dart';
@ -44,6 +43,7 @@ void setupLocator() {
locator.registerLazySingleton(() => InsuranceCardService());
locator.registerLazySingleton(() => VitalSignService());
locator.registerLazySingleton(() => MedicalService());
locator.registerLazySingleton(() => NavigationService());
locator.registerLazySingleton(() => ReportsService());
locator.registerLazySingleton(() => DashboardService());
locator.registerLazySingleton(() => AppointmentRateService());

@ -1,4 +1,7 @@
import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart';
import 'package:diplomaticquarterapp/pages/login/login.dart';
import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/uitl/navigation_service.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
@ -9,7 +12,7 @@ import 'config/size_config.dart';
import 'core/viewModels/project_view_model.dart';
import 'locator.dart';
void main() {
void main() async {
setupLocator();
runApp(MyApp());
}

@ -0,0 +1,108 @@
class PatientERVirtualHistoryResponse {
List<ErRequestHistoryList> erRequestHistoryList;
PatientERVirtualHistoryResponse({this.erRequestHistoryList});
PatientERVirtualHistoryResponse.fromJson(Map<String, dynamic> json) {
if (json['ErRequestHistoryList'] != null) {
erRequestHistoryList = new List<ErRequestHistoryList>();
json['ErRequestHistoryList'].forEach((v) {
erRequestHistoryList.add(new ErRequestHistoryList.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.erRequestHistoryList != null) {
data['ErRequestHistoryList'] =
this.erRequestHistoryList.map((v) => v.toJson()).toList();
}
return data;
}
}
class ErRequestHistoryList {
dynamic appointmentNo;
String arrivalTime;
int callDuration;
int callStatus;
String clientRequestID;
String doctorID;
String doctorName;
String doctorNameN;
String doctorTitle;
String exWaitingTime;
bool isAppointmentHaveRating;
int patCount;
int projectID;
String sArrivalTime;
int serviceID;
String stringCallStatus;
int vCID;
int watingtimeInteger;
ErRequestHistoryList(
{this.appointmentNo,
this.arrivalTime,
this.callDuration,
this.callStatus,
this.clientRequestID,
this.doctorID,
this.doctorName,
this.doctorNameN,
this.doctorTitle,
this.exWaitingTime,
this.isAppointmentHaveRating,
this.patCount,
this.projectID,
this.sArrivalTime,
this.serviceID,
this.stringCallStatus,
this.vCID,
this.watingtimeInteger});
ErRequestHistoryList.fromJson(Map<String, dynamic> json) {
appointmentNo = json['AppointmentNo'] != null ? json['AppointmentNo'] : "0";
arrivalTime = json['ArrivalTime'];
callDuration = json['CallDuration'];
callStatus = json['CallStatus'];
clientRequestID = json['ClientRequestID'];
doctorID = json['DoctorID'];
doctorName = json['DoctorName'];
doctorNameN = json['DoctorNameN'];
doctorTitle = json['DoctorTitle'];
exWaitingTime = json['Ex_WaitingTime'];
isAppointmentHaveRating = json['IsAppointmentHaveRating'];
patCount = json['Pat_Count'];
projectID = json['ProjectID'];
sArrivalTime = json['SArrivalTime'];
serviceID = json['ServiceID'];
stringCallStatus = json['StringCallStatus'];
vCID = json['VC_ID'];
watingtimeInteger = json['WatingtimeInteger'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['AppointmentNo'] = this.appointmentNo;
data['ArrivalTime'] = this.arrivalTime;
data['CallDuration'] = this.callDuration;
data['CallStatus'] = this.callStatus;
data['ClientRequestID'] = this.clientRequestID;
data['DoctorID'] = this.doctorID;
data['DoctorName'] = this.doctorName;
data['DoctorNameN'] = this.doctorNameN;
data['DoctorTitle'] = this.doctorTitle;
data['Ex_WaitingTime'] = this.exWaitingTime;
data['IsAppointmentHaveRating'] = this.isAppointmentHaveRating;
data['Pat_Count'] = this.patCount;
data['ProjectID'] = this.projectID;
data['SArrivalTime'] = this.sArrivalTime;
data['ServiceID'] = this.serviceID;
data['StringCallStatus'] = this.stringCallStatus;
data['VC_ID'] = this.vCID;
data['WatingtimeInteger'] = this.watingtimeInteger;
return data;
}
}

@ -0,0 +1,122 @@
class ClinicsServiceTimingsResponse {
List<PatientERGetClinicsServiceTimingsList>
patientERGetClinicsServiceTimingsList;
ClinicsServiceTimingsResponse({this.patientERGetClinicsServiceTimingsList});
ClinicsServiceTimingsResponse.fromJson(Map<String, dynamic> json) {
if (json['PatientER_GetClinicsServiceTimingsList'] != null) {
patientERGetClinicsServiceTimingsList =
new List<PatientERGetClinicsServiceTimingsList>();
json['PatientER_GetClinicsServiceTimingsList'].forEach((v) {
patientERGetClinicsServiceTimingsList
.add(new PatientERGetClinicsServiceTimingsList.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.patientERGetClinicsServiceTimingsList != null) {
data['PatientER_GetClinicsServiceTimingsList'] = this
.patientERGetClinicsServiceTimingsList
.map((v) => v.toJson())
.toList();
}
return data;
}
}
class PatientERGetClinicsServiceTimingsList {
int iD;
int serviceID;
Null shiftID;
int dayOfWeek;
String dayOfWeekStr;
Null startTime;
Null endTime;
bool isActive;
String createdOn;
String createdBy;
bool projectOutSA;
String dayOfWeekStrN;
List<ShiftTimings> shiftTimings;
PatientERGetClinicsServiceTimingsList(
{this.iD,
this.serviceID,
this.shiftID,
this.dayOfWeek,
this.dayOfWeekStr,
this.startTime,
this.endTime,
this.isActive,
this.createdOn,
this.createdBy,
this.projectOutSA,
this.dayOfWeekStrN,
this.shiftTimings});
PatientERGetClinicsServiceTimingsList.fromJson(Map<String, dynamic> json) {
iD = json['ID'];
serviceID = json['ServiceID'];
shiftID = json['ShiftID'];
dayOfWeek = json['DayOfWeek'];
dayOfWeekStr = json['DayOfWeekStr'];
startTime = json['StartTime'];
endTime = json['EndTime'];
isActive = json['IsActive'];
createdOn = json['CreatedOn'];
createdBy = json['CreatedBy'];
projectOutSA = json['ProjectOutSA'];
dayOfWeekStrN = json['DayOfWeekStrN'];
if (json['ShiftTimings'] != null) {
shiftTimings = new List<ShiftTimings>();
json['ShiftTimings'].forEach((v) {
shiftTimings.add(new ShiftTimings.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ID'] = this.iD;
data['ServiceID'] = this.serviceID;
data['ShiftID'] = this.shiftID;
data['DayOfWeek'] = this.dayOfWeek;
data['DayOfWeekStr'] = this.dayOfWeekStr;
data['StartTime'] = this.startTime;
data['EndTime'] = this.endTime;
data['IsActive'] = this.isActive;
data['CreatedOn'] = this.createdOn;
data['CreatedBy'] = this.createdBy;
data['ProjectOutSA'] = this.projectOutSA;
data['DayOfWeekStrN'] = this.dayOfWeekStrN;
if (this.shiftTimings != null) {
data['ShiftTimings'] = this.shiftTimings.map((v) => v.toJson()).toList();
}
return data;
}
}
class ShiftTimings {
String endTime;
int shiftID;
String startTime;
ShiftTimings({this.endTime, this.shiftID, this.startTime});
ShiftTimings.fromJson(Map<String, dynamic> json) {
endTime = json['EndTime'];
shiftID = json['ShiftID'];
startTime = json['StartTime'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['EndTime'] = this.endTime;
data['ShiftID'] = this.shiftID;
data['StartTime'] = this.startTime;
return data;
}
}

@ -0,0 +1,61 @@
class ERAppointmentFeesResponse {
GetERAppointmentFeesList getERAppointmentFeesList;
ERAppointmentFeesResponse({this.getERAppointmentFeesList});
ERAppointmentFeesResponse.fromJson(Map<String, dynamic> json) {
getERAppointmentFeesList = json['GetERAppointmentFeesList'] != null
? new GetERAppointmentFeesList.fromJson(
json['GetERAppointmentFeesList'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.getERAppointmentFeesList != null) {
data['GetERAppointmentFeesList'] = this.getERAppointmentFeesList.toJson();
}
return data;
}
}
class GetERAppointmentFeesList {
String amount;
String companyName;
bool isInsured;
bool isShowInsuranceUpdateModule;
String tax;
String total;
String currency;
GetERAppointmentFeesList(
{this.amount,
this.companyName,
this.isInsured,
this.isShowInsuranceUpdateModule,
this.tax,
this.total,
this.currency});
GetERAppointmentFeesList.fromJson(Map<String, dynamic> json) {
amount = json['Amount'];
companyName = json['CompanyName'];
isInsured = json['IsInsured'];
isShowInsuranceUpdateModule = json['IsShowInsuranceUpdateModule'];
tax = json['Tax'];
total = json['Total'];
currency = json['currency'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['Amount'] = this.amount;
data['CompanyName'] = this.companyName;
data['IsInsured'] = this.isInsured;
data['IsShowInsuranceUpdateModule'] = this.isShowInsuranceUpdateModule;
data['Tax'] = this.tax;
data['Total'] = this.total;
data['currency'] = this.currency;
return data;
}
}

@ -0,0 +1,104 @@
class IncomingCallData {
String msgID;
String notfID;
String notificationForeground;
String count;
String message;
String appointmentNo;
String title;
String projectID;
String notificationType;
String background;
String doctorname;
String clinicname;
String speciality;
String appointmentdate;
String appointmenttime;
String type;
String sessionId;
String identity;
String name;
String videoUrl;
String picture;
String isCall;
String sound;
IncomingCallData(
{this.msgID,
this.notfID,
this.notificationForeground,
this.count,
this.message,
this.appointmentNo,
this.title,
this.projectID,
this.notificationType,
this.background,
this.doctorname,
this.clinicname,
this.speciality,
this.appointmentdate,
this.appointmenttime,
this.type,
this.sessionId,
this.identity,
this.name,
this.videoUrl,
this.picture,
this.isCall,
this.sound});
IncomingCallData.fromJson(Map<String, dynamic> json) {
msgID = json['msgID'];
notfID = json['notfID'];
notificationForeground = json['notification_foreground'];
count = json['count'];
message = json['message'];
appointmentNo = json['AppointmentNo'];
title = json['title'];
projectID = json['ProjectID'];
notificationType = json['NotificationType'];
background = json['background'];
doctorname = json['doctorname'];
clinicname = json['clinicname'];
speciality = json['speciality'];
appointmentdate = json['appointmentdate'];
appointmenttime = json['appointmenttime'];
type = json['type'];
sessionId = json['session_id'];
identity = json['identity'];
name = json['name'];
videoUrl = json['videoUrl'];
picture = json['picture'];
isCall = json['is_call'];
sound = json['sound'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['msgID'] = this.msgID;
data['notfID'] = this.notfID;
data['notification_foreground'] = this.notificationForeground;
data['count'] = this.count;
data['message'] = this.message;
data['AppointmentNo'] = this.appointmentNo;
data['title'] = this.title;
data['ProjectID'] = this.projectID;
data['NotificationType'] = this.notificationType;
data['background'] = this.background;
data['doctorname'] = this.doctorname;
data['clinicname'] = this.clinicname;
data['speciality'] = this.speciality;
data['appointmentdate'] = this.appointmentdate;
data['appointmenttime'] = this.appointmenttime;
data['type'] = this.type;
data['session_id'] = this.sessionId;
data['identity'] = this.identity;
data['name'] = this.name;
data['videoUrl'] = this.videoUrl;
data['picture'] = this.picture;
data['is_call'] = this.isCall;
data['sound'] = this.sound;
return data;
}
}

@ -0,0 +1,129 @@
class LiveCareClinicsListResponse {
List<PatientERGetClinicsList> patientERGetClinicsList;
LiveCareClinicsListResponse({this.patientERGetClinicsList});
LiveCareClinicsListResponse.fromJson(Map<String, dynamic> json) {
if (json['PatientER_GetClinicsList'] != null) {
patientERGetClinicsList = new List<PatientERGetClinicsList>();
json['PatientER_GetClinicsList'].forEach((v) {
patientERGetClinicsList.add(new PatientERGetClinicsList.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.patientERGetClinicsList != null) {
data['PatientER_GetClinicsList'] =
this.patientERGetClinicsList.map((v) => v.toJson()).toList();
}
return data;
}
}
class PatientERGetClinicsList {
int iD;
int serviceID;
String serviceName;
String serviceNameN;
int clinicID;
int age;
bool isCheckAgeBelow;
int gender;
bool isActive;
String createdOn;
String createdBy;
int isOnline;
Null endTime;
bool projectOutSA;
List<ShiftTimings> shiftTimings;
Null startTime;
PatientERGetClinicsList(
{this.iD,
this.serviceID,
this.serviceName,
this.serviceNameN,
this.clinicID,
this.age,
this.isCheckAgeBelow,
this.gender,
this.isActive,
this.createdOn,
this.createdBy,
this.isOnline,
this.endTime,
this.projectOutSA,
this.shiftTimings,
this.startTime});
PatientERGetClinicsList.fromJson(Map<String, dynamic> json) {
iD = json['ID'];
serviceID = json['ServiceID'];
serviceName = json['ServiceName'];
serviceNameN = json['ServiceNameN'];
clinicID = json['ClinicID'];
age = json['Age'];
isCheckAgeBelow = json['IsCheckAgeBelow'];
gender = json['Gender'];
isActive = json['IsActive'];
createdOn = json['CreatedOn'];
createdBy = json['CreatedBy'];
isOnline = json['IsOnline'];
endTime = json['EndTime'];
projectOutSA = json['ProjectOutSA'];
if (json['ShiftTimings'] != null) {
shiftTimings = new List<ShiftTimings>();
json['ShiftTimings'].forEach((v) {
shiftTimings.add(new ShiftTimings.fromJson(v));
});
}
startTime = json['StartTime'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ID'] = this.iD;
data['ServiceID'] = this.serviceID;
data['ServiceName'] = this.serviceName;
data['ServiceNameN'] = this.serviceNameN;
data['ClinicID'] = this.clinicID;
data['Age'] = this.age;
data['IsCheckAgeBelow'] = this.isCheckAgeBelow;
data['Gender'] = this.gender;
data['IsActive'] = this.isActive;
data['CreatedOn'] = this.createdOn;
data['CreatedBy'] = this.createdBy;
data['IsOnline'] = this.isOnline;
data['EndTime'] = this.endTime;
data['ProjectOutSA'] = this.projectOutSA;
if (this.shiftTimings != null) {
data['ShiftTimings'] = this.shiftTimings.map((v) => v.toJson()).toList();
}
data['StartTime'] = this.startTime;
return data;
}
}
class ShiftTimings {
String endTime;
int shiftID;
String startTime;
ShiftTimings({this.endTime, this.shiftID, this.startTime});
ShiftTimings.fromJson(Map<String, dynamic> json) {
endTime = json['EndTime'];
shiftID = json['ShiftID'];
startTime = json['StartTime'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['EndTime'] = this.endTime;
data['ShiftID'] = this.shiftID;
data['StartTime'] = this.startTime;
return data;
}
}

@ -0,0 +1,65 @@
import 'package:diplomaticquarterapp/models/LiveCare/room_validators.dart';
import 'package:diplomaticquarterapp/models/LiveCare/twilio_enums.dart';
class RoomModel with RoomValidators {
final String name;
final bool isLoading;
final bool isSubmitted;
final String token;
final String identity;
final TwilioRoomType type;
RoomModel({
this.name,
this.isLoading = false,
this.isSubmitted = false,
this.token,
this.identity,
this.type = TwilioRoomType.groupSmall,
});
static String getTypeText(TwilioRoomType type) {
switch (type) {
case TwilioRoomType.peerToPeer:
return 'peer 2 peer';
break;
case TwilioRoomType.group:
return 'large (max 50 participants)';
break;
case TwilioRoomType.groupSmall:
return 'small (max 4 participants)';
break;
}
return '';
}
String get nameErrorText {
return isSubmitted && !nameValidator.isValid(name) ? invalidNameErrorText : null;
}
String get typeText {
return RoomModel.getTypeText(type);
}
bool get canSubmit {
return nameValidator.isValid(name);
}
RoomModel copyWith({
String name,
bool isLoading,
bool isSubmitted,
String token,
String identity,
TwilioRoomType type,
}) {
return RoomModel(
name: name ?? this.name,
token: token ?? this.token,
identity: identity ?? this.identity,
isLoading: isLoading ?? this.isLoading,
isSubmitted: isSubmitted ?? this.isSubmitted,
type: type ?? this.type,
);
}
}

@ -0,0 +1,6 @@
import 'package:diplomaticquarterapp/models/LiveCare/validators.dart';
mixin RoomValidators {
final StringValidator nameValidator = NonEmptyStringValidator();
final String invalidNameErrorText = 'Room name can\'t be empty';
}

@ -0,0 +1,17 @@
enum TwilioRoomType {
peerToPeer,
group,
groupSmall,
}
enum TwilioRoomStatus {
completed,
inProgress,
}
enum TwilioStatusCallbackMethod {
GET,
POST,
}
enum TwilioVideoCodec { VP8, H264 }

@ -0,0 +1,13 @@
abstract class StringValidator {
bool isValid(String value);
}
class NonEmptyStringValidator implements StringValidator {
@override
bool isValid(String value) {
if (value == null) {
return false;
}
return value.isNotEmpty;
}
}

@ -13,6 +13,7 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:rating_bar/rating_bar.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
import 'BookSuccess.dart';
@ -33,7 +34,6 @@ class BookConfirm extends StatefulWidget {
PatientShareResponse patientShareResponse;
AuthenticatedUser authUser;
@override
_BookConfirmState createState() => _BookConfirmState();
}
@ -303,14 +303,19 @@ class _BookConfirmState extends State<BookConfirm> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(widget.authUser.firstName + " " + widget.authUser.lastName,
Text(
widget.authUser.firstName +
" " +
widget.authUser.lastName,
style: TextStyle(
fontSize: 14.0,
color: Colors.grey[900],
letterSpacing: 1.0)),
Container(
margin: EdgeInsets.only(top: 5.0),
child: Text("Gender: " + widget.authUser.genderDescription,
child: Text(
"Gender: " +
widget.authUser.genderDescription,
style: TextStyle(
fontSize: 12.0,
color: Colors.grey[600],
@ -318,7 +323,8 @@ class _BookConfirmState extends State<BookConfirm> {
),
Container(
margin: EdgeInsets.only(top: 5.0, bottom: 3.0),
child: Text("Age: " + widget.authUser.age.toString(),
child: Text(
"Age: " + widget.authUser.age.toString(),
style: TextStyle(
fontSize: 12.0,
color: Colors.grey[600],
@ -352,7 +358,6 @@ class _BookConfirmState extends State<BookConfirm> {
disabledTextColor: Colors.white,
disabledColor: new Color(0xFFbcc2c4),
onPressed: () {
// navigateToBookSuccess(context);
insertAppointment(context, widget.doctor);
},
child: Text(TranslationBase.of(context).bookNow,
@ -363,31 +368,43 @@ class _BookConfirmState extends State<BookConfirm> {
);
}
cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context) {
cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo,
BuildContext context) {
ConfirmDialog.closeAlertDialog(context);
DoctorsListService service = new DoctorsListService();
service.cancelAppointment(appo, context).then((res) {
if (res['MessageStatus'] == 1) {
insertAppointment(context, docObject);
Future.delayed(new Duration(milliseconds: 1500), () {
insertAppointment(context, docObject);
});
} else {
AppToast.showErrorToast(message: res['ErrorEndUserMessage']);
}
}).catchError((err) {
print(err);
});
}).showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
insertAppointment(context, DoctorList docObject) {
AppoitmentAllHistoryResultList appo;
widget.service
.insertAppointment(docObject.doctorID, docObject.clinicID,
docObject.projectID, widget.selectedTime, widget.selectedDate, context)
.insertAppointment(
docObject.doctorID,
docObject.clinicID,
docObject.projectID,
widget.selectedTime,
widget.selectedDate,
context)
.then((res) {
if (res['MessageStatus'] == 1) {
AppToast.showSuccessToast(message: "Appointment Booked Successfully");
print(res['AppointmentNo']);
getPatientShare(context, res['AppointmentNo'], docObject.clinicID,
docObject.projectID, docObject);
Future.delayed(new Duration(milliseconds: 1800), () {
getPatientShare(context, res['AppointmentNo'], docObject.clinicID,
docObject.projectID, docObject);
});
} else {
appo = new AppoitmentAllHistoryResultList();
appo.appointmentNo = res['SameClinicApptList'][0]['AppointmentNo'];
@ -411,8 +428,10 @@ class _BookConfirmState extends State<BookConfirm> {
dialog.showAlertDialog(context);
}
}).catchError((err) {
AppToast.showErrorToast(message: err);
print(err);
});
}).showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
getPatientShare(context, String appointmentNo, int clinicID, int projectID,
@ -425,7 +444,8 @@ class _BookConfirmState extends State<BookConfirm> {
navigateToBookSuccess(context, docObject, widget.patientShareResponse);
}).catchError((err) {
print(err);
});
}).showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
String getTime(DateTime dateTime) {
@ -471,8 +491,8 @@ class _BookConfirmState extends State<BookConfirm> {
getPatientData() async {
AppSharedPreferences sharedPref = AppSharedPreferences();
if (await sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await sharedPref.getObject(USER_PROFILE));
var data =
AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE));
setState(() {
print(data);
widget.authUser = data;

@ -12,6 +12,7 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart';
import 'package:flutter/material.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
import 'QRCode.dart';
@ -506,7 +507,6 @@ class _BookSuccessState extends State<BookSuccess> {
if (url.contains(element)) {
if (widget.browser.isOpened()) widget.browser.close();
MyInAppBrowser.isPaymentDone = true;
Utils.hideProgressDialog();
return;
}
});
@ -515,7 +515,6 @@ class _BookSuccessState extends State<BookSuccess> {
if (url.contains(element)) {
if (widget.browser.isOpened()) widget.browser.close();
MyInAppBrowser.isPaymentDone = false;
Utils.hideProgressDialog();
return;
}
});
@ -544,7 +543,7 @@ class _BookSuccessState extends State<BookSuccess> {
}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
createAdvancePayment(res, AppoitmentAllHistoryResultList appo) {
@ -561,7 +560,7 @@ class _BookSuccessState extends State<BookSuccess> {
appo.appointmentNo.toString());
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
//
// Future navigateToQR(
@ -586,7 +585,7 @@ class _BookSuccessState extends State<BookSuccess> {
getAppoQR(context);
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
Widget _getQRAppo() {
@ -743,7 +742,7 @@ class _BookSuccessState extends State<BookSuccess> {
navigateToQR(context, res['AppointmentQR']);
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
Future navigateToQR(context, String appoQR) async {

@ -1,7 +1,12 @@
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart';
import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:rating_bar/rating_bar.dart';
@ -14,6 +19,8 @@ class DoctorProfile extends StatefulWidget {
DoctorList doctor;
DoctorProfileList docProfileList;
AuthenticatedUser authUser;
DoctorProfile({@required this.doctor, @required this.docProfileList});
@override
@ -28,6 +35,8 @@ class _DoctorProfileState extends State<DoctorProfile>
@override
void initState() {
_tabController = new TabController(length: 2, vsync: this);
widget.authUser = new AuthenticatedUser();
getPatientData();
super.initState();
}
@ -175,13 +184,43 @@ class _DoctorProfileState extends State<DoctorProfile>
);
}
getPatientData() async {
AppSharedPreferences sharedPref = AppSharedPreferences();
if (await sharedPref.getObject(USER_PROFILE) != null) {
var data =
AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE));
setState(() {
print(data);
widget.authUser = data;
});
}
}
void goToBookConfirm() {
if (DocAvailableAppointments.areSlotsAvailable)
navigateToBookConfirm(context);
else
if (DocAvailableAppointments.areSlotsAvailable) {
if (widget.authUser.patientID != null) {
navigateToBookConfirm(context);
} else {
ConfirmDialog dialog = new ConfirmDialog(
context: context,
confirmMessage: "You have to login to use this service",
okText: TranslationBase.of(context).confirm,
cancelText: TranslationBase.of(context).cancel_nocaps,
okFunction: () => {navigateToLogin()},
cancelFunction: () => {});
dialog.showAlertDialog(context);
}
} else
AppToast.showErrorToast(message: "Please select Time Slot to continue");
}
navigateToLogin() {
ConfirmDialog.closeAlertDialog(context);
Navigator.of(context).pushNamed(
WELCOME_LOGIN,
);
}
Future navigateToBookConfirm(context) async {
Navigator.push(
context,

@ -14,6 +14,7 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
class QRCode extends StatefulWidget {
PatientShareResponse patientShareResponse;
@ -251,7 +252,7 @@ class _QRCodeState extends State<QRCode> {
ConfirmDialog.closeAlertDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
},
cancelFunction: () => {});
dialog.showAlertDialog(context);

@ -7,6 +7,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
import '../../../uitl/date_uitl.dart';
@ -339,7 +340,7 @@ class _DocAvailableAppointmentsState extends State<DocAvailableAppointments>
}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
Widget _buildEventsMarker(DateTime date, List events) {

@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:flutter/material.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
import '../SearchResults.dart';
@ -96,7 +97,7 @@ class _SearchByClinicState extends State<SearchByClinic> {
} else {}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
getDoctorsList(BuildContext context) {
@ -118,7 +119,7 @@ class _SearchByClinicState extends State<SearchByClinic> {
}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
Future navigateToSearchResults(context, docList) async {

@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsLis
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:flutter/material.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
import '../SearchResults.dart';
@ -94,7 +95,7 @@ class _SearchByDoctorState extends State<SearchByDoctor> {
}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
_onDocTextChanged(content) {

@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsLis
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:flutter/material.dart';
import 'package:rating_bar/rating_bar.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
import '../DoctorProfile.dart';
@ -130,7 +131,7 @@ class DoctorView extends StatelessWidget {
}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
Future navigateToDoctorProfile(context, docObject, docProfile) async {

@ -6,6 +6,7 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
class MyAppointments extends StatefulWidget {
List<AppoitmentAllHistoryResultList> appoList = [];
@ -93,7 +94,7 @@ class _MyAppointmentsState extends State<MyAppointments>
}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
bool isConfirmed(AppoitmentAllHistoryResultList appo) {

@ -6,6 +6,7 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart';
import 'package:flutter/material.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
class VisitTicket extends StatefulWidget {
List<DoctorList> appoList = [];
@ -68,7 +69,7 @@ class _VisitTicketState extends State<VisitTicket> {
}).catchError((err) {
print(err);
loading(false);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
loading(bool flag) {

@ -30,8 +30,8 @@ class ArrivedButtons {
{
"title": "Vital Signs",
"subtitle": "Values",
"icon": "assets/images/new-design/location_icon.png",
"caller": "navigateToProject"
"icon": "assets/images/new-design/vital_signs.png",
"caller": "VitalSigns"
},
{
"title": TranslationBase.of(AppGlobal.context).raise,

@ -30,8 +30,8 @@ class ArrivedButtons {
{
"title": "Vital Signs",
"subtitle": "Values",
"icon": "assets/images/new-design/location_icon.png",
"caller": "navigateToProject"
"icon": "assets/images/new-design/vital_signs.png",
"caller": "VitalSigns"
},
{
"title": TranslationBase.of(AppGlobal.context).raise,

@ -14,10 +14,11 @@ import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/askDocDialog.d
import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/reminder_dialog.dart';
import 'package:diplomaticquarterapp/pages/insurance/insurance_approval_screen.dart';
import 'package:diplomaticquarterapp/pages/medical/radiology/radiology_details_page.dart';
import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart';
import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
@ -184,6 +185,10 @@ class _AppointmentActionsState extends State<AppointmentActions> {
case "Insurance":
navigateToInsuranceApprovals(widget.appo.appointmentNo);
break;
case "VitalSigns":
navigateToVitalSigns(widget.appo.appointmentNo, widget.appo.projectID);
break;
}
}
@ -352,7 +357,7 @@ class _AppointmentActionsState extends State<AppointmentActions> {
}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
openAppointmentRadiology() {
@ -369,7 +374,7 @@ class _AppointmentActionsState extends State<AppointmentActions> {
}).catchError((err) {
print(err);
AppToast.showErrorToast(message: err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
openPrescriptionReport() {
@ -389,7 +394,7 @@ class _AppointmentActionsState extends State<AppointmentActions> {
}).catchError((err) {
print(err);
AppToast.showErrorToast(message: err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
Future navigateToMedicinePrescriptionReport(
@ -455,7 +460,7 @@ class _AppointmentActionsState extends State<AppointmentActions> {
}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
getCallRequestType() {
@ -465,19 +470,15 @@ class _AppointmentActionsState extends State<AppointmentActions> {
res['ListReqTypes'].forEach((element) {
requestData.add(new AskDocRequestType.fromJson(element));
});
// print(requestData.length);
Utils.hideProgressDialog();
Future.delayed(const Duration(milliseconds: 400), () {
showAskDocRequestDialog(requestData);
});
}).catchError((err) {
print(err);
Utils.hideProgressDialog();
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
showAskDocRequestDialog(List<AskDocRequestType> requestData) {
Utils.hideProgressDialog();
showGeneralDialog(
barrierColor: Colors.black.withOpacity(0.5),
transitionBuilder: (context, a1, a2, widget) {
@ -519,7 +520,7 @@ class _AppointmentActionsState extends State<AppointmentActions> {
}).catchError((err) {
print(err);
AppToast.showErrorToast(message: err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
confirmAppointment() {
@ -536,7 +537,7 @@ class _AppointmentActionsState extends State<AppointmentActions> {
}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
navigateToInsuranceApprovals(int appoNo) {
@ -544,6 +545,11 @@ class _AppointmentActionsState extends State<AppointmentActions> {
context, FadePage(page: InsuranceApproval(appointmentNo: appoNo)));
}
navigateToVitalSigns(int appoNo, int projectID) {
Navigator.push(
context, FadePage(page: VitalSignDetailsScreen(appointmentNo: appoNo, projectID: projectID)));
}
rateAppointment() {
widget.browser = new MyInAppBrowser();
widget.browser.openBrowser('http://hmg.com/SitePages/pso.aspx?p=' +

@ -4,7 +4,7 @@ import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResu
import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_details_page.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
import 'package:diplomaticquarterapp/widgets/buttons/button.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
@ -115,12 +115,10 @@ class _PrescriptionReportState extends State<PrescriptionReportPage> {
DoctorsListService service = new DoctorsListService();
service.sendPrescriptionEmail(widget.appo.appointmentDate, widget.appo.setupID, widget.listPres, context).then((res) {
AppToast.showSuccessToast(message: 'A copy has been sent to the e-mail');
Utils.hideProgressDialog();
}).catchError((err) {
print(err);
Utils.hideProgressDialog();
AppToast.showErrorToast(message: err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
navigateToPrescriptionDetails(PrescriptionReportEnh prescriptionReportEnh) {

@ -13,11 +13,11 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/widgets/bottom_navigation/bottom_nav_bar.dart';
import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:rating_bar/rating_bar.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
class ToDo extends StatefulWidget {
PatientShareResponse patientShareResponse;
@ -443,7 +443,8 @@ class _ToDoState extends State<ToDo> {
}
}).catchError((err) {
print(err);
});
AppToast.showErrorToast(message: err);
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
getPatientShare(context, AppoitmentAllHistoryResultList appo) {
@ -456,7 +457,7 @@ class _ToDoState extends State<ToDo> {
openPaymentDialog(appo, widget.patientShareResponse);
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
getAppoQR(context, AppoitmentAllHistoryResultList appo) {
@ -477,7 +478,7 @@ class _ToDoState extends State<ToDo> {
navigateToQR(context, res['AppointmentQR'], patientShareResponse);
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
Future navigateToQR(
@ -555,7 +556,6 @@ class _ToDoState extends State<ToDo> {
if (url.contains(element)) {
if (widget.browser.isOpened()) widget.browser.close();
MyInAppBrowser.isPaymentDone = true;
Utils.hideProgressDialog();
return;
}
});
@ -564,7 +564,6 @@ class _ToDoState extends State<ToDo> {
if (url.contains(element)) {
if (widget.browser.isOpened()) widget.browser.close();
MyInAppBrowser.isPaymentDone = false;
Utils.hideProgressDialog();
return;
}
});
@ -593,7 +592,7 @@ class _ToDoState extends State<ToDo> {
}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
createAdvancePayment(res, AppoitmentAllHistoryResultList appo) {
@ -611,7 +610,7 @@ class _ToDoState extends State<ToDo> {
appo);
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
addAdvancedNumberRequest(String advanceNumber, String paymentReference,
@ -625,7 +624,7 @@ class _ToDoState extends State<ToDo> {
getAppoQR(context, appo);
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
Future navigateToPaymentMethod(
@ -671,6 +670,6 @@ class _ToDoState extends State<ToDo> {
}
}).catchError((err) {
print(err);
});
}).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
}

@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
class ClippedVideo extends StatefulWidget {
final double width;
final double height;
final Widget child;
const ClippedVideo({
Key key,
@required this.width,
@required this.height,
@required this.child,
}) : super(key: key);
@override
_ClippedVideoState createState() => _ClippedVideoState();
}
class _ClippedVideoState extends State<ClippedVideo> {
@override
Widget build(BuildContext context) {
return Container(
width: widget.width,
height: widget.height,
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(20)),
border: Border.all(
color: Colors.white24,
),
),
child: ClipRRect(
child: widget.child,
borderRadius: const BorderRadius.all(Radius.circular(20)),
),
);
}
}

@ -0,0 +1,238 @@
import 'dart:async';
import 'package:after_layout/after_layout.dart';
import 'package:diplomaticquarterapp/pages/conference/widgets/circle_button.dart';
import 'package:flutter/material.dart';
class ConferenceButtonBar extends StatefulWidget {
final VoidCallback onVideoEnabled;
final VoidCallback onAudioEnabled;
final VoidCallback onHangup;
final VoidCallback onSwitchCamera;
final VoidCallback onPersonAdd;
final VoidCallback onPersonRemove;
final void Function(double) onHeight;
final VoidCallback onHide;
final VoidCallback onShow;
final Stream<bool> videoEnabled;
final Stream<bool> audioEnabled;
const ConferenceButtonBar({
Key key,
this.onVideoEnabled,
this.onAudioEnabled,
this.onHangup,
this.onSwitchCamera,
this.onPersonAdd,
this.onPersonRemove,
@required this.videoEnabled,
@required this.audioEnabled,
this.onHeight,
this.onHide,
this.onShow,
}) : assert(videoEnabled != null),
assert(audioEnabled != null),
super(key: key);
@override
_ConferenceButtonBarState createState() => _ConferenceButtonBarState();
}
class _ConferenceButtonBarState extends State<ConferenceButtonBar> with AfterLayoutMixin<ConferenceButtonBar> {
var _bottom = -100.0;
Timer _timer;
int _remaining;
var _videoEnabled = true;
var _audioEnabled = true;
double _hidden;
double _visible;
final _keyButtonBarHeight = GlobalKey();
final Duration timeout = const Duration(seconds: 5);
final Duration ms = const Duration(milliseconds: 1);
final Duration periodicDuration = const Duration(milliseconds: 100);
Timer startTimeout([int milliseconds]) {
final duration = milliseconds == null ? timeout : ms * milliseconds;
_remaining = duration.inMilliseconds;
return Timer.periodic(periodicDuration, (Timer timer) {
_remaining -= periodicDuration.inMilliseconds;
if (_remaining <= 0) {
timer.cancel();
_toggleBar();
}
});
}
void _pauseTimer() {
if (_timer == null) {
return;
}
_timer.cancel();
_timer = null;
}
void _resumeTimer() {
// resume the timer only when there is no timer active or when
// the bar is not already hidden.
if ((_timer != null && _timer.isActive) || _bottom == _hidden) {
return;
}
_timer = startTimeout(_remaining);
}
void _toggleBar() {
setState(() {
_bottom = _bottom == _visible ? _hidden : _visible;
if (_bottom == _visible && widget.onShow != null) {
widget.onShow();
}
if (_bottom == _hidden && widget.onHide != null) {
widget.onHide();
}
});
}
void _toggleBarOnEnd() {
if (_timer != null) {
if (_timer.isActive) {
_timer.cancel();
}
_timer = null;
}
if (_bottom == 0) {
_timer = startTimeout();
}
}
@override
void initState() {
super.initState();
_timer = startTimeout();
}
@override
void didChangeDependencies() {
_visible = MediaQuery.of(context).viewPadding.bottom;
super.didChangeDependencies();
}
@override
void afterFirstLayout(BuildContext context) {
final RenderBox renderBoxButtonBar = _keyButtonBarHeight.currentContext.findRenderObject();
final heightButtonBar = renderBoxButtonBar.size.height;
// Because the `didChangeDependencies` fires before the `afterFirstLayout`, we can use the `_visible` property here.
_hidden = -(heightButtonBar + _visible);
widget.onHeight(heightButtonBar);
_toggleBar();
}
@override
void dispose() {
super.dispose();
if (_timer != null && _timer.isActive) {
_timer.cancel();
_timer = null;
}
}
@override
Widget build(BuildContext context) {
return Positioned(
top: 0,
left: 0,
right: 0,
bottom: 0,
child: GestureDetector(
key: Key('show-hide-button-bar-gesture'),
behavior: HitTestBehavior.translucent,
onTapDown: (_) => _pauseTimer(),
onTapUp: (_) => _toggleBar(),
onTapCancel: () => _resumeTimer(),
child: Stack(
children: <Widget>[
AnimatedPositioned(
key: Key('button-bar'),
bottom: _bottom,
left: 0,
right: 0,
duration: const Duration(milliseconds: 300),
curve: Curves.linear,
child: _buildRow(context),
onEnd: _toggleBarOnEnd,
),
],
),
),
);
}
void _onPressed(VoidCallback callback) {
if (callback != null) {
callback();
}
if (_timer != null && _timer.isActive) {
_timer.cancel();
}
_timer = startTimeout();
}
Widget _buildRow(BuildContext context) {
return Padding(
key: _keyButtonBarHeight,
padding: const EdgeInsets.only(bottom: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
CircleButton(
child: StreamBuilder<bool>(
stream: widget.videoEnabled,
initialData: _videoEnabled,
builder: (context, snapshot) {
_videoEnabled = snapshot.data;
return Icon(
_videoEnabled ? Icons.videocam : Icons.videocam_off,
color: Colors.white,
);
}),
key: Key('camera-button'),
onPressed: () => _onPressed(widget.onVideoEnabled),
),
CircleButton(
child: StreamBuilder<bool>(
stream: widget.audioEnabled,
initialData: _audioEnabled,
builder: (context, snapshot) {
_audioEnabled = snapshot.data;
return Icon(
_audioEnabled ? Icons.mic : Icons.mic_off,
color: Colors.white,
);
}),
key: Key('microphone-button'),
onPressed: () => _onPressed(widget.onAudioEnabled),
),
CircleButton(
radius: 35,
child: const RotationTransition(
turns: AlwaysStoppedAnimation<double>(135 / 360),
child: Icon(
Icons.phone,
color: Colors.white,
size: 40,
),
),
color: Colors.red.withAlpha(200),
key: Key('hangup-button'),
onPressed: () => _onPressed(widget.onHangup),
),
CircleButton(
child: const Icon(Icons.switch_camera, color: Colors.white),
key: Key('switch-camera-button'),
onPressed: () => _onPressed(widget.onSwitchCamera),
),
],
),
);
}
}

@ -0,0 +1,388 @@
import 'dart:async';
import 'package:diplomaticquarterapp/models/LiveCare/room_model.dart';
import 'package:diplomaticquarterapp/pages/conference/conference_button_bar.dart';
import 'package:diplomaticquarterapp/pages/conference/conference_room.dart';
import 'package:diplomaticquarterapp/pages/conference/draggable_publisher.dart';
import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart';
import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart';
import 'package:diplomaticquarterapp/pages/conference/widgets/platform_alert_dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:wakelock/wakelock.dart';
class ConferencePage extends StatefulWidget {
final RoomModel roomModel;
const ConferencePage({Key key, this.roomModel}) : super(key: key);
@override
_ConferencePageState createState() => _ConferencePageState();
}
class _ConferencePageState extends State<ConferencePage> {
final StreamController<bool> _onButtonBarVisibleStreamController = StreamController<bool>.broadcast();
final StreamController<double> _onButtonBarHeightStreamController = StreamController<double>.broadcast();
ConferenceRoom _conferenceRoom;
StreamSubscription _onConferenceRoomException;
@override
void initState() {
super.initState();
_lockInPortrait();
_connectToRoom();
_wakeLock(true);
}
void _connectToRoom() async {
try {
final conferenceRoom = ConferenceRoom(
name: widget.roomModel.name,
token: widget.roomModel.token,
identity: widget.roomModel.identity,
);
await conferenceRoom.connect();
setState(() {
_conferenceRoom = conferenceRoom;
_onConferenceRoomException = _conferenceRoom.onException.listen((err) async {
await PlatformAlertDialog(
title: err is PlatformException ? err.message : 'An error occured',
content: err is PlatformException ? err.details : err.toString(),
defaultActionText: 'OK',
).show(context);
});
_conferenceRoom.addListener(_conferenceRoomUpdated);
});
} catch (err) {
print(err);
await PlatformAlertDialog(
title: err is PlatformException ? err.message : 'An error occured',
content: err is PlatformException ? err.details : err.toString(),
defaultActionText: 'OK',
).show(context);
Navigator.of(context).pop();
}
}
Future<void> _lockInPortrait() async {
await SystemChrome.setPreferredOrientations(<DeviceOrientation>[
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
}
@override
void dispose() {
_freePortraitLock();
_wakeLock(false);
_disposeStreamsAndSubscriptions();
if (_conferenceRoom != null) _conferenceRoom.removeListener(_conferenceRoomUpdated);
super.dispose();
}
Future<void> _freePortraitLock() async {
await SystemChrome.setPreferredOrientations(<DeviceOrientation>[
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
}
Future<void> _disposeStreamsAndSubscriptions() async {
if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close();
if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close();
if (_onConferenceRoomException != null) await _onConferenceRoomException.cancel();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: Scaffold(
backgroundColor: Colors.black,
body: _conferenceRoom == null ? showProgress() : buildLayout(),
),
);
}
LayoutBuilder buildLayout() {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Stack(
children: <Widget>[
_buildParticipants(context, constraints.biggest, _conferenceRoom),
ConferenceButtonBar(
audioEnabled: _conferenceRoom.onAudioEnabled,
videoEnabled: _conferenceRoom.onVideoEnabled,
onAudioEnabled: _conferenceRoom.toggleAudioEnabled,
onVideoEnabled: _conferenceRoom.toggleVideoEnabled,
onHangup: _onHangup,
onSwitchCamera: _conferenceRoom.switchCamera,
onPersonAdd: _onPersonAdd,
onPersonRemove: _onPersonRemove,
onHeight: _onHeightBar,
onShow: _onShowBar,
onHide: _onHideBar,
),
],
);
},
);
}
Widget showProgress() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Center(child: CircularProgressIndicator()),
SizedBox(
height: 10,
),
Text(
'Connecting to the call...',
style: TextStyle(color: Colors.white),
),
],
);
}
Future<void> _onHangup() async {
print('onHangup');
await _conferenceRoom.disconnect();
Navigator.of(context).pop();
}
void _onPersonAdd() {
print('onPersonAdd');
try {
_conferenceRoom.addDummy(
child: Stack(
children: <Widget>[
const Placeholder(),
Center(
child: Text(
(_conferenceRoom.participants.length + 1).toString(),
style: const TextStyle(
shadows: <Shadow>[
Shadow(
blurRadius: 3.0,
color: Color.fromARGB(255, 0, 0, 0),
),
Shadow(
blurRadius: 8.0,
color: Color.fromARGB(255, 255, 255, 255),
),
],
fontSize: 80,
),
),
),
],
),
);
} on PlatformException catch (err) {
PlatformAlertDialog(
title: err.message,
content: err.details,
defaultActionText: 'OK',
).show(context);
}
}
void _onPersonRemove() {
print('onPersonRemove');
_conferenceRoom.removeDummy();
}
Widget _buildParticipants(BuildContext context, Size size, ConferenceRoom conferenceRoom) {
final children = <Widget>[];
final length = conferenceRoom.participants.length;
if (length <= 2) {
_buildOverlayLayout(context, size, children);
return Stack(children: children);
}
void buildInCols(bool removeLocalBeforeChunking, bool moveLastOfEachRowToNextRow, int columns) {
_buildLayoutInGrid(
context,
size,
children,
removeLocalBeforeChunking: removeLocalBeforeChunking,
moveLastOfEachRowToNextRow: moveLastOfEachRowToNextRow,
columns: columns,
);
}
if (length <= 3) {
buildInCols(true, false, 1);
} else if (length == 5) {
buildInCols(false, true, 2);
} else if (length <= 6 || length == 8) {
buildInCols(false, false, 2);
} else if (length == 7 || length == 9) {
buildInCols(true, false, 2);
} else if (length == 10) {
buildInCols(false, true, 3);
} else if (length == 13 || length == 16) {
buildInCols(true, false, 3);
} else if (length <= 18) {
buildInCols(false, false, 3);
}
return Column(
children: children,
);
}
void _buildOverlayLayout(BuildContext context, Size size, List<Widget> children) {
final participants = _conferenceRoom.participants;
if (participants.length == 1) {
children.add(_buildNoiseBox());
} else {
final remoteParticipant = participants.firstWhere((ParticipantWidget participant) => participant.isRemote, orElse: () => null);
if (remoteParticipant != null) {
children.add(remoteParticipant);
}
}
final localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null);
if (localParticipant != null) {
children.add(DraggablePublisher(
key: Key('publisher'),
child: localParticipant,
availableScreenSize: size,
onButtonBarVisible: _onButtonBarVisibleStreamController.stream,
onButtonBarHeight: _onButtonBarHeightStreamController.stream,
));
}
}
void _buildLayoutInGrid(
BuildContext context,
Size size,
List<Widget> children, {
bool removeLocalBeforeChunking = false,
bool moveLastOfEachRowToNextRow = false,
int columns = 2,
}) {
final participants = _conferenceRoom.participants;
ParticipantWidget localParticipant;
if (removeLocalBeforeChunking) {
localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null);
if (localParticipant != null) {
participants.remove(localParticipant);
}
}
final chunkedParticipants = chunk(array: participants, size: columns);
if (localParticipant != null) {
chunkedParticipants.last.add(localParticipant);
participants.add(localParticipant);
}
if (moveLastOfEachRowToNextRow) {
for (var i = 0; i < chunkedParticipants.length - 1; i++) {
var participant = chunkedParticipants[i].removeLast();
chunkedParticipants[i + 1].insert(0, participant);
}
}
for (final participantChunk in chunkedParticipants) {
final rowChildren = <Widget>[];
for (final participant in participantChunk) {
rowChildren.add(
Container(
width: size.width / participantChunk.length,
height: size.height / chunkedParticipants.length,
child: participant,
),
);
}
children.add(
Container(
height: size.height / chunkedParticipants.length,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: rowChildren,
),
),
);
}
}
NoiseBox _buildNoiseBox() {
return NoiseBox(
density: NoiseBoxDensity.xLow,
backgroundColor: Colors.grey.shade900,
child: Center(
child: Container(
color: Colors.black54,
width: double.infinity,
height: 40,
child: Center(
child: Text(
'Waiting for another participant to connect to the call...',
key: Key('text-wait'),
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
),
),
),
),
);
}
List<List<T>> chunk<T>({@required List<T> array, @required int size}) {
final result = <List<T>>[];
if (array.isEmpty || size <= 0) {
return result;
}
var first = 0;
var last = size;
final totalLoop = array.length % size == 0 ? array.length ~/ size : array.length ~/ size + 1;
for (var i = 0; i < totalLoop; i++) {
if (last > array.length) {
result.add(array.sublist(first, array.length));
} else {
result.add(array.sublist(first, last));
}
first = last;
last = last + size;
}
return result;
}
void _onHeightBar(double height) {
_onButtonBarHeightStreamController.add(height);
}
void _onShowBar() {
setState(() {
SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]);
});
_onButtonBarVisibleStreamController.add(true);
}
void _onHideBar() {
setState(() {
SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
});
_onButtonBarVisibleStreamController.add(false);
}
Future<void> _wakeLock(bool enable) async {
try {
return await (enable ? Wakelock.enable() : Wakelock.disable());
} catch (err) {
print('Unable to change the Wakelock and set it to $enable');
print(err);
}
}
void _conferenceRoomUpdated() {
setState(() {});
}
}

@ -0,0 +1,530 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:twilio_programmable_video/twilio_programmable_video.dart';
class ConferenceRoom with ChangeNotifier {
final String name;
final String token;
final String identity;
final StreamController<bool> _onAudioEnabledStreamController = StreamController<bool>.broadcast();
Stream<bool> onAudioEnabled;
final StreamController<bool> _onVideoEnabledStreamController = StreamController<bool>.broadcast();
Stream<bool> onVideoEnabled;
final StreamController<Exception> _onExceptionStreamController = StreamController<Exception>.broadcast();
Stream<Exception> onException;
final Completer<Room> _completer = Completer<Room>();
final List<ParticipantWidget> _participants = [];
final List<ParticipantBuffer> _participantBuffer = [];
final List<StreamSubscription> _streamSubscriptions = [];
final List<RemoteDataTrack> _dataTracks = [];
final List<String> _messages = [];
CameraCapturer _cameraCapturer;
Room _room;
Timer _timer;
ConferenceRoom({
@required this.name,
@required this.token,
@required this.identity,
}) {
onAudioEnabled = _onAudioEnabledStreamController.stream;
onVideoEnabled = _onVideoEnabledStreamController.stream;
onException = _onExceptionStreamController.stream;
}
List<ParticipantWidget> get participants {
return [..._participants];
}
Future<Room> connect() async {
print('ConferenceRoom.connect()');
try {
await TwilioProgrammableVideo.debug(dart: true, native: true);
await TwilioProgrammableVideo.setSpeakerphoneOn(true);
_cameraCapturer = CameraCapturer(CameraSource.FRONT_CAMERA);
var connectOptions = ConnectOptions(
token,
roomName: name,
preferredAudioCodecs: [OpusCodec()],
audioTracks: [LocalAudioTrack(true)],
dataTracks: [LocalDataTrack()],
videoTracks: [LocalVideoTrack(true, _cameraCapturer)],
enableDominantSpeaker: true,
);
_room = await TwilioProgrammableVideo.connect(connectOptions);
_streamSubscriptions.add(_room.onConnected.listen(_onConnected));
_streamSubscriptions.add(_room.onConnectFailure.listen(_onConnectFailure));
return _completer.future;
} catch (err) {
print(err);
rethrow;
}
}
Future<void> disconnect() async {
print('ConferenceRoom.disconnect()');
if (_timer != null) {
_timer.cancel();
}
await _room.disconnect();
}
@override
void dispose() {
print('ConferenceRoom.dispose()');
_disposeStreamsAndSubscriptions();
super.dispose();
}
Future<void> _disposeStreamsAndSubscriptions() async {
await _onAudioEnabledStreamController.close();
await _onVideoEnabledStreamController.close();
await _onExceptionStreamController.close();
for (var streamSubscription in _streamSubscriptions) {
await streamSubscription.cancel();
}
}
Future<void> sendMessage(String message) async {
final tracks = _room.localParticipant.localDataTracks;
final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack;
if (localDataTrack == null || _messages.isNotEmpty) {
print('ConferenceRoom.sendMessage => Track is not available yet, buffering message.');
_messages.add(message);
return;
}
await localDataTrack.send(message);
}
Future<void> sendBufferMessage(ByteBuffer message) async {
final tracks = _room.localParticipant.localDataTracks;
final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack;
if (localDataTrack == null) {
return;
}
await localDataTrack.sendBuffer(message);
}
Future<void> toggleVideoEnabled() async {
final tracks = _room.localParticipant.localVideoTracks;
final localVideoTrack = tracks.isEmpty ? null : tracks[0].localVideoTrack;
if (localVideoTrack == null) {
print('ConferenceRoom.toggleVideoEnabled() => Track is not available yet!');
return;
}
await localVideoTrack.enable(!localVideoTrack.isEnabled);
var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote);
if (index < 0) {
return;
}
var participant = _participants[index];
_participants.replaceRange(
index,
index + 1,
[
participant.copyWith(videoEnabled: localVideoTrack.isEnabled),
],
);
print('ConferenceRoom.toggleVideoEnabled() => ${localVideoTrack.isEnabled}');
_onVideoEnabledStreamController.add(localVideoTrack.isEnabled);
notifyListeners();
}
Future<void> toggleAudioEnabled() async {
final tracks = _room.localParticipant.localAudioTracks;
final localAudioTrack = tracks.isEmpty ? null : tracks[0].localAudioTrack;
if (localAudioTrack == null) {
print('ConferenceRoom.toggleAudioEnabled() => Track is not available yet!');
return;
}
await localAudioTrack.enable(!localAudioTrack.isEnabled);
var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote);
if (index < 0) {
return;
}
var participant = _participants[index];
_participants.replaceRange(
index,
index + 1,
[
participant.copyWith(audioEnabled: localAudioTrack.isEnabled),
],
);
print('ConferenceRoom.toggleAudioEnabled() => ${localAudioTrack.isEnabled}');
_onAudioEnabledStreamController.add(localAudioTrack.isEnabled);
notifyListeners();
}
Future<void> switchCamera() async {
print('ConferenceRoom.switchCamera()');
try {
await _cameraCapturer.switchCamera();
} on FormatException catch (e) {
print(
'ConferenceRoom.switchCamera() failed because of FormatException with message: ${e.message}',
);
}
}
void addDummy({Widget child}) {
print('ConferenceRoom.addDummy()');
if (_participants.length >= 18) {
throw PlatformException(
code: 'ConferenceRoom.maximumReached',
message: 'Maximum reached',
details: 'Currently the lay-out can only render a maximum of 18 participants',
);
}
_participants.insert(
0,
ParticipantWidget(
id: (_participants.length + 1).toString(),
child: child,
isRemote: true,
audioEnabled: true,
videoEnabled: true,
isDummy: true,
),
);
notifyListeners();
}
void removeDummy() {
print('ConferenceRoom.removeDummy()');
var dummy = _participants.firstWhere((participant) => participant.isDummy, orElse: () => null);
if (dummy != null) {
_participants.remove(dummy);
notifyListeners();
}
}
void _onConnected(Room room) {
print('ConferenceRoom._onConnected => state: ${room.state}');
// When connected for the first time, add remote participant listeners
_streamSubscriptions.add(_room.onParticipantConnected.listen(_onParticipantConnected));
_streamSubscriptions.add(_room.onParticipantDisconnected.listen(_onParticipantDisconnected));
_streamSubscriptions.add(_room.onDominantSpeakerChange.listen(_onDominantSpeakerChanged));
// Only add ourselves when connected for the first time too.
_participants.add(
_buildParticipant(
child: room.localParticipant.localVideoTracks[0].localVideoTrack.widget(),
id: identity,
audioEnabled: true,
videoEnabled: true,
),
);
for (final remoteParticipant in room.remoteParticipants) {
var participant = _participants.firstWhere((participant) => participant.id == remoteParticipant.sid, orElse: () => null);
if (participant == null) {
print('Adding participant that was already present in the room ${remoteParticipant.sid}, before I connected');
_addRemoteParticipantListeners(remoteParticipant);
}
}
// We have to listen for the [onDataTrackPublished] event on the [LocalParticipant] in
// order to be able to use the [send] method.
_streamSubscriptions.add(room.localParticipant.onDataTrackPublished.listen(_onLocalDataTrackPublished));
notifyListeners();
_completer.complete(room);
_timer = Timer.periodic(const Duration(minutes: 1), (_) {
// Let's see if we can send some data over the DataTrack API
sendMessage('And another minute has passed since I connected...');
// Also try the ByteBuffer way of sending data
final list = 'This data has been sent over the ByteBuffer channel of the DataTrack API'.codeUnits;
var bytes = Uint8List.fromList(list);
sendBufferMessage(bytes.buffer);
});
}
void _onLocalDataTrackPublished(LocalDataTrackPublishedEvent event) {
// Send buffered messages, if any...
while (_messages.isNotEmpty) {
var message = _messages.removeAt(0);
print('Sending buffered message: $message');
event.localDataTrackPublication.localDataTrack.send(message);
}
}
void _onConnectFailure(RoomConnectFailureEvent event) {
print('ConferenceRoom._onConnectFailure: ${event.exception}');
_completer.completeError(event.exception);
}
void _onDominantSpeakerChanged(DominantSpeakerChangedEvent event) {
print('ConferenceRoom._onDominantSpeakerChanged: ${event.remoteParticipant.identity}');
var oldDominantParticipant = _participants.firstWhere((p) => p.isDominant, orElse: () => null);
if (oldDominantParticipant != null) {
var oldDominantParticipantIndex = _participants.indexOf(oldDominantParticipant);
_participants.replaceRange(oldDominantParticipantIndex, oldDominantParticipantIndex + 1, [oldDominantParticipant.copyWith(isDominant: false)]);
}
var newDominantParticipant = _participants.firstWhere((p) => p.id == event.remoteParticipant.sid);
var newDominantParticipantIndex = _participants.indexOf(newDominantParticipant);
_participants.replaceRange(newDominantParticipantIndex, newDominantParticipantIndex + 1, [newDominantParticipant.copyWith(isDominant: true)]);
notifyListeners();
}
void _onParticipantConnected(RoomParticipantConnectedEvent event) {
print('ConferenceRoom._onParticipantConnected, ${event.remoteParticipant.sid}');
_addRemoteParticipantListeners(event.remoteParticipant);
}
void _onParticipantDisconnected(RoomParticipantDisconnectedEvent event) {
print('ConferenceRoom._onParticipantDisconnected: ${event.remoteParticipant.sid}');
_participants.removeWhere((ParticipantWidget p) => p.id == event.remoteParticipant.sid);
notifyListeners();
}
ParticipantWidget _buildParticipant({
@required Widget child,
@required String id,
@required bool audioEnabled,
@required bool videoEnabled,
RemoteParticipant remoteParticipant,
}) {
return ParticipantWidget(
id: remoteParticipant?.sid,
isRemote: remoteParticipant != null,
child: child,
audioEnabled: audioEnabled,
videoEnabled: videoEnabled,
);
}
void _addRemoteParticipantListeners(RemoteParticipant remoteParticipant) {
print('ConferenceRoom._addRemoteParticipantListeners() => Adding listeners to remoteParticipant ${remoteParticipant.sid}');
_streamSubscriptions.add(remoteParticipant.onAudioTrackDisabled.listen(_onAudioTrackDisabled));
_streamSubscriptions.add(remoteParticipant.onAudioTrackEnabled.listen(_onAudioTrackEnabled));
_streamSubscriptions.add(remoteParticipant.onAudioTrackPublished.listen(_onAudioTrackPublished));
_streamSubscriptions.add(remoteParticipant.onAudioTrackSubscribed.listen(_onAudioTrackSubscribed));
_streamSubscriptions.add(remoteParticipant.onAudioTrackSubscriptionFailed.listen(_onAudioTrackSubscriptionFailed));
_streamSubscriptions.add(remoteParticipant.onAudioTrackUnpublished.listen(_onAudioTrackUnpublished));
_streamSubscriptions.add(remoteParticipant.onAudioTrackUnsubscribed.listen(_onAudioTrackUnsubscribed));
_streamSubscriptions.add(remoteParticipant.onDataTrackPublished.listen(_onDataTrackPublished));
_streamSubscriptions.add(remoteParticipant.onDataTrackSubscribed.listen(_onDataTrackSubscribed));
_streamSubscriptions.add(remoteParticipant.onDataTrackSubscriptionFailed.listen(_onDataTrackSubscriptionFailed));
_streamSubscriptions.add(remoteParticipant.onDataTrackUnpublished.listen(_onDataTrackUnpublished));
_streamSubscriptions.add(remoteParticipant.onDataTrackUnsubscribed.listen(_onDataTrackUnsubscribed));
_streamSubscriptions.add(remoteParticipant.onVideoTrackDisabled.listen(_onVideoTrackDisabled));
_streamSubscriptions.add(remoteParticipant.onVideoTrackEnabled.listen(_onVideoTrackEnabled));
_streamSubscriptions.add(remoteParticipant.onVideoTrackPublished.listen(_onVideoTrackPublished));
_streamSubscriptions.add(remoteParticipant.onVideoTrackSubscribed.listen(_onVideoTrackSubscribed));
_streamSubscriptions.add(remoteParticipant.onVideoTrackSubscriptionFailed.listen(_onVideoTrackSubscriptionFailed));
_streamSubscriptions.add(remoteParticipant.onVideoTrackUnpublished.listen(_onVideoTrackUnpublished));
_streamSubscriptions.add(remoteParticipant.onVideoTrackUnsubscribed.listen(_onVideoTrackUnsubscribed));
}
void _onAudioTrackDisabled(RemoteAudioTrackEvent event) {
print('ConferenceRoom._onAudioTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}');
_setRemoteAudioEnabled(event);
}
void _onAudioTrackEnabled(RemoteAudioTrackEvent event) {
print('ConferenceRoom._onAudioTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}');
_setRemoteAudioEnabled(event);
}
void _onAudioTrackPublished(RemoteAudioTrackEvent event) {
print('ConferenceRoom._onAudioTrackPublished(), ${event.remoteParticipant.sid}}');
}
void _onAudioTrackSubscribed(RemoteAudioTrackSubscriptionEvent event) {
print('ConferenceRoom._onAudioTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}');
_addOrUpdateParticipant(event);
}
void _onAudioTrackSubscriptionFailed(RemoteAudioTrackSubscriptionFailedEvent event) {
print('ConferenceRoom._onAudioTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}');
_onExceptionStreamController.add(
PlatformException(
code: 'ConferenceRoom.audioTrackSubscriptionFailed',
message: 'AudioTrack Subscription Failed',
details: event.exception.toString(),
),
);
}
void _onAudioTrackUnpublished(RemoteAudioTrackEvent event) {
print('ConferenceRoom._onAudioTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}');
}
void _onAudioTrackUnsubscribed(RemoteAudioTrackSubscriptionEvent event) {
print('ConferenceRoom._onAudioTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrack.sid}');
}
void _onDataTrackPublished(RemoteDataTrackEvent event) {
print('ConferenceRoom._onDataTrackPublished(), ${event.remoteParticipant.sid}}');
}
void _onDataTrackSubscribed(RemoteDataTrackSubscriptionEvent event) {
print('ConferenceRoom._onDataTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}');
final dataTrack = event.remoteDataTrackPublication.remoteDataTrack;
_dataTracks.add(dataTrack);
_streamSubscriptions.add(dataTrack.onMessage.listen(_onMessage));
_streamSubscriptions.add(dataTrack.onBufferMessage.listen(_onBufferMessage));
}
void _onDataTrackSubscriptionFailed(RemoteDataTrackSubscriptionFailedEvent event) {
print('ConferenceRoom._onDataTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}');
_onExceptionStreamController.add(
PlatformException(
code: 'ConferenceRoom.dataTrackSubscriptionFailed',
message: 'DataTrack Subscription Failed',
details: event.exception.toString(),
),
);
}
void _onDataTrackUnpublished(RemoteDataTrackEvent event) {
print('ConferenceRoom._onDataTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}');
}
void _onDataTrackUnsubscribed(RemoteDataTrackSubscriptionEvent event) {
print('ConferenceRoom._onDataTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrack.sid}');
}
void _onVideoTrackDisabled(RemoteVideoTrackEvent event) {
print('ConferenceRoom._onVideoTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}');
_setRemoteVideoEnabled(event);
}
void _onVideoTrackEnabled(RemoteVideoTrackEvent event) {
print('ConferenceRoom._onVideoTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}');
_setRemoteVideoEnabled(event);
}
void _onVideoTrackPublished(RemoteVideoTrackEvent event) {
print('ConferenceRoom._onVideoTrackPublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}');
}
void _onVideoTrackSubscribed(RemoteVideoTrackSubscriptionEvent event) {
print('ConferenceRoom._onVideoTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}');
_addOrUpdateParticipant(event);
}
void _onVideoTrackSubscriptionFailed(RemoteVideoTrackSubscriptionFailedEvent event) {
print('ConferenceRoom._onVideoTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}');
_onExceptionStreamController.add(
PlatformException(
code: 'ConferenceRoom.videoTrackSubscriptionFailed',
message: 'VideoTrack Subscription Failed',
details: event.exception.toString(),
),
);
}
void _onVideoTrackUnpublished(RemoteVideoTrackEvent event) {
print('ConferenceRoom._onVideoTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}');
}
void _onVideoTrackUnsubscribed(RemoteVideoTrackSubscriptionEvent event) {
print('ConferenceRoom._onVideoTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}');
}
void _onMessage(RemoteDataTrackStringMessageEvent event) {
print('onMessage => ${event.remoteDataTrack.sid}, ${event.message}');
}
void _onBufferMessage(RemoteDataTrackBufferMessageEvent event) {
print('onBufferMessage => ${event.remoteDataTrack.sid}, ${String.fromCharCodes(event.message.asUint8List())}');
}
void _setRemoteAudioEnabled(RemoteAudioTrackEvent event) {
if (event.remoteAudioTrackPublication == null) {
return;
}
var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid);
if (index < 0) {
return;
}
var participant = _participants[index];
_participants.replaceRange(
index,
index + 1,
[
participant.copyWith(audioEnabled: event.remoteAudioTrackPublication.isTrackEnabled),
],
);
notifyListeners();
}
void _setRemoteVideoEnabled(RemoteVideoTrackEvent event) {
if (event.remoteVideoTrackPublication == null) {
return;
}
var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid);
if (index < 0) {
return;
}
var participant = _participants[index];
_participants.replaceRange(
index,
index + 1,
[
participant.copyWith(videoEnabled: event.remoteVideoTrackPublication.isTrackEnabled),
],
);
notifyListeners();
}
void _addOrUpdateParticipant(RemoteParticipantEvent event) {
print('ConferenceRoom._addOrUpdateParticipant(), ${event.remoteParticipant.sid}');
final participant = _participants.firstWhere(
(ParticipantWidget participant) => participant.id == event.remoteParticipant.sid,
orElse: () => null,
);
if (participant != null) {
print('Participant found: ${participant.id}, updating A/V enabled values');
_setRemoteVideoEnabled(event);
_setRemoteAudioEnabled(event);
} else {
final bufferedParticipant = _participantBuffer.firstWhere(
(ParticipantBuffer participant) => participant.id == event.remoteParticipant.sid,
orElse: () => null,
);
if (bufferedParticipant != null) {
_participantBuffer.remove(bufferedParticipant);
} else if (event is RemoteAudioTrackEvent) {
print('Audio subscription came first, waiting for the video subscription...');
_participantBuffer.add(
ParticipantBuffer(
id: event.remoteParticipant.sid,
audioEnabled: event.remoteAudioTrackPublication?.remoteAudioTrack?.isEnabled ?? true,
),
);
return;
}
if (event is RemoteVideoTrackSubscriptionEvent) {
print('New participant, adding: ${event.remoteParticipant.sid}');
_participants.insert(
0,
_buildParticipant(
child: event.remoteVideoTrack.widget(),
id: event.remoteParticipant.sid,
remoteParticipant: event.remoteParticipant,
audioEnabled: bufferedParticipant?.audioEnabled ?? true,
videoEnabled: event.remoteVideoTrackPublication?.remoteVideoTrack?.isEnabled ?? true,
),
);
}
notifyListeners();
}
}
}

@ -0,0 +1,173 @@
import 'dart:async';
import 'dart:io';
import 'package:diplomaticquarterapp/pages/conference/clipped_video.dart';
import 'package:flutter/material.dart';
class DraggablePublisher extends StatefulWidget {
final Size availableScreenSize;
final Widget child;
final double scaleFactor;
final Stream<bool> onButtonBarVisible;
final Stream<double> onButtonBarHeight;
const DraggablePublisher({
Key key,
@required this.availableScreenSize,
this.child,
@required this.onButtonBarVisible,
@required this.onButtonBarHeight,
/// The portion of the screen the DraggableWidget should use.
this.scaleFactor = .25,
}) : assert(scaleFactor != null && scaleFactor > 0 && scaleFactor <= .4),
assert(availableScreenSize != null),
assert(onButtonBarVisible != null),
assert(onButtonBarHeight != null),
super(key: key);
@override
_DraggablePublisherState createState() => _DraggablePublisherState();
}
class _DraggablePublisherState extends State<DraggablePublisher> {
bool _isButtonBarVisible = true;
double _buttonBarHeight = 0;
double _width;
double _height;
double _top;
double _left;
double _viewPaddingTop;
double _viewPaddingBottom;
final double _padding = 8.0;
final Duration _duration300ms = const Duration(milliseconds: 300);
final Duration _duration0ms = const Duration(milliseconds: 0);
Duration _duration;
StreamSubscription _streamSubscription;
StreamSubscription _streamHeightSubscription;
@override
void initState() {
super.initState();
_duration = _duration300ms;
_width = widget.availableScreenSize.width * widget.scaleFactor;
_height = _width * (widget.availableScreenSize.height / widget.availableScreenSize.width);
_top = widget.availableScreenSize.height - (_buttonBarHeight + _padding) - _height;
_left = widget.availableScreenSize.width - _padding - _width;
_streamSubscription = widget.onButtonBarVisible.listen(_buttonBarVisible);
_streamHeightSubscription = widget.onButtonBarHeight.listen(_getButtonBarHeight);
}
@override
void didChangeDependencies() {
final mediaQuery = MediaQuery.of(context);
_viewPaddingTop = mediaQuery.viewPadding.top;
_viewPaddingBottom = mediaQuery.viewPadding.bottom;
super.didChangeDependencies();
}
@override
void dispose() {
_streamSubscription.cancel();
_streamHeightSubscription.cancel();
super.dispose();
}
void _getButtonBarHeight(double height) {
setState(() {
_buttonBarHeight = height;
_positionWidget();
});
}
void _buttonBarVisible(bool visible) {
if (!mounted) {
return;
}
setState(() {
_isButtonBarVisible = visible;
if (_duration == _duration300ms) {
// only position the widget when we are not currently dragging it around
_positionWidget();
}
});
}
@override
Widget build(BuildContext context) {
return AnimatedPositioned(
top: _top,
left: _left,
width: _width,
height: _height,
duration: _duration,
child: Listener(
onPointerDown: (_) => _duration = _duration0ms,
onPointerMove: (PointerMoveEvent event) {
setState(() {
_left = (_left + event.delta.dx).roundToDouble();
_top = (_top + event.delta.dy).roundToDouble();
});
},
onPointerUp: (_) => _positionWidget(),
onPointerCancel: (_) => _positionWidget(),
child: ClippedVideo(
height: _height,
width: _width,
child: widget.child,
),
),
);
}
double _getCurrentStatusBarHeight() {
if (_isButtonBarVisible) {
return _viewPaddingTop;
}
final _defaultViewPaddingTop = Platform.isIOS ? 20.0 : Platform.isAndroid ? 24.0 : 0.0;
if (_viewPaddingTop > _defaultViewPaddingTop) {
// There must be a hardware notch in the display.
return _viewPaddingTop;
}
return 0.0;
}
double _getCurrentButtonBarHeight() {
if (_isButtonBarVisible) {
return _buttonBarHeight + _viewPaddingBottom;
}
return _viewPaddingBottom;
}
void _positionWidget() {
// Determine the center of the object being dragged so we can decide
// in which corner the object should be placed.
var dx = (_width / 2) + _left;
dx = dx < 0 ? 0 : dx >= widget.availableScreenSize.width ? widget.availableScreenSize.width - 1 : dx;
var dy = (_height / 2) + _top;
dy = dy < 0 ? 0 : dy >= widget.availableScreenSize.height ? widget.availableScreenSize.height - 1 : dy;
final draggableCenter = Offset(dx, dy);
setState(() {
_duration = _duration300ms;
if (Rect.fromLTRB(0, 0, widget.availableScreenSize.width / 2, widget.availableScreenSize.height / 2).contains(draggableCenter)) {
// Top-left
_top = _getCurrentStatusBarHeight() + _padding;
_left = _padding;
} else if (Rect.fromLTRB(widget.availableScreenSize.width / 2, 0, widget.availableScreenSize.width, widget.availableScreenSize.height / 2).contains(draggableCenter)) {
// Top-right
_top = _getCurrentStatusBarHeight() + _padding;
_left = widget.availableScreenSize.width - _padding - _width;
} else if (Rect.fromLTRB(0, widget.availableScreenSize.height / 2, widget.availableScreenSize.width / 2, widget.availableScreenSize.height).contains(draggableCenter)) {
// Bottom-left
_top = widget.availableScreenSize.height - (_getCurrentButtonBarHeight() + _padding) - _height;
_left = _padding;
} else if (Rect.fromLTRB(widget.availableScreenSize.width / 2, widget.availableScreenSize.height / 2, widget.availableScreenSize.width, widget.availableScreenSize.height).contains(draggableCenter)) {
// Bottom-right
_top = widget.availableScreenSize.height - (_getCurrentButtonBarHeight() + _padding) - _height;
_left = widget.availableScreenSize.width - _padding - _width;
}
});
}
}

@ -0,0 +1,197 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class ParticipantBuffer {
final bool audioEnabled;
final String id;
ParticipantBuffer({
@required this.audioEnabled,
@required this.id,
}) : assert(audioEnabled != null),
assert(id != null);
}
class ParticipantWidget extends StatelessWidget {
final Widget child;
final String id;
final bool audioEnabled;
final bool videoEnabled;
final bool isRemote;
final bool isDummy;
final bool isDominant;
const ParticipantWidget({
Key key,
@required this.child,
@required this.audioEnabled,
@required this.videoEnabled,
@required this.id,
@required this.isRemote,
this.isDominant = false,
this.isDummy = false,
}) : assert(child != null),
assert(audioEnabled != null),
assert(videoEnabled != null),
assert(isRemote != null),
assert(isDominant != null),
assert(isDummy != null),
super(key: key);
ParticipantWidget copyWith({
Widget child,
bool audioEnabled,
bool videoEnabled,
bool isDominant,
}) {
return ParticipantWidget(
id: id,
child: child ?? this.child,
audioEnabled: audioEnabled ?? this.audioEnabled,
videoEnabled: videoEnabled ?? this.videoEnabled,
isDominant: isDominant ?? this.isDominant,
isRemote: isRemote,
);
}
@override
Widget build(BuildContext context) {
final children = <Widget>[];
final icons = <Widget>[];
if (!videoEnabled) {
icons.add(_buildVideoEnabledIcon());
children.add(
ClipRect(
// Need to clip this BackdropFilter, otherwise it will blur the entire screen
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Container(
decoration: BoxDecoration(color: Colors.black.withOpacity(.1)),
child: child,
),
),
),
);
} else {
children.add(child);
}
children.add(Padding(
padding: const EdgeInsets.all(8.0),
child: AnimatedOpacity(
duration: Duration(milliseconds: 500),
opacity: isDominant ? 1 : 0,
child: Icon(
Icons.volume_up,
color: Colors.white,
),
),
));
if (!audioEnabled) {
icons.add(_buildAudioEnabledIcon());
}
if (icons.isNotEmpty) {
if (isRemote) {
final rows = <Widget>[];
rows.add(_buildRow(icons));
if (!audioEnabled && !videoEnabled) {
rows.add(_buildRow(_fitText('The camera and microphone are off', Colors.white24)));
} else if (!audioEnabled) {
rows.add(_buildRow(_fitText('The microphone is off', Colors.black26)));
} else if (!videoEnabled) {
rows.add(_buildRow(_fitText('The camera is off', Colors.white24)));
}
children.add(
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: rows,
),
);
} else {
children.add(Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: icons,
));
}
}
return Stack(
children: children,
);
}
List<Widget> _fitText(String text, Color color) {
return [
Flexible(
child: FittedBox(
fit: BoxFit.scaleDown,
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: Text(text, maxLines: 1, style: _buildTextStyle(color)),
),
),
),
];
}
TextStyle _buildTextStyle(Color color) {
return TextStyle(
color: color,
shadows: <Shadow>[
Shadow(
blurRadius: 1.0,
color: Color.fromARGB(255, 0, 0, 0),
),
Shadow(
blurRadius: 1.0,
color: Color.fromARGB(24, 255, 255, 255),
),
],
fontSize: 15,
);
}
Widget _buildRow(List<Widget> children) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
);
}
Widget _buildAudioEnabledIcon() {
return Padding(
padding: const EdgeInsets.all(8),
child: CircleAvatar(
maxRadius: 15,
child: FittedBox(
child: Icon(
Icons.mic_off,
color: Colors.black,
key: Key('microphone-off-icon'),
),
),
backgroundColor: Colors.white24,
),
);
}
Widget _buildVideoEnabledIcon() {
return Padding(
padding: const EdgeInsets.all(8),
child: CircleAvatar(
maxRadius: 15,
child: FittedBox(
child: Icon(
Icons.videocam_off,
color: Colors.black,
key: Key('videocam-off-icon'),
),
),
backgroundColor: Colors.white24,
),
);
}
}

@ -0,0 +1,106 @@
import 'dart:async';
import 'dart:math' as math;
import 'package:flutter/material.dart';
class ButtonToProgress extends StatefulWidget {
final double height;
final double progressHeight;
final String loadingText;
final Duration duration;
final TextStyle loadingTextStyle;
final VoidCallback onPressed;
final Stream<bool> onLoading;
final Widget child;
const ButtonToProgress({
Key key,
this.height = 40.0,
this.progressHeight = 5.0,
this.loadingText,
this.duration = const Duration(milliseconds: 300),
this.loadingTextStyle,
this.onPressed,
this.onLoading,
@required this.child,
}) : assert(child != null),
assert(height != null && height > 0),
assert(progressHeight != null && progressHeight > 0 && progressHeight <= height),
super(key: key);
@override
_ButtonToProgressState createState() => _ButtonToProgressState();
}
class _ButtonToProgressState extends State<ButtonToProgress> {
double _height;
double _opacity = 0;
bool _isLoading = false;
StreamSubscription<bool> _subscription;
@override
void initState() {
super.initState();
_height = widget.height;
if (widget.onLoading != null) {
_subscription = widget.onLoading.listen((bool isLoading) {
setState(() {
_isLoading = isLoading;
_height = isLoading ? widget.progressHeight : widget.height;
_opacity = isLoading ? 1 : 0;
});
});
}
}
@override
void dispose() {
if (_subscription != null) {
_subscription.cancel();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
height: widget.height,
child: Stack(
children: [
if (widget.loadingText == null)
Container()
else
Padding(
padding: EdgeInsets.only(bottom: widget.progressHeight),
child: AnimatedOpacity(
child: Center(
child: FittedBox(
child: Text(
widget.loadingText,
style: widget.loadingTextStyle,
),
),
),
opacity: _opacity,
duration: Duration(milliseconds: widget.duration.inMilliseconds + 200),
curve: Curves.easeInCubic,
),
),
AnimatedPadding(
duration: widget.duration,
padding: EdgeInsets.only(
top: math.max(widget.height - _height, 0),
),
child: AnimatedContainer(
duration: widget.duration,
height: _height,
width: double.infinity,
child: _isLoading ? const LinearProgressIndicator() : widget.child,
),
),
],
),
);
}
}

@ -0,0 +1,103 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:native_device_orientation/native_device_orientation.dart';
class CircleButton extends StatefulWidget {
final VoidCallback onLongPress;
final VoidCallback onPressed;
final GestureTapDownCallback onTapDown;
final VoidCallback onTapCancel;
final Widget child;
final Color color;
final double radius;
const CircleButton({
Key key,
this.onLongPress,
this.onPressed,
this.child,
this.color,
this.radius = 25.0,
this.onTapCancel,
this.onTapDown,
}) : assert(radius != null),
super(key: key);
@override
_CircleButtonState createState() => _CircleButtonState();
}
class _CircleButtonState extends State<CircleButton> {
double _rotationAngle = 0.0;
final Stream<NativeDeviceOrientation> _orientationStream = NativeDeviceOrientationCommunicator().onOrientationChanged(useSensor: true);
StreamSubscription<NativeDeviceOrientation> _orientationSubscription;
void _handleOrientationChange(NativeDeviceOrientation orientation) {
var targetAngle = 0.0;
switch (orientation) {
case NativeDeviceOrientation.unknown:
case NativeDeviceOrientation.portraitUp:
targetAngle = 0.0;
break;
case NativeDeviceOrientation.portraitDown:
targetAngle = 180.0;
break;
case NativeDeviceOrientation.landscapeLeft:
targetAngle = 90.0;
break;
case NativeDeviceOrientation.landscapeRight:
targetAngle = 270.0;
break;
}
setState(() {
_rotationAngle = targetAngle;
});
}
@override
void initState() {
super.initState();
_orientationSubscription = _orientationStream.listen(
_handleOrientationChange,
onError: (dynamic err) => print(err),
);
}
@override
void dispose() {
super.dispose();
_orientationSubscription.cancel();
}
@override
Widget build(BuildContext context) {
final size = 2 * widget.radius;
return Container(
width: size,
height: size,
decoration: BoxDecoration(
color: (widget.color ?? Colors.blue).withAlpha(200),
borderRadius: BorderRadius.all(
Radius.circular(widget.radius),
),
),
child: GestureDetector(
onLongPress: widget.onLongPress,
onTapDown: widget.onTapDown,
onTapCancel: widget.onTapCancel,
child: RawMaterialButton(
onPressed: widget.onPressed,
child: RotationTransition(
child: widget.child,
turns: AlwaysStoppedAnimation<double>(_rotationAngle / 360),
),
elevation: 0,
shape: const CircleBorder(),
),
),
);
}
}

@ -0,0 +1,144 @@
import 'dart:math' as math;
import 'dart:ui';
import 'package:flutter/material.dart';
enum NoiseBoxDensity {
high,
medium,
low,
xHigh,
xLow,
}
class NoiseBox extends StatefulWidget {
final NoiseBoxDensity density;
final Color backgroundColor;
final Widget child;
const NoiseBox({
Key key,
this.backgroundColor,
this.child,
this.density = NoiseBoxDensity.medium,
}) : assert(density != null),
super(key: key);
@override
_NoiseBoxState createState() => _NoiseBoxState();
}
class _NoiseBoxState extends State<NoiseBox> with SingleTickerProviderStateMixin {
AnimationController _animationController;
int _density;
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this,
duration: const Duration(seconds: 60),
);
_animationController.repeat();
switch (widget.density) {
case NoiseBoxDensity.high:
_density = 5;
break;
case NoiseBoxDensity.medium:
_density = 7;
break;
case NoiseBoxDensity.low:
_density = 10;
break;
case NoiseBoxDensity.xHigh:
_density = 3;
break;
case NoiseBoxDensity.xLow:
_density = 12;
break;
}
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) => Container(
color: widget.backgroundColor,
width: constraints.biggest.width,
height: constraints.biggest.height,
child: AnimatedBuilder(
animation: _animationController,
builder: (BuildContext context, Widget w) {
final children = <Widget>[
CustomPaint(
painter: NoisePainter(
width: constraints.biggest.width,
height: constraints.biggest.height,
density: _density,
),
),
];
if (widget.child != null) {
children.add(widget.child);
}
return Stack(
children: children,
);
},
),
),
);
}
}
class NoisePainter extends CustomPainter {
final double width;
final double height;
final int density;
NoisePainter({
@required this.width,
@required this.height,
@required this.density,
}) : assert(width != null),
assert(height != null),
assert(density != null && density >= 3 && density < math.min(width, height));
List<Color> colors = <Color>[
Colors.black,
Colors.grey,
Colors.blueGrey,
Colors.red,
Colors.green,
Colors.blue,
Colors.white,
];
@override
void paint(Canvas canvas, Size size) {
final random = math.Random();
for (var w = 0; w < width; w += density) {
for (var h = 0; h < height; h += density) {
final offset = Offset(
random.nextDouble() * width,
random.nextDouble() * height,
);
final paint = Paint();
paint.color = colors[random.nextInt(colors.length)];
paint.strokeWidth = random.nextDouble() * 2;
canvas.drawPoints(PointMode.points, <Offset>[offset], paint);
}
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}

@ -0,0 +1,98 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import './platform_widget.dart';
class PlatformAlertDialog extends PlatformWidget {
PlatformAlertDialog({@required this.title, @required this.content, @required this.defaultActionText, this.cancelActionText})
: assert(title != null),
assert(content != null),
assert(defaultActionText != null);
final String title;
final String content;
final String defaultActionText;
final String cancelActionText;
Future<bool> show(BuildContext context) async {
return Platform.isIOS
? await showCupertinoDialog<bool>(
context: context,
builder: (BuildContext context) => this,
)
: await showDialog<bool>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) => this,
);
}
@override
Widget buildCupertinoWidget(BuildContext context) {
return CupertinoAlertDialog(
title: Text(title),
content: Text(content),
actions: _buildActions(context),
);
}
@override
Widget buildMaterialWidget(BuildContext context) {
return AlertDialog(
title: Text(title),
content: Text(content),
actions: _buildActions(context),
);
}
List<Widget> _buildActions(BuildContext context) {
final actions = <Widget>[];
if (cancelActionText != null) {
actions.add(
PlatformAlertDialogAction(
child: Text(cancelActionText),
onPressed: () {
Navigator.of(context).pop(false);
},
),
);
}
actions.add(
PlatformAlertDialogAction(
child: Text(defaultActionText),
onPressed: () {
Navigator.of(context).pop(true);
},
),
);
return actions;
}
}
class PlatformAlertDialogAction extends PlatformWidget {
PlatformAlertDialogAction({
this.child,
this.onPressed,
});
final Widget child;
final VoidCallback onPressed;
@override
Widget buildCupertinoWidget(BuildContext context) {
return CupertinoDialogAction(
child: child,
onPressed: onPressed,
);
}
@override
Widget buildMaterialWidget(BuildContext context) {
return FlatButton(
child: child,
onPressed: onPressed,
);
}
}

@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import './platform_alert_dialog.dart';
class PlatformExceptionAlertDialog extends PlatformAlertDialog {
PlatformExceptionAlertDialog({
String title = 'An error occurred',
@required Exception exception,
}) : super(
title: title,
content: exception is PlatformException ? _message(exception) : exception.toString(),
defaultActionText: 'OK',
);
static String _message(PlatformException exception) {
return _errors[exception.code] ?? (exception.details != null ? (exception.details['message'] ?? exception.message) : exception.message);
}
static final Map<String, String> _errors = <String, String>{
'ERROR_CODE': 'Error description...',
};
}

@ -0,0 +1,16 @@
import 'dart:io';
import 'package:flutter/material.dart';
abstract class PlatformWidget extends StatelessWidget {
Widget buildCupertinoWidget(BuildContext context);
Widget buildMaterialWidget(BuildContext context);
@override
Widget build(BuildContext context) {
if (Platform.isIOS) {
return buildCupertinoWidget(context);
}
return buildMaterialWidget(context);
}
}

@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
typedef ResponsiveBuilder = Widget Function(
BuildContext context,
Size size,
);
class ResponsiveSafeArea extends StatelessWidget {
const ResponsiveSafeArea({
@required ResponsiveBuilder builder,
Key key,
}) : responsiveBuilder = builder,
assert(builder != null),
super(key: key);
final ResponsiveBuilder responsiveBuilder;
@override
Widget build(BuildContext context) {
return SafeArea(
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return responsiveBuilder(
context,
constraints.biggest,
);
},
),
);
}
}

@ -1,6 +1,7 @@
import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/cupertino.dart';

@ -1,33 +1,46 @@
import 'dart:io';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart';
import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/BookingOptions.dart';
import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/pages/livecare/incoming_call.dart';
import 'package:diplomaticquarterapp/pages/medical/medical_profile_page.dart';
import 'package:diplomaticquarterapp/pages/medical/my_admissions_page.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/bottom_navigation/bottom_nav_bar.dart';
import 'package:diplomaticquarterapp/widgets/drawer/app_drawer_widget.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'home_page.dart';
class LandingPage extends StatefulWidget {
static bool isOpenCallPage = false;
static IncomingCallData incomingCallData = new IncomingCallData();
@override
_LandingPageState createState() => _LandingPageState();
}
class _LandingPageState extends State<LandingPage> {
class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
int currentTab = 0;
PageController pageController;
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
final authService = new AuthProvider();
bool isPageNavigated = false;
_changeCurrentTab(int tab) {
setState(() {
currentTab = tab;
@ -35,19 +48,150 @@ class _LandingPageState extends State<LandingPage> {
});
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
var route = ModalRoute.of(context);
if (route != null) {
print(route.settings.name);
}
setState(() {
print("didChangeAppLifecycleState");
print('state = $state');
AppGlobal.context = context;
if (state == AppLifecycleState.resumed) {
print(LandingPage.isOpenCallPage);
if (LandingPage.isOpenCallPage) {
if (!isPageNavigated) {
isPageNavigated = true;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => IncomingCall(
incomingCallData: LandingPage.incomingCallData)))
.then((value) {
isPageNavigated = false;
});
}
}
}
if (state == AppLifecycleState.paused) {
isPageNavigated = false;
}
if (state == AppLifecycleState.inactive) {
isPageNavigated = false;
}
});
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
setState(() {
AppGlobal.context = context;
});
pageController = PageController(keepPage: true);
_firebaseMessaging.setAutoInitEnabled(true);
_firebaseMessaging.getToken().then((String token) {
sharedPref.setString(PUSH_TOKEN, token);
if (token != null) {
checkUserStatus(token);
}
requestPermissions();
//assert(token != null);
});
//_firebase Background message handler
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
print(message);
print(message['name']);
print(message['appointmentdate']);
if (Platform.isIOS) {
if (message['is_call'] == "true") {
var route = ModalRoute.of(context);
if (route != null) {
print(route.settings.name);
}
Map<String, dynamic> myMap =
new Map<String, dynamic>.from(message);
print(myMap);
LandingPage.isOpenCallPage = true;
LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
if (!isPageNavigated) {
isPageNavigated = true;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => IncomingCall(
incomingCallData: LandingPage.incomingCallData)))
.then((value) {
isPageNavigated = false;
});
}
} else {
print("Is Call Not Found iOS");
}
} else {
print("Is Call Not Found iOS");
}
if (Platform.isAndroid) {
if (message['data'].containsKey("is_call")) {
var route = ModalRoute.of(context);
if (route != null) {
print(route.settings.name);
}
Map<String, dynamic> myMap =
new Map<String, dynamic>.from(message['data']);
print(myMap);
LandingPage.isOpenCallPage = true;
LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
if (!isPageNavigated) {
isPageNavigated = true;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => IncomingCall(
incomingCallData: LandingPage.incomingCallData)))
.then((value) {
isPageNavigated = false;
});
}
} else {
print("Is Call Not Found Android");
}
} else {
print("Is Call Not Found Android");
}
},
onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler,
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
);
}
void requestPermissions() async {
await [
Permission.location,
@ -85,7 +229,12 @@ class _LandingPageState extends State<LandingPage> {
physics: NeverScrollableScrollPhysics(),
controller: pageController,
children: [
HomePage(), MedicalProfilePage(), MyAdmissionsPage(), ToDo(), BookingOptions()], // Please do not remove the BookingOptions from this array
HomePage(),
MedicalProfilePage(),
MyAdmissionsPage(),
ToDo(),
BookingOptions()
], // Please do not remove the BookingOptions from this array
),
bottomNavigationBar: BottomNavBar(changeIndex: _changeCurrentTab),
);
@ -122,6 +271,25 @@ class _LandingPageState extends State<LandingPage> {
}
}
static Future<dynamic> myBackgroundMessageHandler(
Map<String, dynamic> message) async {
Map<String, dynamic> myMap = new Map<String, dynamic>.from(message['data']);
print(myMap);
print("myBackgroundMessageHandler Out");
if (message.containsKey('data')) {
print("myBackgroundMessageHandler Inside");
LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
print(LandingPage.incomingCallData.doctorname);
LandingPage.isOpenCallPage = true;
}
if (message.containsKey('notification')) {
final dynamic notification = message['notification'];
print(notification);
}
}
void setUserValues(value) async {
sharedPref.setObject(IMEI_USER_DATA, value);
}

@ -0,0 +1,255 @@
import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart';
import 'package:diplomaticquarterapp/models/LiveCare/room_model.dart';
import 'package:diplomaticquarterapp/pages/conference/conference_page.dart';
import 'package:diplomaticquarterapp/pages/conference/widgets/platform_exception_alert_dialog.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
class IncomingCall extends StatefulWidget {
IncomingCallData incomingCallData;
IncomingCall({@required this.incomingCallData});
@override
_IncomingCallState createState() => _IncomingCallState();
}
class _IncomingCallState extends State<IncomingCall>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
final player = AudioPlayer();
@override
void initState() {
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 500));
WidgetsBinding.instance.addPostFrameCallback((_) => _runAnimation());
print(widget.incomingCallData.doctorname);
print(widget.incomingCallData.clinicname);
print(widget.incomingCallData.speciality);
super.initState();
}
@override
void dispose() {
_animationController.dispose();
player.stop();
disposeAudioResources();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AppScaffold(
isShowAppBar: false,
body: SafeArea(
child: Container(
decoration: BoxDecoration(color: Colors.grey[700]),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 30.0),
alignment: Alignment.center,
child: Text("Incoming Video Call",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 26.0,
color: Colors.white,
letterSpacing: 1.0)),
),
Container(
alignment: Alignment.center,
margin: EdgeInsets.fromLTRB(50.0, 30.0, 50.0, 20.0),
child: Image.asset(
'assets/images/new-design/hmg_full_logo_hd_white.png'),
),
Container(
margin: EdgeInsets.fromLTRB(30.0, 10.0, 30.0, 0.0),
child: Divider(
color: Colors.white,
thickness: 1.0,
),
),
Container(
margin: EdgeInsets.only(top: 20.0),
alignment: Alignment.center,
child: Text("Dr Eyad Ismail Abu Jayab",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
letterSpacing: 0.8,
color: Colors.white)),
),
Container(
margin: EdgeInsets.only(top: 10.0),
alignment: Alignment.center,
child: Text("ENT Clinic",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22.0,
letterSpacing: 0.8,
color: Colors.white)),
),
Container(
margin: EdgeInsets.only(top: 10.0),
alignment: Alignment.center,
child: Text("Speciality",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22.0,
letterSpacing: 0.8,
color: Colors.white)),
),
Container(
decoration: BoxDecoration(
color: Colors.grey[900].withOpacity(0.8),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
padding: EdgeInsets.all(20.0),
margin: EdgeInsets.only(top: 20.0),
child: Column(
children: <Widget>[
Text("Appointment Information",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
letterSpacing: 1.0,
color: Colors.white)),
Container(
margin: EdgeInsets.only(top: 20.0),
child: Text("Sun, 15th Dec, 2019, 09:00",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
letterSpacing: 1.0,
color: Colors.white)),
),
Container(
margin: EdgeInsets.only(top: 20.0),
child: Text("ENT Clinic",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
letterSpacing: 1.0,
color: Colors.white)),
),
],
),
),
Container(
margin: EdgeInsets.only(top: 100.0),
alignment: Alignment.center,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RotationTransition(
turns: Tween(begin: 0.0, end: -.1)
.chain(CurveTween(curve: Curves.elasticIn))
.animate(_animationController),
child: Container(
child: RawMaterialButton(
onPressed: () {
_submit();
},
elevation: 2.0,
fillColor: Colors.green,
child: Icon(
Icons.call,
color: Colors.white,
size: 35.0,
),
padding: EdgeInsets.all(15.0),
shape: CircleBorder(),
),
)),
Container(
child: RawMaterialButton(
onPressed: () {
backToHome();
},
elevation: 2.0,
fillColor: Colors.red,
child: Icon(
Icons.call_end,
color: Colors.white,
size: 35.0,
),
padding: EdgeInsets.all(15.0),
shape: CircleBorder(),
),
),
],
),
),
],
)),
),
);
}
void _runAnimation() async {
setAudioFile();
for (int i = 0; i < 100; i++) {
await _animationController.forward();
await _animationController.reverse();
}
}
Future<void> _submit() async {
backToHome();
try {
final roomModel = RoomModel(
name: widget.incomingCallData.name,
token: widget.incomingCallData.sessionId,
identity: widget.incomingCallData.identity);
await Navigator.of(context).push(
MaterialPageRoute<ConferencePage>(
fullscreenDialog: true,
builder: (BuildContext context) =>
ConferencePage(roomModel: roomModel),
),
);
} catch (err) {
print(err);
await PlatformExceptionAlertDialog(
exception: err,
).show(context);
}
}
void backToHome() {
player.stop();
// disposeAudioResources();
Navigator.of(context).pop();
}
disposeAudioResources() async {
await player.dispose();
}
void setAudioFile() async {
player.stop();
await player.setVolume(1.0); // full volume
try {
await player.setAsset('assets/sounds/ring_60Sec.mp3').then((value) {
player.setLoopMode(LoopMode.one); // loop ring sound
player.play();
}).catchError((err) {
print("Error: $err");
});
} catch (e) {
print("Error: $e");
}
}
}

@ -0,0 +1,130 @@
import 'package:diplomaticquarterapp/models/FamilyFiles/PatientERVirtualHistoryResponse.dart';
import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCarePendingRequest.dart';
import 'package:diplomaticquarterapp/pages/livecare/widgets/clinic_list.dart';
import 'package:diplomaticquarterapp/pages/livecare/widgets/livecare_logs.dart';
import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
class LiveCareHome extends StatefulWidget {
static bool showFooterButton = true;
@override
_LiveCareHomeState createState() => _LiveCareHomeState();
}
class _LiveCareHomeState extends State<LiveCareHome>
with SingleTickerProviderStateMixin {
TabController _tabController;
bool isDataLoaded = false;
bool hasLiveCareRequest = false;
List<ErRequestHistoryList> erRequestHistoryList;
ErRequestHistoryList pendingERRequestHistoryList;
@override
void initState() {
_tabController = new TabController(length: 2, vsync: this);
erRequestHistoryList = List();
pendingERRequestHistoryList = new ErRequestHistoryList();
WidgetsBinding.instance.addPostFrameCallback((_) => getLiveCareHistory());
super.initState();
}
@override
Widget build(BuildContext context) {
return AppScaffold(
appBarTitle: "LiveCare",
isShowAppBar: true,
body: Container(
child: Column(children: [
/// this is will not colored with theme data
TabBar(
tabs: [
Tab(text: TranslationBase.of(context).consultation),
Tab(text: TranslationBase.of(context).logs),
],
controller: _tabController,
),
Divider(
color: Colors.grey[600],
thickness: 0.5,
),
Expanded(
child: TabBarView(
physics: NeverScrollableScrollPhysics(),
children: [
isDataLoaded && !hasLiveCareRequest
? ClinicList(
getLiveCareHistory: getLiveCareHistory,
)
: isDataLoaded
? LiveCarePendingRequest(
getLiveCareHistory: getLiveCareHistory,
pendingERRequestHistoryList:
pendingERRequestHistoryList)
: Container(),
isDataLoaded
? LiveCareLogs(
erRequestHistoryList: erRequestHistoryList,
)
: Container(),
],
controller: _tabController,
),
),
]),
),
);
}
void getLiveCareHistory() {
setState(() {
isDataLoaded = false;
hasLiveCareRequest = false;
});
LiveCareService service = new LiveCareService();
PatientERVirtualHistoryResponse patientERVirtualHistoryResponse =
new PatientERVirtualHistoryResponse();
service
.getLivecareHistory(context)
.then((res) {
setState(() {
print(res['ErRequestHistoryList'].length);
if (res['ErRequestHistoryList'].length != 0) {
patientERVirtualHistoryResponse =
PatientERVirtualHistoryResponse.fromJson(res);
erRequestHistoryList =
patientERVirtualHistoryResponse.erRequestHistoryList;
if (patientERVirtualHistoryResponse
.erRequestHistoryList[0].callStatus <
4) {
pendingERRequestHistoryList =
patientERVirtualHistoryResponse.erRequestHistoryList[0];
hasLiveCareRequest = true;
} else {
hasLiveCareRequest = false;
}
}
});
})
.catchError((err) {
print(err);
})
.showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6))
.then((value) {
setState(() {
isDataLoaded = true;
});
});
}
}

@ -0,0 +1,118 @@
import 'package:diplomaticquarterapp/models/LiveCare/ClinicsServiceTimingsResponse.dart';
import 'package:flutter/material.dart';
class ClinicTimingsDialog extends StatefulWidget {
final clinicName;
final List<PatientERGetClinicsServiceTimingsList>
patientERGetClinicsServiceTimingsList;
ClinicTimingsDialog(
{@required this.clinicName,
@required this.patientERGetClinicsServiceTimingsList});
@override
_ClinicTimingsDialogState createState() => _ClinicTimingsDialogState();
}
class _ClinicTimingsDialogState extends State<ClinicTimingsDialog> {
@override
void initState() {
print(widget.patientERGetClinicsServiceTimingsList);
super.initState();
}
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
final double itemHeight = ((size.height - kToolbarHeight - 24) * 0.42) / 2;
final double itemWidth = size.width / 2;
return Container(
child: Dialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
child: Container(
height: MediaQuery.of(context).size.height * 0.68,
margin: EdgeInsets.all(20.0),
width: 450.0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
alignment: Alignment.center,
margin: EdgeInsets.only(bottom: 10.0),
child: Text("Clinic Schedule",
textAlign: TextAlign.center,
style:
TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)),
),
Divider(
thickness: 1.0,
color: Colors.grey[400],
),
Container(
margin: EdgeInsets.only(bottom: 20.0, top: 10.0),
child: Text(widget.clinicName,
style:
TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)),
),
CustomScrollView(
primary: false,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
slivers: <Widget>[
SliverPadding(
padding: const EdgeInsets.fromLTRB(15, 0, 15, 0),
sliver: SliverGrid.count(
crossAxisCount: 2,
childAspectRatio: (itemWidth / itemHeight),
children: widget.patientERGetClinicsServiceTimingsList
.map((e) => Container(
height: 10.0,
child: Column(
children: <Widget>[
Text(e.dayOfWeekStr),
Text(e.shiftTimings[0].startTime +
" - " +
e.shiftTimings[0].endTime),
],
),
))
.toList()),
),
],
),
Divider(
thickness: 1.0,
color: Colors.grey[400],
),
Container(
alignment: Alignment.center,
height: 30.0,
child: Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
child: Text("OK",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0,
)),
),
),
),
],
),
),
],
),
),
),
);
}
}

@ -0,0 +1,212 @@
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/FamilyFiles/PatientERVirtualHistoryResponse.dart';
import 'package:diplomaticquarterapp/pages/feedback/feedback_home_page.dart';
import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
class LiveCareHistoryCard extends StatefulWidget {
ErRequestHistoryList erRequestHistoryList;
LiveCareHistoryCard({this.erRequestHistoryList});
@override
_LiveCareHistoryCardState createState() => _LiveCareHistoryCardState();
}
class _LiveCareHistoryCardState extends State<LiveCareHistoryCard> {
AuthenticatedUser authUser = new AuthenticatedUser();
AppSharedPreferences sharedPref = AppSharedPreferences();
@override
void initState() {
getAuthenticatedUser();
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(10.0),
child: Card(
margin: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 8.0),
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.22,
padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Requested date:",
style:
TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)),
Container(
margin: EdgeInsets.only(top: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(widget.erRequestHistoryList.sArrivalTime,
style: TextStyle(fontSize: 14.0)),
Text(
"Call Duration\n" +
getCallTime(
widget.erRequestHistoryList.callDuration),
textAlign: TextAlign.center,
style:
TextStyle(fontSize: 14.0, color: Colors.grey[600])),
],
),
),
Container(
padding: EdgeInsets.all(7.0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(5)),
color: Colors.green,
),
margin: EdgeInsets.only(top: 5.0, bottom: 5.0),
child: Text(widget.erRequestHistoryList.stringCallStatus,
style: TextStyle(fontSize: 14.0, color: Colors.white)),
),
Divider(
color: Colors.grey[500],
),
Container(
margin: EdgeInsets.all(5.0),
child: Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
child: InkWell(
onTap: () {
print("Invoice");
openInvoice();
},
child: Container(
child: Row(
children: <Widget>[
Icon(Icons.content_paste, color: Colors.blue),
Container(
margin: EdgeInsets.only(left: 10.0),
child: Text("Invoice",
textAlign: TextAlign.center),
),
],
),
),
),
),
Expanded(
child: InkWell(
onTap: () {
print("Complaints");
openComplaint();
},
child: Container(
child: Row(
children: <Widget>[
Icon(Icons.add, size: 24.0, color: Colors.red),
Container(
margin: EdgeInsets.only(left: 10.0),
child: Text("Complaints",
textAlign: TextAlign.center),
),
],
),
),
),
),
Expanded(
child: InkWell(
onTap: () {
print("Rate Dr & Appointment");
},
child: Container(
child: Row(
children: <Widget>[
Icon(Icons.star,
size: 24.0, color: Colors.yellow[700]),
Container(
width: MediaQuery.of(context).size.width * 0.2,
margin: EdgeInsets.only(left: 10.0),
child: Text("Rate Dr & Appointment",
overflow: TextOverflow.clip,
textAlign: TextAlign.center),
),
],
),
),
),
),
],
),
),
],
),
),
),
);
}
openInvoice() {
ConfirmDialog dialog = new ConfirmDialog(
context: context,
confirmMessage: "Send a copy of this invoice to the email: " +
authUser.emailAddress,
okText: TranslationBase.of(context).confirm,
cancelText: TranslationBase.of(context).cancel_nocaps,
okFunction: () => {sendInvoiceEmail(context)},
cancelFunction: () => {});
dialog.showAlertDialog(context);
}
openComplaint() {
Navigator.push(context, FadePage(page: FeedbackHomePage()));
}
sendInvoiceEmail(context) {
ConfirmDialog.closeAlertDialog(context);
LiveCareService service = new LiveCareService();
service
.sendLiveCareInvoiceEmail(
widget.erRequestHistoryList.appointmentNo.toString(),
widget.erRequestHistoryList.projectID,
authUser.emailAddress,
context)
.then((res) {
AppToast.showSuccessToast(message: "LiveCare invoice sent successfully");
}).catchError((err) {
AppToast.showErrorToast(message: err);
print(err);
}).showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
getAuthenticatedUser() async {
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE));
setState(() {
authUser = data;
});
}
}
getCallTime(int number) {
number = number.round();
var hours = (number / 60 / 60).floor();
var minutes = (number / 60).floor() - (hours * 60).floor();
var seconds = number % 60;
return '${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
}
}

@ -0,0 +1,108 @@
import 'package:flutter/material.dart';
class LiveCareInfoDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: Dialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
child: Container(
height: MediaQuery.of(context).size.height * 0.61,
margin: EdgeInsets.all(20.0),
width: 450.0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
alignment: Alignment.center,
margin: EdgeInsets.only(bottom: 10.0),
child: Icon(Icons.info_outline,
size: 80.0, color: Colors.red[900]),
),
Container(
alignment: Alignment.center,
margin: EdgeInsets.only(bottom: 20.0),
child: Text("Important Instructions",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
color: Colors.red[900])),
),
Container(
alignment: Alignment.center,
margin: EdgeInsets.only(bottom: 20.0),
child: Text(
"Please make sure that you're logged in on Al Habib Mobile Application",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
color: Colors.black)),
),
Container(
alignment: Alignment.center,
margin: EdgeInsets.only(bottom: 20.0),
child: Icon(Icons.not_interested,
size: 80.0, color: Colors.red[900]),
),
Container(
alignment: Alignment.center,
margin: EdgeInsets.only(bottom: 40.0),
child: Text(
"Otherwise, you will not receive the doctor's call.",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
color: Colors.red[900])),
),
Divider(
thickness: 1.0,
color: Colors.grey[400],
),
Container(
alignment: Alignment.center,
height: 40.0,
child: Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
child: InkWell(
onTap: () {
Navigator.pop(context, false);
},
child: Container(
child: Text("Cancel",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0, color: Colors.red[700])),
),
),
),
Expanded(
child: InkWell(
onTap: () {
Navigator.pop(context, true);
},
child: Container(
child: Text("Ok",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0,
)),
),
),
),
],
),
),
],
),
),
),
);
}
}

@ -0,0 +1,296 @@
import 'package:diplomaticquarterapp/models/LiveCare/ERAppointmentFeesResponse.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:flutter/material.dart';
class LiveCarePaymentDialog extends StatefulWidget {
GetERAppointmentFeesList getERAppointmentFeesList;
int waitingTime;
String clinicName;
LiveCarePaymentDialog(
{@required this.getERAppointmentFeesList, @required this.waitingTime, @required this.clinicName});
@override
_LiveCarePaymentDialogState createState() => _LiveCarePaymentDialogState();
}
class _LiveCarePaymentDialogState extends State<LiveCarePaymentDialog> {
int _selected = 0;
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
final double itemHeight = ((size.height - kToolbarHeight - 24) * 0.42) / 2;
final double itemWidth = size.width / 2;
return Container(
child: Dialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
child: Container(
height: MediaQuery.of(context).size.height * 0.691,
margin: EdgeInsets.all(20.0),
width: 450.0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
alignment: Alignment.center,
margin: EdgeInsets.only(bottom: 10.0),
child: Text("Online Consultation",
textAlign: TextAlign.center,
style:
TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)),
),
Divider(
thickness: 1.0,
color: Colors.grey[400],
),
Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
child: Text("Waiting time to start LiveCare consultation",
textAlign: TextAlign.end,
style: TextStyle(fontSize: 13.0)),
),
Expanded(
child: Container(
child: Icon(Icons.access_time,
size: 36.0, color: Colors.red[800]),
),
),
Expanded(
child: Text(widget.waitingTime.toString() + " Minutes",
textAlign: TextAlign.start,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.red[900])),
),
],
),
Container(
alignment: Alignment.center,
margin: EdgeInsets.only(bottom: 10.0, top: 10.0),
child: Text(widget.clinicName,
textAlign: TextAlign.center,
style:
TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)),
),
Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.black87,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(5.0),
topRight: const Radius.circular(5.0),
),
border: Border.all(color: Colors.black87)),
alignment: Alignment.center,
margin: EdgeInsets.only(top: 5.0),
padding: EdgeInsets.all(5.0),
child: Text("Consultation fee",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.bold,
color: Colors.white)),
),
Container(
decoration: BoxDecoration(
borderRadius: new BorderRadius.only(
bottomLeft: const Radius.circular(5.0),
bottomRight: const Radius.circular(5.0),
),
border: Border.all(color: Colors.black54)),
child: Table(
children: [
TableRow(children: [
TableCell(
child: _getNormalText(
TranslationBase.of(context).patientShareToDo)),
TableCell(
child: _getNormalText(
widget.getERAppointmentFeesList.amount +
" " +
widget.getERAppointmentFeesList.currency)),
]),
TableRow(children: [
TableCell(
child: _getNormalText(
TranslationBase.of(context).patientTaxToDo)),
TableCell(
child: _getNormalText(
widget.getERAppointmentFeesList.tax +
" " +
widget.getERAppointmentFeesList.currency)),
]),
TableRow(children: [
TableCell(
child: _getMarginText(TranslationBase.of(context)
.patientShareTotalToDo)),
TableCell(
child: _getMarginText(
widget.getERAppointmentFeesList.total +
" " +
widget.getERAppointmentFeesList.currency)),
]),
],
),
),
Container(
padding: EdgeInsets.only(top: 10.0, bottom: 10.0, left: 10.0),
decoration: BoxDecoration(
borderRadius: new BorderRadius.all(
const Radius.circular(5.0),
),
color: Colors.green[200].withOpacity(0.5)),
margin: EdgeInsets.only(top: 20.0),
child: Row(
children: <Widget>[
Image.asset("assets/images/new-design/alert-triangle.png"),
Container(
margin: EdgeInsets.only(left: 10.0),
width: MediaQuery.of(context).size.width * 0.55,
child: Text(
"If you're Insurance patient, you have only have to pay the co-payment",
style: TextStyle(fontSize: 13.0)),
),
],
),
),
Container(
margin: EdgeInsets.only(top: 10.0),
child: Row(
children: <Widget>[
Container(
child: new Radio(
value: 1,
groupValue: _selected,
onChanged: onRadioChanged,
),
),
Container(
child: new Text(
'I Accept the Terms And Conditions',
style: new TextStyle(fontSize: 14.0),
),
),
// Container(
//// alignment: Alignment.centerRight,
// child: new Text(
// 'Click Here',
// textAlign: TextAlign.end,
// style: new TextStyle(fontSize: 16.0),
// ),
// ),
],
),
),
Divider(
thickness: 1.0,
color: Colors.grey[400],
),
Container(
alignment: Alignment.center,
margin: EdgeInsets.only(top: 10.0),
child: new Text(
'You can pay by the following Options:',
textAlign: TextAlign.center,
style: new TextStyle(fontSize: 14.0),
),
),
Container(
alignment: Alignment.center,
margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 5.0),
child: Image.asset(
"assets/images/new-design/payment_options_invoice_confirmation.png",
width: 300),
),
Divider(
thickness: 1.0,
color: Colors.grey[400],
),
Container(
alignment: Alignment.center,
height: 40.0,
child: Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
child: InkWell(
onTap: () {
Navigator.pop(context, false);
},
child: Container(
child: Text("Cancel",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0, color: Colors.red[700])),
),
),
),
Expanded(
child: InkWell(
onTap: () {
if(_selected == 0) {
AppToast.showErrorToast(message: "Please accept terms & conditions to continue");
} else {
Navigator.pop(context, true);
}
},
child: Container(
child: Text("Ok",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0,
)),
),
),
),
],
),
),
],
),
),
),
);
}
void onRadioChanged(int value) {
setState(() {
_selected = value;
});
}
_getNormalText(text) {
return Container(
margin: EdgeInsets.only(top: 10.0, right: 10.0),
child: Text(text,
textAlign: TextAlign.end,
style: TextStyle(
fontSize: 14,
fontFamily: 'Open-Sans',
letterSpacing: 0.5,
color: Colors.black)),
);
}
_getMarginText(text) {
return Container(
margin: EdgeInsets.only(top: 10.0, right: 10.0, bottom: 10.0),
child: Text(text,
textAlign: TextAlign.end,
style: TextStyle(
fontSize: 14,
fontFamily: 'Open-Sans',
letterSpacing: 0.5,
fontWeight: FontWeight.bold,
color: Colors.black)),
);
}
}

@ -0,0 +1,167 @@
import 'package:circular_countdown_timer/circular_countdown_timer.dart';
import 'package:diplomaticquarterapp/models/FamilyFiles/PatientERVirtualHistoryResponse.dart';
import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:flutter/material.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
class LiveCarePendingRequest extends StatefulWidget {
ErRequestHistoryList pendingERRequestHistoryList;
final Function getLiveCareHistory;
LiveCarePendingRequest(
{@required this.getLiveCareHistory, this.pendingERRequestHistoryList});
@override
_LiveCarePendingRequestState createState() => _LiveCarePendingRequestState();
}
class _LiveCarePendingRequestState extends State<LiveCarePendingRequest> {
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[300]),
borderRadius: BorderRadius.circular(10),
color: Colors.white,
shape: BoxShape.rectangle,
),
margin: EdgeInsets.all(15.0),
padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
child: Text("In Progress:",
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)),
),
Container(
alignment: Alignment.center,
margin: EdgeInsets.only(top: 10.0),
child: Text("Estimated Waiting Time: ",
style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)),
),
Container(
transform: Matrix4.translationValues(0.0, -50.0, 0.0),
alignment: Alignment.center,
child: CircularCountDownTimer(
duration:
widget.pendingERRequestHistoryList.watingtimeInteger * 60,
width: MediaQuery.of(context).size.width / 3,
height: MediaQuery.of(context).size.height / 3,
color: Colors.white,
fillColor: Colors.green[700],
strokeWidth: 15.0,
textStyle: TextStyle(
fontSize: 22.0,
color: Colors.black87,
fontWeight: FontWeight.bold),
isReverse: true,
isTimerTextShown: true,
onComplete: () {
print('Countdown Ended');
},
),
),
Container(
transform: Matrix4.translationValues(0.0, -60.0, 0.0),
child: Divider(
color: Colors.grey[500],
thickness: 0.7,
),
),
Container(
transform: Matrix4.translationValues(0.0, -50.0, 0.0),
child: Text("Requested date:",
style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold)),
),
Container(
transform: Matrix4.translationValues(0.0, -30.0, 0.0),
child: Text(
DateUtil.getDateFormatted(
widget.pendingERRequestHistoryList.arrivalTime),
style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)),
),
Container(
transform: Matrix4.translationValues(0.0, -20.0, 0.0),
padding: EdgeInsets.all(7.0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(5)),
color: Colors.red[800],
),
margin: EdgeInsets.only(top: 5.0, bottom: 5.0),
child: Text(widget.pendingERRequestHistoryList.stringCallStatus,
style: TextStyle(fontSize: 14.0, color: Colors.white)),
),
Container(
transform: Matrix4.translationValues(0.0, 0.0, 0.0),
child: Divider(
color: Colors.grey[500],
thickness: 0.7,
),
),
Container(
alignment: Alignment.center,
transform: Matrix4.translationValues(0.0, 10.0, 0.0),
child: Text(
"Your turn is after " +
widget.pendingERRequestHistoryList.patCount.toString() +
" Patients",
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)),
),
Container(
transform: Matrix4.translationValues(0.0, 130.0, 0.0),
alignment: Alignment.bottomCenter,
width: MediaQuery.of(context).size.width,
child: ButtonTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
minWidth: MediaQuery.of(context).size.width,
height: 45.0,
child: RaisedButton(
color: Colors.red[800],
textColor: Colors.white,
disabledTextColor: Colors.white,
disabledColor: new Color(0xFFbcc2c4),
onPressed: () {
cancelLiveCareRequest();
},
child: Text(TranslationBase.of(context).cancel,
style: TextStyle(fontSize: 18.0)),
),
),
),
],
),
);
}
cancelLiveCareRequest() {
LiveCareService service = new LiveCareService();
service
.cancelLiveCareRequest(widget.pendingERRequestHistoryList.vCID, context)
.then((res) {
AppToast.showSuccessToast(
message: "LiveCare request cancelled successfully");
})
.catchError((err) {
print(err);
})
.showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6))
.then((value) {
widget.getLiveCareHistory();
});
}
}

@ -0,0 +1,136 @@
import 'package:diplomaticquarterapp/models/LiveCare/ClinicsServiceTimingsResponse.dart';
import 'package:diplomaticquarterapp/models/LiveCare/LiveCareClinicsListResponse.dart';
import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:flutter/material.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
import 'ClinicTimingsDialog.dart';
// ignore: must_be_immutable
class ClinicCard extends StatefulWidget {
bool isSelected;
final PatientERGetClinicsList patientERGetClinicsList;
var languageID;
ClinicCard(
{this.isSelected,
this.languageID,
@required this.patientERGetClinicsList});
@override
_State createState() => _State();
}
class _State extends State<ClinicCard> {
ClinicsServiceTimingsResponse clinicsServiceTimingsResponse;
@override
void initState() {
clinicsServiceTimingsResponse = new ClinicsServiceTimingsResponse();
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Card(
margin: EdgeInsets.fromLTRB(13.0, 10.0, 8.0, 8.0),
color: widget.isSelected ? Colors.blue : Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Container(
width: MediaQuery.of(context).size.width * 0.8,
padding: EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
child: Text(
widget.languageID == 'ar'
? widget.patientERGetClinicsList.serviceNameN
: widget.patientERGetClinicsList.serviceName,
style: TextStyle(
fontSize: 16.0,
color:
widget.isSelected ? Colors.white : Colors.black)),
),
],
),
),
),
InkWell(
onTap: () {
getClinicTimings(widget.patientERGetClinicsList);
},
child: Card(
margin: EdgeInsets.fromLTRB(8.0, 10.0, 8.0, 8.0),
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Container(
padding: EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Icon(Icons.access_time, size: 26.0, color: Colors.red[800]),
],
),
),
),
),
],
);
}
getClinicTimings(PatientERGetClinicsList patientERGetClinicsList) {
LiveCareService service = new LiveCareService();
service
.getLivecareClinicTiming(patientERGetClinicsList.serviceID, context)
.then((res) {
if (res['MessageStatus'] == 1) {
setState(() {
clinicsServiceTimingsResponse =
ClinicsServiceTimingsResponse.fromJson(res);
print(clinicsServiceTimingsResponse
.patientERGetClinicsServiceTimingsList.length);
showGeneralDialog(
barrierColor: Colors.black.withOpacity(0.5),
transitionBuilder: (context, a1, a2, widget) {
final curvedValue =
Curves.easeInOutBack.transform(a1.value) - 1.0;
return Transform(
transform:
Matrix4.translationValues(0.0, curvedValue * 200, 0.0),
child: Opacity(
opacity: a1.value,
child: ClinicTimingsDialog(
clinicName: patientERGetClinicsList.serviceName,
patientERGetClinicsServiceTimingsList:
clinicsServiceTimingsResponse
.patientERGetClinicsServiceTimingsList,
),
),
);
},
transitionDuration: Duration(milliseconds: 500),
barrierDismissible: true,
barrierLabel: '',
context: context,
pageBuilder: (context, animation1, animation2) {});
});
} else {
AppToast.showErrorToast(message: res['ErrorEndUserMessage']);
}
}).catchError((err) {
print(err);
}).showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
}

@ -0,0 +1,388 @@
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/LiveCare/ERAppointmentFeesResponse.dart';
import 'package:diplomaticquarterapp/models/LiveCare/LiveCareClinicsListResponse.dart';
import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart';
import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCareInfoDialog.dart';
import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCarePaymentDialog.dart';
import 'package:diplomaticquarterapp/pages/livecare/widgets/clinic_card.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:smart_progress_bar/smart_progress_bar.dart';
class ClinicList extends StatefulWidget {
final Function getLiveCareHistory;
ClinicList({@required this.getLiveCareHistory});
@override
_clinic_listState createState() => _clinic_listState();
}
class _clinic_listState extends State<ClinicList> {
int currentSelectedIndex = 0;
LiveCareClinicsListResponse liveCareClinicsListResponse;
bool isDataLoaded = false;
var languageID;
int selectedClinicID = 1;
String selectedClinicName = "-";
AppSharedPreferences sharedPref = AppSharedPreferences();
AuthenticatedUser authUser;
AuthProvider authProvider = new AuthProvider();
MyInAppBrowser browser;
@override
void initState() {
liveCareClinicsListResponse = new LiveCareClinicsListResponse();
WidgetsBinding.instance.addPostFrameCallback((_) {
// Future.delayed(new Duration(milliseconds: 1200), () {
getLiveCareClinicsList();
// });
});
getLanguageID();
super.initState();
}
@override
Widget build(BuildContext context) {
return AppScaffold(
isShowAppBar: false,
body: SingleChildScrollView(
child: isDataLoaded
? Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets.all(15.0),
child: Text("Online Clinics: ",
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold)),
),
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: ScrollPhysics(),
padding: EdgeInsets.all(0.0),
itemCount: liveCareClinicsListResponse
.patientERGetClinicsList.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
updateSelectedIndex(liveCareClinicsListResponse
.patientERGetClinicsList[index]);
},
child: ClinicCard(
isSelected: selectedClinicID ==
liveCareClinicsListResponse
.patientERGetClinicsList[index]
.serviceID
? true
: false,
patientERGetClinicsList: liveCareClinicsListResponse
.patientERGetClinicsList[index],
languageID: languageID,
),
);
},
),
Container(
height: 80.0,
),
],
),
)
: Container(),
),
bottomSheet: Container(
width: MediaQuery.of(context).size.width,
height: 50.0,
margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
child: ButtonTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
minWidth: MediaQuery.of(context).size.width * 0.7,
height: 45.0,
child: RaisedButton(
color: new Color(0xFF60686b),
textColor: Colors.white,
disabledTextColor: Colors.white,
disabledColor: new Color(0xFFbcc2c4),
onPressed: startLiveCare,
child: Text("Start", style: TextStyle(fontSize: 18.0)),
),
),
),
);
}
void startLiveCare() {
LiveCareService service = new LiveCareService();
ERAppointmentFeesResponse erAppointmentFeesResponse =
new ERAppointmentFeesResponse();
service
.getERAppointmentFees(selectedClinicID, context)
.then((res) {
erAppointmentFeesResponse = ERAppointmentFeesResponse.fromJson(res);
})
.catchError((err) {
print(err);
})
.showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6))
.then((value) {
getERAppointmentTime(
erAppointmentFeesResponse.getERAppointmentFeesList);
});
}
getERAppointmentTime(GetERAppointmentFeesList getERAppointmentFeesList) {
LiveCareService service = new LiveCareService();
service.getERAppointmentTime(selectedClinicID, context).then((res) {
print(res['WatingtimeInteger']);
showLiveCarePaymentDialog(
getERAppointmentFeesList, res['WatingtimeInteger']);
}).catchError((err) {
print(err);
}).showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
showLiveCarePaymentDialog(
GetERAppointmentFeesList getERAppointmentFeesList, int waitingTime) {
showGeneralDialog(
barrierColor: Colors.black.withOpacity(0.5),
transitionBuilder: (context, a1, a2, widget) {
final curvedValue =
Curves.easeInOutBack.transform(a1.value) - 1.0;
return Transform(
transform:
Matrix4.translationValues(0.0, curvedValue * 200, 0.0),
child: Opacity(
opacity: a1.value,
child: LiveCarePaymentDialog(
getERAppointmentFeesList: getERAppointmentFeesList,
waitingTime: waitingTime,
clinicName: selectedClinicName),
),
);
},
transitionDuration: Duration(milliseconds: 500),
barrierDismissible: true,
barrierLabel: '',
context: context,
pageBuilder: (context, animation1, animation2) {})
.then((value) {
if (value) {
if (getERAppointmentFeesList.total == "0" ||
getERAppointmentFeesList.total == "0.0") {
showLiveCareInfoDialog(getERAppointmentFeesList);
} else {
navigateToPaymentMethod(getERAppointmentFeesList, context);
}
}
});
}
showLiveCareInfoDialog(
GetERAppointmentFeesList getERAppointmentFeesList) async {
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE));
setState(() {
authUser = data;
});
}
showGeneralDialog(
barrierColor: Colors.black.withOpacity(0.5),
transitionBuilder: (context, a1, a2, widget) {
final curvedValue =
Curves.easeInOutBack.transform(a1.value) - 1.0;
return Transform(
transform:
Matrix4.translationValues(0.0, curvedValue * 200, 0.0),
child: Opacity(
opacity: a1.value,
child: LiveCareInfoDialog(),
),
);
},
transitionDuration: Duration(milliseconds: 500),
barrierDismissible: true,
barrierLabel: '',
context: context,
pageBuilder: (context, animation1, animation2) {})
.then((value) {
if (value) {
if (getERAppointmentFeesList.total == "0" ||
getERAppointmentFeesList.total == "0.0") {
addNewCallForPatientER(authUser.patientID.toString() +
"" +
DateTime.now().millisecondsSinceEpoch.toString());
} else {
navigateToPaymentMethod(getERAppointmentFeesList, context);
}
}
});
}
Future navigateToPaymentMethod(
GetERAppointmentFeesList getERAppointmentFeesList, context) async {
AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList();
appo.clinicID = selectedClinicID;
appo.appointmentNo = DateTime.now().millisecondsSinceEpoch;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE));
setState(() {
authUser = data;
});
}
Navigator.push(
context, MaterialPageRoute(builder: (context) => PaymentMethod()))
.then((value) {
print(value);
if (value != null) {
openPayment(value, authUser,
double.parse(getERAppointmentFeesList.total), appo);
}
});
}
openPayment(String paymentMethod, AuthenticatedUser authenticatedUser,
double amount, AppoitmentAllHistoryResultList appo) {
browser = new MyInAppBrowser(
onExitCallback: onBrowserExit,
appo: appo,
onLoadStartCallback: onBrowserLoadStart);
browser.openPaymentBrowser(
amount,
"LiveCare Payment",
Utils.getAppointmentTransID(12, appo.clinicID, appo.appointmentNo),
"12",
authenticatedUser.emailAddress,
paymentMethod,
authenticatedUser,
browser);
}
onBrowserLoadStart(String url) {
print("onBrowserLoadStart");
print(url);
MyInAppBrowser.successURLS.forEach((element) {
if (url.contains(element)) {
if (browser.isOpened()) browser.close();
MyInAppBrowser.isPaymentDone = true;
return;
}
});
MyInAppBrowser.errorURLS.forEach((element) {
if (url.contains(element)) {
if (browser.isOpened()) browser.close();
MyInAppBrowser.isPaymentDone = false;
return;
}
});
}
onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) {
print("onBrowserExit Called!!!!");
if (isPaymentMade) checkPaymentStatus(appo);
}
checkPaymentStatus(AppoitmentAllHistoryResultList appo) {
DoctorsListService service = new DoctorsListService();
service
.checkPaymentStatus(
Utils.getAppointmentTransID(
appo.projectID, appo.clinicID, appo.appointmentNo),
context)
.then((res) {
print("Printing Payment Status Reponse!!!!");
print(res);
String paymentInfo = res['Response_Message'];
if (paymentInfo == 'Success') {
addNewCallForPatientER(Utils.getAppointmentTransID(
appo.projectID, appo.clinicID, appo.appointmentNo));
} else {
AppToast.showErrorToast(message: res['Response_Message']);
}
}).catchError((err) {
print(err);
}).showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
addNewCallForPatientER(String clientRequestID) {
LiveCareService service = new LiveCareService();
service
.addNewCallForPatientER(selectedClinicID, clientRequestID, context)
.then((res) {
AppToast.showSuccessToast(
message: "New Call has been added successfully");
}).catchError((err) {
print(err);
}).showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)).then((value) {
widget.getLiveCareHistory();
});
}
getLanguageID() async {
languageID = await sharedPref.getString(APP_LANGUAGE);
}
getLiveCareClinicsList() {
isDataLoaded = false;
LiveCareService service = new LiveCareService();
service.getLivecareClinics(context).then((res) {
print(res['PatientER_GetClinicsList'].length);
if (res['MessageStatus'] == 1) {
setState(() {
liveCareClinicsListResponse =
LiveCareClinicsListResponse.fromJson(res);
print(liveCareClinicsListResponse.patientERGetClinicsList.length);
selectedClinicID =
liveCareClinicsListResponse.patientERGetClinicsList[0].serviceID;
selectedClinicName = liveCareClinicsListResponse
.patientERGetClinicsList[0].serviceName;
isDataLoaded = true;
});
} else {
isDataLoaded = true;
AppToast.showErrorToast(message: res['ErrorEndUserMessage']);
}
}).catchError((err) {
print(err);
}).showProgressBar(
text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6));
}
updateSelectedIndex(PatientERGetClinicsList patientERGetClinicsList) {
setState(() {
selectedClinicID = patientERGetClinicsList.serviceID;
selectedClinicName = patientERGetClinicsList.serviceName;
});
}
}

@ -0,0 +1,40 @@
import 'package:diplomaticquarterapp/models/FamilyFiles/PatientERVirtualHistoryResponse.dart';
import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCareHistoryCard.dart';
import 'package:flutter/material.dart';
class LiveCareLogs extends StatefulWidget {
List<ErRequestHistoryList> erRequestHistoryList;
LiveCareLogs({@required this.erRequestHistoryList});
@override
_LiveCareLogsState createState() => _LiveCareLogsState();
}
class _LiveCareLogsState extends State<LiveCareLogs> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: ScrollPhysics(),
padding: EdgeInsets.all(0.0),
itemCount: widget.erRequestHistoryList.length,
itemBuilder: (context, index) {
return widget.erRequestHistoryList[index].callStatus < 4
? Container()
: LiveCareHistoryCard(
erRequestHistoryList: widget.erRequestHistoryList[index]);
},
),
),
);
}
}

@ -14,174 +14,203 @@ import '../../../d_q_icons_icons.dart';
class VitalSignDetailsScreen extends StatelessWidget {
static const String url = "assets/images/";
int appointmentNo;
int projectID;
VitalSignDetailsScreen({this.appointmentNo, this.projectID});
@override
Widget build(BuildContext context) {
return BaseView<VitalSignViewModel>(
onModelReady: (model) => model.getPatientRadOrders(),
onModelReady: appointmentNo != null && projectID != null
? (model) => model.getPatientRadOrders(
appointmentNo: appointmentNo, projectID: projectID)
: (model) => model.getPatientRadOrders(),
builder: (_, mode, widget) => AppScaffold(
isShowAppBar: true,
appBarTitle: 'Vital Sign',
baseViewModel: mode,
body: mode.vitalSignResModelList.length> 0? Container(
child: ListView(
children: <Widget>[
Row(
children: <Widget>[
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.Height,
pageTitle: 'Height',
vitalList: mode.vitalSignResModelList,
body: mode.vitalSignResModelList.length > 0
? Container(
child: ListView(
children: <Widget>[
Row(
children: <Widget>[
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.Height,
pageTitle: 'Height',
vitalList: mode.vitalSignResModelList,
),
),
),
child: Container(
child: VitalSignItem(
des: TranslationBase.of(context).height,
icon: DQIcons.height,
lastVal: mode
.vitalSignResModelList[
mode.vitalSignResModelList.length - 1]
.heightCm
.toString(),
unit: ' Cm',
),
),
),
),
),
child: Container(
child: VitalSignItem(
des: TranslationBase.of(context).height,
icon: DQIcons.height,
lastVal: mode.vitalSignResModelList[mode.vitalSignResModelList.length-1].heightCm.toString(),
unit: ' Cm',
),
),
),
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.Weight,
pageTitle: 'Weight',
vitalList: mode.vitalSignResModelList,
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.Weight,
pageTitle: 'Weight',
vitalList: mode.vitalSignResModelList,
),
),
),
child: VitalSignItem(
des: TranslationBase.of(context).weight,
icon: DQIcons.weight_scale,
unit: ' Kg',
lastVal: mode
.vitalSignResModelList[
mode.vitalSignResModelList.length - 1]
.weightKg
.toString(),
),
),
),
),
child: VitalSignItem(
des: TranslationBase.of(context).weight,
icon: DQIcons.weight_scale,
unit: ' Kg',
lastVal: mode.vitalSignResModelList[mode.vitalSignResModelList.length-1].weightKg.toString(),
],
),
),
],
),
Row(
children: <Widget>[
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.BodyMeasurements,
pageTitle: 'BMI',
vitalList: mode.vitalSignResModelList,
Row(
children: <Widget>[
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.BodyMeasurements,
pageTitle: 'BMI',
vitalList: mode.vitalSignResModelList,
),
),
),
child: VitalSignItem(
des: TranslationBase.of(context).bodyMeasurements,
icon: DQIcons.bmi,
lastVal: mode
.vitalSignResModelList[0].pulseBeatPerMinute
.toString(),
unit: 'BMI',
),
),
),
),
child: VitalSignItem(
des: TranslationBase.of(context).bodyMeasurements,
icon: DQIcons.bmi,
lastVal: mode.vitalSignResModelList[1].pulseBeatPerMinute
.toString(),
unit: 'BMI',
),
),
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.Temperature,
pageTitle: 'Temperature',
vitalList: mode.vitalSignResModelList,
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.Temperature,
pageTitle: 'Temperature',
vitalList: mode.vitalSignResModelList,
),
),
),
child: Container(
child: VitalSignItem(
des: TranslationBase.of(context).temperature,
icon: DQIcons.thermometer,
lastVal: mode
.vitalSignResModelList[0].temperatureCelcius
.toString(),
unit: 'C',
),
),
),
),
],
),
child: Container(
child: VitalSignItem(
des: TranslationBase.of(context).temperature,
icon: DQIcons.thermometer,
lastVal: mode
.vitalSignResModelList[1].temperatureCelcius
.toString(),
unit: 'C',
),
),
),
],
),
Row(
children: <Widget>[
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.heart,
pageTitle: 'Hart ',
vitalList: mode.vitalSignResModelList,
Row(
children: <Widget>[
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.heart,
pageTitle: 'Hart ',
vitalList: mode.vitalSignResModelList,
),
),
),
child: VitalSignItem(
des: TranslationBase.of(context).heart,
icon: DQIcons.heart,
lastVal: mode
.vitalSignResModelList[
mode.vitalSignResModelList.length - 1]
.pulseBeatPerMinute
.toString(),
unit: ' bpm',
),
),
),
),
child: VitalSignItem(
des: TranslationBase.of(context).heart,
icon: DQIcons.heart,
lastVal: mode.vitalSignResModelList[mode.vitalSignResModelList.length-1].pulseBeatPerMinute
.toString(),
unit: ' bpm',
),
),
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.Respiration,
pageTitle: 'Respiration Rate',
vitalList: mode.vitalSignResModelList,
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.Respiration,
pageTitle: 'Respiration Rate',
vitalList: mode.vitalSignResModelList,
),
),
),
child: VitalSignItem(
des: TranslationBase.of(context).respirationRate,
icon: DQIcons.outline,
lastVal: mode
.vitalSignResModelList[
mode.vitalSignResModelList.length - 1]
.respirationBeatPerMinute
.toString(),
unit: ' bmp',
),
),
),
),
child: VitalSignItem(
des: TranslationBase.of(context).respirationRate,
icon: DQIcons.outline,
lastVal: mode.vitalSignResModelList[mode.vitalSignResModelList.length-1].respirationBeatPerMinute.toString(),
unit: ' bmp',
],
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.BloodPressure,
pageTitle: 'BloodPressure',
vitalList: mode.vitalSignResModelList,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: VitalSignDetails.BloodPressure,
pageTitle: 'BloodPressure',
vitalList: mode.vitalSignResModelList,
),
),
),
child: VitalSignItem(
des: TranslationBase.of(context).pulse,
icon: DQIcons.blood_pressure,
lastVal: mode
.vitalSignResModelList[
mode.vitalSignResModelList.length - 1]
.bloodPressure
.toString(),
unit: ' SBP/DBP',
),
),
),
),
child: VitalSignItem(
des: TranslationBase.of(context).pulse,
icon: DQIcons.blood_pressure,
lastVal: mode.vitalSignResModelList[mode.vitalSignResModelList.length -1].bloodPressure
.toString(),
unit: ' SBP/DBP',
],
),
),
],
],
),
)
: Center(
child: Texts('No Data'),
),
],
),
) : Center(child: Texts('No Data'),),
),
);
}

@ -1,5 +1,6 @@
import 'package:diplomaticquarterapp/pages/family/my-family.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart';
import 'package:diplomaticquarterapp/pages/login/confirm-login.dart';
import 'package:diplomaticquarterapp/pages/login/forgot-password.dart';
import 'package:diplomaticquarterapp/pages/login/register-info.dart';
@ -19,6 +20,7 @@ const String REGISTER = 'register';
const String CONFIRM_LOGIN = 'confrim-login';
const String REGISTER_INFO = 'register-info';
const String MY_FAMILIY = 'my-family';
const String LIVE_CARE = 'live-care';
var routes = {
HOME: (_) => LandingPage(),
WELCOME_LOGIN: (_) => WelcomeLogin(),
@ -28,5 +30,6 @@ var routes = {
REGISTER: (_) => Register(),
CONFIRM_LOGIN: (_) => ConfirmLogin(),
REGISTER_INFO: (_) => RegisterInfo(),
MY_FAMILIY: (_) => MyFamily()
MY_FAMILIY: (_) => MyFamily(),
LIVE_CARE: (_) => LiveCareHome()
};

@ -10,7 +10,6 @@ import 'package:diplomaticquarterapp/models/Request.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:flutter/cupertino.dart';
class DoctorsListService extends BaseService {
@ -22,7 +21,6 @@ class DoctorsListService extends BaseService {
Future<Map> getDoctorsList(
int clinicID, int projectID, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
@ -61,9 +59,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(GET_DOCTORS_LIST_URL,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -117,7 +113,6 @@ class DoctorsListService extends BaseService {
Future<Map> getDoctorsProfile(
int docID, int clinicID, int projectID, context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
var languageID = await sharedPref.getString(APP_LANGUAGE);
Request req = appGlobal.getPublicRequest();
@ -145,9 +140,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(GET_DOCTOR_PROFILE,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -155,7 +148,6 @@ class DoctorsListService extends BaseService {
Future<Map> getDoctorFreeSlots(
int docID, int clinicID, int projectID, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
var languageID = await sharedPref.getString(APP_LANGUAGE);
Request req = appGlobal.getPublicRequest();
@ -183,9 +175,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(GET_DOCTOR_FREE_SLOTS,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -193,8 +183,6 @@ class DoctorsListService extends BaseService {
Future<Map> insertAppointment(int docID, int clinicID, int projectID,
String selectedTime, String selectedDate, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
@ -240,9 +228,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(INSERT_SPECIFIC_APPOINTMENT,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -250,7 +236,6 @@ class DoctorsListService extends BaseService {
Future<Map> getPatientShare(
String appoID, int clinicID, int projectID, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
@ -287,9 +272,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(GET_PATIENT_SHARE,
onSuccess: (response, statusCode) async {
localRes = response['OnlineCheckInAppointments'][0];
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -297,7 +280,6 @@ class DoctorsListService extends BaseService {
Future<Map> getPatientAppointmentHistory(
bool isActiveAppointment, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
@ -331,9 +313,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(GET_PATIENT_APPOINTMENT_HISTORY,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -375,7 +355,6 @@ class DoctorsListService extends BaseService {
Future<Map> confirmAppointment(
int appoNo, int clinicID, int projectID, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
@ -412,9 +391,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(CONFIRM_APPOINTMENT,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -422,7 +399,6 @@ class DoctorsListService extends BaseService {
Future<Map> cancelAppointment(
AppoitmentAllHistoryResultList appo, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
@ -465,9 +441,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(CANCEL_APPOINTMENT,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -475,7 +449,6 @@ class DoctorsListService extends BaseService {
Future<Map> generateAppointmentQR(
PatientShareResponse patientShareResponse, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
@ -512,9 +485,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(GENERATE_QR_APPOINTMENT,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -529,7 +500,6 @@ class DoctorsListService extends BaseService {
String QR,
String speciality,
BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
@ -569,9 +539,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(EMAIL_QR_APPOINTMENT,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -655,7 +623,6 @@ class DoctorsListService extends BaseService {
}
Future<Map> isAllowedToAskDoctor(int docID, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
@ -689,16 +656,13 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(IS_ALLOW_ASK_DOCTOR,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
}
Future<Map> getCallRequestType(BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
@ -727,9 +691,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(GET_CALL_REQUEST_TYPE,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -737,7 +699,6 @@ class DoctorsListService extends BaseService {
Future<Map> sendAskDocCallRequest(AppoitmentAllHistoryResultList appo,
String requestType, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
@ -790,16 +751,13 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(SEND_CALL_REQUEST,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
}
Future<Map> getPatientRadOrders(String appoNo, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
@ -829,9 +787,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(GET_PATIENT_ORDERS,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -839,7 +795,6 @@ class DoctorsListService extends BaseService {
Future<Map> getPatientPrescriptionReports(
AppoitmentAllHistoryResultList appo, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
@ -873,9 +828,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(GET_PRESCRIPTION_REPORT_ENH,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -883,7 +836,6 @@ class DoctorsListService extends BaseService {
Future<Map> sendPrescriptionEmail(String appoDate, String setupId,
dynamic prescriptionReportEnhList, BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
@ -920,9 +872,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(SEND_PRESCRIPTION_EMAIL,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);
@ -934,7 +884,6 @@ class DoctorsListService extends BaseService {
String paymentReference,
String paymentMethodName,
BuildContext context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
@ -978,9 +927,7 @@ class DoctorsListService extends BaseService {
await baseAppClient.post(CREATE_ADVANCE_PAYMENT,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);

@ -1,17 +1,14 @@
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/service/base_service.dart';
import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart';
import 'package:diplomaticquarterapp/models/Request.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
class ClinicListService extends BaseService {
AppSharedPreferences sharedPref = AppSharedPreferences();
AppGlobal appGlobal = new AppGlobal();
Future<Map> getClinicsList(context) async {
Utils.showProgressDialog(context);
Map<String, dynamic> request;
var languageID = await sharedPref.getString(APP_LANGUAGE);
Request req = appGlobal.getPublicRequest();
@ -32,9 +29,7 @@ class ClinicListService extends BaseService {
await baseAppClient.post(GET_CLINICS_LIST_URL,
onSuccess: (response, statusCode) async {
localRes = response;
Utils.hideProgressDialog();
}, onFailure: (String error, int statusCode) {
Utils.hideProgressDialog();
throw error;
}, body: request);
return Future.value(localRes);

@ -0,0 +1,304 @@
import 'dart:io';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/service/base_service.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/Request.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:flutter/material.dart';
class LiveCareService extends BaseService {
AppSharedPreferences sharedPref = AppSharedPreferences();
AppGlobal appGlobal = new AppGlobal();
AuthenticatedUser authUser = new AuthenticatedUser();
AuthProvider authProvider = new AuthProvider();
Future<Map> getLivecareClinics(BuildContext context) async {
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE));
authUser = data;
}
var languageID = await sharedPref.getString(APP_LANGUAGE);
Request req = appGlobal.getPublicRequest();
request = {
"LanguageID": languageID == 'ar' ? 1 : 2,
"IPAdress": "10.20.10.20",
"VersionID": req.VersionID,
"Channel": req.Channel,
"generalid": 'Cs2020@2016\$2958',
"PatientOutSA": 0,
"TokenID": "",
"DeviceTypeID": req.DeviceTypeID,
"SessionID": "YckwoXhUmWBsnHKEKig",
"Age": authUser.age != null ? authUser.age : 0,
"PatientID": authUser.patientID != null ? authUser.patientID : 0,
"Gender": authUser.gender != null ? authUser.gender : 0
};
dynamic localRes;
await baseAppClient.post(GET_LIVECARE_CLINICS,
onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
}
Future<Map> getLivecareHistory(BuildContext context) async {
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE));
authUser = data;
}
var languageID = await sharedPref.getString(APP_LANGUAGE);
// Request req = appGlobal.getPublicRequest();
request = {
"LanguageID": languageID == 'ar' ? 1 : 2,
"TokenID": "",
"SessionID": "YckwoXhUmWBsnHKEKig"
};
dynamic localRes;
await baseAppClient.post(GET_LIVECARE_HISTORY,
onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
}
Future<Map> getLivecareClinicTiming(
int serviceID, BuildContext context) async {
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE));
authUser = data;
}
var languageID = await sharedPref.getString(APP_LANGUAGE);
Request req = appGlobal.getPublicRequest();
request = {
"LanguageID": languageID == 'ar' ? 1 : 2,
"IPAdress": "10.20.10.20",
"VersionID": req.VersionID,
"Channel": req.Channel,
"generalid": 'Cs2020@2016\$2958',
"PatientOutSA": 0,
"ServiceID": serviceID,
"DeviceTypeID": req.DeviceTypeID,
"SessionID": "YckwoXhUmWBsnHKEKig",
"Age": authUser.age != null ? authUser.age : 0,
"PatientID": authUser.patientID != null ? authUser.patientID : 0,
"Gender": authUser.gender != null ? authUser.gender : 0
};
dynamic localRes;
await baseAppClient.post(GET_LIVECARE_CLINIC_TIMING,
onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
}
Future<Map> getERAppointmentFees(int serviceID, BuildContext context) async {
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE));
authUser = data;
}
var languageID = await sharedPref.getString(APP_LANGUAGE);
Request req = appGlobal.getPublicRequest();
request = {
"LanguageID": languageID == 'ar' ? 1 : 2,
"IPAdress": "10.20.10.20",
"VersionID": req.VersionID,
"Channel": req.Channel,
"generalid": 'Cs2020@2016\$2958',
"PatientOutSA": 0,
"ServiceID": serviceID,
"ProjectID": 15,
"DeviceTypeID": req.DeviceTypeID,
"PatientType": authUser.patientType != null ? authUser.patientType : 0,
"PatientTypeID": authUser.patientType != null ? authUser.patientType : 0,
"SessionID": "YckwoXhUmWBsnHKEKig",
"Age": authUser.age != null ? authUser.age : 0,
"PatientID": authUser.patientID != null ? authUser.patientID : 0,
"Gender": authUser.gender != null ? authUser.gender : 0
};
dynamic localRes;
await baseAppClient.post(GET_ER_APPOINTMENT_FEES,
onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
}
Future<Map> getERAppointmentTime(int serviceID, BuildContext context) async {
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE));
authUser = data;
}
var languageID = await sharedPref.getString(APP_LANGUAGE);
Request req = appGlobal.getPublicRequest();
request = {
"LanguageID": languageID == 'ar' ? 1 : 2,
"IPAdress": "10.20.10.20",
"VersionID": req.VersionID,
"Channel": req.Channel,
"generalid": 'Cs2020@2016\$2958',
"PatientOutSA": 0,
"ServiceID": serviceID,
"ProjectID": 15,
"DeviceTypeID": req.DeviceTypeID,
"PatientType": authUser.patientType != null ? authUser.patientType : 0,
"PatientTypeID": authUser.patientType != null ? authUser.patientType : 0,
"SessionID": "YckwoXhUmWBsnHKEKig",
"Age": authUser.age != null ? authUser.age : 0,
"PatientID": authUser.patientID != null ? authUser.patientID : 0,
"Gender": authUser.gender != null ? authUser.gender : 0
};
dynamic localRes;
await baseAppClient.post(GET_ER_APPOINTMENT_TIME,
onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
}
Future<Map> addNewCallForPatientER(
int serviceID, String clientRequestID, BuildContext context) async {
Map<String, dynamic> request;
String deviceToken;
getDeviceToken().then((value) {
print(value);
deviceToken = value;
});
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE));
authUser = data;
}
var languageID = await sharedPref.getString(APP_LANGUAGE);
Request req = appGlobal.getPublicRequest();
request = {
"LanguageID": languageID == 'ar' ? 1 : 2,
"IPAdress": "10.20.10.20",
"VersionID": req.VersionID,
"Channel": req.Channel,
"generalid": 'Cs2020@2016\$2958',
"PatientOutSA": 0,
"ErServiceID": serviceID,
"ClientRequestID": clientRequestID,
"DeviceToken": deviceToken,
"VoipToken": "",
"Latitude": "24.708488",
"Longitude": "46.665925",
"DeviceType": Platform.isIOS ? 'iOS' : 'Android',
"PatientType": authUser.patientType != null ? authUser.patientType : 0,
"PatientTypeID": authUser.patientType != null ? authUser.patientType : 0,
"SessionID": "YckwoXhUmWBsnHKEKig",
"Age": authUser.age != null ? authUser.age : 0,
"PatientID": authUser.patientID != null ? authUser.patientID : 0,
"Gender": authUser.gender != null ? authUser.gender : 0
};
dynamic localRes;
await baseAppClient.post(ADD_NEW_CALL_FOR_PATIENT_ER,
onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
}
Future<String> getDeviceToken() async {
String deviceToken = await sharedPref.getString(PUSH_TOKEN);
return deviceToken;
}
Future<Map> cancelLiveCareRequest(int vc_id, BuildContext context) async {
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE));
authUser = data;
}
request = {"VCID": vc_id};
dynamic localRes;
await baseAppClient.post(CANCEL_LIVECARE_REQUEST,
onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
}
Future<Map> sendLiveCareInvoiceEmail(String appoNo, int projectID,
String emailAddress, BuildContext context) async {
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE));
authUser = data;
}
request = {
"To": emailAddress,
"ProjectID": projectID,
"AppointmentNo": appoNo
};
dynamic localRes;
await baseAppClient.post(SEND_LIVECARE_INVOICE_EMAIL,
onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
}
}

@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class NavigationService {
final GlobalKey<NavigatorState> navigatorKey =
new GlobalKey<NavigatorState>();
Future<dynamic> navigateTo(String routeName) {
return navigatorKey.currentState.pushNamed(routeName);
}
}

@ -421,6 +421,11 @@ class TranslationBase {
String get viewAllWaysReachUs =>localizedValues['ViewAllWaysReachUs'][locale.languageCode];
String get medicalProfile =>localizedValues['medicalProfile'][locale.languageCode];
String get consultation =>
localizedValues['consultation'][locale.languageCode];
String get logs =>
localizedValues['logs'][locale.languageCode];
}
class TranslationBaseDelegate extends LocalizationsDelegate<TranslationBase> {

@ -1,8 +1,6 @@
import 'package:connectivity/connectivity.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:progress_dialog/progress_dialog.dart';
import 'app_shared_preferences.dart';
import 'app_toast.dart';
@ -10,7 +8,6 @@ import 'app_toast.dart';
AppSharedPreferences sharedPref = new AppSharedPreferences();
class Utils {
static ProgressDialog pr;
///show custom Error Toast
/// [message] to show for user
@ -109,34 +106,4 @@ class Utils {
var length = loginType == 1 ? 10 : 7;
return "([0-9]{" + length.toString() + "})";
}
static showProgressDialog(context, [String message = "Loading..."]) async {
pr = ProgressDialog(context,
type: ProgressDialogType.Normal, isDismissible: false, showLogs: false);
pr.style(
message: message,
borderRadius: 10.0,
backgroundColor: Colors.white,
elevation: 10.0,
insetAnimCurve: Curves.easeInOut,
progress: 0.0,
maxProgress: 100.0,
progressTextStyle: TextStyle(
color: Colors.black, fontSize: 13.0, fontWeight: FontWeight.w400),
messageTextStyle: TextStyle(
color: Colors.black, fontSize: 19.0, fontWeight: FontWeight.w600));
if (!pr.isShowing()) {
await pr.show();
} else {
await pr.hide();
await pr.show();
}
}
static hideProgressDialog() async {
if (pr.isShowing()) {
await pr.hide();
}
}
}

@ -0,0 +1,45 @@
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class AlertDialogBox {
final BuildContext context;
final confirmMessage;
final okText;
final Function okFunction;
AlertDialogBox(
{@required this.context,
@required this.confirmMessage,
@required this.okText,
@required this.okFunction});
showAlertDialog(BuildContext context) {
Widget continueButton =
FlatButton(child: Text(this.okText), onPressed: this.okFunction);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text(TranslationBase.of(context).confirm),
content: Text(this.confirmMessage),
actions: [
continueButton,
],
);
// show the dialog
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
static closeAlertDialog(BuildContext context) {
Navigator.of(context).pop();
}
}

@ -38,7 +38,7 @@ dependencies:
url_launcher: ^5.5.0
shared_preferences: ^0.5.8
flutter_flexible_toast: ^0.1.4
firebase_messaging: ^6.0.16
firebase_messaging: 6.0.12
# Progress bar
progress_hud_v2: ^2.0.0
@ -61,7 +61,7 @@ dependencies:
# Notification Banner
dropdown_banner: ^1.4.0
flutter_local_notifications:
# flutter_local_notifications:
# charts
charts_flutter: ^0.9.0
@ -87,13 +87,24 @@ dependencies:
#InAppBrowser
flutter_inappwebview: ^4.0.0+4
#ProgressDialog
progress_dialog: ^1.2.4
#Circular progress bar for reverse timer
circular_countdown_timer: ^0.0.5
smart_progress_bar: ^0.1.6
#Just Audio to play ringing for incoming video call
just_audio: ^0.3.4
#hijri
hijri: ^2.0.3
#Dependencies for video call implementation
native_device_orientation: ^0.3.0
enum_to_string: ^1.0.9
# recase: ^3.0.0
wakelock: ^0.1.4
after_layout: ^1.0.7
twilio_programmable_video: ^0.5.0+3
dev_dependencies:
flutter_test:
@ -112,6 +123,7 @@ flutter:
- assets/images/new-design/
- assets/images/login/
- assets/json/
- assets/sounds/
fonts:

Loading…
Cancel
Save