From d7ab1c8dc269925f050f164028a9d470f1b6a78e Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 13 Apr 2023 15:36:35 +0300 Subject: [PATCH 01/10] PageView added to PR Info page --- lib/ui/work_list/item_history_screen.dart | 119 ++++++++++++++++------ 1 file changed, 87 insertions(+), 32 deletions(-) diff --git a/lib/ui/work_list/item_history_screen.dart b/lib/ui/work_list/item_history_screen.dart index 88abf06..c53a68e 100644 --- a/lib/ui/work_list/item_history_screen.dart +++ b/lib/ui/work_list/item_history_screen.dart @@ -58,6 +58,7 @@ class _ItemHistoryScreenState extends State { List actionHistoryList = []; List getAttachmentList = []; int tabIndex = 0; + PageController controller = PageController(); @override void initState() { @@ -136,7 +137,7 @@ class _ItemHistoryScreenState extends State { backgroundColor: Colors.white, body: ListView( padding: _screenParams!.isPRInfo ? const EdgeInsets.all(0) : const EdgeInsets.all(21), - physics: const BouncingScrollPhysics(), + physics: const NeverScrollableScrollPhysics(), children: [ if (_screenParams!.isPRInfo) prLinesDataView(), if (moItemHistoryList.isNotEmpty) loadMoItemHistoryData(), @@ -150,6 +151,7 @@ class _ItemHistoryScreenState extends State { Widget prLinesDataView() { return Column( + mainAxisSize: MainAxisSize.min, children: [ Container( padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16), @@ -177,36 +179,88 @@ class _ItemHistoryScreenState extends State { ), ), if (tabIndex == 0) _screenParams!.getPRInformationList!.pRHeader![0].dESCRIPTION!.toText14().paddingOnly(top: 20, right: 21, left: 21), - if (tabIndex == 0) - ListView.separated( - padding: const EdgeInsets.all(21), - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (cxt, index) => Column( - children: [ - ItemDetailGrid( - ItemDetailViewCol("Cost Center", _screenParams!.getPRInformationList!.pRLines![index].cOSTCENTER ?? ""), - ItemDetailViewCol("Code", _screenParams!.getPRInformationList!.pRLines![index].iTEMCODE ?? ""), - ), - ItemDetailGrid( - ItemDetailViewCol("Unit", _screenParams!.getPRInformationList!.pRLines![index].uOM ?? ""), - ItemDetailViewCol("Price (SAR)", _screenParams!.getPRInformationList!.pRLines![index].uNITPRICE.toString() ?? ""), - ), - ItemDetailGrid( - ItemDetailViewCol("Amount (SAR)", _screenParams!.getPRInformationList!.pRLines![index].lINEAMOUNT.toString() ?? ""), - ItemDetailViewCol("Quantity", _screenParams!.getPRInformationList!.pRLines![index].qUANTITY.toString() ?? ""), - ), - ItemDetailGrid( - ItemDetailViewCol("AMU (Last 3 months)", _screenParams!.getPRInformationList!.pRLines![index].iTEMAMU.toString() ?? ""), - ItemDetailViewCol("PR Number", _screenParams!.getPRInformationList!.pRHeader![0].pRNUMBER!.toString() ?? ""), - isItLast: true, - ), - ], - ).objectContainerView(), - separatorBuilder: (cxt, index) => 12.height, - itemCount: _screenParams!.getPRInformationList!.pRLines!.length), - if (tabIndex == 1) getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21), - if (tabIndex == 2) getPRAttachments(), + // if (tabIndex == 0) + // ListView.separated( + // padding: const EdgeInsets.all(21), + // shrinkWrap: true, + // physics: const NeverScrollableScrollPhysics(), + // itemBuilder: (cxt, index) => Column( + // children: [ + // ItemDetailGrid( + // ItemDetailViewCol("Cost Center", _screenParams!.getPRInformationList!.pRLines![index].cOSTCENTER ?? ""), + // ItemDetailViewCol("Code", _screenParams!.getPRInformationList!.pRLines![index].iTEMCODE ?? ""), + // ), + // ItemDetailGrid( + // ItemDetailViewCol("Unit", _screenParams!.getPRInformationList!.pRLines![index].uOM ?? ""), + // ItemDetailViewCol("Price (SAR)", _screenParams!.getPRInformationList!.pRLines![index].uNITPRICE.toString() ?? ""), + // ), + // ItemDetailGrid( + // ItemDetailViewCol("Amount (SAR)", _screenParams!.getPRInformationList!.pRLines![index].lINEAMOUNT.toString() ?? ""), + // ItemDetailViewCol("Quantity", _screenParams!.getPRInformationList!.pRLines![index].qUANTITY.toString() ?? ""), + // ), + // ItemDetailGrid( + // ItemDetailViewCol("AMU (Last 3 months)", _screenParams!.getPRInformationList!.pRLines![index].iTEMAMU.toString() ?? ""), + // ItemDetailViewCol("PR Number", _screenParams!.getPRInformationList!.pRHeader![0].pRNUMBER!.toString() ?? ""), + // isItLast: true, + // ), + // ], + // ).objectContainerView(), + // separatorBuilder: (cxt, index) => 12.height, + // itemCount: _screenParams!.getPRInformationList!.pRLines!.length), + // if (tabIndex == 1) getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21), + // if (tabIndex == 2) getPRAttachments(), + + SizedBox( + height: MediaQuery.of(context).size.height, + child: PageView( + controller: controller, + onPageChanged: (pageIndex) { + setState(() { + tabIndex = pageIndex; + if (pageIndex == 1) { + getActionsDataFromApi(); + } + if (pageIndex == 2) { + getAttachmentsDataFromApi(); + } + }); + }, + children: [ + // if (tabIndex == 0) + ListView.separated( + padding: const EdgeInsets.all(21), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + children: [ + ItemDetailGrid( + ItemDetailViewCol("Cost Center", _screenParams!.getPRInformationList!.pRLines![index].cOSTCENTER ?? ""), + ItemDetailViewCol("Code", _screenParams!.getPRInformationList!.pRLines![index].iTEMCODE ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol("Unit", _screenParams!.getPRInformationList!.pRLines![index].uOM ?? ""), + ItemDetailViewCol("Price (SAR)", _screenParams!.getPRInformationList!.pRLines![index].uNITPRICE.toString() ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol("Amount (SAR)", _screenParams!.getPRInformationList!.pRLines![index].lINEAMOUNT.toString() ?? ""), + ItemDetailViewCol("Quantity", _screenParams!.getPRInformationList!.pRLines![index].qUANTITY.toString() ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol("AMU (Last 3 months)", _screenParams!.getPRInformationList!.pRLines![index].iTEMAMU.toString() ?? ""), + ItemDetailViewCol("PR Number", _screenParams!.getPRInformationList!.pRHeader![0].pRNUMBER!.toString() ?? ""), + isItLast: true, + ), + ], + ).objectContainerView(), + separatorBuilder: (cxt, index) => 12.height, + itemCount: _screenParams!.getPRInformationList!.pRLines!.length), + // if (tabIndex == 1) + getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21), + // if (tabIndex == 2) + getPRAttachments(), + ], + ), + ), ], ); } @@ -550,7 +604,8 @@ class _ItemHistoryScreenState extends State { if (index == 2) { getAttachmentsDataFromApi(); } - tabIndex = index; + // tabIndex = index; + controller.jumpToPage(index); }); }).expanded; } From f8c207d33f9ba4e881ab86274c1f38a2270bee40 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 25 May 2023 09:55:14 +0300 Subject: [PATCH 02/10] updates --- lib/ui/login/login_screen.dart | 29 +++++++++++-------- lib/ui/work_list/item_history_screen.dart | 34 ----------------------- 2 files changed, 18 insertions(+), 45 deletions(-) diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 8d8e7c2..0eb7f4f 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -27,7 +27,6 @@ import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'package:mohem_flutter_app/models/privilege_list_model.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; -import 'package:mohem_flutter_app/widgets/button/hmg_connectivity_button.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart'; // import 'package:safe_device/safe_device.dart'; @@ -98,6 +97,7 @@ class _LoginScreenState extends State { Future checkFirebaseToken() async { try { + await checkPrefs(); Utils.showLoading(context); if (Platform.isAndroid) { try { @@ -120,6 +120,9 @@ class _LoginScreenState extends State { await Firebase.initializeApp(); _firebaseMessaging = FirebaseMessaging.instance; firebaseToken = await _firebaseMessaging.getToken(); + String? firebaseAPNSToken = await _firebaseMessaging.getAPNSToken(); + print("Firebase Token: $firebaseToken"); + print("Firebase APNS Token: $firebaseAPNSToken"); AppNotifications().init(firebaseToken); checkLoginInfo(); await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); @@ -132,17 +135,21 @@ class _LoginScreenState extends State { } void checkLoginInfo() async { - loginInfo = await LoginApiClient().getMobileLoginInfoNEW(AppState().getIsHuawei ? AppState().getHuaweiPushToken : firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); - if (loginInfo == null) { - await checkPrefs(); - _autoLogin = false; - Utils.hideLoading(context); - return; - } else { - loginInfo!.deviceToken = firebaseToken; - await checkPrefs(); + try { + loginInfo = await LoginApiClient().getMobileLoginInfoNEW(AppState().getIsHuawei ? AppState().getHuaweiPushToken : firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); + if (loginInfo == null) { + await checkPrefs(); + _autoLogin = false; + Utils.hideLoading(context); + return; + } else { + loginInfo!.deviceToken = firebaseToken; + await checkPrefs(); + Utils.hideLoading(context); + performLogin(); + } + } catch (ex) { Utils.hideLoading(context); - performLogin(); } } diff --git a/lib/ui/work_list/item_history_screen.dart b/lib/ui/work_list/item_history_screen.dart index c53a68e..e88dcba 100644 --- a/lib/ui/work_list/item_history_screen.dart +++ b/lib/ui/work_list/item_history_screen.dart @@ -179,37 +179,6 @@ class _ItemHistoryScreenState extends State { ), ), if (tabIndex == 0) _screenParams!.getPRInformationList!.pRHeader![0].dESCRIPTION!.toText14().paddingOnly(top: 20, right: 21, left: 21), - // if (tabIndex == 0) - // ListView.separated( - // padding: const EdgeInsets.all(21), - // shrinkWrap: true, - // physics: const NeverScrollableScrollPhysics(), - // itemBuilder: (cxt, index) => Column( - // children: [ - // ItemDetailGrid( - // ItemDetailViewCol("Cost Center", _screenParams!.getPRInformationList!.pRLines![index].cOSTCENTER ?? ""), - // ItemDetailViewCol("Code", _screenParams!.getPRInformationList!.pRLines![index].iTEMCODE ?? ""), - // ), - // ItemDetailGrid( - // ItemDetailViewCol("Unit", _screenParams!.getPRInformationList!.pRLines![index].uOM ?? ""), - // ItemDetailViewCol("Price (SAR)", _screenParams!.getPRInformationList!.pRLines![index].uNITPRICE.toString() ?? ""), - // ), - // ItemDetailGrid( - // ItemDetailViewCol("Amount (SAR)", _screenParams!.getPRInformationList!.pRLines![index].lINEAMOUNT.toString() ?? ""), - // ItemDetailViewCol("Quantity", _screenParams!.getPRInformationList!.pRLines![index].qUANTITY.toString() ?? ""), - // ), - // ItemDetailGrid( - // ItemDetailViewCol("AMU (Last 3 months)", _screenParams!.getPRInformationList!.pRLines![index].iTEMAMU.toString() ?? ""), - // ItemDetailViewCol("PR Number", _screenParams!.getPRInformationList!.pRHeader![0].pRNUMBER!.toString() ?? ""), - // isItLast: true, - // ), - // ], - // ).objectContainerView(), - // separatorBuilder: (cxt, index) => 12.height, - // itemCount: _screenParams!.getPRInformationList!.pRLines!.length), - // if (tabIndex == 1) getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21), - // if (tabIndex == 2) getPRAttachments(), - SizedBox( height: MediaQuery.of(context).size.height, child: PageView( @@ -226,7 +195,6 @@ class _ItemHistoryScreenState extends State { }); }, children: [ - // if (tabIndex == 0) ListView.separated( padding: const EdgeInsets.all(21), shrinkWrap: true, @@ -254,9 +222,7 @@ class _ItemHistoryScreenState extends State { ).objectContainerView(), separatorBuilder: (cxt, index) => 12.height, itemCount: _screenParams!.getPRInformationList!.pRLines!.length), - // if (tabIndex == 1) getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21), - // if (tabIndex == 2) getPRAttachments(), ], ), From 9030b9bc817aa5f9ec74b6c3b0206208485848b3 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 29 May 2023 12:30:26 +0300 Subject: [PATCH 03/10] Notification details implemented --- lib/api/my_requests_api_client.dart | 4 +- lib/classes/notifications.dart | 45 +++++- .../get_notifications_response_model.dart | 96 +++++++++++++ lib/ui/login/login_screen.dart | 5 +- .../notification_details_page.dart | 74 ++++++++++ lib/ui/screens/my_requests/my_requests.dart | 132 +++++++++--------- lib/ui/screens/my_requests/new_request.dart | 22 +-- 7 files changed, 299 insertions(+), 79 deletions(-) create mode 100644 lib/models/get_notifications_response_model.dart create mode 100644 lib/ui/notifications/notification_details_page.dart diff --git a/lib/api/my_requests_api_client.dart b/lib/api/my_requests_api_client.dart index c9507b9..96eafa5 100644 --- a/lib/api/my_requests_api_client.dart +++ b/lib/api/my_requests_api_client.dart @@ -60,7 +60,7 @@ class MyRequestsApiClient { }, url, postParams); } - Future getSubmitNewRequest(List> list) async + Future getSubmitNewRequest(List> list) async { String url = "${ApiConsts.erpRest}SUBMIT_CCP_TRANSACTION"; Map postParams = { @@ -73,7 +73,7 @@ class MyRequestsApiClient { postParams["EITTransactionTBL"] = list; return await ApiClient().postJsonForObject((json) { GenericResponseModel? responseData = GenericResponseModel.fromJson(json); - return responseData.submitCcpTransactionList; + return responseData; }, url, postParams); } diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index 9528616..e29b29c 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -3,12 +3,16 @@ import 'dart:io'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; // import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; import 'package:huawei_push/huawei_push.dart' as huawei_push; import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/date_uitl.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/models/get_notifications_response_model.dart'; +import 'package:mohem_flutter_app/ui/notifications/notification_details_page.dart'; import 'package:permission_handler/permission_handler.dart'; final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); @@ -24,6 +28,8 @@ class AppNotifications { String _huaweiToken = ''; + late BuildContext context; + Future requestPermissions() async { if (Platform.isIOS) { await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); @@ -40,11 +46,13 @@ class AppNotifications { } } - void init(String? firebaseToken) async { + void init(String? firebaseToken, BuildContext context) async { // if (Platform.isAndroid) { // hmsApiAvailability = HmsApiAvailability(); // } + this.context = context; + await requestPermissions(); AppState().setDeviceToken = firebaseToken; await Permission.notification.isDenied.then((bool value) { @@ -113,12 +121,47 @@ class AppNotifications { void _handleMessage(RemoteMessage message) { Utils.saveStringFromPrefs("isAppOpendByChat", "false"); + GetNotificationsResponseModel notification = GetNotificationsResponseModel(); + + notification.createdOn = DateUtil.getMonthDayYearDateFormatted(DateTime.now()); + notification.messageTypeData = message.data['picture']; + notification.message = message.data['message']; + notification.notificationType = message.data["NotificationType"].toString(); + if (message.data["NotificationType"] == "2") { + notification.videoURL = message.data["VideoUrl"]; + } + + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => NotificationsDetailsPage( + notification: notification, + ), + ), + ); } void _handleOpenApp(RemoteMessage message) { if (message.data.isNotEmpty && message.data["type"] == 'chat') { Utils.saveStringFromPrefs("isAppOpendByChat", "true"); Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString()); + } else { + GetNotificationsResponseModel notification = GetNotificationsResponseModel(); + + notification.createdOn = DateUtil.getMonthDayYearDateFormatted(DateTime.now()); + notification.messageTypeData = message.data['picture']; + notification.message = message.data['message']; + notification.notificationType = message.data["NotificationType"].toString(); + if (message.data["NotificationType"] == "2") { + notification.videoURL = message.data["VideoUrl"]; + } + + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => NotificationsDetailsPage( + notification: notification, + ), + ), + ); } } } diff --git a/lib/models/get_notifications_response_model.dart b/lib/models/get_notifications_response_model.dart new file mode 100644 index 0000000..adf08ee --- /dev/null +++ b/lib/models/get_notifications_response_model.dart @@ -0,0 +1,96 @@ +class GetNotificationsResponseModel { + int? id; + int? recordId; + int? patientID; + bool? projectOutSA; + String? deviceType; + String? deviceToken; + String? message; + String? messageType; + String? messageTypeData; + dynamic videoURL; + bool? isQueue; + String? isQueueOn; + String? createdOn; + String? createdBy; + String? notificationType; + bool? isSent; + String? isSentOn; + bool? isRead; + String? isReadOn; + int? channelID; + int? projectID; + + GetNotificationsResponseModel( + {this.id, + this.recordId, + this.patientID, + this.projectOutSA, + this.deviceType, + this.deviceToken, + this.message, + this.messageType, + this.messageTypeData, + this.videoURL, + this.isQueue, + this.isQueueOn, + this.createdOn, + this.createdBy, + this.notificationType, + this.isSent, + this.isSentOn, + this.isRead, + this.isReadOn, + this.channelID, + this.projectID}); + + GetNotificationsResponseModel.fromJson(Map json) { + id = json['Id']; + recordId = json['RecordId']; + patientID = json['PatientID']; + projectOutSA = json['ProjectOutSA']; + deviceType = json['DeviceType']; + deviceToken = json['DeviceToken']; + message = json['Message']; + messageType = json['MessageType']; + messageTypeData = json['MessageTypeData']; + videoURL = json['VideoURL']; + isQueue = json['IsQueue']; + isQueueOn = json['IsQueueOn']; + createdOn = json['CreatedOn']; + createdBy = json['CreatedBy']; + notificationType = json['NotificationType']; + isSent = json['IsSent']; + isSentOn = json['IsSentOn']; + isRead = json['IsRead']; + isReadOn = json['IsReadOn']; + channelID = json['ChannelID']; + projectID = json['ProjectID']; + } + + Map toJson() { + Map data = new Map(); + data['Id'] = this.id; + data['RecordId'] = this.recordId; + data['PatientID'] = this.patientID; + data['ProjectOutSA'] = this.projectOutSA; + data['DeviceType'] = this.deviceType; + data['DeviceToken'] = this.deviceToken; + data['Message'] = this.message; + data['MessageType'] = this.messageType; + data['MessageTypeData'] = this.messageTypeData; + data['VideoURL'] = this.videoURL; + data['IsQueue'] = this.isQueue; + data['IsQueueOn'] = this.isQueueOn; + data['CreatedOn'] = this.createdOn; + data['CreatedBy'] = this.createdBy; + data['NotificationType'] = this.notificationType; + data['IsSent'] = this.isSent; + data['IsSentOn'] = this.isSentOn; + data['IsRead'] = this.isRead; + data['IsReadOn'] = this.isReadOn; + data['ChannelID'] = this.channelID; + data['ProjectID'] = this.projectID; + return data; + } +} diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 0eb7f4f..3293e43 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -110,7 +110,8 @@ class _LoginScreenState extends State { await Firebase.initializeApp(); _firebaseMessaging = FirebaseMessaging.instance; firebaseToken = await _firebaseMessaging.getToken(); - AppNotifications().init(firebaseToken); + print(firebaseToken); + AppNotifications().init(firebaseToken, context); checkLoginInfo(); await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); } @@ -123,7 +124,7 @@ class _LoginScreenState extends State { String? firebaseAPNSToken = await _firebaseMessaging.getAPNSToken(); print("Firebase Token: $firebaseToken"); print("Firebase APNS Token: $firebaseAPNSToken"); - AppNotifications().init(firebaseToken); + AppNotifications().init(firebaseToken, context); checkLoginInfo(); await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); } diff --git a/lib/ui/notifications/notification_details_page.dart b/lib/ui/notifications/notification_details_page.dart new file mode 100644 index 0000000..67573dc --- /dev/null +++ b/lib/ui/notifications/notification_details_page.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; +import 'package:lottie/lottie.dart'; +import 'package:mohem_flutter_app/models/get_notifications_response_model.dart'; +import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; + +class NotificationsDetailsPage extends StatefulWidget { + final GetNotificationsResponseModel notification; + + NotificationsDetailsPage({required this.notification}); + + @override + State createState() => _NotificationsDetailsPageState(); +} + +class _NotificationsDetailsPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBarWidget( + context, + title: "Notification Details", + ), + body: ListView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + children: [ + Text( + widget.notification.createdOn!, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.64, + ), + ), + if (widget.notification.messageTypeData != null) + if (widget.notification.messageTypeData!.isNotEmpty && widget.notification.notificationType != "2") + Padding( + padding: const EdgeInsets.only(top: 18), + child: Image.network(widget.notification.messageTypeData!, loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: SizedBox( + width: 40.0, + height: 40.0, + child: showLoadingAnimation(), + ), + ); + }, fit: BoxFit.fill), + ), + SizedBox(height: 18), + Text( + widget.notification.message!.trim(), + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + letterSpacing: -0.48, + ), + ), + ], + ), + ); + } + + Widget showLoadingAnimation() { + return Lottie.asset( + 'assets/lottie/loading.json', + repeat: true, + reverse: false, + ); + } +} diff --git a/lib/ui/screens/my_requests/my_requests.dart b/lib/ui/screens/my_requests/my_requests.dart index dd6147f..4d16219 100644 --- a/lib/ui/screens/my_requests/my_requests.dart +++ b/lib/ui/screens/my_requests/my_requests.dart @@ -76,70 +76,72 @@ class _MyRequestsState extends State { }), ), 12.height, - getCCPTransactionsList.isNotEmpty ? Expanded( - child: ListView.separated( - physics: const BouncingScrollPhysics(), - shrinkWrap: true, - itemBuilder: (BuildContext context, int index) { - return Container( - width: double.infinity, - padding: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 12), - margin: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(10), - boxShadow: [ - BoxShadow( - color: const Color(0xff000000).withOpacity(.05), - blurRadius: 26, - offset: const Offset(0, -3), - ), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - ("Request ID: " + getCCPTransactionsList[index].rEQUESTID.toString()).toText12(color: MyColors.grey57Color), - DateUtil.formatDateToDate(DateUtil.convertStringToDate(getCCPTransactionsList[index].rEQUESTDATE!), false).toText12(color: MyColors.grey70Color), - ], - ), - Container( - padding: const EdgeInsets.only(top: 10.0), - child: ("Phase: " + getCCPTransactionsList[index].cCPPHASE!).toText12(color: MyColors.grey57Color, isBold: true), - ), - Container( - padding: const EdgeInsets.only(top: 10.0), - child: "Program Name: ".toText12(color: MyColors.grey57Color, isBold: true), - ), - getCCPTransactionsList[index].cONCURRENTPROGRAMNAME!.toText12(color: MyColors.gradiantEndColor), - Container( - padding: const EdgeInsets.only(top: 10.0), - child: InkWell( - onTap: () { - getCCPOutput(getCCPTransactionsList[index].rEQUESTID.toString()); - }, - child: Row( - children: [ - "Output: ".toText12(color: MyColors.grey57Color), - 8.width, - "Open PDF".toText12(color: MyColors.grey57Color), - 6.width, - const Icon(Icons.launch, size: 16.0), - ], - ), + getCCPTransactionsList.isNotEmpty + ? Expanded( + child: ListView.separated( + physics: const BouncingScrollPhysics(), + shrinkWrap: true, + itemBuilder: (BuildContext context, int index) { + return Container( + width: double.infinity, + padding: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 12), + margin: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], ), - ), - ], - ), - ); - }, - separatorBuilder: (BuildContext context, int index) => 12.height, - itemCount: getCCPTransactionsList.length), - ) : Container(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ("Request ID: " + getCCPTransactionsList[index].rEQUESTID.toString()).toText12(color: MyColors.grey57Color), + DateUtil.formatDateToDate(DateUtil.convertStringToDate(getCCPTransactionsList[index].rEQUESTDATE!), false).toText12(color: MyColors.grey70Color), + ], + ), + Container( + padding: const EdgeInsets.only(top: 10.0), + child: ("Phase: " + getCCPTransactionsList[index].cCPPHASE!).toText12(color: MyColors.grey57Color, isBold: true), + ), + Container( + padding: const EdgeInsets.only(top: 10.0), + child: "Program Name: ".toText12(color: MyColors.grey57Color, isBold: true), + ), + getCCPTransactionsList[index].cONCURRENTPROGRAMNAME!.toText12(color: MyColors.gradiantEndColor), + Container( + padding: const EdgeInsets.only(top: 10.0), + child: InkWell( + onTap: () { + getCCPOutput(getCCPTransactionsList[index].rEQUESTID.toString()); + }, + child: Row( + children: [ + "Output: ".toText12(color: MyColors.grey57Color), + 8.width, + "Open PDF".toText12(color: MyColors.grey57Color), + 6.width, + const Icon(Icons.launch, size: 16.0), + ], + ), + ), + ), + ], + ), + ); + }, + separatorBuilder: (BuildContext context, int index) => 12.height, + itemCount: getCCPTransactionsList.length), + ) + : Container(), ], ).expanded, 1.divider, @@ -153,7 +155,9 @@ class _MyRequestsState extends State { void openNewRequest() async { await Navigator.pushNamed(context, AppRoutes.newRequest).then((value) { - // getOpenTickets(); + if (value != null && value == "refresh") { + getCCPTransactions(selectedConcurrentProgramList?.cONCURRENTPROGRAMNAME); + } }); } diff --git a/lib/ui/screens/my_requests/new_request.dart b/lib/ui/screens/my_requests/new_request.dart index 670b18d..04d7cb4 100644 --- a/lib/ui/screens/my_requests/new_request.dart +++ b/lib/ui/screens/my_requests/new_request.dart @@ -5,12 +5,12 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/api/my_requests_api_client.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; -import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/dyanmic_forms/validate_eit_transaction_model.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/get_eit_dff_structure_list_model.dart'; import 'package:mohem_flutter_app/models/my_requests/get_ccp_transactions_model.dart'; import 'package:mohem_flutter_app/models/my_requests/get_ccp_transations_list_model.dart'; @@ -118,14 +118,14 @@ class _NewRequestState extends State { return ValidateEitTransactionModel(dATEVALUE: dateVal, nAME: e.aPPLICATIONCOLUMNNAME, nUMBERVALUE: numberVal, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: vatcherVal.toString()).toJson(); }).toList(); Utils.showLoading(context); - submitCcpTransactionList = await MyRequestsApiClient().getSubmitNewRequest(values); - getCCPTransactionsList = await MyRequestsApiClient().getCcpTransactions(values); + GenericResponseModel responseModel = await MyRequestsApiClient().getSubmitNewRequest(values); Utils.hideLoading(context); - Navigator.pushNamed( - context, - AppRoutes.myRequests, - ); - setState(() {}); + + if (responseModel.messageStatus == 1) { + Navigator.pop(context, "refresh"); + } else { + Utils.showToast(responseModel.errorEndUserMessage ?? ""); + } } catch (ex) { Utils.hideLoading(context); Utils.handleException(ex, context, null); @@ -214,13 +214,15 @@ class _NewRequestState extends State { pIDCOLUMNNAME: DateFormat('yyyy/MM/dd HH:MM:SS', "en_US").format(date1), pRETURNMSG: "null", pRETURNSTATUS: getCCPDFFStructureModelList![index].dEFAULTVALUE, - pVALUECOLUMNNAME: getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy/MM/dd HH:MM:SS', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date)); + pVALUECOLUMNNAME: + getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy/MM/dd HH:MM:SS', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date)); } else { eservicesdv = ESERVICESDV( pIDCOLUMNNAME: DateFormat('yyyy-MM-dd', "en_US").format(date1), pRETURNMSG: "null", pRETURNSTATUS: getCCPDFFStructureModelList![index].dEFAULTVALUE, - pVALUECOLUMNNAME: getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy-MM-dd hh:mm:ss', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date)); + pVALUECOLUMNNAME: + getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy-MM-dd hh:mm:ss', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date)); } getCCPDFFStructureModelList![index].eSERVICESDV = eservicesdv; setState(() {}); From ab1aa33ff3db863a8a612b1f432a726c58ccc563 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 7 Jun 2023 10:07:26 +0300 Subject: [PATCH 04/10] notifications update --- lib/classes/notifications.dart | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index e29b29c..47d4acd 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -131,13 +131,15 @@ class AppNotifications { notification.videoURL = message.data["VideoUrl"]; } - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) => NotificationsDetailsPage( - notification: notification, + Future.delayed(Duration(seconds: 5), () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => NotificationsDetailsPage( + notification: notification, + ), ), - ), - ); + ); + }); } void _handleOpenApp(RemoteMessage message) { @@ -155,13 +157,15 @@ class AppNotifications { notification.videoURL = message.data["VideoUrl"]; } - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) => NotificationsDetailsPage( - notification: notification, + Future.delayed(Duration(seconds: 5), () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => NotificationsDetailsPage( + notification: notification, + ), ), - ), - ); + ); + }); } } } From c4dc3e941dbb5b7452f5c59796915ae2aa753c88 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 14 Jun 2023 14:52:52 +0300 Subject: [PATCH 05/10] auth key --- AuthKey_67L2G322GR.p8 | 6 ++++ ios/Runner.xcodeproj/project.pbxproj | 43 ++++++++++------------------ 2 files changed, 21 insertions(+), 28 deletions(-) create mode 100644 AuthKey_67L2G322GR.p8 diff --git a/AuthKey_67L2G322GR.p8 b/AuthKey_67L2G322GR.p8 new file mode 100644 index 0000000..eddd4c6 --- /dev/null +++ b/AuthKey_67L2G322GR.p8 @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg+oBl9YdOiMRXfQZe +nIe6tR1tojoOvvcohNJmJtH+SsagCgYIKoZIzj0DAQehRANCAATDY9E82MAgMI/g +bKF1t4zLHJ1Yt9uoOnedNYsfyZLhh3l3ZyXRj02uDXz04AsNbNFjkLJXPc4xY9ad ++A4rY70x +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 43841a1..073c15f 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -144,7 +144,6 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, C4CFBC4C5CAC00182015ACD5 /* [CP] Embed Pods Frameworks */, - 1C704830960BB41251F31356 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -204,23 +203,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 1C704830960BB41251F31356 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; 2D06B7AD3B87C9C9059E4168 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -245,6 +227,7 @@ }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -259,6 +242,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -382,17 +366,18 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest; + MARKETING_VERSION = 3.7.2; + PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -519,17 +504,18 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest; + MARKETING_VERSION = 3.7.2; + PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -548,17 +534,18 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest; + MARKETING_VERSION = 3.7.2; + PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; From 15c8e807994490e3e2973391d866a639892b5056 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 12 Jul 2023 17:00:43 +0300 Subject: [PATCH 06/10] ERM Video fixes --- ios/Runner/Info.plist | 2 + lib/classes/utils.dart | 11 +++ .../itg/its_add_screen_video_image.dart | 70 +++++++++++++------ .../dynamic_screens/dynamic_input_screen.dart | 13 ++-- 4 files changed, 72 insertions(+), 24 deletions(-) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 75c680b..8108c0a 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -91,5 +91,7 @@ TAG + UIApplicationSupportsIndirectInputEvents + diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index 34831c2..1838cb8 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -401,4 +401,15 @@ class Utils { } return false; } + + static bool isDate(String input, String format) { + try { + DateTime d = DateFormat(format).parseStrict(input); + //print(d); + return true; + } catch (e) { + //print(e); + return false; + } + } } diff --git a/lib/ui/landing/itg/its_add_screen_video_image.dart b/lib/ui/landing/itg/its_add_screen_video_image.dart index 61b2766..160f773 100644 --- a/lib/ui/landing/itg/its_add_screen_video_image.dart +++ b/lib/ui/landing/itg/its_add_screen_video_image.dart @@ -39,6 +39,12 @@ class _ITGAdsScreenState extends State { String? masterID; int videoDuration = 0; + bool hasTimerEndedBool = false; + + final ValueNotifier hasTimerEnded = ValueNotifier(false); + + late CountdownTimerController timerController; + void checkFileType() async { String? rFile = advertisementData!.viewAttachFileColl!.first.base64String; String? rFileExt = advertisementData!.viewAttachFileColl!.first.fileName; @@ -56,6 +62,17 @@ class _ITGAdsScreenState extends State { setState(() {}); } + void changeTimer(bool isTimerEnd) { + hasTimerEndedBool = isTimerEnd; + hasTimerEnded.value = !hasTimerEnded.value; + } + + void onTimerEnd() { + changeTimer(true); + timerController.disposeTimer(); + timerController.dispose(); + } + Future processImage(String encodedBytes) async { try { Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last); @@ -69,18 +86,20 @@ class _ITGAdsScreenState extends State { Future createVideoPlayer(String encodedBytes) async { try { - Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last); - Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1 - File file = Io.File("${appDocumentsDirectory.path}/myAdsVideo.mp4"); - file.writeAsBytesSync(decodedBytes); - VideoPlayerController controller = VideoPlayerController.file(file); + // Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last); + // Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1 + // File file = Io.File("${appDocumentsDirectory.path}/myAdsVideo.mp4"); + // file.writeAsBytesSync(decodedBytes); + // VideoPlayerController controller = VideoPlayerController.file(file); + VideoPlayerController controller = VideoPlayerController.network(advertisementData!.viewAttachFileColl!.first.base64String!); await controller.initialize(); await controller.play(); await controller.setVolume(1.0); await controller.setLooping(false); return controller; } catch (e) { - return VideoPlayerController.asset("dataSource"); + print(e); + return VideoPlayerController.network("https://apimohemmweb.cloudsolutions.com.sa/ErmAttachment/compressedvideo.mp4"); } } @@ -107,6 +126,7 @@ class _ITGAdsScreenState extends State { if (advertisementData != null) { checkFileType(); videoDuration = advertisementData?.durationInSeconds ?? 0; + timerController = CountdownTimerController(endTime: DateTime.now().millisecondsSinceEpoch + 1000 * videoDuration, onEnd: onTimerEnd); } return Scaffold( backgroundColor: Colors.black, @@ -131,24 +151,34 @@ class _ITGAdsScreenState extends State { ), 30.height, CountdownTimer( + controller: timerController, endTime: DateTime.now().millisecondsSinceEpoch + 1000 * videoDuration, - onEnd: null, - endWidget: "00:00:00".toText14(color: Colors.white, isBold: true), + endWidget: "00:00:00".toText16(color: Colors.white, isBold: true), textStyle: const TextStyle(color: Colors.white, fontSize: 16, letterSpacing: -0.48, fontWeight: FontWeight.bold), ), 50.height, - Container(padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)) - .onPress(() { - try { - DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { - logger.d(value); - Navigator.pop(context); - }); - } catch (ex) { - logger.wtf(ex); - Utils.handleException(ex, context, null); - } - }), + ValueListenableBuilder( + valueListenable: hasTimerEnded, + builder: (context, val, child) { + if (hasTimerEndedBool) { + return Container( + padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)) + .onPress(() { + try { + DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { + logger.d(value); + Navigator.pop(context); + }); + } catch (ex) { + logger.wtf(ex); + Utils.handleException(ex, context, null); + } + }); + } else { + return Container(); + } + }), + // DefaultButton(LocaleKeys.home.tr(), () async { // DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { // logger.d(value); diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart index bd9305d..3e75813 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -340,10 +340,15 @@ class _DynamicInputScreenState extends State { idColName = val; if (getEitDffStructureList![j].fORMATTYPE == "X") { - idColName = Utils.formatDateDefault(idColName!); - // commenting to test - // DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!); - // idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date); + idColName = Utils.reverseFormatDate(idColName!); + if (Utils.isDate(Utils.reverseFormatDate(Utils.formatDateNew(idColName)), "yyyy-MM-dd")) { + idColName = Utils.formatStandardDate(Utils.formatStandardDate(Utils.formatDateNew(idColName))); + // idColName = DateFormat('yyyy/MM/dd HH:mm:ss').format(date); + } else if (Utils.isDate(Utils.reverseFormatDate(idColName), "dd-MM-yyyy")) { + // // change date format on 31/05/2023 + DateTime date = DateFormat('dd-MM-yyyy').parse(idColName); + idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date); + } } } From 4aa35349e1bfa2a112a8d98e818cbe77209e0011 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 17 Jul 2023 09:49:07 +0300 Subject: [PATCH 07/10] VersionID Update --- lib/app_state/app_state.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 7ccdd4f..f59994c 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -90,7 +90,7 @@ class AppState { String get getHuaweiPushToken => _huaweiPushToken; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.8, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.9, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; From 13c5b49fc2f9fe9136d6724357d0a5bf46fb45d6 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 17 Jul 2023 10:03:11 +0300 Subject: [PATCH 08/10] info plist --- ios/Runner/Info.plist | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 8108c0a..24ba08c 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,15 +2,6 @@ - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - NSAllowsArbitraryLoadsForMedia - - NSAllowsArbitraryLoadsInWebContent - - CADisableMinimumFrameDurationOnPhone CFBundleDevelopmentRegion @@ -31,6 +22,10 @@ ???? CFBundleVersion $(FLUTTER_BUILD_NUMBER) + FirebaseAppDelegateProxyEnabled + + ITSAppUsesNonExemptEncryption + LSApplicationQueriesSchemes sms @@ -41,6 +36,15 @@ NFCReaderUsageDescription This App requires access to NFC to mark your attendance. + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + NSAllowsArbitraryLoadsForMedia + + NSAllowsArbitraryLoadsInWebContent + + NSCameraUsageDescription This app requires camera access to capture & upload picture as profile image. NSFaceIDUsageDescription @@ -51,17 +55,18 @@ This App requires access to your location to mark your attendance. NSLocationWhenInUseUsageDescription This App requires access to your location to mark your attendance. - NSPhotoLibraryUsageDescription - This app requires photo library access to select image as document & upload it. NSMicrophoneUsageDescription This app requires microphone access to for call. + NSPhotoLibraryUsageDescription + This app requires photo library access to select image as document & upload it. + UIApplicationSupportsIndirectInputEvents + UIBackgroundModes fetch remote-notification + voip - FirebaseAppDelegateProxyEnabled - UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -85,13 +90,9 @@ 0000 - ITSAppUsesNonExemptEncryption - com.apple.developer.nfc.readersession.formats TAG - UIApplicationSupportsIndirectInputEvents - From 59116b700ab8d3138d5b0e6824bd698270b0847a Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 18 Jul 2023 10:47:21 +0300 Subject: [PATCH 09/10] Location check added --- lib/classes/consts.dart | 4 +- lib/widgets/location/Location.dart | 2 +- lib/widgets/mark_attendance_widget.dart | 179 +++++++++++++++++------- 3 files changed, 134 insertions(+), 51 deletions(-) diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 32b3fc7..45ef661 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - // static String baseUrl = "https://hmgwebservices.com"; // Live server + // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; diff --git a/lib/widgets/location/Location.dart b/lib/widgets/location/Location.dart index 62bd016..e324618 100644 --- a/lib/widgets/location/Location.dart +++ b/lib/widgets/location/Location.dart @@ -8,7 +8,7 @@ import 'package:mohem_flutter_app/classes/utils.dart'; class Location { static void havePermission(Function(bool) callback) { Geolocator.checkPermission().then((value) async { - if (value == LocationPermission.denied) { + if (value == LocationPermission.denied || value == LocationPermission.deniedForever) { value = await Geolocator.requestPermission(); callback(![LocationPermission.denied, LocationPermission.deniedForever].contains(value)); } else { diff --git a/lib/widgets/mark_attendance_widget.dart b/lib/widgets/mark_attendance_widget.dart index f11fafe..dfb4357 100644 --- a/lib/widgets/mark_attendance_widget.dart +++ b/lib/widgets/mark_attendance_widget.dart @@ -54,8 +54,6 @@ class _MarkAttendanceWidgetState extends State { } void checkAttendanceAvailability() async { - String? deviceID = await PlatformDeviceId.getDeviceId; - print("Platform Device ID: $deviceID"); bool isAvailable = await NfcManager.instance.isAvailable(); setState(() { AppState().privilegeListModel!.forEach((PrivilegeListModel element) { @@ -124,7 +122,7 @@ class _MarkAttendanceWidgetState extends State { mainAxisSize: MainAxisSize.min, children: [ LocaleKeys.markAttendance.tr().toSectionHeading(), - LocaleKeys.selectMethodOfAttendance.tr().tr().toText11(color: const Color(0xff535353)), + LocaleKeys.selectMethodOfAttendance.tr().toText11(color: const Color(0xff535353)), GridView( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, @@ -132,60 +130,145 @@ class _MarkAttendanceWidgetState extends State { gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), children: [ - // if (isNfcEnabled) attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { - // if (isNfcLocationEnabled) { + if (AppState().getIsHuawei) { + checkHuaweiLocationPermission("NFC"); + } else { + Location.isEnabled((bool isEnabled) { + if (isEnabled) { + Location.havePermission((bool permission) { + if (permission) { + Location.getCurrentLocation( + (Position position, bool isMocked) { + if (isMocked) { + markFakeAttendance("NFC", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); + } else { + performNfcAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); + } + }, + context, + ); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to give location permission to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openAppSettings(); + }, + ), + ); + } + }); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to enable location services to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openLocationSettings(); + }, + ), + ); + } + }); + } + }), + if (isWifiEnabled) + attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () { if (AppState().getIsHuawei) { - checkHuaweiLocationPermission("NFC"); + checkHuaweiLocationPermission("WIFI"); } else { - Location.getCurrentLocation((Position position, bool isMocked) { - if (isMocked) { - markFakeAttendance("NFC", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); + Location.isEnabled((bool isEnabled) { + if (isEnabled) { + Location.havePermission((bool permission) { + if (permission) { + Location.getCurrentLocation( + (Position position, bool isMocked) { + if (isMocked) { + markFakeAttendance("WIFI", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); + } else { + performWifiAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); + } + }, + context, + ); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to give location permission to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openAppSettings(); + }, + ), + ); + } + }); } else { - performNfcAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to enable location services to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openLocationSettings(); + }, + ), + ); } - }, context); + }); } - // } else { - // performNfcAttendance(widget.model); - // } - }), - if (isWifiEnabled) - attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () { - // if (isWifiLocationEnabled) { - if (AppState().getIsHuawei) { - checkHuaweiLocationPermission("WIFI"); - } else { - Location.getCurrentLocation((Position position, bool isMocked) { - if (isMocked) { - markFakeAttendance("WIFI", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); - } else { - performWifiAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); - } - }, context); - } - // } else { - // performWifiAttendance(widget.model); - // } }), if (isQrEnabled) attendanceMethod("QR", "assets/images/ic_qr.svg", isQrEnabled, () async { - // if (isQrLocationEnabled) { - if (AppState().getIsHuawei) { - checkHuaweiLocationPermission("QR"); - } else { - Location.getCurrentLocation((Position position, bool isMocked) { - if (isMocked) { - markFakeAttendance("QR", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); - } else { - performQrCodeAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); - } - }, context); - } - // } else { - // performQrCodeAttendance(widget.model); - // } - // performQrCodeAttendance(model); + if (AppState().getIsHuawei) { + checkHuaweiLocationPermission("QR"); + } else { + Location.isEnabled((bool isEnabled) { + if (isEnabled) { + Location.havePermission((bool permission) { + if (permission) { + Location.getCurrentLocation( + (Position position, bool isMocked) { + if (isMocked) { + markFakeAttendance("QR", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); + } else { + performQrCodeAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); + } + }, + context, + ); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to give location permission to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openAppSettings(); + }, + ), + ); + } + }); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to enable location services to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openLocationSettings(); + }, + ), + ); + } + }); + } }), ], ) From 1a8db3b0eec0632a22f40a4145616f94a87cb92d Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 27 Jul 2023 14:56:13 +0300 Subject: [PATCH 10/10] ERM Channel updates --- android/build.gradle | 2 +- lib/api/dashboard_api_client.dart | 6 +- lib/models/itg/advertisement.dart | 9 ++ .../itg/its_add_screen_video_image.dart | 94 ++++++++++--------- 4 files changed, 65 insertions(+), 46 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 7991b9d..dc67123 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.6.0' + ext.kotlin_version = '1.7.20' repositories { google() mavenCentral() diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index dfa4801..544ba71 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -201,13 +201,15 @@ class DashboardApiClient { }, url, postParams); } - Future setAdvertisementViewed(String masterID, int advertisementId) async { + Future setAdvertisementViewed(String masterID, int advertisementId, String ackValue) async { String url = "${ApiConsts.cocRest}Mohemm_ITG_UpdateAdvertisementAsViewed"; Map postParams = { "ItgNotificationMasterId": masterID, "EmployeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "ItgAdvertisement": {"advertisementId": advertisementId, "acknowledgment": true} //Mobile Id + "ItgAdvertisementId": advertisementId, + "ItgAcknowledgment": ackValue, + // "ItgAdvertisement": {"ItgAdvertisementId": advertisementId, "ItgAcknowledgment": ackValue} //Mobile Id }; postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { diff --git a/lib/models/itg/advertisement.dart b/lib/models/itg/advertisement.dart index 598a248..96f4037 100644 --- a/lib/models/itg/advertisement.dart +++ b/lib/models/itg/advertisement.dart @@ -10,6 +10,9 @@ class Advertisement { this.pageSize, this.pageNo, this.languageId, + this.isOptional, + this.skipButtonTextEn, + this.skipButtonTextAr, }); final int? advertisementId; @@ -22,6 +25,9 @@ class Advertisement { final dynamic pageSize; final dynamic pageNo; final dynamic languageId; + final bool? isOptional; + final String? skipButtonTextEn; + final String? skipButtonTextAr; factory Advertisement.fromJson(Map json) => Advertisement( advertisementId: json["advertisementId"] == null ? null : json["advertisementId"], @@ -34,6 +40,9 @@ class Advertisement { pageSize: json["pageSize"], pageNo: json["pageNo"], languageId: json["languageId"], + isOptional: json["isOptional"] == null ? null : json["isOptional"], + skipButtonTextEn: json["skipBtnTextEn"] == null ? null : json["skipBtnTextEn"], + skipButtonTextAr: json["skipBtnTextAr"] == null ? null : json["skipBtnTextAr"], ); Map toJson() => { diff --git a/lib/ui/landing/itg/its_add_screen_video_image.dart b/lib/ui/landing/itg/its_add_screen_video_image.dart index 160f773..1e280d8 100644 --- a/lib/ui/landing/itg/its_add_screen_video_image.dart +++ b/lib/ui/landing/itg/its_add_screen_video_image.dart @@ -7,6 +7,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_countdown_timer/index.dart'; import 'package:lottie/lottie.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/lottie_consts.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; @@ -15,6 +16,7 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/itg/advertisement.dart' as ads; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:path_provider/path_provider.dart'; import 'package:video_player/video_player.dart'; @@ -86,11 +88,6 @@ class _ITGAdsScreenState extends State { Future createVideoPlayer(String encodedBytes) async { try { - // Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last); - // Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1 - // File file = Io.File("${appDocumentsDirectory.path}/myAdsVideo.mp4"); - // file.writeAsBytesSync(decodedBytes); - // VideoPlayerController controller = VideoPlayerController.file(file); VideoPlayerController controller = VideoPlayerController.network(advertisementData!.viewAttachFileColl!.first.base64String!); await controller.initialize(); await controller.play(); @@ -113,8 +110,6 @@ class _ITGAdsScreenState extends State { @override void dispose() { if (_controller != null) _controller.dispose(); - // player.stop(); - // player.dispose(); super.dispose(); } @@ -158,41 +153,54 @@ class _ITGAdsScreenState extends State { ), 50.height, ValueListenableBuilder( - valueListenable: hasTimerEnded, - builder: (context, val, child) { - if (hasTimerEndedBool) { - return Container( - padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)) - .onPress(() { - try { - DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { - logger.d(value); + valueListenable: hasTimerEnded, + builder: (context, val, child) { + if (hasTimerEndedBool) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)) + .onPress(() { + try { Navigator.pop(context); - }); - } catch (ex) { - logger.wtf(ex); - Utils.handleException(ex, context, null); - } - }); - } else { - return Container(); - } - }), - - // DefaultButton(LocaleKeys.home.tr(), () async { - // DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { - // logger.d(value); - // }); - // }).paddingOnly(left: 50, right: 50) - - // ElevatedButton( - // onPressed: () async { - // // DashboardApiClient().setAdvertisementViewed(widget.addMasterId, widget.advertisement!.advertisementId!).then((value) { - // // logger.d(value); - // // }); - // }, - // child: const Text("Go To Dashboard"), - // ) + DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Like").then((value) { + logger.d(value); + }); + } catch (ex) { + logger.wtf(ex); + Utils.handleException(ex, context, null); + } + }), + 20.width, + Container( + padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_down, color: MyColors.gradiantEndColor)) + .onPress(() { + try { + Navigator.pop(context); + DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Dislike").then((value) { + logger.d(value); + }); + } catch (ex) { + logger.wtf(ex); + Utils.handleException(ex, context, null); + } + }), + ], + ); + } else { + return Container(); + } + }, + ), + 20.height, + if (advertisementData?.isOptional ?? false) + DefaultButton(AppState().isArabic(context) ? advertisementData?.skipButtonTextAr ?? "Skip" : advertisementData?.skipButtonTextEn ?? "Skip", () async { + Navigator.pop(context); + DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Skip").then((value) { + logger.d(value); + }); + }).paddingOnly(left: 100, right: 100) ], ); } else { @@ -212,9 +220,9 @@ class _ITGAdsScreenState extends State { Container(padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)).onPress( () { try { - DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { + Navigator.pop(context); + DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Like").then((value) { logger.d(value); - Navigator.pop(context); }); } catch (ex) { logger.wtf(ex);