From 3be279d57197c11c54237d8965a3b61435f2b52e Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 9 Nov 2022 18:00:26 +0300 Subject: [PATCH 01/62] Worklist images added --- lib/ui/work_list/itg_detail_screen.dart | 18 +++++++----------- lib/ui/work_list/worklist_detail_screen.dart | 9 +++++++++ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/ui/work_list/itg_detail_screen.dart b/lib/ui/work_list/itg_detail_screen.dart index b215435..0a29a72 100644 --- a/lib/ui/work_list/itg_detail_screen.dart +++ b/lib/ui/work_list/itg_detail_screen.dart @@ -274,16 +274,19 @@ class _ItgDetailScreenState extends State { returnActionImage = "assets/images/request_info.svg"; break; case "ReportGenerated": - returnActionImage = "assets/images/request_info.svg"; + returnActionImage = "assets/images/worklist/report_generated.svg"; break; case "DataCorrected": - returnActionImage = "assets/images/request_info.svg"; + returnActionImage = "assets/images/worklist/report_generated.svg"; break; case "Doable": - returnActionImage = "assets/images/request_info.svg"; + returnActionImage = "assets/images/worklist/doable.svg"; break; case "NotDoable": - returnActionImage = "assets/images/request_info.svg"; + returnActionImage = "assets/images/worklist/not_doable.svg"; + break; + case "Answer": + returnActionImage = "assets/images/worklist/answer_hr.svg"; break; default: returnActionImage = "assets/images/request_info.svg"; @@ -358,13 +361,6 @@ class _ItgDetailScreenState extends State { case "Answer": performAction("Answer"); break; - - case "RFC": - // do something else - break; - case "UPDATE_ACTION": - // do something else - break; } setState(() { showFabOptions = false; diff --git a/lib/ui/work_list/worklist_detail_screen.dart b/lib/ui/work_list/worklist_detail_screen.dart index 262ec4f..3c05204 100644 --- a/lib/ui/work_list/worklist_detail_screen.dart +++ b/lib/ui/work_list/worklist_detail_screen.dart @@ -404,6 +404,15 @@ class _WorkListDetailScreenState extends State { case "UPDATE_ACTION": returnActionImage = "assets/images/worklist/update_action.svg"; break; + case "APPROVE_AND_FORWARD": + returnActionImage = "assets/images/worklist/approve_and_forward.svg"; + break; + case "FORWARD": + returnActionImage = "assets/images/worklist/forward.svg"; + break; + default: + returnActionImage = "assets/images/request_info.svg"; + break; } return returnActionImage; From 22ac89e74435f182da5fe6f1d5c1174db4e54520 Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Thu, 10 Nov 2022 09:45:29 +0300 Subject: [PATCH 02/62] fix issues --- lib/classes/consts.dart | 4 +- lib/models/generic_response_model.dart | 2 +- .../attendance/add_vacation_rule_screen.dart | 2 +- .../dynamic_screens/dynamic_input_screen.dart | 37 ++++++++++--------- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index eea2481..6276213 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/models/generic_response_model.dart b/lib/models/generic_response_model.dart index 2c8e98f..cf799fd 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -1273,7 +1273,7 @@ class GenericResponseModel { if (json['RespondRolesList'] != null) { respondRolesList = []; json['RespondRolesList'].forEach((v) { - respondRolesList!.add(v); + // respondRolesList!.add(v); }); } resubmitAbsenceTransactionList = json['ResubmitAbsenceTransactionList']; diff --git a/lib/ui/attendance/add_vacation_rule_screen.dart b/lib/ui/attendance/add_vacation_rule_screen.dart index a698adc..caa1ee3 100644 --- a/lib/ui/attendance/add_vacation_rule_screen.dart +++ b/lib/ui/attendance/add_vacation_rule_screen.dart @@ -98,7 +98,7 @@ class _AddVacationRuleScreenState extends State { } void callCombineApis() async { - try { + try { Utils.showLoading(context); List results = await Future.wait([ VacationRuleApiClient().getNotificationReassignMode(), 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 519bb6c..f71e6f1 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -57,7 +57,7 @@ class _DynamicInputScreenState extends State { } void validateTransaction() async { - try { + // try { Utils.showLoading(context); List> values = getEitDffStructureList!.map((e) { String tempVar = e.eSERVICESDV?.pIDCOLUMNNAME ?? ""; @@ -98,10 +98,10 @@ class _DynamicInputScreenState extends State { Utils.showLoading(context); await LeaveBalanceApiClient().cancelHrTransaction(submitEITTransactionList.pTRANSACTIONID!); Utils.hideLoading(context); - } catch (ex) { - Utils.hideLoading(context); - Utils.handleException(ex, context, null); - } + // } catch (ex) { + // Utils.hideLoading(context); + // Utils.handleException(ex, context, null); + // } } String dESCFLEXCONTEXTCODE = ""; @@ -136,7 +136,7 @@ class _DynamicInputScreenState extends State { } Future getDefaultValues(GetEITDFFStructureList structureList) async { - try { + // try { Utils.showLoading(context); for (int i = 0; i < (structureList.cHILDSEGMENTSDVSplited?.length ?? 0); i++) { String segmentId = structureList.cHILDSEGMENTSDVSplited![i]; @@ -163,10 +163,10 @@ class _DynamicInputScreenState extends State { await Future.delayed(const Duration(seconds: 1)); Utils.hideLoading(context); setState(() {}); - } catch (ex) { - Utils.hideLoading(context); - Utils.handleException(ex, context, null); - } + // } catch (ex) { + // Utils.hideLoading(context); + // Utils.handleException(ex, context, null); + // } } // List> calGetValueSetValuesIonicLogic(GetEITDFFStructureList structureElement) { @@ -180,7 +180,7 @@ class _DynamicInputScreenState extends State { // } List> getDefaultValuesIonicLogic(GetEITDFFStructureList structureElement) { - try { + // try { List parentValue = structureElement.pARENTSEGMENTSVSSplitedVS ?? []; List parentsList = structureElement.pARENTSEGMENTSDVSplited ?? []; @@ -248,11 +248,11 @@ class _DynamicInputScreenState extends State { // } // Utils.hideLoading(context); // setState(() {}); - } catch (ex) { - Utils.hideLoading(context); - Utils.handleException(ex, context, null); - return []; - } + // } catch (ex) { + // Utils.hideLoading(context); + // Utils.handleException(ex, context, null); + // return []; + // } } List> getDependenciesParams(parentsList) { @@ -340,7 +340,7 @@ class _DynamicInputScreenState extends State { String? text = data?.pVALUECOLUMNNAME; String? val = data?.pIDCOLUMNNAME; - if ((val ?? "").isEmpty && parentsList[i].IsRequired == "REQUIRED") { + if ((val ?? "").isEmpty && parentsList[i].isRequired == "REQUIRED") { //alert(parentsList[i].Name +" Is required"); return []; } else {} @@ -362,7 +362,8 @@ class _DynamicInputScreenState extends State { String? text = data?.pVALUECOLUMNNAME; String? val = data?.pIDCOLUMNNAME; - if ((val ?? "").isEmpty && parentsList[i].IsRequired == "REQUIRED") { + /// + if ((val ?? "").isEmpty && parentsList[i].isRequired == "REQUIRED") { //alert(parentsList[i].Name +" Is required"); return []; } else {} From 4d0d3a980eeab4acacd10a2d97059e9b2dc83cd6 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 10 Nov 2022 10:44:15 +0300 Subject: [PATCH 03/62] Item history updated --- lib/ui/work_list/item_history_screen.dart | 48 ++++++++++++++++------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/lib/ui/work_list/item_history_screen.dart b/lib/ui/work_list/item_history_screen.dart index 6cf80ca..782e34d 100644 --- a/lib/ui/work_list/item_history_screen.dart +++ b/lib/ui/work_list/item_history_screen.dart @@ -131,21 +131,39 @@ class _ItemHistoryScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - ItemDetailView(LocaleKeys.operatingUnit.tr(), poItemHistoryList[index].oUNAME ?? ""), - ItemDetailView(LocaleKeys.poNumber.tr(), poItemHistoryList[index].pONUMBER ?? ""), - ItemDetailView(LocaleKeys.revision.tr(), poItemHistoryList[index].rEVISIONNUM?.toString() ?? ""), - ItemDetailView(LocaleKeys.creationDate.tr(), poItemHistoryList[index].cREATIONDATE ?? ""), - ItemDetailView(LocaleKeys.supplier.tr(), poItemHistoryList[index].sUPPLIER ?? ""), - ItemDetailView(LocaleKeys.buyer.tr(), poItemHistoryList[index].bUYER ?? ""), - ItemDetailView(LocaleKeys.uom.tr(), poItemHistoryList[index].uOM ?? ""), - ItemDetailView(LocaleKeys.quantityOrdered.tr(), poItemHistoryList[index].qUANTITYORDERED?.toString() ?? ""), - ItemDetailView(LocaleKeys.quantityReceived.tr(), poItemHistoryList[index].qUANTITYRECEIVED?.toString() ?? ""), - ItemDetailView(LocaleKeys.bonusQuantity.tr(), poItemHistoryList[index].bONUSQUANTITY?.toString() ?? ""), - ItemDetailView(LocaleKeys.purchasePrice.tr(), poItemHistoryList[index].pURCHASEPRICE?.toString() ?? ""), - ItemDetailView(LocaleKeys.discountPer.tr(), poItemHistoryList[index].dISCOUNTPERCENTAGE?.toString() ?? ""), - ItemDetailView(LocaleKeys.balanceQuantity.tr(), poItemHistoryList[index].bALANCEQUANTITY?.toString() ?? ""), - ItemDetailView(LocaleKeys.netPrice.tr(), poItemHistoryList[index].nETPRICE?.toString() ?? ""), - ItemDetailView(LocaleKeys.closureStatus.tr(), poItemHistoryList[index].cLOSEDCODE ?? ""), + // ItemDetailGrid( + // ItemDetailViewCol(LocaleKeys.from.tr(), workListData!.fROMUSER ?? ""), + // ItemDetailViewCol(LocaleKeys.to.tr(), workListData!.tOUSER ?? ""), + // ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.operatingUnit.tr(), poItemHistoryList[index].oUNAME ?? ""), + ItemDetailViewCol(LocaleKeys.poNumber.tr(), poItemHistoryList[index].pONUMBER ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.revision.tr(), poItemHistoryList[index].rEVISIONNUM?.toString() ?? ""), + ItemDetailViewCol(LocaleKeys.creationDate.tr(), poItemHistoryList[index].cREATIONDATE ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.supplier.tr(), poItemHistoryList[index].sUPPLIER ?? ""), + ItemDetailViewCol(LocaleKeys.buyer.tr(), poItemHistoryList[index].bUYER ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.uom.tr(), poItemHistoryList[index].uOM ?? ""), + ItemDetailViewCol(LocaleKeys.quantityOrdered.tr(), poItemHistoryList[index].qUANTITYORDERED?.toString() ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.quantityReceived.tr(), poItemHistoryList[index].qUANTITYRECEIVED?.toString() ?? ""), + ItemDetailViewCol(LocaleKeys.bonusQuantity.tr(), poItemHistoryList[index].bONUSQUANTITY?.toString() ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.purchasePrice.tr(), poItemHistoryList[index].pURCHASEPRICE?.toString() ?? ""), + ItemDetailViewCol(LocaleKeys.discountPer.tr(), poItemHistoryList[index].dISCOUNTPERCENTAGE?.toString() ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.balanceQuantity.tr(), poItemHistoryList[index].bALANCEQUANTITY?.toString() ?? ""), + ItemDetailViewCol(LocaleKeys.netPrice.tr(), poItemHistoryList[index].nETPRICE?.toString() ?? ""), + ), + ItemDetailGrid(ItemDetailViewCol(LocaleKeys.closureStatus.tr(), poItemHistoryList[index].cLOSEDCODE ?? ""), Container(), isItLast: true,) ], ).objectContainerView(), separatorBuilder: (cxt, index) => 12.height, From c22556d9b6afae97cf514ce7c63ac4674baa7484 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 10 Nov 2022 15:43:28 +0300 Subject: [PATCH 04/62] fixes --- lib/classes/consts.dart | 4 +- lib/main.dart | 6 ++ lib/ui/dialogs/success_dialog.dart | 2 +- lib/ui/landing/dashboard_screen.dart | 4 +- lib/ui/landing/widget/services_widget.dart | 90 ++++++++++++++++++- .../fragments/add_details_fragment.dart | 6 +- .../fragments/item_review_fragment.dart | 2 + pubspec.yaml | 1 + 8 files changed, 107 insertions(+), 8 deletions(-) diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 6276213..eea2481 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/main.dart b/lib/main.dart index adca4aa..a2ae0ae 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -92,6 +92,12 @@ class MyApp extends StatelessWidget { MonthYearPickerLocalizations.delegate, ); return MaterialApp( + builder: (BuildContext context, Widget? child) { + return MediaQuery( + data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), + child: child!, + ); + }, theme: AppTheme.getTheme( EasyLocalization.of(context)?.locale.languageCode == "ar", ), diff --git a/lib/ui/dialogs/success_dialog.dart b/lib/ui/dialogs/success_dialog.dart index 5150110..a5df64f 100644 --- a/lib/ui/dialogs/success_dialog.dart +++ b/lib/ui/dialogs/success_dialog.dart @@ -53,8 +53,8 @@ class _SuccessDialogState extends State with TickerProviderStateM repeat: false, reverse: false, controller: _controller, + frameRate: FrameRate(60.0), onLoaded: (LottieComposition v) async { - print("calling_lottie " + v.seconds.toString()); await playSuccessSound(); _controller ..duration = v.duration diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index d342072..b49b98b 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -256,7 +256,7 @@ class _DashboardScreenState extends State { margin: EdgeInsets.only(top: AppState().isArabic(context) ? 6 : 0), width: 45, height: 45, - padding: const EdgeInsets.only(left: 14, right: 14), + padding: const EdgeInsets.only(left: 10, right: 10), decoration: BoxDecoration( color: Color(0xff259EA4), borderRadius: BorderRadius.only( @@ -296,7 +296,7 @@ class _DashboardScreenState extends State { ), ], ).paddingOnly(left: 21, right: 21, top: 7), - MarathonBanner().paddingAll(20), + const MarathonBanner().paddingAll(20), ServicesWidget(), // 8.height, Container( diff --git a/lib/ui/landing/widget/services_widget.dart b/lib/ui/landing/widget/services_widget.dart index 0b257c5..ae24dde 100644 --- a/lib/ui/landing/widget/services_widget.dart +++ b/lib/ui/landing/widget/services_widget.dart @@ -39,7 +39,7 @@ class ServicesWidget extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, - children: [ + children: [ data.homeMenus![parentIndex].menuEntry.prompt!.toSectionHeading().paddingOnly(left: 21, right: 21), SizedBox( height: 105 + 26, @@ -69,7 +69,7 @@ class ServicesWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - SvgPicture.asset(iconT[index]), + SvgPicture.asset(AppState().isArabic(context) ? getMenuIconAr(data.homeMenus![parentIndex].menuEntiesList[index].prompt!) : getMenuIconEn(data.homeMenus![parentIndex].menuEntiesList[index].prompt!)), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ @@ -102,6 +102,92 @@ class ServicesWidget extends StatelessWidget { ); } + String getMenuIconAr(String name) { + String returnImage = ""; + switch (name) { + case "الحضور الشهري": + returnImage = "assets/images/services_icons/monthly_attendance.svg"; + break; + case "كشف الراتب": + returnImage = "assets/images/services_icons/payslips.svg"; + break; + case "تغيير معلومات البنك": + returnImage = "assets/images/services_icons/change_bank_details.svg"; + break; + case "طلب بدل السكن مقدما": + returnImage = "assets/images/services_icons/housing_allowance.svg"; + break; + case "شهادات تعريف الموظف": + returnImage = "assets/images/services_icons/employee_certificates.svg"; + break; + case "البيانات الشخصية": + returnImage = "assets/images/personal-info.svg"; + break; + case "الحضور": + returnImage = "assets/images/services_icons/my_attendance.svg"; + break; + case "طلبات أخرى": + returnImage = "assets/images/services_icons/other_requests.svg"; + break; + case "الإجازات": + returnImage = "assets/images/services_icons/my_leaves.svg"; + break; + case "طلب تذكرة": + returnImage = "assets/images/services_icons/ticket_bal.svg"; + break; + case "قاعدة الاجازات": + returnImage = "assets/images/services_icons/vacation_rule.svg"; + break; + default: + returnImage = "assets/images/monthly_attendance.svg"; + break; + } + return returnImage; + } + + String getMenuIconEn(String name) { + String returnImage = ""; + switch (name) { + case "Monthly Attendance": + returnImage = "assets/images/services_icons/monthly_attendance.svg"; + break; + case "Payslip": + returnImage = "assets/images/services_icons/payslips.svg"; + break; + case "Change Bank Details": + returnImage = "assets/images/services_icons/change_bank_details.svg"; + break; + case "Housing Advance": + returnImage = "assets/images/services_icons/housing_allowance.svg"; + break; + case "Employee Certificate": + returnImage = "assets/images/services_icons/employee_certificates.svg"; + break; + case "Personal Information": + returnImage = "assets/images/personal-info.svg"; + break; + case "My Attendance": + returnImage = "assets/images/services_icons/my_attendance.svg"; + break; + case "Other Requests": + returnImage = "assets/images/services_icons/other_requests.svg"; + break; + case "My Leave": + returnImage = "assets/images/services_icons/my_leaves.svg"; + break; + case "Ticket Request": + returnImage = "assets/images/services_icons/ticket_bal.svg"; + break; + case "Vacation Rule": + returnImage = "assets/images/services_icons/vacation_rule.svg"; + break; + default: + returnImage = "assets/images/monthly_attendance.svg"; + break; + } + return returnImage; + } + void handleOnPress(context, GetMenuEntriesList menuEntry) { var pro = Provider.of(context, listen: false); if (menuEntry.requestType == "MONTHLY_ATTENDANCE") { diff --git a/lib/ui/screens/items_for_sale/fragments/add_details_fragment.dart b/lib/ui/screens/items_for_sale/fragments/add_details_fragment.dart index b2791ec..f0f2c62 100644 --- a/lib/ui/screens/items_for_sale/fragments/add_details_fragment.dart +++ b/lib/ui/screens/items_for_sale/fragments/add_details_fragment.dart @@ -25,8 +25,9 @@ class AddItemDetailsFragment extends StatefulWidget { final Function changePageViewIndex; final GetSaleCategoriesList selectedSaleCategory; static late ItemReviewModel itemReviewModel; + static late bool isUpdate; - const AddItemDetailsFragment({Key? key, required this.changePageViewIndex, required this.selectedSaleCategory}) : super(key: key); + AddItemDetailsFragment({Key? key, required this.changePageViewIndex, required this.selectedSaleCategory}) : super(key: key); @override State createState() => _AddItemDetailsFragmentState(); @@ -246,6 +247,7 @@ class _AddItemDetailsFragmentState extends State { String details = await Utils.getStringFromPrefs(SharedPrefsConsts.editItemForSale); if(details.isNotEmpty) { var body = json.decode(details); + AddItemDetailsFragment.isUpdate = true; GetRegionsList selectedRegionAd = GetRegionsList(); @@ -268,6 +270,8 @@ class _AddItemDetailsFragmentState extends State { AddItemDetailsFragment.itemReviewModel = itemReviewModel; SelectCategoryFragment.selectedSaleCategory = selectedSaleCategoryAd; + } else { + AddItemDetailsFragment.isUpdate = false; } } diff --git a/lib/ui/screens/items_for_sale/fragments/item_review_fragment.dart b/lib/ui/screens/items_for_sale/fragments/item_review_fragment.dart index 0b02658..190460e 100644 --- a/lib/ui/screens/items_for_sale/fragments/item_review_fragment.dart +++ b/lib/ui/screens/items_for_sale/fragments/item_review_fragment.dart @@ -26,11 +26,13 @@ class ItemReviewFragment extends StatefulWidget { class _ItemReviewFragmentState extends State { ItemReviewModel? itemReviewModel; + late bool isUpdate; @override void initState() { itemReviewModel = AddItemDetailsFragment.itemReviewModel; itemReviewModel!.selectedSaleCategory = SelectCategoryFragment.selectedSaleCategory; + isUpdate = AddItemDetailsFragment.isUpdate; super.initState(); } diff --git a/pubspec.yaml b/pubspec.yaml index bba295d..9fb50ac 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -128,6 +128,7 @@ flutter: - assets/audio/ - assets/images/ - assets/images/worklist/ + - assets/images/services_icons/ - assets/images/login/ - assets/icons/chat/ - assets/images/logos/ From 8ba3dcf43bf1f35b6e734811bc3790919e0a6862 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 10 Nov 2022 16:00:55 +0300 Subject: [PATCH 05/62] Chat Fixes & Favorite Api Implementation --- assets/icons/chat/doc.svg | 54 ++ assets/icons/chat/ppt.svg | 51 ++ assets/icons/chat/txt.svg | 51 ++ assets/icons/chat/xls.svg | 53 ++ assets/icons/chat/zip.svg | 51 ++ lib/api/chat/chat_provider_model.dart | 461 +++++++++++++++--- lib/classes/colors.dart | 1 + lib/classes/consts.dart | 9 +- lib/extensions/string_extensions.dart | 2 +- ...t => get_single_user_chat_list_model.dart} | 77 ++- ...e_user_favotire_unfavorite_chat_model.dart | 53 ++ lib/ui/chat/chat_bubble.dart | 85 ++-- lib/ui/chat/chat_detailed_screen.dart | 306 +++++++++--- lib/ui/chat/chat_home.dart | 121 +++-- .../search_employee_bottom_sheet.dart | 88 +++- lib/widgets/image_picker.dart | 9 +- pubspec.yaml | 4 + 17 files changed, 1251 insertions(+), 225 deletions(-) create mode 100644 assets/icons/chat/doc.svg create mode 100644 assets/icons/chat/ppt.svg create mode 100644 assets/icons/chat/txt.svg create mode 100644 assets/icons/chat/xls.svg create mode 100644 assets/icons/chat/zip.svg rename lib/models/chat/{get_single_user_chat_list_Model.dart => get_single_user_chat_list_model.dart} (58%) create mode 100644 lib/models/chat/make_user_favotire_unfavorite_chat_model.dart diff --git a/assets/icons/chat/doc.svg b/assets/icons/chat/doc.svg new file mode 100644 index 0000000..1f678df --- /dev/null +++ b/assets/icons/chat/doc.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/chat/ppt.svg b/assets/icons/chat/ppt.svg new file mode 100644 index 0000000..5134010 --- /dev/null +++ b/assets/icons/chat/ppt.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/chat/txt.svg b/assets/icons/chat/txt.svg new file mode 100644 index 0000000..bbaf693 --- /dev/null +++ b/assets/icons/chat/txt.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/chat/xls.svg b/assets/icons/chat/xls.svg new file mode 100644 index 0000000..325f974 --- /dev/null +++ b/assets/icons/chat/xls.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/chat/zip.svg b/assets/icons/chat/zip.svg new file mode 100644 index 0000000..9aaaf6b --- /dev/null +++ b/assets/icons/chat/zip.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index bcb748c..b3f37ab 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -1,8 +1,9 @@ import 'dart:convert'; - +import 'dart:io'; +import 'dart:math'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; -import 'package:fluttertoast/fluttertoast.dart'; import 'package:http/http.dart'; import 'package:logging/logging.dart'; import 'package:mohem_flutter_app/api/api_client.dart'; @@ -10,11 +11,14 @@ import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; -import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_Model.dart'; +import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart'; import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as login; -import 'package:shared_preferences/shared_preferences.dart'; +import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; +import 'package:mohem_flutter_app/widgets/image_picker.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:signalr_netcore/signalr_client.dart'; import 'package:logger/logger.dart' as L; +import 'package:uuid/uuid.dart'; class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List userChatHistory = []; @@ -22,8 +26,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { late HubConnection hubConnection; L.Logger logger = L.Logger(); TextEditingController message = TextEditingController(); - ScrollController scrollController = ScrollController(); bool isLoading = true; + bool isChatScreenActive = false; + late File selectedFile; + bool isFileSelected = false; + String sFileType = ""; + bool isMsgReply = false; + List repliedMsg = []; + int paginationVal = 0; Future getUserAutoLoginToken() async { String userName = AppState().memberInformationList!.eMPLOYEEEMAILADDRESS!.split("@").first.toString(); @@ -40,9 +50,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { token: AppState().chatDetails!.response!.token, ); return searchUserJsonModel(response.body); - logger.d(response.body); - isLoading = false; - notifyListeners(); } List searchUserJsonModel(String str) => List.from(json.decode(str).map((x) => ChatUser.fromJson(x))); @@ -52,25 +59,52 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatRecentUrl}", token: AppState().chatDetails!.response!.token, ); + + logger.d(AppState().chatDetails!.response!.token); ChatUserModel recentChat = userToList(response.body); + + Response favRes = await ApiClient().getJsonForResponse( + "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatFavoriteUsers}${AppState().chatDetails!.response!.id}", + token: AppState().chatDetails!.response!.token, + ); + print("============================== Fav Response ====================================="); + ChatUserModel favUsersList = userToList(favRes.body); + for (var user in recentChat.response!) { + for (var favUser in favUsersList.response!) { + logger.d(favUser.isFav); + if (user.id == favUser.id) { + user.isFav = favUser.isFav; + } + } + } + pChatHistory = recentChat.response; searchedChats = pChatHistory; isLoading = false; notifyListeners(); } - void getSingleUserChatHistory({required String senderUID, required int receiverUID, required String pagination}) async { + void getSingleUserChatHistory({required String senderUID, required int receiverUID, required bool loadMore}) async { isLoading = true; + if (!loadMore) paginationVal = 0; + logger.d(paginationVal); + isChatScreenActive = true; Response response = await ApiClient().getJsonForResponse( - "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$pagination", + "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal", token: AppState().chatDetails!.response!.token, ); - logger.d(response.statusCode); - print(response.body); + + logger.d(response.body); if (response.statusCode == 204) { - userChatHistory = []; + if (!loadMore) userChatHistory = []; + Utils.showToast("No More Data To Load"); } else { - userChatHistory = getSingleUserChatModel(response.body); + if (loadMore) { + List temp = getSingleUserChatModel(response.body); + userChatHistory.insertAll(0, temp); + } else { + userChatHistory = getSingleUserChatModel(response.body); + } } isLoading = false; notifyListeners(); @@ -80,6 +114,23 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ChatUserModel userToList(String str) => ChatUserModel.fromJson(json.decode(str)); + Future uploadAttachments(String userId, File file) async { + dynamic result; + dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatMediaImageUploadUrl}')); + request.fields.addAll({'userId': userId, 'fileSource': '1'}); + request.files.add(await MultipartFile.fromPath('files', file.path)); + request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'}); + try { + StreamedResponse response = await request.send(); + if (response.statusCode == 200) { + result = jsonDecode(await response.stream.bytesToString()); + } else { + result = []; + } + } catch (e) {} + return result; + } + Future buildHubConnection() async { HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); hubConnection = await HubConnectionBuilder() @@ -113,7 +164,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { hubConnection.on("OnUserTypingAsync", onUserTyping); // hubConnection.on("OnUserCountAsync", userCountAsync); // hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); - // hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); + hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); } else { hubConnection.on("OnUpdateUserStatusAsync", changeStatus); @@ -219,7 +270,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } userChatHistory.add(data.first); notifyListeners(); - scrollDown(); + logger.d(isChatScreenActive); + // if (isChatScreenActive) scrollDown(); } void onUserTyping(List? parameters) { @@ -228,7 +280,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { for (ChatUser user in searchedChats!) { if (user.id == parameters![1] && parameters[0] == true) { user.isTyping = parameters[0] as bool?; - Future.delayed( const Duration(seconds: 2), () { @@ -241,12 +292,122 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } - void sendChatMessage(String chatMessage, int targetUserId, String targetUserName) async { - if (chatMessage == null || chatMessage.isEmpty) { - return; + int getFileType(String value) { + switch (value) { + case ".pdf": + return 1; + case ".png": + return 3; + case ".txt": + return 5; + case ".jpg": + return 12; + case ".jpeg": + return 4; + case ".xls": + return 7; + case ".xlsx": + return 7; + case ".doc": + return 6; + case ".docx": + return 6; + case ".ppt": + return 8; + case ".pptx": + return 8; + case ".zip": + return 2; + case ".rar": + return 2; + default: + return 0; } + } - var contain = searchedChats!.where((ChatUser element) => element.id == targetUserId); + String getFileTypeDescription(String value) { + switch (value) { + case ".pdf": + return "application/pdf"; + case ".png": + return "image/png"; + case ".txt": + return "text/plain"; + case ".jpg": + return "image/jpg"; + case ".jpeg": + return "image/jpeg"; + case ".ppt": + return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; + case ".pptx": + return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; + case ".doc": + return "application/vnd.openxmlformats-officedocument.wordprocessingm"; + case ".docx": + return "application/vnd.openxmlformats-officedocument.wordprocessingm"; + case ".xls": + return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + case ".xlsx": + return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + case ".zip": + return "application/octet-stream"; + case ".rar": + return "application/octet-stream"; + default: + return ""; + } + } + + // void scrollDown() { + // scrollController.animateTo( + // scrollController.position.maxScrollExtent + 100, + // curve: Curves.easeOut, + // duration: const Duration(milliseconds: 300), + // ); + // notifyListeners(); + // } + + Future sendChatToServer( + {required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { + Uuid uuid = const Uuid(); + SingleUserChatModel data = SingleUserChatModel( + chatEventId: chatEventId, + chatSource: 1, + contant: message.text, + contantNo: uuid.v4(), + conversationId: uuid.v4(), + createdDate: DateTime.now(), + currentUserId: AppState().chatDetails!.response!.id, + currentUserName: AppState().chatDetails!.response!.userName, + targetUserId: targetUserId, + targetUserName: targetUserName, + isReplied: false, + fileTypeId: fileTypeId, + userChatReplyResponse: isReply ? UserChatReplyResponse.fromJson(repliedMsg.first.toJson()) : null, + fileTypeResponse: isAttachment + ? FileTypeResponse( + fileTypeId: fileTypeId, + fileTypeName: getFileType(getFileExtension(selectedFile.path).toString()), + fileKind: getFileExtension(selectedFile.path), + fileName: selectedFile.path.split("/").last, + fileTypeDescription: getFileTypeDescription(getFileExtension(selectedFile.path).toString()), + ) + : null, + ); + String chatData = + '{"contant":"${message.text}","contantNo":"${uuid.v4()}","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"${uuid.v4()}"}'; + await hubConnection.invoke("AddChatUserAsync", args: [json.decode(chatData)]); + userChatHistory.add(data); + isFileSelected = false; + isMsgReply = false; + sFileType = ""; + message.clear(); + notifyListeners(); + // scrollDown(); + } + + void sendChatMessage(int targetUserId, String targetUserName) async { + dynamic contain = searchedChats!.where((ChatUser element) => element.id == targetUserId); if (contain.isEmpty) { searchedChats!.add( ChatUser( @@ -254,51 +415,233 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { userName: targetUserName, ), ); + notifyListeners(); + } + if (!isFileSelected && !isMsgReply) { + logger.d("Normal Text Message"); + if (message.text == null || message.text.isEmpty) { + return; + } + sendChatToServer(chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: false, chatReplyId: null, isReply: false); + } + if (isFileSelected && !isMsgReply) { + logger.d("Normal Attachment Message"); + dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); + String? ext = getFileExtension(selectedFile.path); + sendChatToServer(chatEventId: 2, fileTypeId: getFileType(ext.toString()), targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: true, chatReplyId: null, isReply: false); + } + if (!isFileSelected && isMsgReply) { + logger.d("Normal Text Message With Reply"); + if (message.text == null || message.text.isEmpty) { + return; + } + sendChatToServer( + chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, chatReplyId: repliedMsg.first.userChatHistoryId, isAttachment: false, isReply: true); +//chatReplyId + } + if (isFileSelected && isMsgReply) { + logger.d("Attachment Message With Reply"); + logger.d(repliedMsg.first.userChatHistoryId); + dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); + String? ext = getFileExtension(selectedFile.path); + sendChatToServer( + chatEventId: 2, + fileTypeId: getFileType(ext.toString()), + targetUserId: targetUserId, + targetUserName: targetUserName, + isAttachment: true, + chatReplyId: repliedMsg.first.userChatHistoryId, + isReply: true); } - String chatData = - '{"contant":"$chatMessage","contantNo":"8a129295-36d7-7185-5d34-cc4eec7bcba4","chatEventId":1,"fileTypeId":null,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"conversationId":"715f8b13-96ee-cd36-cb07-5a982a219982"}'; - await hubConnection.invoke("AddChatUserAsync", args: [json.decode(chatData)]); - userChatHistory.add( - SingleUserChatModel( - chatEventId: 1, - chatSource: 1, - contant: chatMessage, - contantNo: "8a129295-36d7-7185-5d34-cc4eec7bcba4", - conversationId: "715f8b13-96ee-cd36-cb07-5a982a219982", - createdDate: DateTime.now(), - currentUserId: AppState().chatDetails!.response!.id, - currentUserName: AppState().chatDetails!.response!.userName, - targetUserId: targetUserId, - targetUserName: targetUserName, - ), - ); - message.clear(); + // dynamic contain = searchedChats!.where((ChatUser element) => element.id == targetUserId); + // if (contain.isEmpty) { + // searchedChats!.add( + // ChatUser( + // id: targetUserId, + // userName: targetUserName, + // ), + // ); + // notifyListeners(); + // } + // Uuid uuid = const Uuid(); + // dynamic fileID = fileUploadResponse.isEmpty ? null : getFileType(chatMessage); + // SingleUserChatModel data = SingleUserChatModel( + // chatEventId: fileUploadResponse.isEmpty ? 1 : 2, + // chatSource: 1, + // contant: chatMessage, + // contantNo: uuid.v4(), + // conversationId: uuid.v4(), + // createdDate: DateTime.now(), + // currentUserId: AppState().chatDetails!.response!.id, + // currentUserName: AppState().chatDetails!.response!.userName, + // targetUserId: targetUserId, + // targetUserName: targetUserName, + // fileTypeId: fileID, + // isReplied: false, + // // fileTypeResponse: FileTypeResponse( + // // fileTypeId: 0, + // // fileTypeDescription: fileUploadResponse.isEmpty ? null : fileUploadResponse.first["filePath"], + // // fileName: fileUploadResponse.isEmpty ? null : fileUploadResponse.first["filePath"], + // // fileKind: "image", + // // fileTypeName: fileUploadResponse.isEmpty ? null : fileUploadResponse.first["filePath"].toString().split(".").last), + // ); + // + // String chatData = + // '{"contant":"$chatMessage","contantNo":"${uuid.v4()}","chatEventId":${fileUploadResponse.isEmpty ? 1 : 2},"fileTypeId": $fileID,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"conversationId":"${uuid.v4()}"}'; + // await hubConnection.invoke("AddChatUserAsync", args: [json.decode(chatData)]); + // userChatHistory.add(data); + // message.clear(); + // notifyListeners(); + // scrollDown(); + } + + void scrollListener() { + if (userChatHistory.length < paginationVal) { + print("Get New Data"); + } + } + + void selectImageToUpload(BuildContext context) { + ImageOptions.showImageOptionsNew(context, true, (String image, File file) async { + if (checkFileSize(file.path)) { + selectedFile = file; + isFileSelected = true; + sFileType = getFileExtension(file.path)!; + message.text = file.path.split("/").last; + Navigator.of(context).pop(); + } else { + Utils.showToast("Max 1 mb size is allowed to upload"); + } + //Utils.showLoading(context); + notifyListeners(); + //Utils.hideLoading(context); + // Utils.showLoading(context); + // await m.uploadAttachments(AppState().chatDetails!.response!.id.toString(), file).then((value) { + // if (value == null) { + // m.logger.d("Returned EMPTY"); + // } else { + // m.sendChatMessage(value.isEmpty ? m.message.text : value.first["filePath"], userDetails["targetUser"].id, userDetails["targetUser"].userName, value); + // } + // }); + // Utils.hideLoading(context); + }); + } + + void removeAttachment() { + isFileSelected = false; + sFileType = ""; + message.text = ''; notifyListeners(); - scrollDown(); } - void scrollDown() { - scrollController.animateTo( - scrollController.position.maxScrollExtent + 100, - curve: Curves.easeOut, - duration: const Duration(milliseconds: 300), - ); + String? getFileExtension(String fileName) { + try { + return "." + fileName.split('.').last; + } catch (e) { + return null; + } + } + + bool checkFileSize(String path) { + int fileSizeLimit = 1024; + File f = File(path); + double fileSizeInKB = f.lengthSync() / 1024; + double fileSizeInMB = fileSizeInKB / 1024; + if (fileSizeInKB > fileSizeLimit) { + return false; + } else { + return true; + } + } + + String getType(String type) { + switch (type) { + case ".pdf": + return "assets/images/pdf.svg"; + case ".png": + return "assets/images/png.svg"; + case ".txt": + return "assets/icons/chat/txt.svg"; + case ".jpg": + return "assets/images/jpg.svg"; + case ".jpeg": + return "assets/images/jpg.svg"; + case ".xls": + return "assets/icons/chat/xls.svg"; + case ".xlsx": + return "assets/icons/chat/xls.svg"; + case ".doc": + return "assets/icons/chat/doc.svg"; + case ".docx": + return "assets/icons/chat/doc.svg"; + case ".ppt": + return "assets/icons/chat/ppt.svg"; + case ".pptx": + return "assets/icons/chat/ppt.svg"; + case ".zip": + return "assets/icons/chat/zip.svg"; + case ".rar": + return "assets/icons/chat/zip.svg"; + default: + return "assets/images/thumb.svg"; + } + } + + void chatReply(SingleUserChatModel data) { + repliedMsg = []; + data.isReplied = true; + isMsgReply = true; + repliedMsg.add(data); + notifyListeners(); + } + + void closeMe() { + repliedMsg = []; + isMsgReply = false; + notifyListeners(); + } + + String dateFormte(DateTime data) { + DateFormat f = new DateFormat('hh:mm a dd MMM yyyy'); + f.format(data); + return f.format(data); + } + + Future favoriteUser({required int userID, required int targetUserID}) async { + Response response = + await ApiClient().postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token); + fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); + if (favoriteChatUser.response != null) { + for (var user in searchedChats!) { + if (user.id == favoriteChatUser.response!.targetUserId!) { + user.isFav = favoriteChatUser.response!.isFav; + } + } + } notifyListeners(); } -// void _scrollListener() { -// if (scrollController.position.extentAfter.toInt() <= 0 && canCallApi) { -// if (userChatHistory.length < _ayatTangheemTypeMapped.totalItemsCount) { -// currentPageNo++; -// if (widget.tangheemQuery == null) { -// getTangheemData(); -// } else { -// getTangheemDataByKeyword(); -// } -// } -// canCallApi = false; -// } -// } + Future unFavoriteUser({required int userID, required int targetUserID}) async { + Response response = await ApiClient() + .postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/deleteFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token); + fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); + if (favoriteChatUser.response != null) { + for (var user in searchedChats!) { + if (user.id == favoriteChatUser.response!.targetUserId!) { + user.isFav = favoriteChatUser.response!.isFav; + } + } + } + notifyListeners(); + } + void clearSelections() { + isChatScreenActive = false; + paginationVal = 0; + message.text = ''; + isFileSelected = false; + repliedMsg = []; + sFileType = ""; + } } diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart index e670bbc..5e390c7 100644 --- a/lib/classes/colors.dart +++ b/lib/classes/colors.dart @@ -58,4 +58,5 @@ class MyColors { static const Color greyC4Color = Color(0xffC4C4C4); static const Color grey35Color = Color(0xff535353); static const Color grey9DColor = Color(0xff9D9D9D); + static const Color grey71Color = Color(0xff717171); } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index e82c30a..c98d136 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/"; @@ -16,7 +16,12 @@ class ApiConsts { static String chatSearchMember = "user/getUserWithStatusAndFavAsync/"; static String chatRecentUrl = "UserChatHistory/getchathistorybyuserid"; //For a Mem static String chatSingleUserHistoryUrl = "UserChatHistory/GetUserChatHistory"; + static String chatMediaImageUploadUrl = "shared/upload"; + static String chatFavoriteUsers = "FavUser/getFavUserById/"; + //https://apiderichat.hmg.com/api/FavUser/getFavUserById/42062 +//https://apiderichat.hmg.com/api/shared/upload // 42062 is CurrentUserID and 36745 is targetUserID and 0 is For Pagination + // static String chatSearchMember = "https://apiderichat.hmg.com/api/user/getUserWithStatusAndFavAsync/aamir.muhammad/36239"; } diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 37f41ae..9af8f2b 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -18,7 +18,7 @@ extension EmailValidator on String { Widget toText10({Color? color, bool isBold = false, int? maxlines, FontStyle? fontStyle}) => Text( this, - //maxLines: maxlines, + maxLines: maxlines, style: TextStyle(fontSize: 10, fontStyle: fontStyle ?? FontStyle.normal, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), ); diff --git a/lib/models/chat/get_single_user_chat_list_Model.dart b/lib/models/chat/get_single_user_chat_list_model.dart similarity index 58% rename from lib/models/chat/get_single_user_chat_list_Model.dart rename to lib/models/chat/get_single_user_chat_list_model.dart index 0e3cb22..6a35f0e 100644 --- a/lib/models/chat/get_single_user_chat_list_Model.dart +++ b/lib/models/chat/get_single_user_chat_list_model.dart @@ -1,3 +1,9 @@ +import 'dart:convert'; + +List singleUserChatModelFromJson(String str) => List.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); + +String singleUserChatModelToJson(List data) => json.encode(List.from(data.map((x) => x.toJson()))); + class SingleUserChatModel { SingleUserChatModel({ this.userChatHistoryId, @@ -19,6 +25,7 @@ class SingleUserChatModel { this.conversationId, this.fileTypeResponse, this.userChatReplyResponse, + this.isReplied, }); int? userChatHistoryId; @@ -29,17 +36,18 @@ class SingleUserChatModel { String? currentUserName; int? targetUserId; String? targetUserName; - dynamic encryptedTargetUserId; - dynamic encryptedTargetUserName; + String? encryptedTargetUserId; + String? encryptedTargetUserName; int? chatEventId; - dynamic fileTypeId; + dynamic? fileTypeId; bool? isSeen; bool? isDelivered; DateTime? createdDate; int? chatSource; String? conversationId; FileTypeResponse? fileTypeResponse; - dynamic userChatReplyResponse; + UserChatReplyResponse? userChatReplyResponse; + bool? isReplied; factory SingleUserChatModel.fromJson(Map json) => SingleUserChatModel( userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"], @@ -50,8 +58,8 @@ class SingleUserChatModel { currentUserName: json["currentUserName"] == null ? null : json["currentUserName"], targetUserId: json["targetUserId"] == null ? null : json["targetUserId"], targetUserName: json["targetUserName"] == null ? null : json["targetUserName"], - encryptedTargetUserId: json["encryptedTargetUserId"], - encryptedTargetUserName: json["encryptedTargetUserName"], + encryptedTargetUserId: json["encryptedTargetUserId"] == null ? null : json["encryptedTargetUserId"], + encryptedTargetUserName: json["encryptedTargetUserName"] == null ? null : json["encryptedTargetUserName"], chatEventId: json["chatEventId"] == null ? null : json["chatEventId"], fileTypeId: json["fileTypeId"], isSeen: json["isSeen"] == null ? null : json["isSeen"], @@ -60,7 +68,8 @@ class SingleUserChatModel { chatSource: json["chatSource"] == null ? null : json["chatSource"], conversationId: json["conversationId"] == null ? null : json["conversationId"], fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]), - userChatReplyResponse: json["userChatReplyResponse"], + userChatReplyResponse: json["userChatReplyResponse"] == null ? null : UserChatReplyResponse.fromJson(json["userChatReplyResponse"]), + isReplied: false, ); Map toJson() => { @@ -72,8 +81,8 @@ class SingleUserChatModel { "currentUserName": currentUserName == null ? null : currentUserName, "targetUserId": targetUserId == null ? null : targetUserId, "targetUserName": targetUserName == null ? null : targetUserName, - "encryptedTargetUserId": encryptedTargetUserId, - "encryptedTargetUserName": encryptedTargetUserName, + "encryptedTargetUserId": encryptedTargetUserId == null ? null : encryptedTargetUserId, + "encryptedTargetUserName": encryptedTargetUserName == null ? null : encryptedTargetUserName, "chatEventId": chatEventId == null ? null : chatEventId, "fileTypeId": fileTypeId, "isSeen": isSeen == null ? null : isSeen, @@ -82,7 +91,7 @@ class SingleUserChatModel { "chatSource": chatSource == null ? null : chatSource, "conversationId": conversationId == null ? null : conversationId, "fileTypeResponse": fileTypeResponse == null ? null : fileTypeResponse!.toJson(), - "userChatReplyResponse": userChatReplyResponse, + "userChatReplyResponse": userChatReplyResponse == null ? null : userChatReplyResponse!.toJson(), }; } @@ -117,3 +126,51 @@ class FileTypeResponse { "fileName": fileName, }; } + +class UserChatReplyResponse { + UserChatReplyResponse({ + this.userChatHistoryId, + this.chatEventId, + this.contant, + this.contantNo, + this.fileTypeId, + this.createdDate, + this.targetUserId, + this.targetUserName, + this.fileTypeResponse, + }); + + int? userChatHistoryId; + int? chatEventId; + String? contant; + String? contantNo; + dynamic? fileTypeId; + DateTime? createdDate; + int? targetUserId; + String? targetUserName; + FileTypeResponse? fileTypeResponse; + + factory UserChatReplyResponse.fromJson(Map json) => UserChatReplyResponse( + userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"], + chatEventId: json["chatEventId"] == null ? null : json["chatEventId"], + contant: json["contant"] == null ? null : json["contant"], + contantNo: json["contantNo"] == null ? null : json["contantNo"], + fileTypeId: json["fileTypeId"], + createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]), + targetUserId: json["targetUserId"] == null ? null : json["targetUserId"], + targetUserName: json["targetUserName"] == null ? null : json["targetUserName"], + fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]), + ); + + Map toJson() => { + "userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId, + "chatEventId": chatEventId == null ? null : chatEventId, + "contant": contant == null ? null : contant, + "contantNo": contantNo == null ? null : contantNo, + "fileTypeId": fileTypeId, + "createdDate": createdDate == null ? null : createdDate!.toIso8601String(), + "targetUserId": targetUserId == null ? null : targetUserId, + "targetUserName": targetUserName == null ? null : targetUserName, + "fileTypeResponse": fileTypeResponse == null ? null : fileTypeResponse!.toJson(), + }; +} diff --git a/lib/models/chat/make_user_favotire_unfavorite_chat_model.dart b/lib/models/chat/make_user_favotire_unfavorite_chat_model.dart new file mode 100644 index 0000000..64eb6b1 --- /dev/null +++ b/lib/models/chat/make_user_favotire_unfavorite_chat_model.dart @@ -0,0 +1,53 @@ +// To parse this JSON data, do +// +// final favoriteChatUser = favoriteChatUserFromJson(jsonString); + +import 'dart:convert'; + +class FavoriteChatUser { + FavoriteChatUser({ + this.response, + this.errorResponses, + }); + + Response? response; + dynamic? errorResponses; + + factory FavoriteChatUser.fromRawJson(String str) => FavoriteChatUser.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory FavoriteChatUser.fromJson(Map json) => FavoriteChatUser( + response: json["response"] == null ? null : Response.fromJson(json["response"]), + errorResponses: json["errorResponses"], + ); + + Map toJson() => { + "response": response == null ? null : response!.toJson(), + "errorResponses": errorResponses, + }; +} + +class Response { + Response({ + this.targetUserId, + this.isFav, + }); + + int? targetUserId; + bool? isFav; + + factory Response.fromRawJson(String str) => Response.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Response.fromJson(Map json) => Response( + targetUserId: json["targetUserId"] == null ? null : json["targetUserId"], + isFav: json["isFav"] == null ? null : json["isFav"], + ); + + Map toJson() => { + "targetUserId": targetUserId == null ? null : targetUserId, + "isFav": isFav == null ? null : isFav, + }; +} diff --git a/lib/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index 74d2e2b..1e8aec4 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -2,82 +2,105 @@ import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/classes/colors.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:sizer/sizer.dart'; class ChatBubble extends StatelessWidget { const ChatBubble( {Key? key, required this.text, + required this.replyText, required this.isCurrentUser, required this.isSeen, required this.isDelivered, - required this.dateTime}) + required this.dateTime, + required this.isReplied, + required this.userName}) : super(key: key); final String text; + final String replyText; final bool isCurrentUser; final bool isSeen; final bool isDelivered; final String dateTime; + final bool isReplied; + final String userName; @override Widget build(BuildContext context) { return Padding( - // asymmetric padding - padding: EdgeInsets.fromLTRB( - isCurrentUser ? 64.0 : 16.0, - 4, - isCurrentUser ? 16.0 : 64.0, - 4, - ), + // padding: EdgeInsets.zero, + padding: EdgeInsets.only(left: isCurrentUser ? 110 : 20, right: isCurrentUser ? 20 : 110, bottom: 9), + child: Align( - // align the child within the container alignment: isCurrentUser ? Alignment.centerRight : Alignment.centerLeft, child: DecoratedBox( - // chat bubble decoration decoration: BoxDecoration( color: Colors.white, gradient: isCurrentUser ? null - : LinearGradient( + : const LinearGradient( transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomLeft, - colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ], + ), borderRadius: BorderRadius.circular(10), ), child: Padding( - padding: const EdgeInsets.all(12), + padding: EdgeInsets.only(top: isReplied ? 8 : 5, right:8, left: 8, bottom: 5), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - text.toText12( - color: - isCurrentUser ? MyColors.grey57Color : MyColors.white), - 8.height, + if (isReplied) + ClipRRect( + borderRadius: BorderRadius.circular(5.0), + child: Container( + decoration: BoxDecoration( + border: Border( + left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white), + ), + color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30), + ), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + (userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5), + replyText + .toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4) + .paddingOnly(right: 5, top: 5, bottom: 8, left: 5), + ], + ), + ), + ], + ), + ), + ), + if (isReplied) 8.height, + text.toText12(color: isCurrentUser ? MyColors.grey57Color : MyColors.white), + Row( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, children: [ - dateTime.toText12( - color: isCurrentUser - ? MyColors.grey41Color.withOpacity(.5) - : Colors.white.withOpacity(0.7)), + dateTime.toText12(color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : Colors.white.withOpacity(0.7)), if (isCurrentUser) 5.width, if (isCurrentUser) Icon( - isDelivered - ? Icons.done_all - : Icons.done_all, - color: isSeen - ? MyColors.textMixColor - : MyColors.grey9DColor, + isDelivered ? Icons.done_all : Icons.done_all, + color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor, size: 14, - ) + ), ], ), + ], ), ), diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 5f2fa97..d2d3598 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -1,4 +1,6 @@ import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -6,27 +8,53 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/api/chat/chat_provider_model.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/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.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/ui/chat/chat_bubble.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; +import 'package:mohem_flutter_app/widgets/image_picker.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:provider/provider.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; +import 'package:sizer/sizer.dart'; +import 'package:swipe_to/swipe_to.dart'; class ChatDetailScreen extends StatelessWidget { + ChatDetailScreen({Key? key}) : super(key: key); dynamic userDetails; late ChatProviderModel data; + ScrollController scrollController = ScrollController(); + RefreshController _refreshController = RefreshController(initialRefresh: false); - ChatDetailScreen({Key? key}) : super(key: key); + void onRefresh() async { + print("Refresh Triggered"); + await Future.delayed(Duration(milliseconds: 1000)); + if (userDetails != null) { + data.paginationVal = data.paginationVal + 10; + data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true); + } + _refreshController.refreshCompleted(); + } @override Widget build(BuildContext context) { - userDetails = ModalRoute - .of(context)! - .settings - .arguments; + userDetails = ModalRoute.of(context)!.settings.arguments; data = Provider.of(context, listen: false); - data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, pagination: "0"); - Timer(const Duration(seconds: 1), () => data.scrollDown()); + if (userDetails != null) data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: false); + // + // if (userDetails != null) { + // scrollController.addListener(() { + // if (scrollController.position.minScrollExtent == scrollController.offset) { + // data.paginationVal++; + // data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true); + // } + // }); + // } + return Scaffold( backgroundColor: const Color(0xFFF8F8F8), appBar: AppBarWidget(context, title: userDetails["targetUser"].userName, showHomeButton: false, image: userDetails["targetUser"].image), @@ -35,73 +63,217 @@ class ChatDetailScreen extends StatelessWidget { return (m.isLoading ? ChatHomeShimmer() : Column( - children: [ - Expanded( - child: ListView.builder( - controller: m.scrollController, - shrinkWrap: true, - itemCount: m.userChatHistory.length, - padding: const EdgeInsets.symmetric(vertical: 10), - itemBuilder: (BuildContext context, int i) { - i == 0 ? m.logger.d(m.userChatHistory.length) : ""; - return ChatBubble( - text: m.userChatHistory[i].contant.toString(), - isSeen: m.userChatHistory[i].isSeen == true ? true : false, - isCurrentUser: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id ? true : false, - isDelivered: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id && m.userChatHistory[i].isDelivered == true ? true : false, - dateTime: m.userChatHistory[i].createdDate.toString(), - ); - }, - ), - ), - Card( - margin: EdgeInsets.zero, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: TextField( - controller: m.message, - decoration: InputDecoration( - hintText: LocaleKeys.typeheretoreply.tr(), - hintStyle: const TextStyle(color: MyColors.grey98Color), - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - errorBorder: InputBorder.none, - disabledBorder: InputBorder.none, - contentPadding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15), - suffixIcon: SizedBox( - width: 100, - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - IconButton( - icon: const Icon( - Icons.attach_file_rounded, - size: 27, - color: MyColors.lightGreenColor, + children: [ + Expanded( + flex: 2, + child: SmartRefresher( + enablePullDown: true, + enablePullUp: false, + header: const MaterialClassicHeader( + color: MyColors.gradiantEndColor, + ), + controller: _refreshController, + onRefresh: onRefresh, + child: ListView.builder( + controller: scrollController, + shrinkWrap: true, + itemCount: m.userChatHistory.length, + padding: EdgeInsets.zero, + itemBuilder: (BuildContext context, int i) { + return GestureDetector( + onTap: () { + m.logger.d(jsonEncode(m.userChatHistory[i])); + m.logger.d(jsonEncode(m.userChatHistory.length)); + }, + child: SwipeTo( + iconColor: MyColors.lightGreenColor, + child: ChatBubble( + text: m.userChatHistory[i].contant.toString(), + replyText: m.userChatHistory[i].userChatReplyResponse != null ? m.userChatHistory[i].userChatReplyResponse!.contant.toString() : "", + isSeen: m.userChatHistory[i].isSeen == true ? true : false, + isCurrentUser: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id ? true : false, + isDelivered: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id && m.userChatHistory[i].isDelivered == true ? true : false, + dateTime: m.dateFormte(m.userChatHistory[i].createdDate!), + isReplied: m.userChatHistory[i].userChatReplyResponse != null ? true : false, + userName: AppState().chatDetails!.response!.userName == m.userChatHistory[i].currentUserName.toString() ? "You" : m.userChatHistory[i].currentUserName.toString(), + ), + onRightSwipe: () { + m.chatReply(m.userChatHistory[i]); + }, + ), + ); + }, + ), + ), + ), + if (m.isMsgReply) + Row( + children: [ + Container( + height: 80, + color: MyColors.textMixColor, + width: 6, + ), + Expanded( + child: Container( + height: 80, + color: MyColors.black.withOpacity(0.10), + child: ListTile( + title: (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString() ? "You" : m.repliedMsg.first.currentUserName.toString()) + .toText14(color: MyColors.lightGreenColor), + subtitle: (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(color: MyColors.white, maxLine: 2), + trailing: GestureDetector( + onTap: m.closeMe, + child: Container( + decoration: BoxDecoration( + color: MyColors.white.withOpacity(0.5), + borderRadius: const BorderRadius.all( + Radius.circular(20), + ), + ), + child: const Icon( + Icons.close, + size: 23, + color: MyColors.white, + ), + ), + ), ), - onPressed: () {}, ), - IconButton( - icon: SvgPicture.asset( - "assets/icons/chat/chat_send_icon.svg", - height: 26, - width: 35, + ), + ], + ), + if (m.isFileSelected && m.sFileType == ".png" || m.sFileType == ".jpeg" || m.sFileType == ".jpg") + Card( + margin: EdgeInsets.zero, + elevation: 0, + child: Padding( + padding: const EdgeInsets.only(left: 20.0, right: 20, top: 20, bottom: 0), + child: Card( + margin: EdgeInsets.zero, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(0.0), + ), + elevation: 0, + child: Container( + height: 200, + decoration: BoxDecoration( + image: DecorationImage( + image: FileImage( + m.selectedFile, + ), + fit: BoxFit.cover), + borderRadius: const BorderRadius.all( + Radius.circular(0), + ), ), - onPressed: () { - m.sendChatMessage(m.message.text, userDetails["targetUser"].id, userDetails["targetUser"].userName); - }, + child: const SizedBox( + width: double.infinity, + height: 200, + ), + ), + ), + ), + ), + Card( + margin: EdgeInsets.zero, + child: TextField( + controller: m.message, + decoration: InputDecoration( + hintText: m.isFileSelected ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(), + hintStyle: TextStyle(color: m.isFileSelected ? MyColors.darkTextColor : MyColors.grey98Color, fontSize: 14), + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + errorBorder: InputBorder.none, + disabledBorder: InputBorder.none, + contentPadding: EdgeInsets.only(left: m.sFileType.isNotEmpty ? 10 : 20, right: m.sFileType.isNotEmpty ? 0 : 5, top: 20, bottom: 20), + prefixIcon: m.sFileType.isNotEmpty + ? Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SvgPicture.asset( + m.getType(m.sFileType), + height: 30, + width: 25, + alignment: Alignment.center, + fit: BoxFit.cover, + ).paddingOnly(left: 20), + ], + ) + : null, + suffixIcon: Container( + width: 96, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, // added line + children: [ + if (m.sFileType.isNotEmpty) + IconButton( + padding: EdgeInsets.zero, + alignment: Alignment.centerRight, + icon: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + decoration: const BoxDecoration( + color: MyColors.redA3Color, + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + ), + child: const Icon( + Icons.close, + size: 15, + color: MyColors.white, + ), + ), + ("Clear").toText11(color: MyColors.redA3Color).paddingOnly(left: 4), + ], + ), + onPressed: () async { + m.removeAttachment(); + }, + ), + if (m.sFileType.isEmpty) + RotationTransition( + turns: const AlwaysStoppedAnimation(45 / 360), + child: IconButton( + padding: EdgeInsets.zero, + alignment: Alignment.topRight, + icon: const Icon( + Icons.attach_file_rounded, + size: 26, + color: MyColors.grey3AColor, + ), + onPressed: () async { + m.selectImageToUpload(context); + }, + ), + ), + IconButton( + alignment: Alignment.centerRight, + padding: EdgeInsets.zero, + icon: SvgPicture.asset( + "assets/icons/chat/chat_send_icon.svg", + height: 26, + width: 26, + ), + onPressed: () { + m.sendChatMessage(userDetails["targetUser"].id, userDetails["targetUser"].userName); + }, + ) + ], ), - ], + ).paddingOnly(right: 20), ), ), ), - ), - ), - ), - ], - )); + ], + )); }, ), ); diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index f6f8e24..106a4b3 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -8,13 +8,16 @@ import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.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/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_sheet.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:provider/provider.dart'; +import 'package:sizer/sizer.dart'; class ChatHomeScreen extends StatefulWidget { const ChatHomeScreen({Key? key}) : super(key: key); @@ -81,45 +84,92 @@ class _ChatHomeScreenState extends State { if (m.searchedChats != null) ListView.separated( itemCount: m.searchedChats!.length, - padding: const EdgeInsets.only(top: 0), + padding: const EdgeInsets.only(top: 20), shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (BuildContext context, int index) { - return ListTile( - leading: Stack( - children: [ - SvgPicture.asset( - "assets/images/user.svg", - height: 48, - width: 48, - ), - Positioned( - right: 5, - bottom: 1, - child: Container( - width: 10, - height: 10, - decoration: BoxDecoration( - color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, - borderRadius: const BorderRadius.all( - Radius.circular(10), + return SizedBox( + height: 55, + child: ListTile( + leading: Stack( + children: [ + SvgPicture.asset( + "assets/images/user.svg", + height: 48, + width: 48, + ), + Positioned( + right: 5, + bottom: 1, + child: Container( + width: 10, + height: 10, + decoration: BoxDecoration( + color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, + borderRadius: const BorderRadius.all( + Radius.circular(10), + ), ), ), - ), - ) - ], + ) + ], + ), + title: (m.searchedChats![index].userName ?? "").toText14(color: MyColors.darkTextColor), + // subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), + trailing: SizedBox( + width: 60, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + if (m.searchedChats![index].unreadMessageCount! > 0) + Flexible( + child: Container( + padding: EdgeInsets.zero, + alignment: Alignment.centerRight, + width: 18, + height: 18, + decoration: const BoxDecoration( + color: MyColors.redColor, + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + ), + child: (m.searchedChats![index].unreadMessageCount!.toString()) + .toText10( + color: MyColors.white, + ) + .center, + ), + ), + Flexible( + child: IconButton( + alignment: Alignment.centerRight, + padding: EdgeInsets.zero, + icon: Icon(m.searchedChats![index].isFav! ? Icons.star : Icons.star_border), + color: m.searchedChats![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, + onPressed: () { + if (m.searchedChats![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + if (!m.searchedChats![index].isFav!) m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + }, + ), + ) + ], + ), + ), + minVerticalPadding: 0, + onTap: () { + Navigator.pushNamed( + context, + AppRoutes.chatDetailed, + arguments: {"targetUser": m.searchedChats![index]}, + ).then((value) { + m.clearSelections(); + }); + }, + onLongPress: () {}, ), - title: (m.searchedChats![index].userName ?? "").toText14(color: MyColors.darkTextColor), - subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), - trailing: ("Today").toText10(color: MyColors.lightTextColor), - minVerticalPadding: 0, - onTap: () { - Navigator.pushNamed( - context, - AppRoutes.chatDetailed, - arguments: {"targetUser": m.searchedChats![index]}, - ); - }, ); }, separatorBuilder: (BuildContext context, int index) => const Padding( @@ -129,7 +179,6 @@ class _ChatHomeScreenState extends State { ), ), ), - // if (searchedUsersList == null) Utils.getNoChatWidget(context), ], ); }), @@ -156,11 +205,9 @@ class _ChatHomeScreenState extends State { ), ), onPressed: () async { - // var userData = await ChatApiClient() - // .getChatMemberFromSearch("aamir.muhammad", 36239); showMyBottomSheet( context, - callBackFunc: (){}, + callBackFunc: () {}, child: SearchEmployeeBottomSheet( title: LocaleKeys.searchForEmployee.tr(), apiMode: LocaleKeys.delegate.tr(), diff --git a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart index 16942c5..fb14141 100644 --- a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart +++ b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart @@ -183,16 +183,66 @@ class _SearchEmployeeBottomSheetState extends State { if (widget.fromChat) if (chatUsersList != null && widget.fromChat) chatUsersList!.isEmpty - ? Utils.getNoDataWidget(context) + ? Column( + children: [ + 20.height, + Utils.getNoDataWidget(context), + ], + ) : ListView( physics: const BouncingScrollPhysics(), - padding: EdgeInsets.only(top: 0, bottom: 8), - children: [ + padding: const EdgeInsets.only(top: 15,), + children: [ ListView.separated( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemBuilder: (cxt, index) { - return ListTile( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (BuildContext cxt, int index) { + + + + + // return ListTile( + // leading: Stack( + // children: [ + // SvgPicture.asset( + // "assets/images/user.svg", + // height: 48, + // width: 48, + // ), + // Positioned( + // right: 5, + // bottom: 1, + // child: Container( + // width: 10, + // height: 10, + // decoration: BoxDecoration( + // color: chatUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, + // borderRadius: const BorderRadius.all( + // Radius.circular(10), + // ), + // ), + // ), + // ) + // ], + // ), + // title: (chatUsersList![index].userName ?? "").toText14(color: MyColors.darkTextColor), + // // subtitle: (chatUsersList![index].isTyping == true ? "Something is Typing" : "Last message text").toText11(color: MyColors.normalTextColor), + // // trailing: ("Today").toText10(color: MyColors.lightTextColor), + // minVerticalPadding: 0, + // onTap: () { + // Navigator.pop(context); + // Navigator.pushNamed( + // context, + // AppRoutes.chatDetailed, + // arguments: {"targetUser": chatUsersList![index]}, + // ); + // }, + // ); + + + return SizedBox( + height: 55, + child: ListTile( leading: Stack( children: [ SvgPicture.asset( @@ -217,8 +267,6 @@ class _SearchEmployeeBottomSheetState extends State { ], ), title: (chatUsersList![index].userName ?? "").toText14(color: MyColors.darkTextColor), - // subtitle: (chatUsersList![index].isTyping == true ? "Something is Typing" : "Last message text").toText11(color: MyColors.normalTextColor), - // trailing: ("Today").toText10(color: MyColors.lightTextColor), minVerticalPadding: 0, onTap: () { Navigator.pop(context); @@ -228,13 +276,21 @@ class _SearchEmployeeBottomSheetState extends State { arguments: {"targetUser": chatUsersList![index]}, ); }, - ); - }, - separatorBuilder: (BuildContext cxt, int index) => Container( - height: 1, - color: MyColors.borderE3Color, - ), - itemCount: chatUsersList?.length ?? 0), + onLongPress: () {}, + ), + ); + + + + }, + separatorBuilder: (BuildContext context, int index) => const Padding( + padding: EdgeInsets.only(right: 10, left: 70, bottom: 0,top: 0), + child: Divider( + color: Color(0xFFE5E5E5), + ), + ), + itemCount: chatUsersList?.length ?? 0, + ), 12.height, ], ).expanded, diff --git a/lib/widgets/image_picker.dart b/lib/widgets/image_picker.dart index 5e5ac01..9fa0336 100644 --- a/lib/widgets/image_picker.dart +++ b/lib/widgets/image_picker.dart @@ -13,7 +13,7 @@ class ImageOptions { static void showImageOptionsNew(BuildContext context, bool showFilesOption, Function(String, File) image) { showMyBottomSheet( context, - callBackFunc: (){}, + callBackFunc: () {}, child: AttachmentOptions( showFilesOption: showFilesOption, onCameraTap: () async { @@ -43,7 +43,12 @@ class ImageOptions { } }, onFilesTap: () async { - FilePickerResult? result = await FilePicker.platform.pickFiles(); + FilePickerResult? result = await FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: ['jpg', 'jpeg ', 'pdf', 'txt', 'docx', 'doc', 'pptx', 'xlsx', 'png', 'rar', 'zip', 'xls'], + ); + List files = result!.paths.map((path) => File(path!)).toList(); + image(result!.files.first.path.toString(), files.first); }, ), ); diff --git a/pubspec.yaml b/pubspec.yaml index 633edd7..f2fbba8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -85,9 +85,13 @@ dependencies: appinio_swiper: ^1.1.1 expandable: ^5.0.1 + + #Chat signalr_netcore: ^1.3.3 logging: ^1.0.1 + swipe_to: ^1.0.2 + From 67f4fdef289f3d1165d978beea1f9c13c4be44f6 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 10 Nov 2022 16:06:25 +0300 Subject: [PATCH 06/62] Chat Fixes & Favorite Api Implementation --- lib/api/chat/chat_provider_model.dart | 88 +++---------------- lib/classes/consts.dart | 7 +- lib/ui/chat/chat_bubble.dart | 6 +- lib/ui/chat/chat_detailed_screen.dart | 59 ++++--------- lib/ui/chat/chat_home.dart | 4 +- .../search_employee_bottom_sheet.dart | 83 +++++------------ 6 files changed, 56 insertions(+), 191 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index b3f37ab..b85aa85 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -141,20 +141,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ) .build(); hubConnection.onclose( - ({Exception? error}) { - // logger.d(error); - }, + ({Exception? error}) {}, ); hubConnection.onreconnecting( - ({Exception? error}) { - // logger.d(error); - // logger.d("Reconnecting"); - }, + ({Exception? error}) {}, ); hubConnection.onreconnected( - ({String? connectionId}) { - // logger.d("Reconnected"); - }, + ({String? connectionId}) {}, ); if (hubConnection.state != HubConnectionState.Connected) { await hubConnection.start(); @@ -403,7 +396,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { sFileType = ""; message.clear(); notifyListeners(); - // scrollDown(); } void sendChatMessage(int targetUserId, String targetUserName) async { @@ -437,7 +429,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } sendChatToServer( chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, chatReplyId: repliedMsg.first.userChatHistoryId, isAttachment: false, isReply: true); -//chatReplyId } if (isFileSelected && isMsgReply) { logger.d("Attachment Message With Reply"); @@ -445,60 +436,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); String? ext = getFileExtension(selectedFile.path); sendChatToServer( - chatEventId: 2, - fileTypeId: getFileType(ext.toString()), - targetUserId: targetUserId, - targetUserName: targetUserName, - isAttachment: true, - chatReplyId: repliedMsg.first.userChatHistoryId, - isReply: true); - } - - // dynamic contain = searchedChats!.where((ChatUser element) => element.id == targetUserId); - // if (contain.isEmpty) { - // searchedChats!.add( - // ChatUser( - // id: targetUserId, - // userName: targetUserName, - // ), - // ); - // notifyListeners(); - // } - // Uuid uuid = const Uuid(); - // dynamic fileID = fileUploadResponse.isEmpty ? null : getFileType(chatMessage); - // SingleUserChatModel data = SingleUserChatModel( - // chatEventId: fileUploadResponse.isEmpty ? 1 : 2, - // chatSource: 1, - // contant: chatMessage, - // contantNo: uuid.v4(), - // conversationId: uuid.v4(), - // createdDate: DateTime.now(), - // currentUserId: AppState().chatDetails!.response!.id, - // currentUserName: AppState().chatDetails!.response!.userName, - // targetUserId: targetUserId, - // targetUserName: targetUserName, - // fileTypeId: fileID, - // isReplied: false, - // // fileTypeResponse: FileTypeResponse( - // // fileTypeId: 0, - // // fileTypeDescription: fileUploadResponse.isEmpty ? null : fileUploadResponse.first["filePath"], - // // fileName: fileUploadResponse.isEmpty ? null : fileUploadResponse.first["filePath"], - // // fileKind: "image", - // // fileTypeName: fileUploadResponse.isEmpty ? null : fileUploadResponse.first["filePath"].toString().split(".").last), - // ); - // - // String chatData = - // '{"contant":"$chatMessage","contantNo":"${uuid.v4()}","chatEventId":${fileUploadResponse.isEmpty ? 1 : 2},"fileTypeId": $fileID,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"conversationId":"${uuid.v4()}"}'; - // await hubConnection.invoke("AddChatUserAsync", args: [json.decode(chatData)]); - // userChatHistory.add(data); - // message.clear(); - // notifyListeners(); - // scrollDown(); - } - - void scrollListener() { - if (userChatHistory.length < paginationVal) { - print("Get New Data"); + chatEventId: 2, + fileTypeId: getFileType(ext.toString()), + targetUserId: targetUserId, + targetUserName: targetUserName, + isAttachment: true, + chatReplyId: repliedMsg.first.userChatHistoryId, + isReply: true, + ); } } @@ -513,18 +458,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } else { Utils.showToast("Max 1 mb size is allowed to upload"); } - //Utils.showLoading(context); notifyListeners(); - //Utils.hideLoading(context); - // Utils.showLoading(context); - // await m.uploadAttachments(AppState().chatDetails!.response!.id.toString(), file).then((value) { - // if (value == null) { - // m.logger.d("Returned EMPTY"); - // } else { - // m.sendChatMessage(value.isEmpty ? m.message.text : value.first["filePath"], userDetails["targetUser"].id, userDetails["targetUser"].userName, value); - // } - // }); - // Utils.hideLoading(context); }); } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index c98d136..c5788f9 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -10,6 +10,7 @@ class ApiConsts { static String user = baseUrlServices + "api/User/"; static String cocRest = baseUrlServices + "COCWS.svc/REST/"; + //Chat static String chatServerBaseUrl = "https://apiderichat.hmg.com"; static String chatServerBaseApiUrl = "https://apiderichat.hmg.com/api/"; static String chatHubConnectionUrl = chatServerBaseUrl + "/ConnectionChatHub"; @@ -18,12 +19,6 @@ class ApiConsts { static String chatSingleUserHistoryUrl = "UserChatHistory/GetUserChatHistory"; static String chatMediaImageUploadUrl = "shared/upload"; static String chatFavoriteUsers = "FavUser/getFavUserById/"; - //https://apiderichat.hmg.com/api/FavUser/getFavUserById/42062 -//https://apiderichat.hmg.com/api/shared/upload -// 42062 is CurrentUserID and 36745 is targetUserID and 0 is For Pagination - -// static String chatSearchMember = "https://apiderichat.hmg.com/api/user/getUserWithStatusAndFavAsync/aamir.muhammad/36239"; - } class SharedPrefsConsts { diff --git a/lib/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index 1e8aec4..5a878ca 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -29,7 +29,7 @@ class ChatBubble extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( - // padding: EdgeInsets.zero, + // padding: EdgeInsets.zero, padding: EdgeInsets.only(left: isCurrentUser ? 110 : 20, right: isCurrentUser ? 20 : 110, bottom: 9), child: Align( @@ -51,7 +51,7 @@ class ChatBubble extends StatelessWidget { borderRadius: BorderRadius.circular(10), ), child: Padding( - padding: EdgeInsets.only(top: isReplied ? 8 : 5, right:8, left: 8, bottom: 5), + padding: EdgeInsets.only(top: isReplied ? 8 : 5, right: 8, left: 8, bottom: 5), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, @@ -85,7 +85,6 @@ class ChatBubble extends StatelessWidget { ), if (isReplied) 8.height, text.toText12(color: isCurrentUser ? MyColors.grey57Color : MyColors.white), - Row( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, @@ -100,7 +99,6 @@ class ChatBubble extends StatelessWidget { ), ], ), - ], ), ), diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index d2d3598..fe7a968 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -8,19 +8,14 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/api/chat/chat_provider_model.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/colors.dart'; -import 'package:mohem_flutter_app/classes/utils.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/ui/chat/chat_bubble.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; -import 'package:mohem_flutter_app/widgets/image_picker.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; -import 'package:sizer/sizer.dart'; import 'package:swipe_to/swipe_to.dart'; class ChatDetailScreen extends StatelessWidget { @@ -30,13 +25,13 @@ class ChatDetailScreen extends StatelessWidget { ScrollController scrollController = ScrollController(); RefreshController _refreshController = RefreshController(initialRefresh: false); - void onRefresh() async { - print("Refresh Triggered"); - await Future.delayed(Duration(milliseconds: 1000)); + void getMoreChat() async { + if (userDetails != null) { data.paginationVal = data.paginationVal + 10; data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true); } + await Future.delayed(Duration(milliseconds: 1000)); _refreshController.refreshCompleted(); } @@ -45,16 +40,6 @@ class ChatDetailScreen extends StatelessWidget { userDetails = ModalRoute.of(context)!.settings.arguments; data = Provider.of(context, listen: false); if (userDetails != null) data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: false); - // - // if (userDetails != null) { - // scrollController.addListener(() { - // if (scrollController.position.minScrollExtent == scrollController.offset) { - // data.paginationVal++; - // data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true); - // } - // }); - // } - return Scaffold( backgroundColor: const Color(0xFFF8F8F8), appBar: AppBarWidget(context, title: userDetails["targetUser"].userName, showHomeButton: false, image: userDetails["targetUser"].image), @@ -73,34 +58,28 @@ class ChatDetailScreen extends StatelessWidget { color: MyColors.gradiantEndColor, ), controller: _refreshController, - onRefresh: onRefresh, + onRefresh: getMoreChat, child: ListView.builder( controller: scrollController, shrinkWrap: true, itemCount: m.userChatHistory.length, padding: EdgeInsets.zero, itemBuilder: (BuildContext context, int i) { - return GestureDetector( - onTap: () { - m.logger.d(jsonEncode(m.userChatHistory[i])); - m.logger.d(jsonEncode(m.userChatHistory.length)); - }, - child: SwipeTo( - iconColor: MyColors.lightGreenColor, - child: ChatBubble( - text: m.userChatHistory[i].contant.toString(), - replyText: m.userChatHistory[i].userChatReplyResponse != null ? m.userChatHistory[i].userChatReplyResponse!.contant.toString() : "", - isSeen: m.userChatHistory[i].isSeen == true ? true : false, - isCurrentUser: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id ? true : false, - isDelivered: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id && m.userChatHistory[i].isDelivered == true ? true : false, - dateTime: m.dateFormte(m.userChatHistory[i].createdDate!), - isReplied: m.userChatHistory[i].userChatReplyResponse != null ? true : false, - userName: AppState().chatDetails!.response!.userName == m.userChatHistory[i].currentUserName.toString() ? "You" : m.userChatHistory[i].currentUserName.toString(), - ), - onRightSwipe: () { - m.chatReply(m.userChatHistory[i]); - }, + return SwipeTo( + iconColor: MyColors.lightGreenColor, + child: ChatBubble( + text: m.userChatHistory[i].contant.toString(), + replyText: m.userChatHistory[i].userChatReplyResponse != null ? m.userChatHistory[i].userChatReplyResponse!.contant.toString() : "", + isSeen: m.userChatHistory[i].isSeen == true ? true : false, + isCurrentUser: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id ? true : false, + isDelivered: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id && m.userChatHistory[i].isDelivered == true ? true : false, + dateTime: m.dateFormte(m.userChatHistory[i].createdDate!), + isReplied: m.userChatHistory[i].userChatReplyResponse != null ? true : false, + userName: AppState().chatDetails!.response!.userName == m.userChatHistory[i].currentUserName.toString() ? "You" : m.userChatHistory[i].currentUserName.toString(), ), + onRightSwipe: () { + m.chatReply(m.userChatHistory[i]); + }, ); }, ), @@ -203,7 +182,7 @@ class ChatDetailScreen extends StatelessWidget { ], ) : null, - suffixIcon: Container( + suffixIcon: SizedBox( width: 96, child: Row( mainAxisAlignment: MainAxisAlignment.end, diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 106a4b3..38388ca 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -27,7 +27,7 @@ class ChatHomeScreen extends StatefulWidget { } class _ChatHomeScreenState extends State { - TextEditingController search = new TextEditingController(); + TextEditingController search = TextEditingController(); late ChatProviderModel data; @override @@ -213,8 +213,6 @@ class _ChatHomeScreenState extends State { apiMode: LocaleKeys.delegate.tr(), fromChat: true, onSelectEmployee: (_selectedEmployee) { - // Navigator.pop(context); - // selectedReplacementEmployee = _selectedEmployee; setState(() {}); }, ), diff --git a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart index fb14141..63ce88b 100644 --- a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart +++ b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart @@ -136,12 +136,13 @@ class _SearchEmployeeBottomSheetState extends State { }, ).expanded, IconButton( - constraints: const BoxConstraints(), - onPressed: () async { - await SystemChannels.textInput.invokeMethod('TextInput.hide'); - widget.fromChat ? fetchChatUser() : fetchUserByInput(); - }, - icon: Icon(Icons.search)) + constraints: const BoxConstraints(), + onPressed: () async { + await SystemChannels.textInput.invokeMethod('TextInput.hide'); + widget.fromChat ? fetchChatUser() : fetchUserByInput(); + }, + icon: const Icon(Icons.search), + ) ], ), if (replacementList != null) @@ -184,62 +185,21 @@ class _SearchEmployeeBottomSheetState extends State { if (chatUsersList != null && widget.fromChat) chatUsersList!.isEmpty ? Column( - children: [ - 20.height, - Utils.getNoDataWidget(context), - ], - ) + children: [ + 20.height, + Utils.getNoDataWidget(context), + ], + ) : ListView( physics: const BouncingScrollPhysics(), - padding: const EdgeInsets.only(top: 15,), + padding: const EdgeInsets.only( + top: 15, + ), children: [ ListView.separated( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (BuildContext cxt, int index) { - - - - - // return ListTile( - // leading: Stack( - // children: [ - // SvgPicture.asset( - // "assets/images/user.svg", - // height: 48, - // width: 48, - // ), - // Positioned( - // right: 5, - // bottom: 1, - // child: Container( - // width: 10, - // height: 10, - // decoration: BoxDecoration( - // color: chatUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, - // borderRadius: const BorderRadius.all( - // Radius.circular(10), - // ), - // ), - // ), - // ) - // ], - // ), - // title: (chatUsersList![index].userName ?? "").toText14(color: MyColors.darkTextColor), - // // subtitle: (chatUsersList![index].isTyping == true ? "Something is Typing" : "Last message text").toText11(color: MyColors.normalTextColor), - // // trailing: ("Today").toText10(color: MyColors.lightTextColor), - // minVerticalPadding: 0, - // onTap: () { - // Navigator.pop(context); - // Navigator.pushNamed( - // context, - // AppRoutes.chatDetailed, - // arguments: {"targetUser": chatUsersList![index]}, - // ); - // }, - // ); - - return SizedBox( height: 55, child: ListTile( @@ -279,12 +239,9 @@ class _SearchEmployeeBottomSheetState extends State { onLongPress: () {}, ), ); - - - }, separatorBuilder: (BuildContext context, int index) => const Padding( - padding: EdgeInsets.only(right: 10, left: 70, bottom: 0,top: 0), + padding: EdgeInsets.only(right: 10, left: 70, bottom: 0, top: 0), child: Divider( color: Color(0xFFE5E5E5), ), @@ -349,7 +306,9 @@ class _SearchEmployeeBottomSheetState extends State { decoration: BoxDecoration( color: Colors.transparent, border: Border.all(color: MyColors.borderColor, width: 1), - borderRadius: const BorderRadius.all(Radius.circular(100)), + borderRadius: const BorderRadius.all( + Radius.circular(100), + ), ), padding: const EdgeInsets.all(4), child: Container( @@ -357,7 +316,9 @@ class _SearchEmployeeBottomSheetState extends State { height: double.infinity, decoration: BoxDecoration( color: value == groupValue ? MyColors.grey3AColor : Colors.transparent, - borderRadius: BorderRadius.all(const Radius.circular(100)), + borderRadius: const BorderRadius.all( + Radius.circular(100), + ), ), ), ), From 6fe015d10466c850e94731fc5678f42f2650d02d Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 10 Nov 2022 16:25:48 +0300 Subject: [PATCH 07/62] fixes --- lib/ui/work_list/sheets/selected_item_sheet.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ui/work_list/sheets/selected_item_sheet.dart b/lib/ui/work_list/sheets/selected_item_sheet.dart index 4f7f6b3..54f87d0 100644 --- a/lib/ui/work_list/sheets/selected_item_sheet.dart +++ b/lib/ui/work_list/sheets/selected_item_sheet.dart @@ -140,7 +140,7 @@ class SelectedItemSheet extends StatelessWidget { Future performNetworkCall(BuildContext context, {String? email, String? userId}) async { Utils.showLoading(context); try { - await WorkListApiClient().submitComment(comment: comment, email: email, userId: userId, notificationId: notificationID, apiMode: apiMode, approverIndex: actionHistoryList!.sEQUENCE); + await WorkListApiClient().submitComment(comment: comment, email: email, userId: userId, notificationId: notificationID, apiMode: apiMode, approverIndex: actionHistoryList != null ? actionHistoryList!.sEQUENCE : null); Utils.hideLoading(context); // Navigator.pop(context); // Navigator.pop(context); @@ -212,7 +212,7 @@ class SelectedItemSheet extends StatelessWidget { : CircularAvatar( height: 40, width: 40, - ).toShimmer() + ) : (actionHistoryList != null && actionHistoryList!.eMPLOYEEIMAGE != null) ? CircularAvatar( height: 40, @@ -223,7 +223,7 @@ class SelectedItemSheet extends StatelessWidget { : CircularAvatar( height: 40, width: 40, - ).toShimmer(), + ), 16.width, Expanded( child: (name ?? "").toText12(), From ea8fd42abd83fcee9544b909c3b534096808666d Mon Sep 17 00:00:00 2001 From: "mirza.shafique" Date: Sun, 13 Nov 2022 11:12:50 +0300 Subject: [PATCH 08/62] Otp clear & resend fixed --- lib/classes/consts.dart | 4 +- lib/dialogs/otp_dialog.dart | 125 ++++++++++++--------- lib/ui/login/forgot_password_screen.dart | 28 +++-- lib/ui/login/login_screen.dart | 4 +- lib/ui/login/verify_last_login_screen.dart | 16 ++- lib/ui/login/verify_login_screen.dart | 4 +- 6 files changed, 105 insertions(+), 76 deletions(-) diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index c5788f9..646e498 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/dialogs/otp_dialog.dart b/lib/dialogs/otp_dialog.dart index 3952e70..9158b94 100644 --- a/lib/dialogs/otp_dialog.dart +++ b/lib/dialogs/otp_dialog.dart @@ -11,10 +11,12 @@ import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/otp_widget.dart'; import 'package:sizer/sizer.dart'; +final ValueNotifier otpFieldClear = ValueNotifier(""); + class OtpDialog { final int type; final int? mobileNo; - final Function(String) onSuccess; + final Function(String, TextEditingController _pinPutController) onSuccess; final Function onFailure; final BuildContext context; final Function onResendCode; @@ -96,58 +98,70 @@ class OtpDialog { 6.height, (LocaleKeys.pleaseEnterTheVerificationCodeSentTo.tr() + ' xxxxxxxx' + mobileNo.toString().substring(mobileNo.toString().length - 3)).toText16(), 18.height, - Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: OTPWidget( - autoFocus: true, - controller: _pinPutController, - defaultBorderColor: const Color(0xffD8D8D8), - maxLength: 4, - onTextChanged: (text) {}, - pinBoxColor: Colors.white, - onDone: (code) => _onOtpCallBack(code, null), - textBorderColor: const Color(0xffD8D8D8), - pinBoxWidth: 60, - pinBoxHeight: 60, - pinTextStyle: const TextStyle(fontSize: 24.0, color: MyColors.darkTextColor), - pinTextAnimatedSwitcherTransition: ProvidedPinBoxTextAnimation.scalingTransition, - pinTextAnimatedSwitcherDuration: const Duration(milliseconds: 300), - pinBoxRadius: 10, - keyboardType: TextInputType.number, - ), - ), - ), - 10.height, - stopTimer - ? Row( - children: [ - Expanded( - child: LocaleKeys.codeExpire.tr().toText16( - color: MyColors.redColor, - ), - ), - 12.width, - Image.asset( - "assets/icons/ic_alarm.png", - width: 20, - height: 20, - color: MyColors.redColor, - ), - ], - ) - : RichText( - text: TextSpan( - text: LocaleKeys.theVerificationCodeWillExpireIn.tr() + '\n', - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.darkTextColor, letterSpacing: -0.48), - children: [ - TextSpan( - text: displayTime, - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.textMixColor, letterSpacing: -0.48), + ValueListenableBuilder( + builder: (BuildContext context, String value, Widget? child) { + // This builder will only get called when the _counter + // is updated. + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: OTPWidget( + autoFocus: true, + controller: _pinPutController, + defaultBorderColor: const Color(0xffD8D8D8), + maxLength: 4, + onTextChanged: (text) {}, + pinBoxColor: Colors.white, + onDone: (code) => _onOtpCallBack(code, null), + textBorderColor: const Color(0xffD8D8D8), + pinBoxWidth: 60, + pinBoxHeight: 60, + pinTextStyle: const TextStyle(fontSize: 24.0, color: MyColors.darkTextColor), + pinTextAnimatedSwitcherTransition: ProvidedPinBoxTextAnimation.scalingTransition, + pinTextAnimatedSwitcherDuration: const Duration(milliseconds: 300), + pinBoxRadius: 10, + keyboardType: TextInputType.number, ), - ], + ), ), - ), + 10.height, + stopTimer + ? Row( + children: [ + Expanded( + child: LocaleKeys.codeExpire.tr().toText16( + color: MyColors.redColor, + ), + ), + 12.width, + Image.asset( + "assets/icons/ic_alarm.png", + width: 20, + height: 20, + color: MyColors.redColor, + ), + ], + ) + : RichText( + text: TextSpan( + text: LocaleKeys.theVerificationCodeWillExpireIn.tr() + '\n', + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.darkTextColor, letterSpacing: -0.48), + children: [ + TextSpan( + text: displayTime, + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.textMixColor, letterSpacing: -0.48), + ), + ], + ), + ), + ], + ); + }, + valueListenable: otpFieldClear, + ), 18.height, DefaultButton( stopTimer ? LocaleKeys.resend.tr() : LocaleKeys.cancel.tr(), @@ -238,14 +252,15 @@ class OtpDialog { }); } - static void hideSMSBox(context) { - Navigator.pop(context); + void hideSMSBox(context) { + onFailure(); } void _onOtpCallBack(String otpCode, bool? isAutofill) { if (otpCode.length == 4) { - stopTimer = true; - onSuccess(otpCode); + // stopTimer = true; + otpFieldClear.value = otpCode; + onSuccess(otpCode, _pinPutController); } } diff --git a/lib/ui/login/forgot_password_screen.dart b/lib/ui/login/forgot_password_screen.dart index 6c1868e..b2d5c92 100644 --- a/lib/ui/login/forgot_password_screen.dart +++ b/lib/ui/login/forgot_password_screen.dart @@ -50,17 +50,25 @@ class _ForgotPasswordScreenState extends State { context, 1, int.tryParse(_basicMemberInformation?.pMOBILENUMBER ?? ""), - (value) async { + (value,TextEditingController _pinPutController) async { Utils.showLoading(context); - GenericResponseModel? genericResponseModel = await LoginApiClient().checkPublicActivationCode(value, employeeId.text); - if (genericResponseModel?.errorMessage != null) { - Utils.showToast(genericResponseModel?.errorMessage ?? ""); - return; - } - Utils.hideLoading(context); - await Navigator.pushNamed(context, AppRoutes.newPassword, arguments: employeeId.text); - Navigator.pop(context); - Navigator.pop(context); + try{ + GenericResponseModel? genericResponseModel = await LoginApiClient().checkPublicActivationCode(value, employeeId.text); + if (genericResponseModel?.errorMessage != null) { + Utils.showToast(genericResponseModel?.errorMessage ?? ""); + return; + } + Utils.hideLoading(context); + await Navigator.pushNamed(context, AppRoutes.newPassword, arguments: employeeId.text); + Navigator.pop(context); + Navigator.pop(context); + }catch(ex){ + print(ex); + _pinPutController.clear(); + otpFieldClear.value = ""; + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } }, () => { Navigator.pop(context), diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 20fa8bc..97282d3 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -142,8 +142,8 @@ class _LoginScreenState extends State { isAppOpenBySystem = (ModalRoute.of(context)!.settings.arguments ?? true) as bool; if (!kReleaseMode) { // username.text = "15444"; // Maha User - // username.text = "15153"; // Tamer User - // password.text = "Abcd@12345"; + username.text = "15153"; // Tamer User + password.text = "Abcd@12345"; // username.text = "206535"; // Hashim User // password.text = "Namira786"; diff --git a/lib/ui/login/verify_last_login_screen.dart b/lib/ui/login/verify_last_login_screen.dart index 0b07b43..81d1ba2 100644 --- a/lib/ui/login/verify_last_login_screen.dart +++ b/lib/ui/login/verify_last_login_screen.dart @@ -335,16 +335,16 @@ class _VerifyLastLoginScreenState extends State { if (!isDirectLogin) BasicMemberInformationModel? memberInformationModel = await LoginApiClient().mohemmSendActivationCodeByOTPNotificationType(0, AppState().memberLoginList?.pMOBILENUMBER, sendVerificationFlat, AppState().getUserName); - if (isDirectLogin) performDirectApiCall(_title, _icon, _flag, ""); + if (isDirectLogin) performDirectApiCall(_title, _icon, _flag, "", null); if (!isDirectLogin) Utils.hideLoading(context); if (!isDirectLogin) OtpDialog( context, sendVerificationFlat, int.tryParse(AppState().memberLoginList?.pMOBILENUMBER ?? ""), - (value) async { + (value, TextEditingController _pinPutController) async { Utils.showLoading(context); - performDirectApiCall(_title, _icon, _flag, value); + performDirectApiCall(_title, _icon, _flag, value, _pinPutController); }, () => { Navigator.pop(context), @@ -359,7 +359,7 @@ class _VerifyLastLoginScreenState extends State { } } - Future performDirectApiCall(String _title, String _icon, int _flag, String value, {bool isDirectLogin = false}) async { + Future performDirectApiCall(String _title, String _icon, int _flag, String value, TextEditingController? _pinPutController, {bool isDirectLogin = false}) async { try { GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); GenericResponseModel? genericResponseModel1 = await LoginApiClient().insertMobileLoginInfoNEW( @@ -372,14 +372,18 @@ class _VerifyLastLoginScreenState extends State { mobileLoginInfoListModel!.deviceToken!, Platform.isAndroid ? "android" : "ios"); AppState().setMemberInformationListModel = genericResponseModel!.memberInformationList?.first; - if (genericResponseModel?.errorMessage != null) { - Utils.showToast(genericResponseModel?.errorMessage ?? ""); + if (genericResponseModel.errorMessage != null) { + Utils.showToast(genericResponseModel.errorMessage ?? ""); // Navigator.pop(context); } Utils.hideLoading(context); Navigator.pop(context); Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route route) => false); } catch (ex) { + if (_pinPutController != null) { + _pinPutController.clear(); + otpFieldClear.value = ""; + } Utils.hideLoading(context); Utils.handleException(ex, context, null); } diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index 8dba16c..ce21b63 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -617,7 +617,7 @@ class _VerifyLoginScreenState extends State { context, sendVerificationFlat, int.tryParse(AppState().memberLoginList?.pMOBILENUMBER ?? ""), - (value) async { + (value, TextEditingController _pinPutController) async { Utils.showLoading(context); try { GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(true, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); @@ -652,6 +652,8 @@ class _VerifyLoginScreenState extends State { Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route route) => false); } catch (ex) { print(ex); + _pinPutController.clear(); + otpFieldClear.value = ""; Utils.hideLoading(context); Utils.handleException(ex, context, null); } From c2a4df89bb518fdb775c3a9957ab14b3f2cf63c2 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 13 Nov 2022 11:19:21 +0300 Subject: [PATCH 09/62] offers & discouts --- .../offers_and_discounts/offers_and_discounts_home.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart b/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart index 45247dc..343eed8 100644 --- a/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart +++ b/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart @@ -173,7 +173,7 @@ class _OffersAndDiscountsHomeState extends State { tag: "ItemImage" + getOffersList.rowID!, transitionOnUserGestures: true, child: AspectRatio( - aspectRatio: 148 / 127, + aspectRatio: 118 / 127, child: ClipRRect( borderRadius: BorderRadius.circular(6), child: Image.network( @@ -192,10 +192,10 @@ class _OffersAndDiscountsHomeState extends State { // // launchUrl(Uri.parse(url!)); // // } // ), - getOffersList.description!.toText12(maxLine: 2, color: const Color(0xff535353)), + // getOffersList.description!.toText12(maxLine: 2, color: const Color(0xff535353)), // 8.height, getOffersList.discount!.toText14(isBold: true, maxlines: 1), - 10.height, + 20.height, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [checkDate(getOffersList.endDate!), SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4)], @@ -211,7 +211,7 @@ class _OffersAndDiscountsHomeState extends State { if (enteredKeyword.isEmpty) { results = getOffersList; } else { - if(AppState().isArabic(context)) { + if (AppState().isArabic(context)) { results = getOffersList.where((offer) => offer.titleAR!.toLowerCase().contains(enteredKeyword.toLowerCase())).toList(); } else { results = getOffersList.where((offer) => offer.title!.toLowerCase().contains(enteredKeyword.toLowerCase())).toList(); From 55ff08c3f3f3e813f7258e30ea796d099e58d9fe Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Sun, 13 Nov 2022 13:50:35 +0300 Subject: [PATCH 10/62] Chat Favorite Screen & Fixes --- assets/langs/ar-SA.json | 5 +- assets/langs/en-US.json | 5 +- lib/api/chat/chat_provider_model.dart | 45 ++-- lib/classes/consts.dart | 4 +- lib/config/routes.dart | 5 +- lib/generated/locale_keys.g.dart | 2 + lib/ui/chat/chat_bubble.dart | 4 +- lib/ui/chat/chat_detailed_screen.dart | 3 +- lib/ui/chat/chat_home.dart | 275 +++++++------------------ lib/ui/chat/chat_home_screen.dart | 226 ++++++++++++++++++++ lib/ui/chat/favorite_users_screen.dart | 102 +++++++++ lib/widgets/image_picker.dart | 2 +- 12 files changed, 445 insertions(+), 233 deletions(-) create mode 100644 lib/ui/chat/chat_home_screen.dart create mode 100644 lib/ui/chat/favorite_users_screen.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index f72ea36..bdec4f0 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -498,5 +498,8 @@ "verification": "تَحَقّق", "resend": "إعادة إرسال", "codeExpire": "انتهت صلاحية رمز التحقق", - "typeheretoreply": "اكتب هنا للرد" + "typeheretoreply": "اكتب هنا للرد", + "favorite" : "مفضل", + "searchfromchat": "البحث من الدردشة" + } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index e0b9019..1cd1a33 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -498,5 +498,8 @@ "resend": "Resend", "codeExpire": "The verification code has been expired", "allQuestionsCorrect": "You have answered all questions correct", - "typeheretoreply": "Type here to reply" + "typeheretoreply": "Type here to reply", + "favorite" : "Favorite", + "searchfromchat": "Search from chat" + } \ No newline at end of file diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index b85aa85..4e79374 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -33,6 +33,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { String sFileType = ""; bool isMsgReply = false; List repliedMsg = []; + List favUsersList = []; int paginationVal = 0; Future getUserAutoLoginToken() async { @@ -60,25 +61,26 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { token: AppState().chatDetails!.response!.token, ); - logger.d(AppState().chatDetails!.response!.token); + //logger.d(AppState().chatDetails!.response!.token); ChatUserModel recentChat = userToList(response.body); Response favRes = await ApiClient().getJsonForResponse( "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatFavoriteUsers}${AppState().chatDetails!.response!.id}", token: AppState().chatDetails!.response!.token, ); - print("============================== Fav Response ====================================="); - ChatUserModel favUsersList = userToList(favRes.body); - for (var user in recentChat.response!) { - for (var favUser in favUsersList.response!) { - logger.d(favUser.isFav); - if (user.id == favUser.id) { - user.isFav = favUser.isFav; + ChatUserModel favUList = userToList(favRes.body); + if (favUList.response != null) { + favUsersList = favUList.response!; + for (dynamic user in recentChat.response!) { + for (dynamic favUser in favUList.response!) { + if (user.id == favUser.id) { + user.isFav = favUser.isFav; + } } } } - pChatHistory = recentChat.response; + pChatHistory!.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase()!.compareTo(b.userName!.toLowerCase()!)); searchedChats = pChatHistory; isLoading = false; notifyListeners(); @@ -87,7 +89,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void getSingleUserChatHistory({required String senderUID, required int receiverUID, required bool loadMore}) async { isLoading = true; if (!loadMore) paginationVal = 0; - logger.d(paginationVal); isChatScreenActive = true; Response response = await ApiClient().getJsonForResponse( "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal", @@ -150,24 +151,16 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ({String? connectionId}) {}, ); if (hubConnection.state != HubConnectionState.Connected) { + print("================= Connection Established =========================="); await hubConnection.start(); hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); - hubConnection.on("OnUserTypingAsync", onUserTyping); + //hubConnection.on("OnUserTypingAsync", onUserTyping); // hubConnection.on("OnUserCountAsync", userCountAsync); - // hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); + hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); - } else { - hubConnection.on("OnUpdateUserStatusAsync", changeStatus); - hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); - - hubConnection.on("OnUserTypingAsync", onUserTyping); - // hubConnection.on("OnUserCountAsync", userCountAsync); - // hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); - // hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); - hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); } isLoading = false; notifyListeners(); @@ -189,8 +182,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void userCountAsync(List? args) { List items = args!.toList(); - print("---------------------------------User Count Async -------------------------------------"); - logger.d(items); + //print("---------------------------------User Count Async -------------------------------------"); + //logger.d(items); // for (var user in searchedChats!) { // if (user.id == items.first["id"]) { // user.userStatus = items.first["userStatus"]; @@ -537,7 +530,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } String dateFormte(DateTime data) { - DateFormat f = new DateFormat('hh:mm a dd MMM yyyy'); + DateFormat f = DateFormat('hh:mm a dd MMM yyyy'); f.format(data); return f.format(data); } @@ -547,9 +540,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { await ApiClient().postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token); fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); if (favoriteChatUser.response != null) { - for (var user in searchedChats!) { + for (ChatUser user in searchedChats!) { if (user.id == favoriteChatUser.response!.targetUserId!) { user.isFav = favoriteChatUser.response!.isFav; + favUsersList.add(user); } } } @@ -566,6 +560,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { user.isFav = favoriteChatUser.response!.isFav; } } + favUsersList.removeWhere((ChatUser element) => element.id == targetUserID); } notifyListeners(); } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index c5788f9..ede22e3 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/config/routes.dart b/lib/config/routes.dart index 1fcbf2e..ab3fb9a 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -5,6 +5,7 @@ import 'package:mohem_flutter_app/ui/attendance/vacation_rule_screen.dart'; import 'package:mohem_flutter_app/ui/bottom_sheets/attendence_details_bottom_sheet.dart'; import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart'; import 'package:mohem_flutter_app/ui/chat/chat_home.dart'; +import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart'; import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; import 'package:mohem_flutter_app/ui/landing/itg/survey_screen.dart'; import 'package:mohem_flutter_app/ui/landing/today_attendance_screen.dart'; @@ -177,6 +178,7 @@ class AppRoutes { //Chat static const String chat = "/chat"; static const String chatDetailed = "/chatDetailed"; + static const String chatFavoriteUsers = "/chatFavoriteUsers"; //Marathon static const String marathonIntroScreen = "/marathonIntroScreen"; @@ -287,8 +289,9 @@ class AppRoutes { changePassword: (BuildContext context) => ChangePasswordScreen(), //Chat - chat: (BuildContext context) => ChatHomeScreen(), + chat: (BuildContext context) => ChatHome(), chatDetailed: (BuildContext context) => ChatDetailScreen(), + chatFavoriteUsers: (BuildContext context) => ChatFavoriteUsersScreen(), // Marathon marathonIntroScreen: (BuildContext context) => MarathonIntroScreen(), diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index f52bb89..f5d4960 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -485,5 +485,7 @@ abstract class LocaleKeys { static const resend = 'resend'; static const codeExpire = 'codeExpire'; static const typeheretoreply = 'typeheretoreply'; + static const favorite = 'favorite'; + static const searchfromchat = 'searchfromchat'; } diff --git a/lib/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index 5a878ca..d9bd599 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -36,7 +36,7 @@ class ChatBubble extends StatelessWidget { alignment: isCurrentUser ? Alignment.centerRight : Alignment.centerLeft, child: DecoratedBox( decoration: BoxDecoration( - color: Colors.white, + color: MyColors.white, gradient: isCurrentUser ? null : const LinearGradient( @@ -89,7 +89,7 @@ class ChatBubble extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, children: [ - dateTime.toText12(color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : Colors.white.withOpacity(0.7)), + dateTime.toText12(color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7)), if (isCurrentUser) 5.width, if (isCurrentUser) Icon( diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index fe7a968..c13e6d3 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -26,7 +26,6 @@ class ChatDetailScreen extends StatelessWidget { RefreshController _refreshController = RefreshController(initialRefresh: false); void getMoreChat() async { - if (userDetails != null) { data.paginationVal = data.paginationVal + 10; data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true); @@ -63,7 +62,7 @@ class ChatDetailScreen extends StatelessWidget { controller: scrollController, shrinkWrap: true, itemCount: m.userChatHistory.length, - padding: EdgeInsets.zero, + padding: const EdgeInsets.only(top: 20), itemBuilder: (BuildContext context, int i) { return SwipeTo( iconColor: MyColors.lightGreenColor, diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 38388ca..5176273 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -1,224 +1,103 @@ -import 'dart:convert'; - import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; -import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.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/ui/chat/chat_home_screen.dart'; +import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart'; +import 'package:mohem_flutter_app/ui/screens/items_for_sale/fragments/items_for_sale.dart'; +import 'package:mohem_flutter_app/ui/screens/items_for_sale/fragments/my_posted_ads_fragment.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; -import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; -import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_sheet.dart'; -import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; -import 'package:provider/provider.dart'; -import 'package:sizer/sizer.dart'; -class ChatHomeScreen extends StatefulWidget { - const ChatHomeScreen({Key? key}) : super(key: key); +class ChatHome extends StatefulWidget { + const ChatHome({Key? key}) : super(key: key); @override - State createState() => _ChatHomeScreenState(); + State createState() => _ChatHomeState(); } -class _ChatHomeScreenState extends State { - TextEditingController search = TextEditingController(); - late ChatProviderModel data; - - @override - void initState() { - super.initState(); - data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().whenComplete(() { - data.getUserRecentChats(); - }); - } - - @override - void dispose() { - super.dispose(); - } +class _ChatHomeState extends State { + int tabIndex = 0; + PageController controller = PageController(); @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Colors.white, - appBar: AppBarWidget(context, title: LocaleKeys.mychats.tr(), showHomeButton: false), - body: Consumer(builder: (BuildContext context, ChatProviderModel m, Widget? child) { - return m.isLoading - ? ChatHomeShimmer() - : ListView( - shrinkWrap: true, - physics: const AlwaysScrollableScrollPhysics(), - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 20), - child: TextField( - onChanged: (String val) { - m.filter(val); - }, - decoration: InputDecoration( - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(5), - borderSide: const BorderSide( - color: Color(0xFFE5E5E5), - ), - ), - errorBorder: InputBorder.none, - disabledBorder: InputBorder.none, - contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), - hintText: "Search from chat", - hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic), - filled: true, - fillColor: const Color(0xFFF7F7F7), - ), - ), - ), - if (m.searchedChats != null) - ListView.separated( - itemCount: m.searchedChats!.length, - padding: const EdgeInsets.only(top: 20), - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (BuildContext context, int index) { - return SizedBox( - height: 55, - child: ListTile( - leading: Stack( - children: [ - SvgPicture.asset( - "assets/images/user.svg", - height: 48, - width: 48, - ), - Positioned( - right: 5, - bottom: 1, - child: Container( - width: 10, - height: 10, - decoration: BoxDecoration( - color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, - borderRadius: const BorderRadius.all( - Radius.circular(10), - ), - ), - ), - ) - ], - ), - title: (m.searchedChats![index].userName ?? "").toText14(color: MyColors.darkTextColor), - // subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), - trailing: SizedBox( - width: 60, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.max, - children: [ - if (m.searchedChats![index].unreadMessageCount! > 0) - Flexible( - child: Container( - padding: EdgeInsets.zero, - alignment: Alignment.centerRight, - width: 18, - height: 18, - decoration: const BoxDecoration( - color: MyColors.redColor, - borderRadius: BorderRadius.all( - Radius.circular(20), - ), - ), - child: (m.searchedChats![index].unreadMessageCount!.toString()) - .toText10( - color: MyColors.white, - ) - .center, - ), - ), - Flexible( - child: IconButton( - alignment: Alignment.centerRight, - padding: EdgeInsets.zero, - icon: Icon(m.searchedChats![index].isFav! ? Icons.star : Icons.star_border), - color: m.searchedChats![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, - onPressed: () { - if (m.searchedChats![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); - if (!m.searchedChats![index].isFav!) m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); - }, - ), - ) - ], - ), - ), - minVerticalPadding: 0, - onTap: () { - Navigator.pushNamed( - context, - AppRoutes.chatDetailed, - arguments: {"targetUser": m.searchedChats![index]}, - ).then((value) { - m.clearSelections(); - }); - }, - onLongPress: () {}, - ), - ); - }, - separatorBuilder: (BuildContext context, int index) => const Padding( - padding: EdgeInsets.only(right: 10, left: 70), - child: Divider( - color: Color(0xFFE5E5E5), - ), - ), - ), + backgroundColor: MyColors.white, + appBar: AppBarWidget( + context, + title: LocaleKeys.chat.tr(), + showHomeButton: true, + ), + body: Column( + children: [ + Container( + padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16), + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(25), + bottomRight: Radius.circular(25), + ), + gradient: LinearGradient( + transform: GradientRotation(.83), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, ], - ); - }), - floatingActionButton: FloatingActionButton( - child: Container( - width: 60, - height: 60, - decoration: const BoxDecoration( - shape: BoxShape.circle, - gradient: LinearGradient( - transform: GradientRotation(.46), - begin: Alignment.topRight, - end: Alignment.bottomLeft, - colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, + ), + ), + child: Row( + children: [ + myTab(LocaleKeys.mychats.tr(), 0), + myTab( + LocaleKeys.favorite.tr(), + 1) ], ), ), - child: const Icon( - Icons.add, - size: 30, - color: MyColors.white, - ), - ), - onPressed: () async { - showMyBottomSheet( - context, - callBackFunc: () {}, - child: SearchEmployeeBottomSheet( - title: LocaleKeys.searchForEmployee.tr(), - apiMode: LocaleKeys.delegate.tr(), - fromChat: true, - onSelectEmployee: (_selectedEmployee) { - setState(() {}); - }, - ), - ); - }, + PageView( + controller: controller, + physics: const NeverScrollableScrollPhysics(), + onPageChanged: (int pageIndex) { + setState(() { + tabIndex = pageIndex; + }); + }, + children: [ChatHomeScreen(), ChatFavoriteUsersScreen()], + ).expanded, + ], ), ); } + + Widget myTab(String title, int index) { + bool isSelected = (index == tabIndex); + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + title.toText12(color: isSelected ? MyColors.white : MyColors.white.withOpacity(.74), isCenter: true), + 4.height, + Container( + height: 8, + width: 8, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: isSelected ? MyColors.white : Colors.transparent, + ), + ).onPress(() { + setState(() { + // showFabOptions = true; + }); + }) + ], + ).onPress(() { + controller.jumpToPage(index); + }).expanded; + } } diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart new file mode 100644 index 0000000..328354b --- /dev/null +++ b/lib/ui/chat/chat_home_screen.dart @@ -0,0 +1,226 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/config/routes.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/widgets/bottom_sheet.dart'; +import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_sheet.dart'; +import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; +import 'package:provider/provider.dart'; + +class ChatHomeScreen extends StatefulWidget { + const ChatHomeScreen({Key? key}) : super(key: key); + + @override + State createState() => _ChatHomeScreenState(); +} + +class _ChatHomeScreenState extends State { + TextEditingController search = TextEditingController(); + late ChatProviderModel data; + + @override + void initState() { + super.initState(); + data = Provider.of(context, listen: false); + data.getUserAutoLoginToken().whenComplete(() { + data.getUserRecentChats(); + }); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: MyColors.white, + body: Consumer(builder: (BuildContext context, ChatProviderModel m, Widget? child) { + return m.isLoading + ? ChatHomeShimmer() + : ListView( + shrinkWrap: true, + physics: const AlwaysScrollableScrollPhysics(), + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20), + child: TextField( + onChanged: (String val) { + m.filter(val); + }, + decoration: InputDecoration( + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide( + color: Color(0xFFE5E5E5), + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide( + color: Color(0xFFE5E5E5), + ), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide( + color: Color(0xFFE5E5E5), + ), + ), + contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), + hintText: LocaleKeys.searchfromchat.tr(), + hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic), + filled: true, + fillColor: const Color(0xFFF7F7F7), + ), + ), + ), + if (m.searchedChats != null) + ListView.separated( + itemCount: m.searchedChats!.length, + padding: const EdgeInsets.only(bottom: 80), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return SizedBox( + height: 55, + child: ListTile( + leading: Stack( + children: [ + SvgPicture.asset( + "assets/images/user.svg", + height: 48, + width: 48, + ), + Positioned( + right: 5, + bottom: 1, + child: Container( + width: 10, + height: 10, + decoration: BoxDecoration( + color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, + borderRadius: const BorderRadius.all( + Radius.circular(10), + ), + ), + ), + ) + ], + ), + title: (m.searchedChats![index].userName ?? "").toText14(color: MyColors.darkTextColor), + // subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), + trailing: SizedBox( + width: 60, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + if (m.searchedChats![index].unreadMessageCount! > 0) + Flexible( + child: Container( + padding: EdgeInsets.zero, + alignment: Alignment.centerRight, + width: 18, + height: 18, + decoration: const BoxDecoration( + color: MyColors.redColor, + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + ), + child: (m.searchedChats![index].unreadMessageCount!.toString()) + .toText10( + color: MyColors.white, + ) + .center, + ), + ), + Flexible( + child: IconButton( + alignment: Alignment.centerRight, + padding: EdgeInsets.zero, + icon: Icon(m.searchedChats![index].isFav! ? Icons.star : Icons.star_border), + color: m.searchedChats![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, + onPressed: () { + if (m.searchedChats![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + if (!m.searchedChats![index].isFav!) m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + }, + ), + ) + ], + ), + ), + minVerticalPadding: 0, + onTap: () { + Navigator.pushNamed( + context, + AppRoutes.chatDetailed, + arguments: {"targetUser": m.searchedChats![index]}, + ).then((value) { + m.clearSelections(); + }); + }, + onLongPress: () {}, + ), + ); + }, + separatorBuilder: (BuildContext context, int index) => const Padding( + padding: EdgeInsets.only(right: 10, left: 70), + child: Divider( + color: Color(0xFFE5E5E5), + ), + ), + ), + ], + ); + }), + floatingActionButton: FloatingActionButton( + child: Container( + width: 60, + height: 60, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + transform: GradientRotation(.46), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ], + ), + ), + child: const Icon( + Icons.add, + size: 30, + color: MyColors.white, + ), + ), + onPressed: () async { + showMyBottomSheet( + context, + callBackFunc: () {}, + child: SearchEmployeeBottomSheet( + title: LocaleKeys.searchForEmployee.tr(), + apiMode: LocaleKeys.delegate.tr(), + fromChat: true, + onSelectEmployee: (_selectedEmployee) { + setState(() {}); + }, + ), + ); + }, + ), + ); + } +} diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart new file mode 100644 index 0000000..b84b827 --- /dev/null +++ b/lib/ui/chat/favorite_users_screen.dart @@ -0,0 +1,102 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/api/chat/chat_provider_model.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/utils.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; +import 'package:provider/provider.dart'; + +class ChatFavoriteUsersScreen extends StatelessWidget { + const ChatFavoriteUsersScreen({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // TODO: implement build + return Scaffold( + backgroundColor: MyColors.white, + body: Consumer(builder: (BuildContext context, ChatProviderModel m, Widget? child) { + return m.isLoading + ? ChatHomeShimmer() + : ListView( + shrinkWrap: true, + physics: const AlwaysScrollableScrollPhysics(), + padding: const EdgeInsets.only(top: 20), + children: [ + if (m.favUsersList != null && m.favUsersList.isNotEmpty) + ListView.separated( + itemCount: m.favUsersList!.length, + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return SizedBox( + height: 55, + child: ListTile( + leading: Stack( + children: [ + SvgPicture.asset( + "assets/images/user.svg", + height: 48, + width: 48, + ), + Positioned( + right: 5, + bottom: 1, + child: Container( + width: 10, + height: 10, + decoration: BoxDecoration( + color: m.favUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, + borderRadius: const BorderRadius.all( + Radius.circular(10), + ), + ), + ), + ) + ], + ), + title: (m.favUsersList![index].userName ?? "").toText14(color: MyColors.darkTextColor), + // subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), + trailing: IconButton( + alignment: Alignment.centerRight, + padding: EdgeInsets.zero, + icon: Icon(m.favUsersList![index].isFav! ? Icons.star : Icons.star_border), + color: m.favUsersList![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, + onPressed: () { + if (m.favUsersList![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.favUsersList![index].id!); + }, + ), + minVerticalPadding: 0, + onTap: () { + Navigator.pushNamed( + context, + AppRoutes.chatDetailed, + arguments: {"targetUser": m.favUsersList![index]}, + ).then((value) { + m.clearSelections(); + }); + }, + onLongPress: () {}, + ), + ); + }, + separatorBuilder: (BuildContext context, int index) => const Padding( + padding: EdgeInsets.only(right: 10, left: 70), + child: Divider( + color: Color(0xFFE5E5E5), + ), + ), + ) + else + Utils.getNoDataWidget(context).expanded + ], + ); + }), + ); + } +} diff --git a/lib/widgets/image_picker.dart b/lib/widgets/image_picker.dart index 9fa0336..f92f9f4 100644 --- a/lib/widgets/image_picker.dart +++ b/lib/widgets/image_picker.dart @@ -48,7 +48,7 @@ class ImageOptions { allowedExtensions: ['jpg', 'jpeg ', 'pdf', 'txt', 'docx', 'doc', 'pptx', 'xlsx', 'png', 'rar', 'zip', 'xls'], ); List files = result!.paths.map((path) => File(path!)).toList(); - image(result!.files.first.path.toString(), files.first); + image(result.files.first.path.toString(), files.first); }, ), ); From cffe185cdad9f6ecc1b65a53b49399173b75a3c3 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 13 Nov 2022 16:32:53 +0300 Subject: [PATCH 11/62] ITG Count fixes --- lib/app_state/app_state.dart | 6 ++++++ lib/classes/consts.dart | 4 ++-- lib/ui/login/login_screen.dart | 4 ++-- lib/ui/work_list/item_history_screen.dart | 12 ++++++++---- lib/ui/work_list/itg_detail_screen.dart | 6 ++++++ lib/ui/work_list/work_list_screen.dart | 1 + 6 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 9e61872..49f4186 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -120,6 +120,12 @@ class AppState { set setItgWorkListIndex(int? _itgWorkListIndex) => itgWorkListIndex = _itgWorkListIndex; + String? itgRequestType; + + set setItgRequestType(String? _itgRequestType) => itgRequestType = _itgRequestType; + + String? get getItgRequestType => itgRequestType; + UserAutoLoginModel? chatDetails; set setchatUserDetails(UserAutoLoginModel details) => chatDetails = details; diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 646e498..789ef40 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 97282d3..20fa8bc 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -142,8 +142,8 @@ class _LoginScreenState extends State { isAppOpenBySystem = (ModalRoute.of(context)!.settings.arguments ?? true) as bool; if (!kReleaseMode) { // username.text = "15444"; // Maha User - username.text = "15153"; // Tamer User - password.text = "Abcd@12345"; + // username.text = "15153"; // Tamer User + // password.text = "Abcd@12345"; // username.text = "206535"; // Hashim User // password.text = "Namira786"; diff --git a/lib/ui/work_list/item_history_screen.dart b/lib/ui/work_list/item_history_screen.dart index 782e34d..fb1066b 100644 --- a/lib/ui/work_list/item_history_screen.dart +++ b/lib/ui/work_list/item_history_screen.dart @@ -86,9 +86,9 @@ class _ItemHistoryScreenState extends State { padding: const EdgeInsets.all(21), physics: const BouncingScrollPhysics(), children: [ - if (moItemHistoryList.isNotEmpty) loadMoItemHistoryData(), - if (poItemHistoryList.isNotEmpty) loadPoItemHistoryData(), - if (quotationAnalysisList.isNotEmpty) loadQuotationAnalysisData() + if (moItemHistoryList.isNotEmpty) loadMoItemHistoryData() else Utils.getNoDataWidget(context), + if (poItemHistoryList.isNotEmpty) loadPoItemHistoryData() else Utils.getNoDataWidget(context), + if (quotationAnalysisList.isNotEmpty) loadQuotationAnalysisData() else Utils.getNoDataWidget(context) ], ), ); @@ -163,7 +163,11 @@ class _ItemHistoryScreenState extends State { ItemDetailViewCol(LocaleKeys.balanceQuantity.tr(), poItemHistoryList[index].bALANCEQUANTITY?.toString() ?? ""), ItemDetailViewCol(LocaleKeys.netPrice.tr(), poItemHistoryList[index].nETPRICE?.toString() ?? ""), ), - ItemDetailGrid(ItemDetailViewCol(LocaleKeys.closureStatus.tr(), poItemHistoryList[index].cLOSEDCODE ?? ""), Container(), isItLast: true,) + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.closureStatus.tr(), poItemHistoryList[index].cLOSEDCODE ?? ""), + Container(), + isItLast: true, + ) ], ).objectContainerView(), separatorBuilder: (cxt, index) => 12.height, diff --git a/lib/ui/work_list/itg_detail_screen.dart b/lib/ui/work_list/itg_detail_screen.dart index 0a29a72..bbb0267 100644 --- a/lib/ui/work_list/itg_detail_screen.dart +++ b/lib/ui/work_list/itg_detail_screen.dart @@ -14,6 +14,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/itg_forms_models/allowed_actions_model.dart'; import 'package:mohem_flutter_app/models/itg_forms_models/itg_request_model.dart'; import 'package:mohem_flutter_app/models/itg_forms_models/request_detail_model.dart'; +import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/ui/work_list/itg_fragments/approval_level_fragment.dart'; import 'package:mohem_flutter_app/ui/work_list/itg_fragments/request_detail_fragment.dart'; import 'package:mohem_flutter_app/ui/work_list/sheets/delegate_sheet.dart'; @@ -21,6 +22,7 @@ import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/dialogs/itg_comments_dialog.dart'; +import 'package:provider/provider.dart'; class ItgDetailScreen extends StatefulWidget { ItgDetailScreen({Key? key}) : super(key: key); @@ -42,8 +44,11 @@ class _ItgDetailScreenState extends State { List allowedActionList = []; + late DashboardProviderModel providerData; + @override void initState() { + providerData = Provider.of(context, listen: false); super.initState(); } @@ -78,6 +83,7 @@ class _ItgDetailScreenState extends State { void getDataFromState() { if (requestDetails == null) { requestDetails = AppState().requestAllList![AppState().itgWorkListIndex!]; // ModalRoute.of(context)!.settings.arguments as WorkListResponseModel; + providerData.itgFormsModel!.totalCount = providerData.itgFormsModel!.totalCount! - 1; getItgData(); } } diff --git a/lib/ui/work_list/work_list_screen.dart b/lib/ui/work_list/work_list_screen.dart index 9471568..8efd789 100644 --- a/lib/ui/work_list/work_list_screen.dart +++ b/lib/ui/work_list/work_list_screen.dart @@ -347,6 +347,7 @@ class _WorkListScreenState extends State { return InkWell( onTap: () async { AppState().setItgWorkListIndex = index; + AppState().setItgRequestType = requestDetails.requestType; var shouldReloadData = await Navigator.pushNamed(context, AppRoutes.itgDetail); if (shouldReloadData != null) { if (shouldReloadData.toString() == "delegate_reload") { From 5412dcaf35a35317b849551cefb04ba3227aa5b5 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 14 Nov 2022 08:28:41 +0300 Subject: [PATCH 12/62] Chat Favorite Screen & Fixes --- lib/api/chat/chat_provider_model.dart | 20 +++++++------------- lib/ui/chat/chat_detailed_screen.dart | 17 ++++++++--------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 4e79374..b826753 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -60,8 +60,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatRecentUrl}", token: AppState().chatDetails!.response!.token, ); - - //logger.d(AppState().chatDetails!.response!.token); ChatUserModel recentChat = userToList(response.body); Response favRes = await ApiClient().getJsonForResponse( @@ -71,6 +69,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ChatUserModel favUList = userToList(favRes.body); if (favUList.response != null) { favUsersList = favUList.response!; + favUsersList.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase())); for (dynamic user in recentChat.response!) { for (dynamic favUser in favUList.response!) { if (user.id == favUser.id) { @@ -80,7 +79,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } pChatHistory = recentChat.response; - pChatHistory!.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase()!.compareTo(b.userName!.toLowerCase()!)); + pChatHistory!.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase())); searchedChats = pChatHistory; isLoading = false; notifyListeners(); @@ -94,8 +93,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal", token: AppState().chatDetails!.response!.token, ); - - logger.d(response.body); if (response.statusCode == 204) { if (!loadMore) userChatHistory = []; Utils.showToast("No More Data To Load"); @@ -134,7 +131,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future buildHubConnection() async { HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); - hubConnection = await HubConnectionBuilder() + hubConnection = HubConnectionBuilder() .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp) .withAutomaticReconnect(retryDelays: [2000, 5000, 10000, 20000]) .configureLogging( @@ -162,8 +159,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); } - isLoading = false; - notifyListeners(); + // notifyListeners(); } void updateUserChatStatus(List? args) { @@ -171,7 +167,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { for (dynamic cItem in items[0]) { for (SingleUserChatModel chat in userChatHistory) { if (chat.userChatHistoryId.toString() == cItem["userChatHistoryId"].toString()) { - logger.d(jsonEncode(chat)); chat.isSeen = cItem["isSeen"]; chat.isDelivered = cItem["isDelivered"]; notifyListeners(); @@ -182,7 +177,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void userCountAsync(List? args) { List items = args!.toList(); - //print("---------------------------------User Count Async -------------------------------------"); + //logger.d("---------------------------------User Count Async -------------------------------------"); //logger.d(items); // for (var user in searchedChats!) { // if (user.id == items.first["id"]) { @@ -256,13 +251,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } userChatHistory.add(data.first); notifyListeners(); - logger.d(isChatScreenActive); // if (isChatScreenActive) scrollDown(); } void onUserTyping(List? parameters) { - print("==================== Typing Active =================="); - logger.d(parameters); + // print("==================== Typing Active =================="); + // logger.d(parameters); for (ChatUser user in searchedChats!) { if (user.id == parameters![1] && parameters[0] == true) { user.isTyping = parameters[0] as bool?; diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index c13e6d3..369bf3c 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -1,8 +1,5 @@ import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; @@ -23,14 +20,14 @@ class ChatDetailScreen extends StatelessWidget { dynamic userDetails; late ChatProviderModel data; ScrollController scrollController = ScrollController(); - RefreshController _refreshController = RefreshController(initialRefresh: false); + final RefreshController _refreshController = RefreshController(initialRefresh: false); void getMoreChat() async { if (userDetails != null) { data.paginationVal = data.paginationVal + 10; data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true); } - await Future.delayed(Duration(milliseconds: 1000)); + await Future.delayed(const Duration(milliseconds: 1000)); _refreshController.refreshCompleted(); } @@ -61,6 +58,7 @@ class ChatDetailScreen extends StatelessWidget { child: ListView.builder( controller: scrollController, shrinkWrap: true, + reverse: false, itemCount: m.userChatHistory.length, padding: const EdgeInsets.only(top: 20), itemBuilder: (BuildContext context, int i) { @@ -137,10 +135,11 @@ class ChatDetailScreen extends StatelessWidget { height: 200, decoration: BoxDecoration( image: DecorationImage( - image: FileImage( - m.selectedFile, - ), - fit: BoxFit.cover), + image: FileImage( + m.selectedFile, + ), + fit: BoxFit.cover, + ), borderRadius: const BorderRadius.all( Radius.circular(0), ), From 83aabd05552aee12222c46317efcf259f447892b Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 14 Nov 2022 09:35:53 +0300 Subject: [PATCH 13/62] Chat Favorite Screen & Fixes --- lib/generated/codegen_loader.g.dart | 8 +- lib/ui/chat/chat_detailed_screen.dart | 4 +- lib/ui/chat/chat_home_screen.dart | 250 +++++++++++++------------ lib/ui/chat/favorite_users_screen.dart | 149 ++++++++------- 4 files changed, 209 insertions(+), 202 deletions(-) diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index e9dd08c..49dac5c 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -514,7 +514,9 @@ class CodegenLoader extends AssetLoader{ "verification": "تَحَقّق", "resend": "إعادة إرسال", "codeExpire": "انتهت صلاحية رمز التحقق", - "typeheretoreply": "اكتب هنا للرد" + "typeheretoreply": "اكتب هنا للرد", + "favorite": "مفضل", + "searchfromchat": "البحث من الدردشة" }; static const Map en_US = { "mohemm": "Mohemm", @@ -1016,7 +1018,9 @@ static const Map en_US = { "resend": "Resend", "codeExpire": "The verification code has been expired", "allQuestionsCorrect": "You have answered all questions correct", - "typeheretoreply": "Type here to reply" + "typeheretoreply": "Type here to reply", + "favorite": "Favorite", + "searchfromchat": "Search from chat" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 369bf3c..7dfb321 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -16,10 +16,12 @@ import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:swipe_to/swipe_to.dart'; class ChatDetailScreen extends StatelessWidget { - ChatDetailScreen({Key? key}) : super(key: key); dynamic userDetails; + late ChatProviderModel data; + ScrollController scrollController = ScrollController(); + final RefreshController _refreshController = RefreshController(initialRefresh: false); void getMoreChat() async { diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 328354b..f10cc26 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -43,147 +43,149 @@ class _ChatHomeScreenState extends State { Widget build(BuildContext context) { return Scaffold( backgroundColor: MyColors.white, - body: Consumer(builder: (BuildContext context, ChatProviderModel m, Widget? child) { - return m.isLoading - ? ChatHomeShimmer() - : ListView( - shrinkWrap: true, - physics: const AlwaysScrollableScrollPhysics(), - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20), - child: TextField( - onChanged: (String val) { - m.filter(val); - }, - decoration: InputDecoration( - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(5), - borderSide: const BorderSide( - color: Color(0xFFE5E5E5), + body: Consumer( + builder: (BuildContext context, ChatProviderModel m, Widget? child) { + return m.isLoading + ? ChatHomeShimmer() + : ListView( + shrinkWrap: true, + physics: const AlwaysScrollableScrollPhysics(), + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20), + child: TextField( + onChanged: (String val) { + m.filter(val); + }, + decoration: InputDecoration( + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide( + color: Color(0xFFE5E5E5), + ), ), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(5), - borderSide: const BorderSide( - color: Color(0xFFE5E5E5), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide( + color: Color(0xFFE5E5E5), + ), ), - ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(5), - borderSide: const BorderSide( - color: Color(0xFFE5E5E5), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide( + color: Color(0xFFE5E5E5), + ), ), + contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), + hintText: LocaleKeys.searchfromchat.tr(), + hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic), + filled: true, + fillColor: const Color(0xFFF7F7F7), ), - contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), - hintText: LocaleKeys.searchfromchat.tr(), - hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic), - filled: true, - fillColor: const Color(0xFFF7F7F7), ), ), - ), - if (m.searchedChats != null) - ListView.separated( - itemCount: m.searchedChats!.length, - padding: const EdgeInsets.only(bottom: 80), - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (BuildContext context, int index) { - return SizedBox( - height: 55, - child: ListTile( - leading: Stack( - children: [ - SvgPicture.asset( - "assets/images/user.svg", - height: 48, - width: 48, - ), - Positioned( - right: 5, - bottom: 1, - child: Container( - width: 10, - height: 10, - decoration: BoxDecoration( - color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, - borderRadius: const BorderRadius.all( - Radius.circular(10), - ), - ), + if (m.searchedChats != null) + ListView.separated( + itemCount: m.searchedChats!.length, + padding: const EdgeInsets.only(bottom: 80), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return SizedBox( + height: 55, + child: ListTile( + leading: Stack( + children: [ + SvgPicture.asset( + "assets/images/user.svg", + height: 48, + width: 48, ), - ) - ], - ), - title: (m.searchedChats![index].userName ?? "").toText14(color: MyColors.darkTextColor), - // subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), - trailing: SizedBox( - width: 60, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.max, - children: [ - if (m.searchedChats![index].unreadMessageCount! > 0) - Flexible( - child: Container( - padding: EdgeInsets.zero, - alignment: Alignment.centerRight, - width: 18, - height: 18, - decoration: const BoxDecoration( - color: MyColors.redColor, - borderRadius: BorderRadius.all( - Radius.circular(20), - ), + Positioned( + right: 5, + bottom: 1, + child: Container( + width: 10, + height: 10, + decoration: BoxDecoration( + color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, + borderRadius: const BorderRadius.all( + Radius.circular(10), ), - child: (m.searchedChats![index].unreadMessageCount!.toString()) - .toText10( - color: MyColors.white, - ) - .center, ), ), - Flexible( - child: IconButton( - alignment: Alignment.centerRight, - padding: EdgeInsets.zero, - icon: Icon(m.searchedChats![index].isFav! ? Icons.star : Icons.star_border), - color: m.searchedChats![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, - onPressed: () { - if (m.searchedChats![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); - if (!m.searchedChats![index].isFav!) m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); - }, - ), ) ], ), + title: (m.searchedChats![index].userName ?? "").toText14(color: MyColors.darkTextColor), + // subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), + trailing: SizedBox( + width: 60, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + if (m.searchedChats![index].unreadMessageCount! > 0) + Flexible( + child: Container( + padding: EdgeInsets.zero, + alignment: Alignment.centerRight, + width: 18, + height: 18, + decoration: const BoxDecoration( + color: MyColors.redColor, + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + ), + child: (m.searchedChats![index].unreadMessageCount!.toString()) + .toText10( + color: MyColors.white, + ) + .center, + ), + ), + Flexible( + child: IconButton( + alignment: Alignment.centerRight, + padding: EdgeInsets.zero, + icon: Icon(m.searchedChats![index].isFav! ? Icons.star : Icons.star_border), + color: m.searchedChats![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, + onPressed: () { + if (m.searchedChats![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + if (!m.searchedChats![index].isFav!) m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + }, + ), + ) + ], + ), + ), + minVerticalPadding: 0, + onTap: () { + Navigator.pushNamed( + context, + AppRoutes.chatDetailed, + arguments: {"targetUser": m.searchedChats![index]}, + ).then((value) { + m.clearSelections(); + }); + }, + onLongPress: () {}, ), - minVerticalPadding: 0, - onTap: () { - Navigator.pushNamed( - context, - AppRoutes.chatDetailed, - arguments: {"targetUser": m.searchedChats![index]}, - ).then((value) { - m.clearSelections(); - }); - }, - onLongPress: () {}, + ); + }, + separatorBuilder: (BuildContext context, int index) => const Padding( + padding: EdgeInsets.only(right: 10, left: 70), + child: Divider( + color: Color(0xFFE5E5E5), ), - ); - }, - separatorBuilder: (BuildContext context, int index) => const Padding( - padding: EdgeInsets.only(right: 10, left: 70), - child: Divider( - color: Color(0xFFE5E5E5), ), ), - ), - ], - ); - }), + ], + ); + }, + ), floatingActionButton: FloatingActionButton( child: Container( width: 60, diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart index b84b827..2e3a3f2 100644 --- a/lib/ui/chat/favorite_users_screen.dart +++ b/lib/ui/chat/favorite_users_screen.dart @@ -12,91 +12,90 @@ import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart' import 'package:provider/provider.dart'; class ChatFavoriteUsersScreen extends StatelessWidget { - const ChatFavoriteUsersScreen({Key? key}) : super(key: key); - @override Widget build(BuildContext context) { - // TODO: implement build return Scaffold( backgroundColor: MyColors.white, - body: Consumer(builder: (BuildContext context, ChatProviderModel m, Widget? child) { - return m.isLoading - ? ChatHomeShimmer() - : ListView( - shrinkWrap: true, - physics: const AlwaysScrollableScrollPhysics(), - padding: const EdgeInsets.only(top: 20), - children: [ - if (m.favUsersList != null && m.favUsersList.isNotEmpty) - ListView.separated( - itemCount: m.favUsersList!.length, - padding: EdgeInsets.zero, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (BuildContext context, int index) { - return SizedBox( - height: 55, - child: ListTile( - leading: Stack( - children: [ - SvgPicture.asset( - "assets/images/user.svg", - height: 48, - width: 48, - ), - Positioned( - right: 5, - bottom: 1, - child: Container( - width: 10, - height: 10, - decoration: BoxDecoration( - color: m.favUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, - borderRadius: const BorderRadius.all( - Radius.circular(10), - ), + body: Consumer( + builder: (BuildContext context, ChatProviderModel m, Widget? child) { + if (m.isLoading) { + return ChatHomeShimmer(); + } else { + return m.favUsersList != null && m.favUsersList.isNotEmpty + ? ListView.separated( + itemCount: m.favUsersList!.length, + padding: const EdgeInsets.only(top: 20), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return SizedBox( + height: 55, + child: ListTile( + leading: Stack( + children: [ + SvgPicture.asset( + "assets/images/user.svg", + height: 48, + width: 48, + ), + Positioned( + right: 5, + bottom: 1, + child: Container( + width: 10, + height: 10, + decoration: BoxDecoration( + color: m.favUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, + borderRadius: const BorderRadius.all( + Radius.circular(10), ), ), - ) - ], - ), - title: (m.favUsersList![index].userName ?? "").toText14(color: MyColors.darkTextColor), - // subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), - trailing: IconButton( - alignment: Alignment.centerRight, - padding: EdgeInsets.zero, - icon: Icon(m.favUsersList![index].isFav! ? Icons.star : Icons.star_border), - color: m.favUsersList![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, - onPressed: () { - if (m.favUsersList![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.favUsersList![index].id!); - }, - ), - minVerticalPadding: 0, - onTap: () { - Navigator.pushNamed( - context, - AppRoutes.chatDetailed, - arguments: {"targetUser": m.favUsersList![index]}, - ).then((value) { - m.clearSelections(); - }); + ), + ) + ], + ), + title: (m.favUsersList![index].userName ?? "").toText14(color: MyColors.darkTextColor), + trailing: IconButton( + alignment: Alignment.centerRight, + padding: EdgeInsets.zero, + icon: Icon(m.favUsersList![index].isFav! ? Icons.star : Icons.star_border), + color: m.favUsersList![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, + onPressed: () { + if (m.favUsersList![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.favUsersList![index].id!); }, - onLongPress: () {}, ), - ); - }, - separatorBuilder: (BuildContext context, int index) => const Padding( - padding: EdgeInsets.only(right: 10, left: 70), - child: Divider( - color: Color(0xFFE5E5E5), + minVerticalPadding: 0, + onTap: () { + Navigator.pushNamed( + context, + AppRoutes.chatDetailed, + arguments: {"targetUser": m.favUsersList![index]}, + ).then( + (Object? value) { + m.clearSelections(); + }, + ); + }, + ), + ); + }, + separatorBuilder: (BuildContext context, int index) => const Padding( + padding: EdgeInsets.only(right: 10, left: 70), + child: Divider( + color: Color( + 0xFFE5E5E5, ), ), - ) - else - Utils.getNoDataWidget(context).expanded - ], - ); - }), + ), + ) + : Column( + children: [ + Utils.getNoDataWidget(context).expanded, + ], + ); + } + }, + ), ); } } From 3e5ce90c9a3885bc85c23f328bc1822abedbace9 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 14 Nov 2022 09:39:23 +0300 Subject: [PATCH 14/62] Chat Favorite Screen & Fixes --- lib/ui/chat/chat_detailed_screen.dart | 10 +++++++++- lib/ui/chat/favorite_users_screen.dart | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 7dfb321..e653fbe 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -15,7 +15,15 @@ import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:swipe_to/swipe_to.dart'; -class ChatDetailScreen extends StatelessWidget { +class ChatDetailScreen extends StatefulWidget { + // ignore: prefer_const_constructors_in_immutables + ChatDetailScreen({Key? key}) : super(key: key); + + @override + State createState() => _ChatDetailScreenState(); +} + +class _ChatDetailScreenState extends State { dynamic userDetails; late ChatProviderModel data; diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart index 2e3a3f2..a41c1b8 100644 --- a/lib/ui/chat/favorite_users_screen.dart +++ b/lib/ui/chat/favorite_users_screen.dart @@ -12,6 +12,8 @@ import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart' import 'package:provider/provider.dart'; class ChatFavoriteUsersScreen extends StatelessWidget { + const ChatFavoriteUsersScreen({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Scaffold( @@ -89,7 +91,7 @@ class ChatFavoriteUsersScreen extends StatelessWidget { ), ) : Column( - children: [ + children: [ Utils.getNoDataWidget(context).expanded, ], ); From 027b6ca7b6558405caae824569454dac334b9eac Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 14 Nov 2022 10:05:03 +0300 Subject: [PATCH 15/62] Chat Fixes --- lib/api/chat/chat_provider_model.dart | 30 +++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index b826753..a4ea408 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -148,7 +148,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ({String? connectionId}) {}, ); if (hubConnection.state != HubConnectionState.Connected) { - print("================= Connection Established =========================="); + if (kDebugMode) { + print("================= Connection Established =========================="); + } await hubConnection.start(); hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); @@ -176,7 +178,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } void userCountAsync(List? args) { - List items = args!.toList(); + dynamic items = args!.toList(); //logger.d("---------------------------------User Count Async -------------------------------------"); //logger.d(items); // for (var user in searchedChats!) { @@ -188,8 +190,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } void updateChatHistoryWindow(List? args) { - List items = args!.toList(); - print("---------------------------------Update Chat History Windows Async -------------------------------------"); + dynamic items = args!.toList(); + if (kDebugMode) { + print("---------------------------------Update Chat History Windows Async -------------------------------------"); + } logger.d(items); // for (var user in searchedChats!) { // if (user.id == items.first["id"]) { @@ -200,21 +204,25 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } void chatNotDelivered(List? args) { - List items = args!.toList(); - print("--------------------------------- Chat Not Delivered Windows Async -------------------------------------"); + dynamic items = args!.toList(); + if (kDebugMode) { + print("--------------------------------- Chat Not Delivered Windows Async -------------------------------------"); + } logger.d(items); // for (var user in searchedChats!) { // if (user.id == items.first["id"]) { // user.userStatus = items.first["userStatus"]; // } // } - // notifyListeners(); + // notifyListeners();2 } void changeStatus(List? args) { - // print("================= Status Online // Offline ===================="); - List items = args!.toList(); - // logger.d(items); + if (kDebugMode) { + print("================= Status Online // Offline ===================="); + } + dynamic items = args!.toList(); + logger.d(items); for (ChatUser user in searchedChats!) { if (user.id == items.first["id"]) { user.userStatus = items.first["userStatus"]; @@ -348,7 +356,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { // } Future sendChatToServer( - {required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { + {required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { Uuid uuid = const Uuid(); SingleUserChatModel data = SingleUserChatModel( chatEventId: chatEventId, From 93e7f7c862d02cd7d6c5b8bd849e2fcdb5350425 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 14 Nov 2022 10:13:25 +0300 Subject: [PATCH 16/62] Chat Fixes --- lib/classes/consts.dart | 4 ++-- lib/ui/chat/chat_home_screen.dart | 2 +- lib/ui/chat/favorite_users_screen.dart | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 646e498..c5788f9 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index f10cc26..b4483dc 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -117,7 +117,7 @@ class _ChatHomeScreenState extends State { ) ], ), - title: (m.searchedChats![index].userName ?? "").toText14(color: MyColors.darkTextColor), + title: (m.searchedChats![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor), // subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), trailing: SizedBox( width: 60, diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart index a41c1b8..8b5eba0 100644 --- a/lib/ui/chat/favorite_users_screen.dart +++ b/lib/ui/chat/favorite_users_screen.dart @@ -56,7 +56,7 @@ class ChatFavoriteUsersScreen extends StatelessWidget { ) ], ), - title: (m.favUsersList![index].userName ?? "").toText14(color: MyColors.darkTextColor), + title: (m.searchedChats![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor), trailing: IconButton( alignment: Alignment.centerRight, padding: EdgeInsets.zero, From 4ff3a5093bd2bc70f49d81df6d6fa2e0a539db67 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 14 Nov 2022 10:22:16 +0300 Subject: [PATCH 17/62] Action duration implemented --- lib/classes/date_uitl.dart | 76 ++++++++----- lib/extensions/string_extensions.dart | 3 +- lib/ui/work_list/item_history_screen.dart | 101 +++++++++++------- .../worklist_fragments/actions_fragment.dart | 28 ++++- 4 files changed, 140 insertions(+), 68 deletions(-) diff --git a/lib/classes/date_uitl.dart b/lib/classes/date_uitl.dart index 73945f8..f7b8192 100644 --- a/lib/classes/date_uitl.dart +++ b/lib/classes/date_uitl.dart @@ -381,6 +381,30 @@ class DateUtil { return ""; } + static String formatDuration(Duration d) { + var seconds = d.inSeconds; + var days = seconds ~/ Duration.secondsPerDay; + seconds -= days * Duration.secondsPerDay; + var hours = seconds ~/ Duration.secondsPerHour; + seconds -= hours * Duration.secondsPerHour; + var minutes = seconds ~/ Duration.secondsPerMinute; + seconds -= minutes * Duration.secondsPerMinute; + + List tokens = []; + if (days != 0) { + tokens.add('$days days'); + } + if (tokens.isNotEmpty || hours != 0) { + tokens.add('$hours hours'); + } + if (tokens.isNotEmpty || minutes != 0) { + tokens.add('$minutes mins'); + } + tokens.add('$seconds secs'); + + return tokens.join(' '); + } + /// get data formatted like 26/4/2020 /// [dateTime] convert DateTime to data formatted according to language static String getDayMonthYearDateFormattedLang(DateTime dateTime, bool isArabic) { @@ -431,30 +455,30 @@ class DateUtil { return "/Date(" + DateFormat('mm-dd-yyy').parse(isoDate).millisecondsSinceEpoch.toString() + ")/"; } - // static String getDay(DayOfWeek dayOfWeek) { - // switch (dayOfWeek) { - // case DayOfWeek.Monday: - // return "Monday"; - // break; - // case DayOfWeek.Tuesday: - // return "Tuesday"; - // break; - // case DayOfWeek.Wednesday: - // return "Wednesday"; - // break; - // case DayOfWeek.Thursday: - // return "Thursday"; - // break; - // case DayOfWeek.Friday: - // return "Friday"; - // break; - // case DayOfWeek.Saturday: - // return "Saturday"; - // break; - // case DayOfWeek.Sunday: - // return "Sunday"; - // break; - // } - // return ""; - // } +// static String getDay(DayOfWeek dayOfWeek) { +// switch (dayOfWeek) { +// case DayOfWeek.Monday: +// return "Monday"; +// break; +// case DayOfWeek.Tuesday: +// return "Tuesday"; +// break; +// case DayOfWeek.Wednesday: +// return "Wednesday"; +// break; +// case DayOfWeek.Thursday: +// return "Thursday"; +// break; +// case DayOfWeek.Friday: +// return "Friday"; +// break; +// case DayOfWeek.Saturday: +// return "Saturday"; +// break; +// case DayOfWeek.Sunday: +// return "Sunday"; +// break; +// } +// return ""; +// } } diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 9af8f2b..8bc15e7 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -22,8 +22,9 @@ extension EmailValidator on String { style: TextStyle(fontSize: 10, fontStyle: fontStyle ?? FontStyle.normal, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), ); - Widget toText11({Color? color, FontWeight? weight, bool isUnderLine = false, bool isBold = false}) => Text( + Widget toText11({Color? color, FontWeight? weight, bool isUnderLine = false, bool isBold = false, int maxLine = 0}) => Text( this, + maxLines: (maxLine > 0) ? maxLine : null, style: TextStyle( fontSize: 11, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600), diff --git a/lib/ui/work_list/item_history_screen.dart b/lib/ui/work_list/item_history_screen.dart index fb1066b..562b59f 100644 --- a/lib/ui/work_list/item_history_screen.dart +++ b/lib/ui/work_list/item_history_screen.dart @@ -86,9 +86,9 @@ class _ItemHistoryScreenState extends State { padding: const EdgeInsets.all(21), physics: const BouncingScrollPhysics(), children: [ - if (moItemHistoryList.isNotEmpty) loadMoItemHistoryData() else Utils.getNoDataWidget(context), - if (poItemHistoryList.isNotEmpty) loadPoItemHistoryData() else Utils.getNoDataWidget(context), - if (quotationAnalysisList.isNotEmpty) loadQuotationAnalysisData() else Utils.getNoDataWidget(context) + if (moItemHistoryList.isNotEmpty) loadMoItemHistoryData(), + if (poItemHistoryList.isNotEmpty) loadPoItemHistoryData(), + if (quotationAnalysisList.isNotEmpty) loadQuotationAnalysisData() ], ), ); @@ -102,21 +102,39 @@ class _ItemHistoryScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - ItemDetailView(LocaleKeys.requestNumber.tr(), moItemHistoryList[index].rEQUESTNUMBER ?? ""), - ItemDetailView(LocaleKeys.uom.tr(), moItemHistoryList[index].uNITOFMEASURE ?? ""), - ItemDetailView(LocaleKeys.quantity.tr(), moItemHistoryList[index].qUANTITY?.toString() ?? ""), - ItemDetailView(LocaleKeys.dateRequired.tr(), moItemHistoryList[index].dATEREQUIRED ?? ""), - ItemDetailView(LocaleKeys.lineStatus.tr(), moItemHistoryList[index].lINESTATUSDIS ?? ""), - ItemDetailView(LocaleKeys.statusDate.tr(), moItemHistoryList[index].sTATUSDATE ?? ""), - ItemDetailView(LocaleKeys.transactionType.tr(), moItemHistoryList[index].tRANSACTIONTYPENAME ?? ""), - ItemDetailView(LocaleKeys.organization.tr(), moItemHistoryList[index].oRGANIZATIONNAME ?? ""), - ItemDetailView(LocaleKeys.operatingCode.tr(), moItemHistoryList[index].oRGANIZATIONCODE ?? ""), - ItemDetailView(LocaleKeys.operatingUnit.tr(), moItemHistoryList[index].oPERATINGUNITNAME ?? ""), - ItemDetailView(LocaleKeys.fromSubInventory.tr(), moItemHistoryList[index].fROMSUBINVENTORYCODE ?? ""), - ItemDetailView(LocaleKeys.fromLocator.tr(), moItemHistoryList[index].fROMLOCATOR ?? ""), - ItemDetailView(LocaleKeys.toSubInventory.tr(), moItemHistoryList[index].tOSUBINVENTORYCODE ?? ""), - ItemDetailView(LocaleKeys.toLocator.tr(), moItemHistoryList[index].tOLOCATOR ?? ""), - ItemDetailView(LocaleKeys.shipToLocation.tr(), moItemHistoryList[index].sHIPTOLOCATION ?? ""), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.requestNumber.tr(), moItemHistoryList[index].rEQUESTNUMBER ?? ""), + ItemDetailViewCol(LocaleKeys.uom.tr(), moItemHistoryList[index].uNITOFMEASURE ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.quantity.tr(), moItemHistoryList[index].qUANTITY?.toString() ?? ""), + ItemDetailViewCol(LocaleKeys.dateRequired.tr(), moItemHistoryList[index].dATEREQUIRED ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.lineStatus.tr(), moItemHistoryList[index].lINESTATUSDIS ?? ""), + ItemDetailViewCol(LocaleKeys.statusDate.tr(), moItemHistoryList[index].sTATUSDATE ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.transactionType.tr(), moItemHistoryList[index].tRANSACTIONTYPENAME ?? ""), + ItemDetailViewCol(LocaleKeys.organization.tr(), moItemHistoryList[index].oRGANIZATIONNAME ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.operatingCode.tr(), moItemHistoryList[index].oRGANIZATIONCODE ?? ""), + ItemDetailViewCol(LocaleKeys.operatingUnit.tr(), moItemHistoryList[index].oPERATINGUNITNAME ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.fromSubInventory.tr(), moItemHistoryList[index].fROMSUBINVENTORYCODE ?? ""), + ItemDetailViewCol(LocaleKeys.fromLocator.tr(), moItemHistoryList[index].fROMLOCATOR ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.toSubInventory.tr(), moItemHistoryList[index].tOSUBINVENTORYCODE ?? ""), + ItemDetailViewCol(LocaleKeys.toLocator.tr(), moItemHistoryList[index].tOLOCATOR ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.shipToLocation.tr(), moItemHistoryList[index].sHIPTOLOCATION ?? ""), + Container(), + isItLast: true, + ), ], ).objectContainerView(), separatorBuilder: (cxt, index) => 12.height, @@ -131,10 +149,6 @@ class _ItemHistoryScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - // ItemDetailGrid( - // ItemDetailViewCol(LocaleKeys.from.tr(), workListData!.fROMUSER ?? ""), - // ItemDetailViewCol(LocaleKeys.to.tr(), workListData!.tOUSER ?? ""), - // ), ItemDetailGrid( ItemDetailViewCol(LocaleKeys.operatingUnit.tr(), poItemHistoryList[index].oUNAME ?? ""), ItemDetailViewCol(LocaleKeys.poNumber.tr(), poItemHistoryList[index].pONUMBER ?? ""), @@ -182,20 +196,35 @@ class _ItemHistoryScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - ItemDetailView(LocaleKeys.quotationNumber.tr(), quotationAnalysisList[index].qUOTNUM ?? ""), - ItemDetailView(LocaleKeys.vendorName.tr(), quotationAnalysisList[index].vENDORNAME ?? ""), - ItemDetailView(LocaleKeys.itemCode.tr(), quotationAnalysisList[index].iTEMCODE ?? ""), - ItemDetailView(LocaleKeys.description.tr(), quotationAnalysisList[index].iTEMDESC ?? ""), - ItemDetailView(LocaleKeys.quotationQty.tr(), quotationAnalysisList[index].qUOTQTY?.toString() ?? ""), - ItemDetailView(LocaleKeys.quotationUOM.tr(), quotationAnalysisList[index].qUOTUOM ?? ""), - ItemDetailView(LocaleKeys.quotationNetPrice.tr(), quotationAnalysisList[index].qUOTUNITPRICE?.toString() ?? ""), - ItemDetailView(LocaleKeys.quotationLineTotal.tr(), quotationAnalysisList[index].qUOTLINETOTAL?.toString() ?? ""), - ItemDetailView(LocaleKeys.quotationBonusQuantity.tr(), quotationAnalysisList[index].qUOTBONUSQTY ?? ""), - ItemDetailView(LocaleKeys.quotationDeliveryDate.tr(), quotationAnalysisList[index].qUOTDELIVERYDATE ?? ""), - ItemDetailView(LocaleKeys.quotationMFGPartNumber.tr(), quotationAnalysisList[index].qUOTMFGPARTNUM ?? ""), - ItemDetailView(LocaleKeys.rfqNumber.tr(), quotationAnalysisList[index].rFQNUM ?? ""), - ItemDetailView(LocaleKeys.rfqQty.tr(), quotationAnalysisList[index].rFQQTY?.toString() ?? ""), - ItemDetailView(LocaleKeys.rfqUOM.tr(), quotationAnalysisList[index].rFQUOM ?? ""), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.quotationNumber.tr(), quotationAnalysisList[index].qUOTNUM ?? ""), + ItemDetailViewCol(LocaleKeys.vendorName.tr(), quotationAnalysisList[index].vENDORNAME ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.itemCode.tr(), quotationAnalysisList[index].iTEMCODE ?? ""), + ItemDetailViewCol(LocaleKeys.description.tr(), quotationAnalysisList[index].iTEMDESC ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.quotationQty.tr(), quotationAnalysisList[index].qUOTQTY?.toString() ?? ""), + ItemDetailViewCol(LocaleKeys.quotationUOM.tr(), quotationAnalysisList[index].qUOTUOM ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.quotationNetPrice.tr(), quotationAnalysisList[index].qUOTUNITPRICE?.toString() ?? ""), + ItemDetailViewCol(LocaleKeys.quotationLineTotal.tr(), quotationAnalysisList[index].qUOTLINETOTAL?.toString() ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.quotationBonusQuantity.tr(), quotationAnalysisList[index].qUOTBONUSQTY ?? ""), + ItemDetailViewCol(LocaleKeys.quotationDeliveryDate.tr(), quotationAnalysisList[index].qUOTDELIVERYDATE ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.quotationMFGPartNumber.tr(), quotationAnalysisList[index].qUOTMFGPARTNUM ?? ""), + ItemDetailViewCol(LocaleKeys.rfqNumber.tr(), quotationAnalysisList[index].rFQNUM ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol(LocaleKeys.rfqQty.tr(), quotationAnalysisList[index].rFQQTY?.toString() ?? ""), + ItemDetailViewCol(LocaleKeys.rfqUOM.tr(), quotationAnalysisList[index].rFQUOM ?? ""), + isItLast: true, + ) ], ).objectContainerView(title: "${quotationAnalysisList[index].iTEMCODE}-${quotationAnalysisList[index].iTEMDESC}"), separatorBuilder: (cxt, index) => 12.height, diff --git a/lib/ui/work_list/worklist_fragments/actions_fragment.dart b/lib/ui/work_list/worklist_fragments/actions_fragment.dart index 8a69599..439888b 100644 --- a/lib/ui/work_list/worklist_fragments/actions_fragment.dart +++ b/lib/ui/work_list/worklist_fragments/actions_fragment.dart @@ -27,7 +27,7 @@ class ActionsFragment extends StatelessWidget { itemCount: actionHistoryList.length, padding: EdgeInsets.all(21), itemBuilder: (context, index) { - return showItem(context, actionHistoryList[index]); + return showItem(context, actionHistoryList[index], index); }, separatorBuilder: (BuildContext context, int index) { return 12.height; @@ -36,7 +36,7 @@ class ActionsFragment extends StatelessWidget { ); } - Widget showItem(BuildContext context, GetActionHistoryList actionHistory) { + Widget showItem(BuildContext context, GetActionHistoryList actionHistory, int index) { return Container( width: double.infinity, decoration: BoxDecoration( @@ -89,7 +89,9 @@ class ActionsFragment extends StatelessWidget { if (actionHistory.nOTIFICATIONDATE!.isNotEmpty) DateUtil.formatDateToDate(DateUtil.convertSimpleStringDateToDateddMMyyyy(actionHistory.nOTIFICATIONDATE!), false).toText12(color: MyColors.lightTextColor), ], - ) + ), + 10.height, + getActionDuration(index).toText11(maxLine: 1, color: const Color(0xff1FA269)) ], ), ) @@ -127,8 +129,24 @@ class ActionsFragment extends StatelessWidget { ); } + String getActionDuration(int index) { + if (actionHistoryList[index].aCTIONCODE == "SUBMIT") { + return ""; + } else if(actionHistoryList[index].aCTIONCODE == "PENDING") { + DateTime dateTimeFrom = DateUtil.convertSimpleStringDateToDate(actionHistoryList[++index].nOTIFICATIONDATE!); + Duration duration = DateTime.now().difference(dateTimeFrom); + return "Action duration: " + DateUtil.formatDuration(duration); + } else { + DateTime dateTimeTo = DateUtil.convertSimpleStringDateToDate(actionHistoryList[index].nOTIFICATIONDATE!); + DateTime dateTimeFrom = DateUtil.convertSimpleStringDateToDate(actionHistoryList[++index].nOTIFICATIONDATE!); + Duration duration = dateTimeTo.difference(dateTimeFrom); + print(dateTimeTo); + print(dateTimeFrom); + return "Action duration: " + DateUtil.formatDuration(duration); + } + } + Color getStatusColor(String code) { - print("code:$code"); if (code == "SUBMIT") { return const Color(0xff2E303A); } else if (code == "REJECTED") { @@ -139,7 +157,7 @@ class ActionsFragment extends StatelessWidget { return MyColors.orange; } else if (code == "APPROVED" || code == "APPROVE" || code == "ANSWER_INFO") { return const Color(0xff1FA269); - } else if (code == "REQUEST_INFO"|| code == "FORWARD") { + } else if (code == "REQUEST_INFO" || code == "FORWARD") { return const Color(0xff2E303A); } else if (code != "SUBMIT" && code != "REJECT" && code != "PENDING") { return MyColors.orange; From 2fe41977d8a9f83e9e3158004b9fe8b9f859ed23 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 14 Nov 2022 10:26:36 +0300 Subject: [PATCH 18/62] Chat Fixes --- lib/ui/chat/chat_detailed_screen.dart | 44 +++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index e653fbe..b9a7ea2 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -1,4 +1,5 @@ import 'dart:async'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -25,6 +26,8 @@ class ChatDetailScreen extends StatefulWidget { class _ChatDetailScreenState extends State { dynamic userDetails; + bool _firstAutoscrollExecuted = false; + bool _shouldAutoscroll = false; late ChatProviderModel data; @@ -40,6 +43,47 @@ class _ChatDetailScreenState extends State { await Future.delayed(const Duration(milliseconds: 1000)); _refreshController.refreshCompleted(); } + // + // void _scrollListener() { + // _firstAutoscrollExecuted = true; + // if (scrollController.hasClients && scrollController.position.pixels == scrollController.position.maxScrollExtent) { + // _shouldAutoscroll = true; + // } else { + // _shouldAutoscroll = false; + // } + // } + // + // void _scrollToBottom() { + // scrollController.jumpTo(scrollController.position.maxScrollExtent); + // } + + // void scrollToMaxExtent() { + // WidgetsBinding.instance.addPostFrameCallback((_) { + // scrollController.animateTo( + // scrollController.position.maxScrollExtent, + // duration: const Duration(milliseconds: 100), + // curve: Curves.easeIn, + // ); + // }); + // } + + + + @override + void initState() { + // TODO: implement initState + super.initState(); + //scrollToMaxExtent(); + + // scrollController.addListener(_scrollListener); + } + + @override + void dispose() { + // TODO: implement dispose + //scrollController.removeListener(_scrollListener); + super.dispose(); + } @override Widget build(BuildContext context) { From 2934203b8b156d5ba12d8c4b16bb4a68e1afd6f3 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 14 Nov 2022 10:30:47 +0300 Subject: [PATCH 19/62] Chat Fixes --- lib/ui/chat/chat_detailed_screen.dart | 4 ++-- lib/ui/chat/chat_home_screen.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index b9a7ea2..a6c0e67 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -92,7 +92,7 @@ class _ChatDetailScreenState extends State { if (userDetails != null) data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: false); return Scaffold( backgroundColor: const Color(0xFFF8F8F8), - appBar: AppBarWidget(context, title: userDetails["targetUser"].userName, showHomeButton: false, image: userDetails["targetUser"].image), + appBar: AppBarWidget(context, title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach, showHomeButton: false, image: userDetails["targetUser"].image), body: Consumer( builder: (BuildContext context, ChatProviderModel m, Widget? child) { return (m.isLoading @@ -149,7 +149,7 @@ class _ChatDetailScreenState extends State { height: 80, color: MyColors.black.withOpacity(0.10), child: ListTile( - title: (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString() ? "You" : m.repliedMsg.first.currentUserName.toString()) + title: (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString() ? "You" : m.repliedMsg.first.currentUserName.toString().replaceAll(".", " ")) .toText14(color: MyColors.lightGreenColor), subtitle: (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(color: MyColors.white, maxLine: 2), trailing: GestureDetector( diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index b4483dc..879e390 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -167,7 +167,7 @@ class _ChatHomeScreenState extends State { context, AppRoutes.chatDetailed, arguments: {"targetUser": m.searchedChats![index]}, - ).then((value) { + ).then((Object? value) { m.clearSelections(); }); }, From f1aadf50314b4d3af6deae4ae2e5b96092b970ae Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 14 Nov 2022 10:53:17 +0300 Subject: [PATCH 20/62] Chat Fixes --- lib/api/chat/chat_provider_model.dart | 4 ++-- lib/ui/chat/chat_detailed_screen.dart | 1 + lib/ui/chat/chat_home_screen.dart | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index a4ea408..fb9e6c5 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -219,10 +219,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void changeStatus(List? args) { if (kDebugMode) { - print("================= Status Online // Offline ===================="); + // print("================= Status Online // Offline ===================="); } dynamic items = args!.toList(); - logger.d(items); + // logger.d(items); for (ChatUser user in searchedChats!) { if (user.id == items.first["id"]) { user.userStatus = items.first["userStatus"]; diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index a6c0e67..e2d0bd7 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:convert'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 879e390..32f97fa 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -37,6 +37,7 @@ class _ChatHomeScreenState extends State { @override void dispose() { super.dispose(); + data.hubConnection.stop(); } @override From d849699489cdc36fb0cfbe33b5e67aa1ad8ef8f8 Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Mon, 14 Nov 2022 11:03:06 +0300 Subject: [PATCH 21/62] fix issues --- .../attendance/monthly_attendance_screen.dart | 2 +- lib/ui/misc/request_submit_screen.dart | 23 +- .../dynamic_screens/dynamic_input_screen.dart | 228 +++++++----------- 3 files changed, 94 insertions(+), 159 deletions(-) diff --git a/lib/ui/attendance/monthly_attendance_screen.dart b/lib/ui/attendance/monthly_attendance_screen.dart index de35da0..3115e46 100644 --- a/lib/ui/attendance/monthly_attendance_screen.dart +++ b/lib/ui/attendance/monthly_attendance_screen.dart @@ -286,7 +286,7 @@ class _MonthlyAttendanceScreenState extends State { showWeekNumber: false, cellBorderColor: Colors.white, selectionDecoration: BoxDecoration( - border: Border.all(color: MyColors.white, width: 10), + border: Border.all(color: MyColors.white, width: 1), shape: BoxShape.circle, ), dataSource: MeetingDataSource(_getDataSource()), diff --git a/lib/ui/misc/request_submit_screen.dart b/lib/ui/misc/request_submit_screen.dart index 7869443..f5a2d1e 100644 --- a/lib/ui/misc/request_submit_screen.dart +++ b/lib/ui/misc/request_submit_screen.dart @@ -68,7 +68,7 @@ class _RequestSubmitScreenState extends State { } void submitRequest() async { - // try { + try { Utils.showLoading(context); List> list = []; if (attachmentFiles.isNotEmpty) { @@ -90,28 +90,28 @@ class _RequestSubmitScreenState extends State { if (params!.approvalFlag == 'phone_numbers') { await ProfileApiClient().startPhoneApprovalProcess( - LocaleKeys.submit.tr(), + "SUBMIT", comments.text, params!.pItemId, params!.transactionId, ); } else if (params!.approvalFlag == 'address') { await ProfileApiClient().startAddressApprovalProcess( - LocaleKeys.submit.tr(), + "SUBMIT", comments.text, params!.pItemId, params!.transactionId, ); } else if (params!.approvalFlag == 'family_member') { await ProfileApiClient().getApproves( - LocaleKeys.submit.tr(), + "SUBMIT", comments.text, params!.transactionId!.toInt(), params!.pItemId.toString(), ); } else if (params!.approvalFlag == 'basicDetails') { await ProfileApiClient().startBasicDetailsApprovalProcess( - LocaleKeys.submit.tr(), + "SUBMIT", comments.text, params!.pItemId, params!.transactionId, @@ -124,15 +124,14 @@ class _RequestSubmitScreenState extends State { ); } else if (params!.approvalFlag == 'eit') { await MyAttendanceApiClient().startEitApprovalProcess( - LocaleKeys.submit.tr(), + "SUBMIT", comments.text, params!.pItemId, params!.transactionId, ); }else if (params!.approvalFlag == 'endEmployment') { await TerminationDffApiClient().startTermApprovalProcess( - // "SUBMIT", - LocaleKeys.submit.tr(), + "SUBMIT", comments.text, params!.pItemId, params!.transactionId, @@ -143,10 +142,10 @@ class _RequestSubmitScreenState extends State { Utils.showToast(LocaleKeys.yourRequestHasBeenSubmittedForApprovals.tr(), longDuration: true); Navigator.of(context).popUntil((route) => route.settings.name == AppRoutes.dashboard); Navigator.pushNamed(context, AppRoutes.workList); - // } catch (ex) { - // Utils.hideLoading(context); - // Utils.handleException(ex, context, null); - // } + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } } @override 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 045b808..519bb6c 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -48,17 +48,6 @@ class _DynamicInputScreenState extends State { descFlexConTextTitle = genericResponseModel!.pDESCFLEXCONTEXTNAME ?? ""; getEitDffStructureList = genericResponseModel?.getEITDFFStructureList ?? []; //getEitDffStructureList = getEitDffStructureList!.where((element) => element.dISPLAYFLAG != "N").toList(); - if (dynamicParams!.collectionNotificationList != null && dynamicParams!.collectionNotificationList!.isNotEmpty) { - getEitDffStructureList!.forEach((element) { - dynamicParams!.collectionNotificationList!.forEach((element2) { - if (element.sEGMENTNAME == element2.segmentName) { - element.fieldAnswer = element2.varchar2Value; - element.eSERVICESDV ??= ESERVICESDV(); - element.eSERVICESDV!.pIDCOLUMNNAME = element2.varchar2Value; - } - }); - }); - } Utils.hideLoading(context); setState(() {}); } catch (ex) { @@ -68,7 +57,7 @@ class _DynamicInputScreenState extends State { } void validateTransaction() async { - // try { + try { Utils.showLoading(context); List> values = getEitDffStructureList!.map((e) { String tempVar = e.eSERVICESDV?.pIDCOLUMNNAME ?? ""; @@ -102,11 +91,6 @@ class _DynamicInputScreenState extends State { values.add(ValidateEitTransactionModel(dATEVALUE: null, nAME: "PEI_OBJECT_VERSION_NUMBER", nUMBERVALUE: 0, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: null).toJson()); genericResponseModel = await MyAttendanceApiClient().validateEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values); - if (dynamicParams!.collectionNotificationList != null && dynamicParams!.collectionNotificationList!.isNotEmpty) { - Utils.hideLoading(context); - Navigator.pop(context, values); - return; - } SubmitEITTransactionList submitEITTransactionList = await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values); Utils.hideLoading(context); await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, @@ -114,10 +98,10 @@ class _DynamicInputScreenState extends State { Utils.showLoading(context); await LeaveBalanceApiClient().cancelHrTransaction(submitEITTransactionList.pTRANSACTIONID!); Utils.hideLoading(context); - // } catch (ex) { - // Utils.hideLoading(context); - // Utils.handleException(ex, context, null); - // } + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } } String dESCFLEXCONTEXTCODE = ""; @@ -126,42 +110,19 @@ class _DynamicInputScreenState extends State { Future calGetValueSetValues(GetEITDFFStructureList structureList) async { try { Utils.showLoading(context); - List> values = []; String segmentId = structureList.cHILDSEGMENTSVS!; - if (dESCFLEXCONTEXTCODE.isEmpty) dESCFLEXCONTEXTCODE = structureList.dESCFLEXCONTEXTCODE!; List filteredList = getEitDffStructureList?.where((element) => element.cHILDSEGMENTSVSSplited!.contains(segmentId)).toList() ?? []; - - if (filteredList.isEmpty && structureList.cHILDSEGMENTSVSSplited!.isNotEmpty) { - segmentId = structureList.cHILDSEGMENTSVSSplited![0]; - filteredList = getEitDffStructureList?.where((element) => element.cHILDSEGMENTSVSSplited!.contains(segmentId)).toList() ?? []; - } - values = filteredList + List> values = filteredList .map((e) => GetSetValuesRequestModel( sEGMENTNAME: e.sEGMENTNAME, vALUECOLUMNNAME: e.eSERVICESDV!.pVALUECOLUMNNAME, dESCRIPTION: "", iDCOLUMNNAME: e.eSERVICESDV!.pIDCOLUMNNAME, fLEXVALUESETNAME: e.fLEXVALUESETNAME) .toJson()) .toList(); - - // if (parentValue.isNotEmpty && (structureList.vALIDATIONTYPE == "F")) { - // values = getDependenciesParams(parentValue); - // } - // if (structureList.pARENTSEGMENTSVSSplitedVS!.isNotEmpty) { - // structureList.pARENTSEGMENTSVSSplitedVS!.forEach((element2) { - // filteredList = getEitDffStructureList?.where((element) => element.sEGMENTNAME == element2.name).toList() ?? []; - // values = filteredList - // .map((e) => GetSetValuesRequestModel( - // sEGMENTNAME: e.sEGMENTNAME, vALUECOLUMNNAME: e.eSERVICESDV!.pVALUECOLUMNNAME, dESCRIPTION: "", iDCOLUMNNAME: e.eSERVICESDV!.pIDCOLUMNNAME, fLEXVALUESETNAME: e.fLEXVALUESETNAME) - // .toJson()) - // .toList(); - // }); - // List filteredList2 = getEitDffStructureList?.where((element) => element.fLEXVALUESETNAME == structureList.fLEXVALUESETNAME).toList() ?? []; - // } - List eServicesResponseModel = await MyAttendanceApiClient().getValueSetValues(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, values); List abc = genericResponseModel?.getEITDFFStructureList ?? []; getEitDffStructureList = abc; - int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId); + int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == structureList.cHILDSEGMENTSVS); getEitDffStructureList![index].eSERVICESVS!.clear(); if (eServicesResponseModel.isNotEmpty) getEitDffStructureList![index].eSERVICESVS!.addAll(eServicesResponseModel); // getEitDffStructureList = genericResponseModel?.getEITDFFStructureList ?? []; @@ -175,7 +136,7 @@ class _DynamicInputScreenState extends State { } Future getDefaultValues(GetEITDFFStructureList structureList) async { - // try { + try { Utils.showLoading(context); for (int i = 0; i < (structureList.cHILDSEGMENTSDVSplited?.length ?? 0); i++) { String segmentId = structureList.cHILDSEGMENTSDVSplited![i]; @@ -197,34 +158,15 @@ class _DynamicInputScreenState extends State { ESERVICESDV defaultValue = await MyAttendanceApiClient().getDefaultValue(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, getSetList); int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId); getEitDffStructureList![index].eSERVICESDV = defaultValue; - GetEITDFFStructureList defaultValueCheck = getEitDffStructureList!.where((GetEITDFFStructureList element) => element.sEGMENTNAME == segmentId).toList().first; - - if (defaultValueCheck.cHILDSEGMENTSDVSplited!.isNotEmpty && defaultValueCheck.rEADONLY == 'Y') { - getDefaultValues(defaultValueCheck); - Utils.hideLoading(context); - - // GetEITDFFStructureList? parent = getEitDffStructureList!.firstWhere((element) => element.sEGMENTNAME == segmentId); - // List> getSetList = getDefaultValuesIonicLogic(parent); - // ESERVICESDV defaultValue = await MyAttendanceApiClient().getDefaultValue(segmentId, defaultValueCheck.dESCFLEXCONTEXTCODE!, defaultValueCheck.dESCFLEXNAME!, getSetList); - // int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId); - // getEitDffStructureList![index].eSERVICESDV = defaultValue; - } else if (defaultValueCheck.cHILDSEGMENTSVSSplited!.isNotEmpty && defaultValueCheck.rEADONLY == 'Y') { - calGetValueSetValues(defaultValueCheck); - Utils.hideLoading(context); - } - } else if (values.isNotEmpty) { - ESERVICESDV defaultValue = await MyAttendanceApiClient().getDefaultValue(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, values); - int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId); - getEitDffStructureList![index].eSERVICESDV = defaultValue; } } await Future.delayed(const Duration(seconds: 1)); Utils.hideLoading(context); setState(() {}); - // } catch (ex) { - // Utils.hideLoading(context); - // Utils.handleException(ex, context, null); - // } + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } } // List> calGetValueSetValuesIonicLogic(GetEITDFFStructureList structureElement) { @@ -238,79 +180,79 @@ class _DynamicInputScreenState extends State { // } List> getDefaultValuesIonicLogic(GetEITDFFStructureList structureElement) { - //try { - List parentValue = structureElement.pARENTSEGMENTSVSSplitedVS ?? []; - List parentsList = structureElement.pARENTSEGMENTSDVSplited ?? []; - - List> dependenciesList = []; - String? parentVal; - bool isStandardDate = false; - bool isStandardTimeDate = false; - bool isStandardTime = false; - bool isHidden = false; - bool isReadOnlyList = false; - bool isSelectElement = false; - - // isStandardDate = this.isStandardDate(obj); - // isStandardTimeDate = this.isStandardDateTime(obj); - // isStandardTime = this.isStandardTime(obj); - if (structureElement.dISPLAYFLAG == "N") isHidden = true; - if (structureElement.vALIDATIONTYPE != "N" && structureElement.rEADONLY == "Y") { - isReadOnlyList = true; - } - if (structureElement.vALIDATIONTYPE != "N" && structureElement.rEADONLY == "N") { - isSelectElement = true; - } + try { + List parentValue = structureElement.pARENTSEGMENTSVSSplitedVS ?? []; + List parentsList = structureElement.pARENTSEGMENTSDVSplited ?? []; + + List> dependenciesList = []; + String? parentVal; + bool isStandardDate = false; + bool isStandardTimeDate = false; + bool isStandardTime = false; + bool isHidden = false; + bool isReadOnlyList = false; + bool isSelectElement = false; + + // isStandardDate = this.isStandardDate(obj); + // isStandardTimeDate = this.isStandardDateTime(obj); + // isStandardTime = this.isStandardTime(obj); + if (structureElement.dISPLAYFLAG == "N") isHidden = true; + if (structureElement.vALIDATIONTYPE != "N" && structureElement.rEADONLY == "Y") { + isReadOnlyList = true; + } + if (structureElement.vALIDATIONTYPE != "N" && structureElement.rEADONLY == "N") { + isSelectElement = true; + } - if (parentValue.isNotEmpty && (structureElement.vALIDATIONTYPE == "D" || structureElement.vALIDATIONTYPE == "Y")) { - List parValue = getDependenciesParams(parentValue); + if (parentValue.isNotEmpty && (structureElement.vALIDATIONTYPE == "D" || structureElement.vALIDATIONTYPE == "Y")) { + List parValue = getDependenciesParams(parentValue); - if (parValue.isNotEmpty) { - parentVal = parValue.first.ID_COLUMN_NAME; - } + if (parValue.isNotEmpty) { + parentVal = parValue.first.ID_COLUMN_NAME; + } - if (parentVal == null) { - return []; + if (parentVal == null) { + return []; + } } - } - if (parentsList.isNotEmpty) { - if (parentValue.isNotEmpty) { - parentsList = parentsList + parentValue.map((e) => PARENTSEGMENTSDVSplited.fromJson(e.toJson())).toList(); - // parentsList.addAll(parentValue.map((e) => PARENTSEGMENTSDVSplited.fromJson(e.toJson()))); - // parentsList.concat(parentValue); + if (parentsList.isNotEmpty) { + if (parentValue.isNotEmpty) { + parentsList = parentsList + parentValue.map((e) => PARENTSEGMENTSDVSplited.fromJson(e.toJson())).toList(); + // parentsList.addAll(parentValue.map((e) => PARENTSEGMENTSDVSplited.fromJson(e.toJson()))); + // parentsList.concat(parentValue); + } + dependenciesList = getDependenciesParams(parentsList); } - dependenciesList = getDependenciesParams(parentsList); + return dependenciesList; + // for (int i = 0; i < (structureList.cHILDSEGMENTSDVSplited?.length ?? 0); i++) { + // String segmentId = structureList.cHILDSEGMENTSDVSplited![i]; + // print("segmentId:$segmentId"); + // print("segmentName:${structureList.sEGMENTNAME}"); + // GetEITDFFStructureList? parent = getEitDffStructureList!.firstWhere((element) => element.sEGMENTNAME == segmentId); + // List parentDvRequired = parent.pARENTSEGMENTSDVSplited ?? []; + // List parentVsRequired = parent.pARENTSEGMENTSVSSplitedVS ?? []; + // + // List filteredList = + // getEitDffStructureList!.where((outerElement) => parentDvRequired.any((element) => outerElement.sEGMENTNAME == element.name && element.isRequired == "REQUIRED")).toList(); + // + // List> values = filteredList + // .map((e) => GetSetValuesRequestModel( + // sEGMENTNAME: e.sEGMENTNAME, vALUECOLUMNNAME: e.eSERVICESDV!.pVALUECOLUMNNAME, dESCRIPTION: "", iDCOLUMNNAME: e.eSERVICESDV!.pIDCOLUMNNAME, fLEXVALUESETNAME: e.fLEXVALUESETNAME) + // .toJson()) + // .toList(); + // print("values:$values"); + // + // ESERVICESDV defaultValue = await MyAttendanceApiClient().getDefaultValue(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, values); + // int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId); + // getEitDffStructureList![index].eSERVICESDV = defaultValue; + // } + // Utils.hideLoading(context); + // setState(() {}); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + return []; } - return dependenciesList; - // for (int i = 0; i < (structureList.cHILDSEGMENTSDVSplited?.length ?? 0); i++) { - // String segmentId = structureList.cHILDSEGMENTSDVSplited![i]; - // print("segmentId:$segmentId"); - // print("segmentName:${structureList.sEGMENTNAME}"); - // GetEITDFFStructureList? parent = getEitDffStructureList!.firstWhere((element) => element.sEGMENTNAME == segmentId); - // List parentDvRequired = parent.pARENTSEGMENTSDVSplited ?? []; - // List parentVsRequired = parent.pARENTSEGMENTSVSSplitedVS ?? []; - // - // List filteredList = - // getEitDffStructureList!.where((outerElement) => parentDvRequired.any((element) => outerElement.sEGMENTNAME == element.name && element.isRequired == "REQUIRED")).toList(); - // - // List> values = filteredList - // .map((e) => GetSetValuesRequestModel( - // sEGMENTNAME: e.sEGMENTNAME, vALUECOLUMNNAME: e.eSERVICESDV!.pVALUECOLUMNNAME, dESCRIPTION: "", iDCOLUMNNAME: e.eSERVICESDV!.pIDCOLUMNNAME, fLEXVALUESETNAME: e.fLEXVALUESETNAME) - // .toJson()) - // .toList(); - // print("values:$values"); - // - // ESERVICESDV defaultValue = await MyAttendanceApiClient().getDefaultValue(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, values); - // int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId); - // getEitDffStructureList![index].eSERVICESDV = defaultValue; - // } - // Utils.hideLoading(context); - // setState(() {}); - // } catch (ex) { - // Utils.hideLoading(context); - // Utils.handleException(ex, context, null); - // return []; - // } } List> getDependenciesParams(parentsList) { @@ -318,7 +260,7 @@ class _DynamicInputScreenState extends State { for (int i = 0; i < parentsList.length; i++) { for (int j = 0; j < (getEitDffStructureList?.length ?? 0); j++) { - if (getEitDffStructureList![j].sEGMENTNAME == parentsList[i]?.name) { + if (getEitDffStructureList![j].sEGMENTNAME == parentsList[i].name) { if (getEitDffStructureList![j].dISPLAYFLAG != "N") { if (getEitDffStructureList![j].vALIDATIONTYPE == "N") { String? idColName; @@ -398,7 +340,7 @@ class _DynamicInputScreenState extends State { String? text = data?.pVALUECOLUMNNAME; String? val = data?.pIDCOLUMNNAME; - if ((val ?? "").isEmpty && parentsList[i].isRequired == "REQUIRED") { + if ((val ?? "").isEmpty && parentsList[i].IsRequired == "REQUIRED") { //alert(parentsList[i].Name +" Is required"); return []; } else {} @@ -420,8 +362,7 @@ class _DynamicInputScreenState extends State { String? text = data?.pVALUECOLUMNNAME; String? val = data?.pIDCOLUMNNAME; - /// - if ((val ?? "").isEmpty && parentsList[i].isRequired == "REQUIRED") { + if ((val ?? "").isEmpty && parentsList[i].IsRequired == "REQUIRED") { //alert(parentsList[i].Name +" Is required"); return []; } else {} @@ -514,11 +455,6 @@ class _DynamicInputScreenState extends State { model.eSERVICESDV ??= ESERVICESDV(); model.eSERVICESDV!.pIDCOLUMNNAME = text; }, - onTap: () async { - if (model.cHILDSEGMENTSDVSplited?.isNotEmpty ?? false) { - await getDefaultValues(model); - } - }, ).paddingOnly(bottom: 12); } else if (model.fORMATTYPE == "X") { String displayText = model.eSERVICESDV?.pIDCOLUMNNAME ?? (getEitDffStructureList![index].fieldAnswer ?? ""); From 29626ea408b1f2f6905b02c6cd93a7daf53b20ba Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 14 Nov 2022 12:26:50 +0300 Subject: [PATCH 22/62] Chat Fixes --- ios/Runner.xcodeproj/project.pbxproj | 6 +-- lib/api/chat/chat_provider_model.dart | 64 ++++++++++++++++++++++---- lib/classes/consts.dart | 4 +- lib/ui/chat/chat_bubble.dart | 2 +- lib/ui/chat/chat_detailed_screen.dart | 60 +++--------------------- lib/ui/chat/chat_home.dart | 6 +++ lib/ui/chat/chat_home_screen.dart | 4 +- lib/ui/chat/favorite_users_screen.dart | 2 +- 8 files changed, 76 insertions(+), 72 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 9daee21..43841a1 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -383,7 +383,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 3A359E86ZF; + DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; @@ -520,7 +520,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 3A359E86ZF; + DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; @@ -549,7 +549,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 3A359E86ZF; + DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index fb9e6c5..0f0e94c 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -1,10 +1,12 @@ +import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'dart:math'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart'; +import 'package:logger/logger.dart' as L; import 'package:logging/logging.dart'; import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; @@ -15,17 +17,17 @@ import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.da import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as login; import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; import 'package:mohem_flutter_app/widgets/image_picker.dart'; -import 'package:path_provider/path_provider.dart'; import 'package:signalr_netcore/signalr_client.dart'; -import 'package:logger/logger.dart' as L; import 'package:uuid/uuid.dart'; class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { + ScrollController scrollController = ScrollController(); + TextEditingController message = TextEditingController(); List userChatHistory = []; List? pChatHistory, searchedChats; late HubConnection hubConnection; L.Logger logger = L.Logger(); - TextEditingController message = TextEditingController(); + bool isLoading = true; bool isChatScreenActive = false; late File selectedFile; @@ -36,6 +38,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List favUsersList = []; int paginationVal = 0; + //Scroll + bool _firstAutoscrollExecuted = false; + bool _shouldAutoscroll = false; + Future getUserAutoLoginToken() async { String userName = AppState().memberInformationList!.eMPLOYEEEMAILADDRESS!.split("@").first.toString(); Response response = @@ -87,12 +93,20 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void getSingleUserChatHistory({required String senderUID, required int receiverUID, required bool loadMore}) async { isLoading = true; + print(loadMore); + print(senderUID); + print(receiverUID); if (!loadMore) paginationVal = 0; + print(paginationVal); isChatScreenActive = true; Response response = await ApiClient().getJsonForResponse( "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal", token: AppState().chatDetails!.response!.token, ); + logger.d("${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal"); + logger.d("${AppState().chatDetails!.response!.token}"); + logger.d(jsonEncode(response.body)); + logger.d(jsonEncode(response.statusCode)); if (response.statusCode == 204) { if (!loadMore) userChatHistory = []; Utils.showToast("No More Data To Load"); @@ -105,7 +119,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } isLoading = false; + //Timer(const Duration(milliseconds: 100),() => scrollToBottom()); notifyListeners(); + + // scrollToBottom(); } List getSingleUserChatModel(String str) => List.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); @@ -218,9 +235,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } void changeStatus(List? args) { - if (kDebugMode) { - // print("================= Status Online // Offline ===================="); - } + if (kDebugMode) { + // print("================= Status Online // Offline ===================="); + } dynamic items = args!.toList(); // logger.d(items); for (ChatUser user in searchedChats!) { @@ -258,6 +275,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { data.first.currentUserName = temp.first.targetUserName; } userChatHistory.add(data.first); + scrollToBottom(); notifyListeners(); // if (isChatScreenActive) scrollDown(); } @@ -356,7 +374,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { // } Future sendChatToServer( - {required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { + {required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { Uuid uuid = const Uuid(); SingleUserChatModel data = SingleUserChatModel( chatEventId: chatEventId, @@ -390,6 +408,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { isMsgReply = false; sFileType = ""; message.clear(); + scrollToBottom(); notifyListeners(); } @@ -575,4 +594,33 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { repliedMsg = []; sFileType = ""; } + + void scrollListener() { + _firstAutoscrollExecuted = true; + if (scrollController.hasClients && scrollController.position.pixels == scrollController.position.maxScrollExtent) { + _shouldAutoscroll = true; + } else { + _shouldAutoscroll = false; + } + } + + void scrollToBottom() { + //scrollController.jumpTo(scrollController.position.maxScrollExtent + 100 ); + scrollController.animateTo( + scrollController.position.maxScrollExtent + 100, + duration: const Duration(milliseconds: 500), + curve: Curves.easeIn, + ); + } + +// void scrollToMaxExtent() { +// WidgetsBinding.instance.addPostFrameCallback((_) { +// scrollController.animateTo( +// scrollController.position.maxScrollExtent, +// duration: const Duration(milliseconds: 100), +// curve: Curves.easeIn, +// ); +// }); +// } + } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index c5788f9..ede22e3 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index d9bd599..c638b34 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -89,7 +89,7 @@ class ChatBubble extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, children: [ - dateTime.toText12(color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7)), + dateTime.toText12(color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7),), if (isCurrentUser) 5.width, if (isCurrentUser) Icon( diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index e2d0bd7..b4838f3 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:convert'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -17,23 +16,14 @@ import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:swipe_to/swipe_to.dart'; -class ChatDetailScreen extends StatefulWidget { +class ChatDetailScreen extends StatelessWidget { // ignore: prefer_const_constructors_in_immutables ChatDetailScreen({Key? key}) : super(key: key); - @override - State createState() => _ChatDetailScreenState(); -} - -class _ChatDetailScreenState extends State { dynamic userDetails; - bool _firstAutoscrollExecuted = false; - bool _shouldAutoscroll = false; late ChatProviderModel data; - ScrollController scrollController = ScrollController(); - final RefreshController _refreshController = RefreshController(initialRefresh: false); void getMoreChat() async { @@ -44,53 +34,13 @@ class _ChatDetailScreenState extends State { await Future.delayed(const Duration(milliseconds: 1000)); _refreshController.refreshCompleted(); } - // - // void _scrollListener() { - // _firstAutoscrollExecuted = true; - // if (scrollController.hasClients && scrollController.position.pixels == scrollController.position.maxScrollExtent) { - // _shouldAutoscroll = true; - // } else { - // _shouldAutoscroll = false; - // } - // } - // - // void _scrollToBottom() { - // scrollController.jumpTo(scrollController.position.maxScrollExtent); - // } - - // void scrollToMaxExtent() { - // WidgetsBinding.instance.addPostFrameCallback((_) { - // scrollController.animateTo( - // scrollController.position.maxScrollExtent, - // duration: const Duration(milliseconds: 100), - // curve: Curves.easeIn, - // ); - // }); - // } - - - - @override - void initState() { - // TODO: implement initState - super.initState(); - //scrollToMaxExtent(); - - // scrollController.addListener(_scrollListener); - } - - @override - void dispose() { - // TODO: implement dispose - //scrollController.removeListener(_scrollListener); - super.dispose(); - } @override Widget build(BuildContext context) { userDetails = ModalRoute.of(context)!.settings.arguments; data = Provider.of(context, listen: false); if (userDetails != null) data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: false); + data.scrollController.addListener(data.scrollListener); return Scaffold( backgroundColor: const Color(0xFFF8F8F8), appBar: AppBarWidget(context, title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach, showHomeButton: false, image: userDetails["targetUser"].image), @@ -111,7 +61,7 @@ class _ChatDetailScreenState extends State { controller: _refreshController, onRefresh: getMoreChat, child: ListView.builder( - controller: scrollController, + controller: m.scrollController, shrinkWrap: true, reverse: false, itemCount: m.userChatHistory.length, @@ -150,7 +100,9 @@ class _ChatDetailScreenState extends State { height: 80, color: MyColors.black.withOpacity(0.10), child: ListTile( - title: (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString() ? "You" : m.repliedMsg.first.currentUserName.toString().replaceAll(".", " ")) + title: (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString() + ? "You" + : m.repliedMsg.first.currentUserName.toString().replaceAll(".", " ")) .toText14(color: MyColors.lightGreenColor), subtitle: (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(color: MyColors.white, maxLine: 2), trailing: GestureDetector( diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 5176273..d3c4d62 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -1,5 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; @@ -11,6 +12,7 @@ import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart'; import 'package:mohem_flutter_app/ui/screens/items_for_sale/fragments/items_for_sale.dart'; import 'package:mohem_flutter_app/ui/screens/items_for_sale/fragments/my_posted_ads_fragment.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; +import 'package:provider/provider.dart'; class ChatHome extends StatefulWidget { const ChatHome({Key? key}) : super(key: key); @@ -22,9 +24,13 @@ class ChatHome extends StatefulWidget { class _ChatHomeState extends State { int tabIndex = 0; PageController controller = PageController(); + late ChatProviderModel data; + @override Widget build(BuildContext context) { + data = Provider.of(context, listen: false); + data.getUserAutoLoginToken().whenComplete(() => null); return Scaffold( backgroundColor: MyColors.white, appBar: AppBarWidget( diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 32f97fa..e55f018 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -29,9 +29,7 @@ class _ChatHomeScreenState extends State { void initState() { super.initState(); data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().whenComplete(() { - data.getUserRecentChats(); - }); + data.getUserRecentChats(); } @override diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart index 8b5eba0..29d4ffa 100644 --- a/lib/ui/chat/favorite_users_screen.dart +++ b/lib/ui/chat/favorite_users_screen.dart @@ -56,7 +56,7 @@ class ChatFavoriteUsersScreen extends StatelessWidget { ) ], ), - title: (m.searchedChats![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor), + title: (m.favUsersList![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor), trailing: IconButton( alignment: Alignment.centerRight, padding: EdgeInsets.zero, From b18ebf7a54efc4c352f183303348de6a33a4712a Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 14 Nov 2022 15:34:31 +0300 Subject: [PATCH 23/62] Chat Favorite Screen & Fixes --- lib/api/chat/chat_provider_model.dart | 32 --------------------------- lib/classes/consts.dart | 2 +- lib/ui/chat/chat_home.dart | 4 +++- lib/ui/chat/chat_home_screen.dart | 4 ---- 4 files changed, 4 insertions(+), 38 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 0f0e94c..a61a57a 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -93,20 +93,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void getSingleUserChatHistory({required String senderUID, required int receiverUID, required bool loadMore}) async { isLoading = true; - print(loadMore); - print(senderUID); - print(receiverUID); if (!loadMore) paginationVal = 0; - print(paginationVal); isChatScreenActive = true; Response response = await ApiClient().getJsonForResponse( "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal", token: AppState().chatDetails!.response!.token, ); - logger.d("${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal"); - logger.d("${AppState().chatDetails!.response!.token}"); - logger.d(jsonEncode(response.body)); - logger.d(jsonEncode(response.statusCode)); if (response.statusCode == 204) { if (!loadMore) userChatHistory = []; Utils.showToast("No More Data To Load"); @@ -119,10 +111,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } isLoading = false; - //Timer(const Duration(milliseconds: 100),() => scrollToBottom()); notifyListeners(); - - // scrollToBottom(); } List getSingleUserChatModel(String str) => List.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); @@ -364,15 +353,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } - // void scrollDown() { - // scrollController.animateTo( - // scrollController.position.maxScrollExtent + 100, - // curve: Curves.easeOut, - // duration: const Duration(milliseconds: 300), - // ); - // notifyListeners(); - // } - Future sendChatToServer( {required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { Uuid uuid = const Uuid(); @@ -605,22 +585,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } void scrollToBottom() { - //scrollController.jumpTo(scrollController.position.maxScrollExtent + 100 ); scrollController.animateTo( scrollController.position.maxScrollExtent + 100, duration: const Duration(milliseconds: 500), curve: Curves.easeIn, ); } - -// void scrollToMaxExtent() { -// WidgetsBinding.instance.addPostFrameCallback((_) { -// scrollController.animateTo( -// scrollController.position.maxScrollExtent, -// duration: const Duration(milliseconds: 100), -// curve: Curves.easeIn, -// ); -// }); -// } - } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index ede22e3..93b4ea8 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - //static String baseUrl = "https://hmgwebservices.com"; // Live 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/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index d3c4d62..ea53d2e 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -30,7 +30,9 @@ class _ChatHomeState extends State { @override Widget build(BuildContext context) { data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().whenComplete(() => null); + data.getUserAutoLoginToken().then((value){ + data.getUserRecentChats(); + }); return Scaffold( backgroundColor: MyColors.white, appBar: AppBarWidget( diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index e55f018..1b351e5 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -23,19 +23,15 @@ class ChatHomeScreen extends StatefulWidget { class _ChatHomeScreenState extends State { TextEditingController search = TextEditingController(); - late ChatProviderModel data; @override void initState() { super.initState(); - data = Provider.of(context, listen: false); - data.getUserRecentChats(); } @override void dispose() { super.dispose(); - data.hubConnection.stop(); } @override From 4433f538b78d636d86508cf633ab998473d31df6 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 14 Nov 2022 15:38:15 +0300 Subject: [PATCH 24/62] Chat Favorite Screen & Fixes --- lib/api/chat/chat_provider_model.dart | 4 ---- lib/ui/chat/chat_home_screen.dart | 23 ++--------------------- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index a61a57a..d033eba 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -154,9 +154,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ({String? connectionId}) {}, ); if (hubConnection.state != HubConnectionState.Connected) { - if (kDebugMode) { - print("================= Connection Established =========================="); - } await hubConnection.start(); hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); @@ -167,7 +164,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); } - // notifyListeners(); } void updateUserChatStatus(List? args) { diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 1b351e5..540a212 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -14,26 +14,9 @@ import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_s import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:provider/provider.dart'; -class ChatHomeScreen extends StatefulWidget { - const ChatHomeScreen({Key? key}) : super(key: key); - - @override - State createState() => _ChatHomeScreenState(); -} - -class _ChatHomeScreenState extends State { +class ChatHomeScreen extends StatelessWidget { TextEditingController search = TextEditingController(); - @override - void initState() { - super.initState(); - } - - @override - void dispose() { - super.dispose(); - } - @override Widget build(BuildContext context) { return Scaffold( @@ -211,9 +194,7 @@ class _ChatHomeScreenState extends State { title: LocaleKeys.searchForEmployee.tr(), apiMode: LocaleKeys.delegate.tr(), fromChat: true, - onSelectEmployee: (_selectedEmployee) { - setState(() {}); - }, + onSelectEmployee: (_selectedEmployee) {}, ), ); }, From 8f80c396d132d5d38227d996f9184e03f23fe313 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 14 Nov 2022 15:50:27 +0300 Subject: [PATCH 25/62] Chat Fixes --- lib/api/chat/chat_provider_model.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index d033eba..00691ec 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -260,9 +260,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { data.first.currentUserName = temp.first.targetUserName; } userChatHistory.add(data.first); - scrollToBottom(); notifyListeners(); - // if (isChatScreenActive) scrollDown(); + if (isChatScreenActive) scrollToBottom(); } void onUserTyping(List? parameters) { From b8e20633c9acb6d28f1d27582f1e3c8816f3ade9 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 14 Nov 2022 16:20:40 +0300 Subject: [PATCH 26/62] Chat Fixes --- lib/ui/chat/chat_home_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 540a212..7fb6965 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -128,7 +128,7 @@ class ChatHomeScreen extends StatelessWidget { child: IconButton( alignment: Alignment.centerRight, padding: EdgeInsets.zero, - icon: Icon(m.searchedChats![index].isFav! ? Icons.star : Icons.star_border), + icon: Icon(m.searchedChats![index].isFav! ? Icons.star_sharp : Icons.star_border), color: m.searchedChats![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, onPressed: () { if (m.searchedChats![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); From fb5440358430fb6d27558384504f56bb5fb7ab03 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Tue, 15 Nov 2022 09:32:30 +0300 Subject: [PATCH 27/62] Chat Favorite Screen & Fixes --- lib/api/chat/chat_provider_model.dart | 38 ++++++++++++++----- lib/ui/chat/chat_detailed_screen.dart | 5 ++- lib/ui/chat/chat_home_screen.dart | 2 +- lib/ui/chat/favorite_users_screen.dart | 2 +- .../search_employee_bottom_sheet.dart | 2 +- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 00691ec..3cfee4f 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -91,7 +91,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } - void getSingleUserChatHistory({required String senderUID, required int receiverUID, required bool loadMore}) async { + void getSingleUserChatHistory({required String senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false}) async { isLoading = true; if (!loadMore) paginationVal = 0; isChatScreenActive = true; @@ -100,8 +100,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { token: AppState().chatDetails!.response!.token, ); if (response.statusCode == 204) { - if (!loadMore) userChatHistory = []; - Utils.showToast("No More Data To Load"); + if (isNewChat) { + userChatHistory = []; + } else if (loadMore) { + // userChatHistory = []; + Utils.showToast("No More Data To Load"); + } } else { if (loadMore) { List temp = getSingleUserChatModel(response.body); @@ -131,7 +135,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } else { result = []; } - } catch (e) {} + } catch (e) { + if (kDebugMode) { + print(e); + } + } + ; return result; } @@ -139,11 +148,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); hubConnection = HubConnectionBuilder() .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp) - .withAutomaticReconnect(retryDelays: [2000, 5000, 10000, 20000]) - .configureLogging( - Logger("Logs Enabled"), - ) - .build(); + .withAutomaticReconnect( + retryDelays: [2000, 5000, 10000, 20000], + ).build(); hubConnection.onclose( ({Exception? error}) {}, ); @@ -157,6 +164,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { await hubConnection.start(); hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); + hubConnection.on("OnSeenChatUserAsync", onChatSeen); //hubConnection.on("OnUserTypingAsync", onUserTyping); // hubConnection.on("OnUserCountAsync", userCountAsync); @@ -179,6 +187,18 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } + void onChatSeen(List? args) { + dynamic items = args!.toList(); + logger.d("---------------------------------Chat Seen -------------------------------------"); + logger.d(items); + // for (var user in searchedChats!) { + // if (user.id == items.first["id"]) { + // user.userStatus = items.first["userStatus"]; + // } + // } + // notifyListeners(); + } + void userCountAsync(List? args) { dynamic items = args!.toList(); //logger.d("---------------------------------User Count Async -------------------------------------"); diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index b4838f3..5c05173 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -29,7 +29,7 @@ class ChatDetailScreen extends StatelessWidget { void getMoreChat() async { if (userDetails != null) { data.paginationVal = data.paginationVal + 10; - data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true); + data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true, isNewChat: false); } await Future.delayed(const Duration(milliseconds: 1000)); _refreshController.refreshCompleted(); @@ -39,7 +39,8 @@ class ChatDetailScreen extends StatelessWidget { Widget build(BuildContext context) { userDetails = ModalRoute.of(context)!.settings.arguments; data = Provider.of(context, listen: false); - if (userDetails != null) data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: false); + if (userDetails != null) + data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: false, isNewChat: userDetails["isNewChat"]); data.scrollController.addListener(data.scrollListener); return Scaffold( backgroundColor: const Color(0xFFF8F8F8), diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 7fb6965..ce866f8 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -144,7 +144,7 @@ class ChatHomeScreen extends StatelessWidget { Navigator.pushNamed( context, AppRoutes.chatDetailed, - arguments: {"targetUser": m.searchedChats![index]}, + arguments: {"targetUser": m.searchedChats![index], "isNewChat" : false}, ).then((Object? value) { m.clearSelections(); }); diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart index 29d4ffa..fd118de 100644 --- a/lib/ui/chat/favorite_users_screen.dart +++ b/lib/ui/chat/favorite_users_screen.dart @@ -71,7 +71,7 @@ class ChatFavoriteUsersScreen extends StatelessWidget { Navigator.pushNamed( context, AppRoutes.chatDetailed, - arguments: {"targetUser": m.favUsersList![index]}, + arguments: {"targetUser": m.favUsersList![index], "isNewChat": false}, ).then( (Object? value) { m.clearSelections(); diff --git a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart index 63ce88b..a30b33d 100644 --- a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart +++ b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart @@ -233,7 +233,7 @@ class _SearchEmployeeBottomSheetState extends State { Navigator.pushNamed( context, AppRoutes.chatDetailed, - arguments: {"targetUser": chatUsersList![index]}, + arguments: {"targetUser": chatUsersList![index], "isNewChat": true}, ); }, onLongPress: () {}, From 670a5fbc03a94976e922bfb7bcb8f39806cf1f9d Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Tue, 15 Nov 2022 10:18:42 +0300 Subject: [PATCH 28/62] Chat Favorite Screen & Fixes --- assets/langs/ar-SA.json | 2 +- assets/langs/en-US.json | 2 +- lib/api/chat/chat_provider_model.dart | 4 +++ lib/generated/codegen_loader.g.dart | 4 +-- lib/ui/chat/chat_home_screen.dart | 37 ++++++++++++--------------- 5 files changed, 24 insertions(+), 25 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index bdec4f0..000e111 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -499,7 +499,7 @@ "resend": "إعادة إرسال", "codeExpire": "انتهت صلاحية رمز التحقق", "typeheretoreply": "اكتب هنا للرد", - "favorite" : "مفضل", + "favorite" : "أُفضله", "searchfromchat": "البحث من الدردشة" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 1cd1a33..c8b8322 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -499,7 +499,7 @@ "codeExpire": "The verification code has been expired", "allQuestionsCorrect": "You have answered all questions correct", "typeheretoreply": "Type here to reply", - "favorite" : "Favorite", + "favorite" : "My Favorite", "searchfromchat": "Search from chat" } \ No newline at end of file diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 3cfee4f..3498a17 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -23,6 +23,7 @@ import 'package:uuid/uuid.dart'; class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ScrollController scrollController = ScrollController(); TextEditingController message = TextEditingController(); + TextEditingController search = TextEditingController(); List userChatHistory = []; List? pChatHistory, searchedChats; late HubConnection hubConnection; @@ -582,12 +583,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } void clearSelections() { + searchedChats = pChatHistory; + search.clear(); isChatScreenActive = false; paginationVal = 0; message.text = ''; isFileSelected = false; repliedMsg = []; sFileType = ""; + notifyListeners(); } void scrollListener() { diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 49dac5c..3d35ccc 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -515,7 +515,7 @@ class CodegenLoader extends AssetLoader{ "resend": "إعادة إرسال", "codeExpire": "انتهت صلاحية رمز التحقق", "typeheretoreply": "اكتب هنا للرد", - "favorite": "مفضل", + "favorite": "أُفضله", "searchfromchat": "البحث من الدردشة" }; static const Map en_US = { @@ -1019,7 +1019,7 @@ static const Map en_US = { "codeExpire": "The verification code has been expired", "allQuestionsCorrect": "You have answered all questions correct", "typeheretoreply": "Type here to reply", - "favorite": "Favorite", + "favorite": "My Favorite", "searchfromchat": "Search from chat" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index ce866f8..f66f3d5 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -32,28 +32,14 @@ class ChatHomeScreen extends StatelessWidget { Padding( padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20), child: TextField( + controller: m.search, onChanged: (String val) { m.filter(val); }, decoration: InputDecoration( - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(5), - borderSide: const BorderSide( - color: Color(0xFFE5E5E5), - ), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(5), - borderSide: const BorderSide( - color: Color(0xFFE5E5E5), - ), - ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(5), - borderSide: const BorderSide( - color: Color(0xFFE5E5E5), - ), - ), + border: fieldBorder(radius: 5, color: 0xFFE5E5E5), + focusedBorder: fieldBorder(radius: 5, color: 0xFFE5E5E5), + enabledBorder: fieldBorder(radius: 5, color: 0xFFE5E5E5), contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), hintText: LocaleKeys.searchfromchat.tr(), hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic), @@ -73,7 +59,7 @@ class ChatHomeScreen extends StatelessWidget { height: 55, child: ListTile( leading: Stack( - children: [ + children: [ SvgPicture.asset( "assets/images/user.svg", height: 48, @@ -144,12 +130,12 @@ class ChatHomeScreen extends StatelessWidget { Navigator.pushNamed( context, AppRoutes.chatDetailed, - arguments: {"targetUser": m.searchedChats![index], "isNewChat" : false}, + arguments: {"targetUser": m.searchedChats![index], "isNewChat": false}, ).then((Object? value) { m.clearSelections(); + m.notifyListeners(); }); }, - onLongPress: () {}, ), ); }, @@ -201,4 +187,13 @@ class ChatHomeScreen extends StatelessWidget { ), ); } + + OutlineInputBorder fieldBorder({required double radius, required int color}) { + return OutlineInputBorder( + borderRadius: BorderRadius.circular(radius), + borderSide: BorderSide( + color: Color(color), + ), + ); + } } From c190fbf5ca5fadeb8fd680ef8660dbb8cceed372 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Tue, 15 Nov 2022 11:14:52 +0300 Subject: [PATCH 29/62] Chat Favorite Screen & Fixes --- lib/api/chat/chat_provider_model.dart | 16 ++++++++++++++-- lib/ui/chat/chat_detailed_screen.dart | 14 +++++++++----- lib/ui/chat/chat_home.dart | 18 +++++++++--------- lib/ui/chat/chat_home_screen.dart | 25 ++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 17 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 3498a17..0cb67e6 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -109,10 +109,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } else { if (loadMore) { - List temp = getSingleUserChatModel(response.body); - userChatHistory.insertAll(0, temp); + List temp = getSingleUserChatModel(response.body).reversed.toList(); + userChatHistory.addAll(temp); } else { userChatHistory = getSingleUserChatModel(response.body); + userChatHistory = userChatHistory.reversed.toList(); } } isLoading = false; @@ -594,6 +595,17 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } + void clearAll() { + searchedChats = pChatHistory; + search.clear(); + isChatScreenActive = false; + paginationVal = 0; + message.text = ''; + isFileSelected = false; + repliedMsg = []; + sFileType = ""; + } + void scrollListener() { _firstAutoscrollExecuted = true; if (scrollController.hasClients && scrollController.position.pixels == scrollController.position.maxScrollExtent) { diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 5c05173..04e84e0 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -32,7 +32,7 @@ class ChatDetailScreen extends StatelessWidget { data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true, isNewChat: false); } await Future.delayed(const Duration(milliseconds: 1000)); - _refreshController.refreshCompleted(); + _refreshController.loadComplete(); } @override @@ -54,17 +54,21 @@ class ChatDetailScreen extends StatelessWidget { Expanded( flex: 2, child: SmartRefresher( - enablePullDown: true, - enablePullUp: false, + enablePullDown: false, + enablePullUp: true, + onLoading: () { + getMoreChat(); + }, header: const MaterialClassicHeader( color: MyColors.gradiantEndColor, ), controller: _refreshController, - onRefresh: getMoreChat, + reverse: true, child: ListView.builder( controller: m.scrollController, shrinkWrap: true, - reverse: false, + physics: const BouncingScrollPhysics(), + reverse: true, itemCount: m.userChatHistory.length, padding: const EdgeInsets.only(top: 20), itemBuilder: (BuildContext context, int i) { diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index ea53d2e..86356bb 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -26,11 +26,16 @@ class _ChatHomeState extends State { PageController controller = PageController(); late ChatProviderModel data; + @override + void dispose() { + data.clearAll(); + super.dispose(); + } @override Widget build(BuildContext context) { data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().then((value){ + data.getUserAutoLoginToken().then((value) { data.getUserRecentChats(); }); return Scaffold( @@ -41,7 +46,7 @@ class _ChatHomeState extends State { showHomeButton: true, ), body: Column( - children: [ + children: [ Container( padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16), decoration: const BoxDecoration( @@ -60,12 +65,7 @@ class _ChatHomeState extends State { ), ), child: Row( - children: [ - myTab(LocaleKeys.mychats.tr(), 0), - myTab( - LocaleKeys.favorite.tr(), - 1) - ], + children: [myTab(LocaleKeys.mychats.tr(), 0), myTab(LocaleKeys.favorite.tr(), 1)], ), ), PageView( @@ -76,7 +76,7 @@ class _ChatHomeState extends State { tabIndex = pageIndex; }); }, - children: [ChatHomeScreen(), ChatFavoriteUsersScreen()], + children: [ChatHomeScreen(), ChatFavoriteUsersScreen()], ).expanded, ], ), diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index f66f3d5..3ac291c 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -14,9 +14,20 @@ import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_s import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:provider/provider.dart'; -class ChatHomeScreen extends StatelessWidget { +class ChatHomeScreen extends StatefulWidget { + @override + State createState() => _ChatHomeScreenState(); +} + +class _ChatHomeScreenState extends State { TextEditingController search = TextEditingController(); + @override + void dispose() { + super.dispose(); + search.clear(); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -45,6 +56,18 @@ class ChatHomeScreen extends StatelessWidget { hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic), filled: true, fillColor: const Color(0xFFF7F7F7), + suffixIcon: m.search.text.isNotEmpty + ? IconButton( + onPressed: () { + m.clearSelections(); + }, + icon: const Icon( + Icons.clear, + size: 22, + ), + color: MyColors.redA3Color, + ) + : null, ), ), ), From 70dd6e1c991eb5a29eb5e59080bfb5407bba1d27 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 15 Nov 2022 11:55:08 +0300 Subject: [PATCH 30/62] Chat Fixes --- lib/api/chat/chat_provider_model.dart | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 0cb67e6..727fd12 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -7,7 +7,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart'; import 'package:logger/logger.dart' as L; -import 'package:logging/logging.dart'; import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; @@ -112,8 +111,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List temp = getSingleUserChatModel(response.body).reversed.toList(); userChatHistory.addAll(temp); } else { - userChatHistory = getSingleUserChatModel(response.body); - userChatHistory = userChatHistory.reversed.toList(); + userChatHistory = getSingleUserChatModel(response.body).reversed.toList(); } } isLoading = false; @@ -400,12 +398,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { String chatData = '{"contant":"${message.text}","contantNo":"${uuid.v4()}","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"${uuid.v4()}"}'; await hubConnection.invoke("AddChatUserAsync", args: [json.decode(chatData)]); - userChatHistory.add(data); + + userChatHistory.insert(0, data); + isFileSelected = false; isMsgReply = false; sFileType = ""; message.clear(); - scrollToBottom(); notifyListeners(); } @@ -622,4 +621,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { curve: Curves.easeIn, ); } + + void msgScroll() { + scrollController.animateTo( + scrollController.position.minScrollExtent - 100, + duration: const Duration(milliseconds: 500), + curve: Curves.easeIn, + ); + } } From ae917a415476f6eec33814b6ad3d550508b7a955 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Tue, 15 Nov 2022 12:44:09 +0300 Subject: [PATCH 31/62] Chat Favorite Screen & Fixes --- lib/api/chat/chat_provider_model.dart | 13 ++++++++++--- lib/ui/chat/chat_home.dart | 17 +++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 727fd12..be5b68c 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -164,7 +164,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { await hubConnection.start(); hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); - hubConnection.on("OnSeenChatUserAsync", onChatSeen); + // hubConnection.on("OnSeenChatUserAsync", onChatSeen); //hubConnection.on("OnUserTypingAsync", onUserTyping); // hubConnection.on("OnUserCountAsync", userCountAsync); @@ -269,6 +269,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } Future onMsgReceived(List? parameters) async { + print("msg Received"); List data = []; List temp = []; for (dynamic msg in parameters!) { @@ -279,9 +280,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { data.first.currentUserId = temp.first.targetUserId; data.first.currentUserName = temp.first.targetUserName; } - userChatHistory.add(data.first); + userChatHistory.insert(0, data.first); + // searchedChats!.forEach((element) { + // if (element.id == data.first.currentUserId) { + // var val = element.unreadMessageCount == null ? 0 : element.unreadMessageCount; + // element.unreadMessageCount = val! + 1; + // } + // }); notifyListeners(); - if (isChatScreenActive) scrollToBottom(); + // if (isChatScreenActive) scrollToBottom(); } void onUserTyping(List? parameters) { diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 86356bb..1fdcb33 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -26,18 +26,27 @@ class _ChatHomeState extends State { PageController controller = PageController(); late ChatProviderModel data; + + @override + void initState() { + // TODO: implement initState + super.initState(); + data = Provider.of(context, listen: false); + data.getUserAutoLoginToken().then((value) { + data.getUserRecentChats(); + }); + } + @override void dispose() { data.clearAll(); + data.hubConnection.stop(); super.dispose(); } @override Widget build(BuildContext context) { - data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().then((value) { - data.getUserRecentChats(); - }); + return Scaffold( backgroundColor: MyColors.white, appBar: AppBarWidget( From c436908d2509c72cbf754245798c7763263e7169 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 15 Nov 2022 14:23:51 +0300 Subject: [PATCH 32/62] updates & fixes --- lib/api/worklist/worklist_api_client.dart | 18 +++ .../attendance/monthly_attendance_screen.dart | 2 +- lib/ui/landing/today_attendance_screen2.dart | 2 +- lib/ui/landing/widget/services_widget.dart | 2 +- lib/ui/marathon/widgets/marathon_banner.dart | 4 +- .../dynamic_screens/dynamic_input_screen.dart | 10 +- lib/ui/my_team/view_attendance.dart | 2 +- lib/ui/profile/add_update_family_member.dart | 2 +- lib/ui/profile/family_members.dart | 3 +- lib/ui/screens/my_requests/my_requests.dart | 6 +- .../offers_and_discounts_details.dart | 4 +- lib/ui/work_list/itg_detail_screen.dart | 29 +++++ lib/ui/work_list/work_list_screen.dart | 1 - lib/ui/work_list/worklist_detail_screen.dart | 11 ++ .../worklist_fragments/actions_fragment.dart | 2 - lib/widgets/app_bar_widget.dart | 110 ++++++++++-------- 16 files changed, 135 insertions(+), 73 deletions(-) diff --git a/lib/api/worklist/worklist_api_client.dart b/lib/api/worklist/worklist_api_client.dart index d999d18..75992e7 100644 --- a/lib/api/worklist/worklist_api_client.dart +++ b/lib/api/worklist/worklist_api_client.dart @@ -403,6 +403,24 @@ class WorkListApiClient { }, url, postParams); } + Future grantITGRequest(String requestType, int taskId, int itemId, String employeeNumber, String newUserEMPId, String comments) async { + String url = "${ApiConsts.cocRest}ITGGrantAccess"; + Map postParams = { + "RequestType": requestType, + "TaskID": taskId, + "ItemID": itemId, + "EmployeeNumber": employeeNumber, + "Comments": "", + "AdditionalFields": null, + "NewUserEMPId":newUserEMPId + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + ItgFormsModel responseData = ItgFormsModel.fromJson(json); + return responseData.itgRequest; + }, url, postParams); + } + Future informationITGRequest(String requestType, int taskId, int itemId, String employeeNumber, String newUserEMPId, String comments) async { String url = "${ApiConsts.cocRest}ITGRequestInformation"; Map postParams = { diff --git a/lib/ui/attendance/monthly_attendance_screen.dart b/lib/ui/attendance/monthly_attendance_screen.dart index de35da0..8b62b7f 100644 --- a/lib/ui/attendance/monthly_attendance_screen.dart +++ b/lib/ui/attendance/monthly_attendance_screen.dart @@ -431,7 +431,7 @@ class _MonthlyAttendanceScreenState extends State { expand: false, builder: (_, controller) { dynamic dmyString = getScheduleShiftsDetailsList!.sCHEDULEDATE; - DateTime dateTime1 = DateFormat("MM/dd/yyyy hh:mm:ss a").parse(dmyString); + DateTime dateTime1 = DateFormat("MM/dd/yyyy hh:mm:ss").parse(dmyString); return Column( children: [ Container( diff --git a/lib/ui/landing/today_attendance_screen2.dart b/lib/ui/landing/today_attendance_screen2.dart index 17bb03a..ada652c 100644 --- a/lib/ui/landing/today_attendance_screen2.dart +++ b/lib/ui/landing/today_attendance_screen2.dart @@ -86,7 +86,7 @@ class _TodayAttendanceScreenState extends State { child: CircularStepProgressBar( totalSteps: 16 * 4, currentStep: (model.progress * 100).toInt(), - selectedColor: MyColors.gradiantEndColor, + selectedColor: MyColors.gradiantStartColor, unselectedColor: MyColors.grey70Color, child: Center( child: Padding( diff --git a/lib/ui/landing/widget/services_widget.dart b/lib/ui/landing/widget/services_widget.dart index ae24dde..2333c18 100644 --- a/lib/ui/landing/widget/services_widget.dart +++ b/lib/ui/landing/widget/services_widget.dart @@ -74,7 +74,7 @@ class ServicesWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( - child: data.homeMenus![parentIndex].menuEntiesList[index].prompt!.toText10(isBold: true), + child: data.homeMenus![parentIndex].menuEntiesList[index].prompt!.toText11(isBold: true), ), RotatedBox(quarterTurns: AppState().isArabic(context) ? 2 : 4, child: SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4)), ], diff --git a/lib/ui/marathon/widgets/marathon_banner.dart b/lib/ui/marathon/widgets/marathon_banner.dart index 5da5ed2..55ff715 100644 --- a/lib/ui/marathon/widgets/marathon_banner.dart +++ b/lib/ui/marathon/widgets/marathon_banner.dart @@ -142,7 +142,7 @@ class MarathonBanner extends StatelessWidget { bottom: 0, child: RotatedBox( quarterTurns: 4, - child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.darkDigitColor), + child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.whiteColor), ).paddingAll(15), ) : Positioned( @@ -150,7 +150,7 @@ class MarathonBanner extends StatelessWidget { left: 0, child: RotatedBox( quarterTurns: 2, - child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.darkDigitColor), + child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.whiteColor), ).paddingAll(15), ), ], 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 045b808..e602c21 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -68,7 +68,7 @@ class _DynamicInputScreenState extends State { } void validateTransaction() async { - // try { + try { Utils.showLoading(context); List> values = getEitDffStructureList!.map((e) { String tempVar = e.eSERVICESDV?.pIDCOLUMNNAME ?? ""; @@ -114,10 +114,10 @@ class _DynamicInputScreenState extends State { Utils.showLoading(context); await LeaveBalanceApiClient().cancelHrTransaction(submitEITTransactionList.pTRANSACTIONID!); Utils.hideLoading(context); - // } catch (ex) { - // Utils.hideLoading(context); - // Utils.handleException(ex, context, null); - // } + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } } String dESCFLEXCONTEXTCODE = ""; diff --git a/lib/ui/my_team/view_attendance.dart b/lib/ui/my_team/view_attendance.dart index 90414d1..0896d5e 100644 --- a/lib/ui/my_team/view_attendance.dart +++ b/lib/ui/my_team/view_attendance.dart @@ -439,7 +439,7 @@ class _ViewAttendanceState extends State { expand: false, builder: (_, controller) { dynamic dmyString = getScheduleShiftsDetailsList!.sCHEDULEDATE; - DateTime dateTime1 = DateFormat("MM/dd/yyyy hh:mm:ss a").parse(dmyString); + DateTime dateTime1 = DateFormat("MM/dd/yyyy hh:mm:ss").parse(dmyString); return Column( children: [ Container( diff --git a/lib/ui/profile/add_update_family_member.dart b/lib/ui/profile/add_update_family_member.dart index 528e38d..36a8394 100644 --- a/lib/ui/profile/add_update_family_member.dart +++ b/lib/ui/profile/add_update_family_member.dart @@ -383,7 +383,7 @@ class _AddUpdateFamilyMemberState extends State { ), ); } else { - DateTime? picked = await showDatePicker(context: context, initialDate: selectedDate, initialEntryMode: DatePickerEntryMode.calendarOnly, firstDate: DateTime(2015, 8), lastDate: DateTime(2101)); + DateTime? picked = await showDatePicker(context: context, initialDate: selectedDate, initialEntryMode: DatePickerEntryMode.calendarOnly, firstDate: DateTime(1920, 1), lastDate: DateTime.now()); if (picked != null && picked != selectedDate) { time = picked; } diff --git a/lib/ui/profile/family_members.dart b/lib/ui/profile/family_members.dart index fd7bd13..25f62c0 100644 --- a/lib/ui/profile/family_members.dart +++ b/lib/ui/profile/family_members.dart @@ -128,7 +128,8 @@ class _FamilyMembersState extends State { ), DefaultButton(LocaleKeys.addNewFamilyMember.tr(), menuEntries.updateButton == 'Y' - ? () async { + ? + () async { Navigator.pushNamed(context, AppRoutes.addUpdateFamilyMember, arguments: {"relationID": relationId, "flag": 1, "actionType": "ADD"}); // ProfileScreen(); } : null).insideContainer, diff --git a/lib/ui/screens/my_requests/my_requests.dart b/lib/ui/screens/my_requests/my_requests.dart index f9d8d39..dd6147f 100644 --- a/lib/ui/screens/my_requests/my_requests.dart +++ b/lib/ui/screens/my_requests/my_requests.dart @@ -76,9 +76,7 @@ class _MyRequestsState extends State { }), ), 12.height, - Expanded( - // todo list don't have data, need to confirm later , because have issues, need fixes - + getCCPTransactionsList.isNotEmpty ? Expanded( child: ListView.separated( physics: const BouncingScrollPhysics(), shrinkWrap: true, @@ -141,7 +139,7 @@ class _MyRequestsState extends State { }, separatorBuilder: (BuildContext context, int index) => 12.height, itemCount: getCCPTransactionsList.length), - ), + ) : Container(), ], ).expanded, 1.divider, diff --git a/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart b/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart index 9a308ba..325f4f3 100644 --- a/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart +++ b/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart @@ -176,8 +176,8 @@ class _OffersAndDiscountsDetailsState extends State { // // launchUrl(Uri.parse(url!)); // // } // ), - getOffersList.description!.toText12(maxLine: 2, color: const Color(0xff535353)), - 16.height, + // getOffersList.description!.toText12(maxLine: 2, color: const Color(0xff535353)), + // 16.height, getOffersList.discount!.toText14(isBold: true, maxlines: 1), 8.height, Row( diff --git a/lib/ui/work_list/itg_detail_screen.dart b/lib/ui/work_list/itg_detail_screen.dart index bbb0267..cf33648 100644 --- a/lib/ui/work_list/itg_detail_screen.dart +++ b/lib/ui/work_list/itg_detail_screen.dart @@ -367,6 +367,12 @@ class _ItgDetailScreenState extends State { case "Answer": performAction("Answer"); break; + case "ReportGenerated": + performDataCorrectionORReportGeneratedAction(requestDetails!.requestType!, requestDetails!.iD!, requestDetails!.itemID!, AppState().memberInformationList?.eMPLOYEENUMBER ?? ""); + break; + case "DataCorrected": + performDataCorrectionORReportGeneratedAction(requestDetails!.requestType!, requestDetails!.iD!, requestDetails!.itemID!, AppState().memberInformationList?.eMPLOYEENUMBER ?? ""); + break; } setState(() { showFabOptions = false; @@ -525,6 +531,29 @@ class _ItgDetailScreenState extends State { } } + void performDataCorrectionORReportGeneratedAction(String requestType, int taskId, int itemId, String employeeNumber) async { + try { + Utils.showLoading(context); + ITGRequest? itgRequest = await WorkListApiClient().grantITGRequest(requestType, taskId, itemId, employeeNumber, "", ""); + Utils.hideLoading(context); + Utils.showToast(LocaleKeys.yourChangeHasBeenSavedSuccessfully.tr()); + AppState().requestAllList!.removeAt(AppState().itgWorkListIndex!); + if (AppState().requestAllList!.isEmpty) { + Navigator.pop(context, "delegate_reload"); + } else { + if (AppState().requestAllList!.length <= AppState().itgWorkListIndex!) { + Navigator.pop(context, "delegate_reload"); + } else { + requestDetails = null; + getDataFromState(); + } + } + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } + void reloadITG() { AppState().requestAllList!.removeAt(AppState().itgWorkListIndex!); if (AppState().requestAllList!.isEmpty) { diff --git a/lib/ui/work_list/work_list_screen.dart b/lib/ui/work_list/work_list_screen.dart index 8efd789..f9f8d91 100644 --- a/lib/ui/work_list/work_list_screen.dart +++ b/lib/ui/work_list/work_list_screen.dart @@ -226,7 +226,6 @@ class _WorkListScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container(width: double.infinity, height: 1, color: MyColors.lightGreyEFColor), SizedBox( height: 40, child: ListView.separated( diff --git a/lib/ui/work_list/worklist_detail_screen.dart b/lib/ui/work_list/worklist_detail_screen.dart index 3c05204..824edc3 100644 --- a/lib/ui/work_list/worklist_detail_screen.dart +++ b/lib/ui/work_list/worklist_detail_screen.dart @@ -476,6 +476,17 @@ class _WorkListDetailScreenState extends State { isUpdate: true, collectionNotificationList: getEitCollectionNotificationBodyList![0].collectionNotification)), ); break; + case "CONTINUE_ACTION": + showMyBottomSheet( + context, + callBackFunc: reloadWorkList, + child: UpdateContinueSheet( + workListData: workListData, + getEitCollectionNotificationBodyList: getEitCollectionNotificationBodyList, + dynamicParams: DynamicListViewParams(workListData!.sUBJECT!, workListData!.fUNCTIONNAME!, + isUpdate: true, collectionNotificationList: getEitCollectionNotificationBodyList![0].collectionNotification)), + ); + break; case "APPROVE_AND_FORWARD": showMyBottomSheet(context, callBackFunc: reloadWorkList, diff --git a/lib/ui/work_list/worklist_fragments/actions_fragment.dart b/lib/ui/work_list/worklist_fragments/actions_fragment.dart index 439888b..58e9ac7 100644 --- a/lib/ui/work_list/worklist_fragments/actions_fragment.dart +++ b/lib/ui/work_list/worklist_fragments/actions_fragment.dart @@ -140,8 +140,6 @@ class ActionsFragment extends StatelessWidget { DateTime dateTimeTo = DateUtil.convertSimpleStringDateToDate(actionHistoryList[index].nOTIFICATIONDATE!); DateTime dateTimeFrom = DateUtil.convertSimpleStringDateToDate(actionHistoryList[++index].nOTIFICATIONDATE!); Duration duration = dateTimeTo.difference(dateTimeFrom); - print(dateTimeTo); - print(dateTimeFrom); return "Action duration: " + DateUtil.formatDuration(duration); } } diff --git a/lib/widgets/app_bar_widget.dart b/lib/widgets/app_bar_widget.dart index 745dedf..35c93ba 100644 --- a/lib/widgets/app_bar_widget.dart +++ b/lib/widgets/app_bar_widget.dart @@ -6,65 +6,73 @@ 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'; -AppBar AppBarWidget(BuildContext context, +PreferredSize AppBarWidget(BuildContext context, {required String title, bool showHomeButton = true, bool showNotificationButton = false, bool showMemberButton = false, String? image}) { - return AppBar( - leadingWidth: 0, - // leading: GestureDetector( - // behavior: HitTestBehavior.opaque, - // onTap: Feedback.wrapForTap(() => Navigator.maybePop(context), context), - // child: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), - // ), - //titleSpacing: -1.44, - title: Row( + return PreferredSize( + preferredSize: const Size.fromHeight(57.0), + child: Column( children: [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: - Feedback.wrapForTap(() => Navigator.maybePop(context), context), - child: - const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + AppBar( + leadingWidth: 0, + // leading: GestureDetector( + // behavior: HitTestBehavior.opaque, + // onTap: Feedback.wrapForTap(() => Navigator.maybePop(context), context), + // child: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + // ), + //titleSpacing: -1.44, + title: Row( + children: [ + GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: + Feedback.wrapForTap(() => Navigator.maybePop(context), context), + child: + const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + ), + 4.width, + if (image != null) SvgPicture.asset( + image, + height: 40, + width: 40, + ), + if (image != null) 14.width, + title.toText24(color: MyColors.darkTextColor, isBold: true).expanded, + ], + ), + centerTitle: false, + elevation: 0, + backgroundColor: Colors.white, + actions: [ + if (showHomeButton) + IconButton( + onPressed: () { + Navigator.popUntil( + context, ModalRoute.withName(AppRoutes.dashboard)); + }, + icon: const Icon(Icons.home, color: MyColors.darkIconColor), + ), + if (showNotificationButton) + IconButton( + onPressed: () { + Navigator.pushNamed(context, AppRoutes.worklistSettings); + }, + icon: const Icon(Icons.notifications, color: MyColors.textMixColor), + ), + if (showMemberButton) + IconButton( + onPressed: () { + Navigator.pushNamed(context, AppRoutes.subordinateLeave); + }, + icon: const Icon(Icons.people, color: MyColors.textMixColor), + ), + ], ), - 4.width, - if (image != null) SvgPicture.asset( - image, - height: 40, - width: 40, - ), - if (image != null) 14.width, - title.toText24(color: MyColors.darkTextColor, isBold: true).expanded, + Container(width: double.infinity, height: 1, color: MyColors.lightGreyEFColor), ], ), - centerTitle: false, - elevation: 0, - backgroundColor: Colors.white, - actions: [ - if (showHomeButton) - IconButton( - onPressed: () { - Navigator.popUntil( - context, ModalRoute.withName(AppRoutes.dashboard)); - }, - icon: const Icon(Icons.home, color: MyColors.darkIconColor), - ), - if (showNotificationButton) - IconButton( - onPressed: () { - Navigator.pushNamed(context, AppRoutes.worklistSettings); - }, - icon: const Icon(Icons.notifications, color: MyColors.textMixColor), - ), - if (showMemberButton) - IconButton( - onPressed: () { - Navigator.pushNamed(context, AppRoutes.subordinateLeave); - }, - icon: const Icon(Icons.people, color: MyColors.textMixColor), - ), - ], ); } From 7c00f7dce8efef654c18167bcd389723c062e2f8 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 15 Nov 2022 15:26:34 +0300 Subject: [PATCH 33/62] Chat Fixes --- lib/api/chat/chat_provider_model.dart | 19 ++++----- lib/ui/chat/chat_home_screen.dart | 57 +++++++++++++++------------ 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index be5b68c..c9767b4 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -44,6 +44,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future getUserAutoLoginToken() async { String userName = AppState().memberInformationList!.eMPLOYEEEMAILADDRESS!.split("@").first.toString(); + //userName Response response = await ApiClient().postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}user/desktopuserlogin", {"userName": userName, "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", "loginType": 2}); login.UserAutoLoginModel userLoginResponse = login.userAutoLoginModelFromJson(response.body); @@ -84,8 +85,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } } - pChatHistory = recentChat.response; - pChatHistory!.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase())); + pChatHistory = recentChat.response == null ? [] : recentChat.response; + if (pChatHistory != null) pChatHistory!.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase())); + searchedChats = pChatHistory; isLoading = false; notifyListeners(); @@ -164,7 +166,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { await hubConnection.start(); hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); - // hubConnection.on("OnSeenChatUserAsync", onChatSeen); + // hubConnection.on("OnSeenChatUserAsync", onChatSeen); //hubConnection.on("OnUserTypingAsync", onUserTyping); // hubConnection.on("OnUserCountAsync", userCountAsync); @@ -288,7 +290,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { // } // }); notifyListeners(); - // if (isChatScreenActive) scrollToBottom(); + // if (isChatScreenActive) scrollToBottom(); } void onUserTyping(List? parameters) { @@ -402,17 +404,16 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ) : null, ); - String chatData = - '{"contant":"${message.text}","contantNo":"${uuid.v4()}","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"${uuid.v4()}"}'; - await hubConnection.invoke("AddChatUserAsync", args: [json.decode(chatData)]); - userChatHistory.insert(0, data); - isFileSelected = false; isMsgReply = false; sFileType = ""; message.clear(); notifyListeners(); + + String chatData = + '{"contant":"${message.text}","contantNo":"${uuid.v4()}","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"${uuid.v4()}"}'; + await hubConnection.invoke("AddChatUserAsync", args: [json.decode(chatData)]); } void sendChatMessage(int targetUserId, String targetUserName) async { diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 3ac291c..d146891 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -7,7 +9,6 @@ import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/config/routes.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/widgets/bottom_sheet.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_sheet.dart'; @@ -113,35 +114,41 @@ class _ChatHomeScreenState extends State { mainAxisAlignment: MainAxisAlignment.end, mainAxisSize: MainAxisSize.max, children: [ - if (m.searchedChats![index].unreadMessageCount! > 0) - Flexible( - child: Container( - padding: EdgeInsets.zero, - alignment: Alignment.centerRight, - width: 18, - height: 18, - decoration: const BoxDecoration( - color: MyColors.redColor, - borderRadius: BorderRadius.all( - Radius.circular(20), - ), - ), - child: (m.searchedChats![index].unreadMessageCount!.toString()) - .toText10( - color: MyColors.white, - ) - .center, - ), - ), + // if (m.searchedChats![index].unreadMessageCount != null) + // Flexible( + // child: Container( + // padding: EdgeInsets.zero, + // alignment: Alignment.centerRight, + // width: 18, + // height: 18, + // decoration: const BoxDecoration( + // color: MyColors.redColor, + // borderRadius: BorderRadius.all( + // Radius.circular(20), + // ), + // ), + // child: (m.searchedChats![index].unreadMessageCount!.toString()) + // .toText10( + // color: MyColors.white, + // ) + // .center, + // ), + // ), Flexible( child: IconButton( alignment: Alignment.centerRight, padding: EdgeInsets.zero, - icon: Icon(m.searchedChats![index].isFav! ? Icons.star_sharp : Icons.star_border), - color: m.searchedChats![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, + icon: Icon(m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == false ? Icons.star_sharp : Icons.star_sharp), + color: m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == true ? MyColors.yellowColor : MyColors.grey35Color, onPressed: () { - if (m.searchedChats![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); - if (!m.searchedChats![index].isFav!) m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + + if (m.searchedChats![index].isFav == null || m.searchedChats![index].isFav == false) { + m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + }else if( m.searchedChats![index].isFav == true){ + m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + } else{ + m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + } }, ), ) From f19d734dbb3cdbd8606d9fb1235566bdb69bc771 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 15 Nov 2022 15:32:17 +0300 Subject: [PATCH 34/62] Chat Fixes --- assets/langs/ar-SA.json | 3 +-- assets/langs/en-US.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 000e111..1c5851a 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -499,7 +499,6 @@ "resend": "إعادة إرسال", "codeExpire": "انتهت صلاحية رمز التحقق", "typeheretoreply": "اكتب هنا للرد", - "favorite" : "أُفضله", + "favorite": "مفضلتي", "searchfromchat": "البحث من الدردشة" - } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index c8b8322..b4b06f0 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -499,7 +499,7 @@ "codeExpire": "The verification code has been expired", "allQuestionsCorrect": "You have answered all questions correct", "typeheretoreply": "Type here to reply", - "favorite" : "My Favorite", + "favorite" : "My Favorites", "searchfromchat": "Search from chat" } \ No newline at end of file From 1fb585a438fe398978af9d1307bd82630232edaa Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 15 Nov 2022 15:36:28 +0300 Subject: [PATCH 35/62] Chat Fixes --- lib/generated/codegen_loader.g.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 3d35ccc..a54ff37 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -515,7 +515,7 @@ class CodegenLoader extends AssetLoader{ "resend": "إعادة إرسال", "codeExpire": "انتهت صلاحية رمز التحقق", "typeheretoreply": "اكتب هنا للرد", - "favorite": "أُفضله", + "favorite": "مفضلتي", "searchfromchat": "البحث من الدردشة" }; static const Map en_US = { @@ -1019,7 +1019,7 @@ static const Map en_US = { "codeExpire": "The verification code has been expired", "allQuestionsCorrect": "You have answered all questions correct", "typeheretoreply": "Type here to reply", - "favorite": "My Favorite", + "favorite": "My Favorites", "searchfromchat": "Search from chat" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; From 55187f4e36688bcfb2006e5d38409a82a474f9b1 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 15 Nov 2022 15:52:59 +0300 Subject: [PATCH 36/62] Chat Fixes --- lib/api/chat/chat_provider_model.dart | 4 +++- lib/classes/consts.dart | 4 ++-- lib/ui/chat/chat_detailed_screen.dart | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index c9767b4..b09ad50 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -416,7 +416,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { await hubConnection.invoke("AddChatUserAsync", args: [json.decode(chatData)]); } - void sendChatMessage(int targetUserId, String targetUserName) async { + void sendChatMessage(int targetUserId, String targetUserName, BuildContext context) async { dynamic contain = searchedChats!.where((ChatUser element) => element.id == targetUserId); if (contain.isEmpty) { searchedChats!.add( @@ -435,9 +435,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { sendChatToServer(chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: false, chatReplyId: null, isReply: false); } if (isFileSelected && !isMsgReply) { + Utils.showLoading(context); logger.d("Normal Attachment Message"); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); String? ext = getFileExtension(selectedFile.path); + Utils.hideLoading(context); sendChatToServer(chatEventId: 2, fileTypeId: getFileType(ext.toString()), targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: true, chatReplyId: null, isReply: false); } if (!isFileSelected && isMsgReply) { diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 93b4ea8..c5788f9 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 04e84e0..782e4e2 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -252,7 +252,7 @@ class ChatDetailScreen extends StatelessWidget { width: 26, ), onPressed: () { - m.sendChatMessage(userDetails["targetUser"].id, userDetails["targetUser"].userName); + m.sendChatMessage(userDetails["targetUser"].id, userDetails["targetUser"].userName, context); }, ) ], From ab6f265ef45e94fa60ad15cd8de85f9ecd611fd8 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Tue, 15 Nov 2022 16:09:34 +0300 Subject: [PATCH 37/62] Chat Favorite Screen & Fixes --- lib/api/chat/chat_provider_model.dart | 8 +++++--- lib/classes/consts.dart | 4 ++-- lib/ui/chat/chat_home.dart | 2 -- lib/ui/chat/chat_home_screen.dart | 5 ++--- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index b09ad50..ead29d7 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -380,10 +380,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future sendChatToServer( {required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { Uuid uuid = const Uuid(); + String msg = message.text; SingleUserChatModel data = SingleUserChatModel( chatEventId: chatEventId, chatSource: 1, - contant: message.text, + contant: msg, contantNo: uuid.v4(), conversationId: uuid.v4(), createdDate: DateTime.now(), @@ -412,7 +413,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); String chatData = - '{"contant":"${message.text}","contantNo":"${uuid.v4()}","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"${uuid.v4()}"}'; + '{"contant":"$msg","contantNo":"${uuid.v4()}","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"${uuid.v4()}"}'; await hubConnection.invoke("AddChatUserAsync", args: [json.decode(chatData)]); } @@ -452,9 +453,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } if (isFileSelected && isMsgReply) { logger.d("Attachment Message With Reply"); - logger.d(repliedMsg.first.userChatHistoryId); + Utils.showLoading(context); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); String? ext = getFileExtension(selectedFile.path); + Utils.hideLoading(context); sendChatToServer( chatEventId: 2, fileTypeId: getFileType(ext.toString()), diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index c5788f9..ede22e3 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 1fdcb33..738fc17 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -26,7 +26,6 @@ class _ChatHomeState extends State { PageController controller = PageController(); late ChatProviderModel data; - @override void initState() { // TODO: implement initState @@ -46,7 +45,6 @@ class _ChatHomeState extends State { @override Widget build(BuildContext context) { - return Scaffold( backgroundColor: MyColors.white, appBar: AppBarWidget( diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index d146891..38bf42c 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -141,12 +141,11 @@ class _ChatHomeScreenState extends State { icon: Icon(m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == false ? Icons.star_sharp : Icons.star_sharp), color: m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == true ? MyColors.yellowColor : MyColors.grey35Color, onPressed: () { - if (m.searchedChats![index].isFav == null || m.searchedChats![index].isFav == false) { m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); - }else if( m.searchedChats![index].isFav == true){ + } else if (m.searchedChats![index].isFav == true) { m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); - } else{ + } else { m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); } }, From bb583def642aa6aeddff9a9af9b3e2834d245569 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Tue, 15 Nov 2022 16:16:40 +0300 Subject: [PATCH 38/62] Chat Favorite Screen & Fixes --- lib/ui/chat/chat_home_screen.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 38bf42c..a22c7e0 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -1,5 +1,3 @@ -import 'dart:convert'; - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; From 68939f6256c1305c19c523da47314172e0acf5d0 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Wed, 16 Nov 2022 12:07:13 +0300 Subject: [PATCH 39/62] Chat Call UI --- lib/models/chat/call.dart | 117 ++++++++ lib/ui/chat/call/chat_call_screen.dart | 379 +++++++++++++++++++++++++ lib/ui/chat/chat_detailed_screen.dart | 116 +++++++- lib/widgets/app_bar_widget.dart | 29 +- pubspec.yaml | 2 + 5 files changed, 614 insertions(+), 29 deletions(-) create mode 100644 lib/models/chat/call.dart create mode 100644 lib/ui/chat/call/chat_call_screen.dart diff --git a/lib/models/chat/call.dart b/lib/models/chat/call.dart new file mode 100644 index 0000000..eacdd03 --- /dev/null +++ b/lib/models/chat/call.dart @@ -0,0 +1,117 @@ +class IncomingCallData { + String? callerID; + String? receiverID; + 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? token; + String? isCall; + String? sound; + String? server; + String? isWebRTC; + + 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 json) { + callerID = json['callerID']; + receiverID = json['PatientID']; + 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']; + token = json['token']; + identity = json['identity']; + name = json['name']; + videoUrl = json['videoUrl']; + picture = json['picture']; + isCall = json['is_call']; + sound = json['sound']; + server = json['server']; + isWebRTC = json['is_webrtc'] ?? "true"; + } + + Map toJson() { + Map data = Map(); + 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['token'] = this.token; + 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; + data['server'] = this.server; + data['is_webrtc'] = this.isWebRTC; + return data; + } +} diff --git a/lib/ui/chat/call/chat_call_screen.dart b/lib/ui/chat/call/chat_call_screen.dart new file mode 100644 index 0000000..0bec1f0 --- /dev/null +++ b/lib/ui/chat/call/chat_call_screen.dart @@ -0,0 +1,379 @@ +import 'dart:ui'; + +import 'package:camera/camera.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:just_audio/just_audio.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/models/chat/call.dart'; + +class IncomingCall extends StatefulWidget { + IncomingCallData incomingCallData; + bool? isVideoCall; + + IncomingCall({Key? key, required this.incomingCallData, this.isVideoCall}) : super(key: key); + + @override + _IncomingCallState createState() => _IncomingCallState(); +} + +class _IncomingCallState extends State with SingleTickerProviderStateMixin { + AnimationController? _animationController; + CameraController? _controller; + Future? _initializeControllerFuture; + bool isCameraReady = false; + + @override + void initState() { + _animationController = AnimationController( + vsync: this, + duration: const Duration( + milliseconds: 500, + ), + ); + //_runAnimation(); + // connectSignaling(); + WidgetsBinding.instance.addPostFrameCallback( + (_) => _runAnimation(), + ); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: FutureBuilder( + future: _initializeControllerFuture, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return Stack( + alignment: FractionalOffset.center, + children: [ + if (widget.isVideoCall!) + Positioned.fill( + child: AspectRatio( + aspectRatio: _controller!.value.aspectRatio, + child: CameraPreview( + _controller!, + ), + ), + ), + Positioned.fill( + child: ClipRect( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), + child: Container( + decoration: BoxDecoration( + color: MyColors.grey57Color.withOpacity( + 0.7, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + margin: const EdgeInsets.all(21.0), + child: Row( + children: [ + Image.asset( + "assets/images/logos/main_mohemm_logo.png", + height: 70, + width: 70, + ), + Container( + margin: const EdgeInsets.only( + left: 10.0, + right: 10.0, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: const [ + Text( + "Aamir Saleem Ahmad", + style: TextStyle( + fontSize: 21, + fontWeight: FontWeight.bold, + color: MyColors.white, + letterSpacing: -1.26, + height: 23 / 12, + ), + ), + Text( + "Calling...", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color( + 0xffC6C6C6, + ), + letterSpacing: -0.48, + height: 23 / 24, + ), + ), + SizedBox( + height: 2, + ), + ], + ), + ), + ], + ), + ), + // Container( + // margin: const EdgeInsets.all(21.0), + // width: MediaQuery.of(context).size.width, + // decoration: cardRadius(15.0, color: MyColors.black, elevation: null), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisSize: MainAxisSize.min, + // children: [ + // Container( + // padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 6.0), + // child: Text( + // "TranslationBase.of(context).appoInfo", + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.white, letterSpacing: -0.64, height: 23 / 12), + // ), + // ), + // Container( + // padding: const EdgeInsets.only(left: 16.0, right: 16.0), + // child: Text( + // "widget.incomingCallData.appointmentdate + widget.incomingCallData.appointmenttime", + // style: TextStyle(fontSize: 12.0, letterSpacing: -0.48, color: Color(0xff8E8E8E), fontWeight: FontWeight.w600), + // ), + // ), + // Container( + // padding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 21.0), + // child: Text( + // "widget.incomingCallData.clinicname", + // style: TextStyle(fontSize: 12.0, letterSpacing: -0.48, color: Color(0xff8E8E8E), fontWeight: FontWeight.w600), + // ), + // ), + // ], + // ), + // ), + const Spacer(), + Container( + margin: const EdgeInsets.only( + bottom: 70.0, + left: 49, + right: 49, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + RotationTransition( + turns: Tween( + begin: 0.0, + end: -.1, + ) + .chain( + CurveTween( + curve: Curves.elasticIn, + ), + ) + .animate( + _animationController!, + ), + child: RawMaterialButton( + onPressed: () { + _submit(); + }, + elevation: 2.0, + fillColor: MyColors.green2DColor, + padding: const EdgeInsets.all( + 15.0, + ), + shape: const CircleBorder(), + child: const Icon( + Icons.call, + color: MyColors.white, + size: 35.0, + ), + ), + ), + RawMaterialButton( + onPressed: () { + backToHome(); + }, + elevation: 2.0, + fillColor: MyColors.redA3Color, + padding: const EdgeInsets.all( + 15.0, + ), + shape: const CircleBorder(), + child: const Icon( + Icons.call_end, + color: MyColors.white, + size: 35.0, + ), + ), + ], + ), + ), + ], + ), + ), + ), + ), + ), + ], + ); + } else { + return const Center( + child: CircularProgressIndicator(), + ); + } + }, + ), + ); + } + + void _runAnimation() async { + List cameras = await availableCameras(); + CameraDescription firstCamera = cameras[1]; + _controller = CameraController( + firstCamera, + ResolutionPreset.medium, + ); + _initializeControllerFuture = _controller!.initialize(); + setState(() {}); + // setAudioFile(); + for (int i = 0; i < 100; i++) { + await _animationController!.forward(); + await _animationController!.reverse(); + } + } + + Future _submit() async { + try { + // backToHome(); + // final roomModel = RoomModel(name: widget.incomingCallData.name, token: widget.incomingCallData.sessionId, identity: widget.incomingCallData.identity); + await _controller?.dispose(); + // changeCallStatusAPI(4); + + // if (_session != null && _signaling != null) { + // await Navigator.of(context).pushReplacement( + // MaterialPageRoute( + // // fullscreenDialog: true, + // builder: (BuildContext context) { + // // if (widget.incomingCallData.isWebRTC == "true") { + // return StartVideoCall(signaling: _signaling, session: _session); + // + // // else { + // // return OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: widget.incomingCallData.sessionId, token: widget.incomingCallData.token); + // // } + // + // // return VideoCallWebPage(receiverId: widget.incomingCallData.receiverID, callerId: widget.incomingCallData.callerID); // Web WebRTC VideoCall + // + // // return CallHomePage(receiverId: widget.incomingCallData.receiverID, callerId: widget.incomingCallData.callerID); // App WebRTC VideoCall + // }, + // ), + // ); + // } else { + // // Invalid Params/Data + // Utils.showToast("Failed to establish connection with server"); + // } + } catch (err) { + print(err); + // await PlatformExceptionAlertDialog( + // exception: err, + // ).show(context); + + Utils.showToast(err.toString()); + } + } + + // void changeCallStatusAPI(int sessionStatus) { + // LiveCareService service = new LiveCareService(); + // service.endCallAPI(widget.incomingCallData.sessionId, sessionStatus, context).then((res) {}).catchError((err) { + // print(err); + // }); + // } + + void backToHome() async { + // final connected = await signaling.declineCall(widget.incomingCallData.callerID, widget.incomingCallData.receiverID); + // LandingPage.isOpenCallPage = false; + // _signaling + // player.stop(); + // changeCallStatusAPI(3); + // _signaling.bye(_session, callRejected: true); + // _signaling.callDisconnected(_session, callRejected: true); + Navigator.of(context).pop(); + } + + // + // void 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"); + // } + // } + // + // void connectSignaling({@required bool iAmCaller = false}) async { + // print("----------------- + Signaling Connection Started ---------------------------"); + // var caller = widget.incomingCallData.callerID; + // var receiver = widget.incomingCallData.receiverID; + // var host = widget.incomingCallData.server; + // + // var selfRole = iAmCaller ? "Caller" : "Receiver"; + // var selfId = iAmCaller ? caller : receiver; + // var selfUser = SocketUser(id: selfId, name: "$selfRole-$selfId", userAgent: DeviceInfo.userAgent, moreInfo: {}); + // + // var remoteRole = !iAmCaller ? "Caller" : "Receiver"; + // var remoteId = !iAmCaller ? caller : receiver; + // var remoteUser = SocketUser(id: remoteId, name: "$remoteRole-$remoteId", userAgent: DeviceInfo.userAgent, moreInfo: {}); + // + // var sessionId = "$caller-$receiver"; + // _session = SessionOneToOne(id: sessionId, local_user: selfUser, remote_user: remoteUser); + // + // _signaling = Signaling(host, session: _session); + // await _signaling.connect(); + // + // if (_signaling.state == SignalingState.Open) { + // return; + // } + // } + + BoxDecoration cardRadius(double radius, {required Color color, double? elevation}) { + return BoxDecoration( + shape: BoxShape.rectangle, + color: color ?? Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(radius), + ), + boxShadow: [ + BoxShadow( + color: const Color( + 0xff000000, + ).withOpacity( + .05, + ), + //spreadRadius: 5, + blurRadius: elevation ?? 27, + offset: const Offset( + -2, + 3, + ), + ), + ], + ); + } +} diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 782e4e2..6ddd19e 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -9,6 +9,8 @@ import 'package:mohem_flutter_app/classes/colors.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/chat/call.dart'; +import 'package:mohem_flutter_app/ui/chat/call/chat_call_screen.dart'; import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; @@ -16,15 +18,18 @@ import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:swipe_to/swipe_to.dart'; -class ChatDetailScreen extends StatelessWidget { +class ChatDetailScreen extends StatefulWidget { // ignore: prefer_const_constructors_in_immutables ChatDetailScreen({Key? key}) : super(key: key); - dynamic userDetails; + @override + State createState() => _ChatDetailScreenState(); +} +class _ChatDetailScreenState extends State { + dynamic userDetails; late ChatProviderModel data; - - final RefreshController _refreshController = RefreshController(initialRefresh: false); + final RefreshController _rc = RefreshController(initialRefresh: false); void getMoreChat() async { if (userDetails != null) { @@ -32,19 +37,54 @@ class ChatDetailScreen extends StatelessWidget { data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true, isNewChat: false); } await Future.delayed(const Duration(milliseconds: 1000)); - _refreshController.loadComplete(); + _rc.loadComplete(); } @override - Widget build(BuildContext context) { - userDetails = ModalRoute.of(context)!.settings.arguments; + void initState() { + super.initState(); data = Provider.of(context, listen: false); if (userDetails != null) - data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: false, isNewChat: userDetails["isNewChat"]); - data.scrollController.addListener(data.scrollListener); + data.getSingleUserChatHistory( + senderUID: AppState().chatDetails!.response!.id.toString(), + receiverUID: userDetails["targetUser"].id, + loadMore: false, + isNewChat: userDetails["isNewChat"], + ); + //data.scrollController.addListener(data.scrollListener); + } + + @override + Widget build(BuildContext context) { + userDetails = ModalRoute.of(context)!.settings.arguments; return Scaffold( backgroundColor: const Color(0xFFF8F8F8), - appBar: AppBarWidget(context, title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach, showHomeButton: false, image: userDetails["targetUser"].image), + appBar: AppBarWidget(context, + title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach, + showHomeButton: false, + image: userDetails["targetUser"].image, + actions: [ + IconButton( + onPressed: () { + makeCall("AUDIO"); + }, + icon: SvgPicture.asset( + "assets/images/call.svg", + width: 25, + height: 25, + ), + ), + IconButton( + onPressed: () { + makeCall("VIDEO"); + }, + icon: SvgPicture.asset( + "assets/images/call.svg", + width: 25, + height: 25, + ), + ), + ]), body: Consumer( builder: (BuildContext context, ChatProviderModel m, Widget? child) { return (m.isLoading @@ -62,7 +102,7 @@ class ChatDetailScreen extends StatelessWidget { header: const MaterialClassicHeader( color: MyColors.gradiantEndColor, ), - controller: _refreshController, + controller: _rc, reverse: true, child: ListView.builder( controller: m.scrollController, @@ -136,11 +176,11 @@ class ChatDetailScreen extends StatelessWidget { margin: EdgeInsets.zero, elevation: 0, child: Padding( - padding: const EdgeInsets.only(left: 20.0, right: 20, top: 20, bottom: 0), + padding: const EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 0), child: Card( margin: EdgeInsets.zero, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(0.0), + borderRadius: BorderRadius.circular(0), ), elevation: 0, child: Container( @@ -267,4 +307,54 @@ class ChatDetailScreen extends StatelessWidget { ), ); } + + void makeCall(String callType) async { + // final server = await SelectionDialog( + // context, + // title: "Select Server", + // items: ["https://livecareturn.hmg.com:8086", "https://104.197.179.1:8086"] + // ).show(); + + Map json = { + "callerID": "9920", + "PatientID": "1231755", + "msgID": "123", + "notfID": "123", + "notification_foreground": "true", + "count": "1", + "message": "Doctor is calling ", + "AppointmentNo": "123", + "title": "Rayyan Hospital", + "ProjectID": "123", + "NotificationType": "10", + "background": "1", + "doctorname": "Dr Sulaiman Al Habib", + "clinicname": "ENT Clinic", + "speciality": "Speciality", + "appointmentdate": "Sun, 15th Dec, 2019", + "appointmenttime": "09:00", + "type": "video", + "session_id": + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImN0eSI6InR3aWxpby1mcGE7dj0xIn0.eyJqdGkiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0LTE1OTg3NzQ1MDYiLCJpc3MiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0Iiwic3ViIjoiQUNhYWQ1YTNmOGM2NGZhNjczNTY3NTYxNTc0N2YyNmMyYiIsImV4cCI6MTU5ODc3ODEwNiwiZ3JhbnRzIjp7ImlkZW50aXR5IjoiSGFyb29uMSIsInZpZGVvIjp7InJvb20iOiJTbWFsbERhaWx5U3RhbmR1cCJ9fX0.7XUS5uMQQJfkrBZu9EjQ6STL6R7iXkso6BtO1HmrQKk", + "identity": "Haroon1", + "name": "SmallDailyStandup", + "videoUrl": "video", + "picture": "video", + "is_call": "true", + "is_webrtc": "true", + // "server": "https://192.168.8.163:8086", + "server": "https://livecareturn.hmg.com:8086", + }; + + IncomingCallData incomingCallData = IncomingCallData.fromJson(json); + await Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => IncomingCall( + incomingCallData: incomingCallData, + isVideoCall: callType == "VIDEO" ? true : false, + ), + ), + ); + } } diff --git a/lib/widgets/app_bar_widget.dart b/lib/widgets/app_bar_widget.dart index 745dedf..d3e7c97 100644 --- a/lib/widgets/app_bar_widget.dart +++ b/lib/widgets/app_bar_widget.dart @@ -7,11 +7,7 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; AppBar AppBarWidget(BuildContext context, - {required String title, - bool showHomeButton = true, - bool showNotificationButton = false, - bool showMemberButton = false, - String? image}) { + {required String title, bool showHomeButton = true, bool showNotificationButton = false, bool showMemberButton = false, String? image, bool, List? actions}) { return AppBar( leadingWidth: 0, // leading: GestureDetector( @@ -24,17 +20,16 @@ AppBar AppBarWidget(BuildContext context, children: [ GestureDetector( behavior: HitTestBehavior.opaque, - onTap: - Feedback.wrapForTap(() => Navigator.maybePop(context), context), - child: - const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + onTap: Feedback.wrapForTap(() => Navigator.maybePop(context), context), + child: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), ), 4.width, - if (image != null) SvgPicture.asset( - image, - height: 40, - width: 40, - ), + if (image != null) + SvgPicture.asset( + image, + height: 40, + width: 40, + ), if (image != null) 14.width, title.toText24(color: MyColors.darkTextColor, isBold: true).expanded, ], @@ -46,8 +41,7 @@ AppBar AppBarWidget(BuildContext context, if (showHomeButton) IconButton( onPressed: () { - Navigator.popUntil( - context, ModalRoute.withName(AppRoutes.dashboard)); + Navigator.popUntil(context, ModalRoute.withName(AppRoutes.dashboard)); }, icon: const Icon(Icons.home, color: MyColors.darkIconColor), ), @@ -65,6 +59,9 @@ AppBar AppBarWidget(BuildContext context, }, icon: const Icon(Icons.people, color: MyColors.textMixColor), ), + + + ...actions??[] ], ); } diff --git a/pubspec.yaml b/pubspec.yaml index 8947c12..5a7c1c5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -91,6 +91,8 @@ dependencies: signalr_netcore: ^1.3.3 logging: ^1.0.1 swipe_to: ^1.0.2 + flutter_webrtc: ^0.9.16 + camera: ^0.10.0+4 From 00dee97bca969b495a5568fcbc96022f287f2904 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Wed, 16 Nov 2022 16:44:46 +0300 Subject: [PATCH 40/62] Chat Count Api / Chat Token Updates / Chat Call UI --- lib/api/chat/chat_provider_model.dart | 42 +++++++--- lib/api/dashboard_api_client.dart | 10 ++- lib/classes/consts.dart | 4 +- .../chat/chat_count_conversation_model.dart | 25 ++++++ .../chat/get_user_login_token_model.dart | 81 ++++++++++++------- lib/provider/dashboard_provider_model.dart | 22 ++++- lib/ui/chat/call/chat_call_screen.dart | 2 + lib/ui/chat/chat_detailed_screen.dart | 28 ++++--- lib/ui/chat/chat_home.dart | 9 ++- lib/ui/landing/dashboard_screen.dart | 33 ++++++-- .../search_employee_bottom_sheet.dart | 2 +- 11 files changed, 191 insertions(+), 67 deletions(-) create mode 100644 lib/models/chat/chat_count_conversation_model.dart diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index ead29d7..cedc158 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -7,6 +7,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart'; import 'package:logger/logger.dart' as L; +import 'package:logging/logging.dart'; import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; @@ -27,6 +28,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List? pChatHistory, searchedChats; late HubConnection hubConnection; L.Logger logger = L.Logger(); + bool hubConInitialized = false; bool isLoading = true; bool isChatScreenActive = false; @@ -43,13 +45,27 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { bool _shouldAutoscroll = false; Future getUserAutoLoginToken() async { - String userName = AppState().memberInformationList!.eMPLOYEEEMAILADDRESS!.split("@").first.toString(); - //userName - Response response = - await ApiClient().postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}user/desktopuserlogin", {"userName": userName, "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", "loginType": 2}); - login.UserAutoLoginModel userLoginResponse = login.userAutoLoginModelFromJson(response.body); - AppState().setchatUserDetails = userLoginResponse; - await buildHubConnection(); + Response response = await ApiClient().postJsonForResponse( + "${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", + { + "employeeNumber": int.parse( + AppState().memberInformationList!.eMPLOYEENUMBER.toString(), + ), + "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" + }, + ); + login.UserAutoLoginModel userLoginResponse = login.userAutoLoginModelFromJson( + response.body, + ); + + if (userLoginResponse.response != null) { + hubConInitialized = true; + AppState().setchatUserDetails = userLoginResponse; + await buildHubConnection(); + } else { + Utils.showToast(userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr"); + return; + } } Future?> getChatMemberFromSearch(String sName, int cUserId) async { @@ -95,6 +111,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void getSingleUserChatHistory({required String senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false}) async { isLoading = true; + if (isNewChat) userChatHistory = []; if (!loadMore) paginationVal = 0; isChatScreenActive = true; Response response = await ApiClient().getJsonForResponse( @@ -151,8 +168,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { hubConnection = HubConnectionBuilder() .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp) .withAutomaticReconnect( - retryDelays: [2000, 5000, 10000, 20000], - ).build(); + retryDelays: [2000, 5000, 10000, 20000], + ) + .configureLogging(Logger("Loggin")) + .build(); hubConnection.onclose( ({Exception? error}) {}, ); @@ -173,6 +192,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); + } } @@ -215,9 +235,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void updateChatHistoryWindow(List? args) { dynamic items = args!.toList(); - if (kDebugMode) { - print("---------------------------------Update Chat History Windows Async -------------------------------------"); - } + print("---------------------------------Update Chat History Windows Async -------------------------------------"); logger.d(items); // for (var user in searchedChats!) { // if (user.id == items.first["id"]) { diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index cce2207..9747e5c 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -1,10 +1,12 @@ import 'dart:async'; import 'dart:convert'; +import 'package:http/http.dart'; import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/date_uitl.dart'; +import 'package:mohem_flutter_app/models/chat/chat_count_conversation_model.dart'; import 'package:mohem_flutter_app/models/dashboard/get_accrual_balances_list_model.dart'; import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart'; import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart'; @@ -15,7 +17,6 @@ import 'package:mohem_flutter_app/models/itg/itg_response_model.dart'; import 'package:uuid/uuid.dart'; - class DashboardApiClient { static final DashboardApiClient _instance = DashboardApiClient._internal(); @@ -178,4 +179,11 @@ class DashboardApiClient { return responseData; }, url, postParams); } + + Future getChatCount() async { + Response response = await ApiClient().getJsonForResponse( + "${ApiConsts.chatServerBaseApiUrl}user/unreadconversationcount/${AppState().getUserName}", + ); + return chatUnreadCovnCountModelFromJson(response.body); + } } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index ede22e3..c5788f9 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/models/chat/chat_count_conversation_model.dart b/lib/models/chat/chat_count_conversation_model.dart new file mode 100644 index 0000000..e584d32 --- /dev/null +++ b/lib/models/chat/chat_count_conversation_model.dart @@ -0,0 +1,25 @@ +import 'dart:convert'; + +ChatUnreadCovnCountModel chatUnreadCovnCountModelFromJson(String str) => ChatUnreadCovnCountModel.fromJson(json.decode(str)); + +String chatUnreadCovnCountModelToJson(ChatUnreadCovnCountModel data) => json.encode(data.toJson()); + +class ChatUnreadCovnCountModel { + ChatUnreadCovnCountModel({ + this.singleChatCount, + this.groupChatCount, + }); + + int? singleChatCount; + int? groupChatCount; + + factory ChatUnreadCovnCountModel.fromJson(Map json) => ChatUnreadCovnCountModel( + singleChatCount: json["singleChatCount"] == null ? null : json["singleChatCount"], + groupChatCount: json["groupChatCount"] == null ? null : json["groupChatCount"], + ); + + Map toJson() => { + "singleChatCount": singleChatCount == null ? null : singleChatCount, + "groupChatCount": groupChatCount == null ? null : groupChatCount, + }; +} diff --git a/lib/models/chat/get_user_login_token_model.dart b/lib/models/chat/get_user_login_token_model.dart index 8afd3a9..8d55461 100644 --- a/lib/models/chat/get_user_login_token_model.dart +++ b/lib/models/chat/get_user_login_token_model.dart @@ -1,4 +1,3 @@ - import 'dart:convert'; UserAutoLoginModel userAutoLoginModelFromJson(String str) => UserAutoLoginModel.fromJson(json.decode(str)); @@ -7,22 +6,22 @@ String userAutoLoginModelToJson(UserAutoLoginModel data) => json.encode(data.toJ class UserAutoLoginModel { UserAutoLoginModel({ - this.response, + this.response, this.errorResponses, }); Response? response; - dynamic? errorResponses; + List? errorResponses; factory UserAutoLoginModel.fromJson(Map json) => UserAutoLoginModel( - response: json["response"] == null ? null : Response.fromJson(json["response"]), - errorResponses: json["errorResponses"], - ); + response: json["response"] == null ? null : Response.fromJson(json["response"]), + errorResponses: json["errorResponses"] == null ? null : List.from(json["errorResponses"].map((x) => ErrorResponse.fromJson(x))), + ); Map toJson() => { - "response": response == null ? null : response!.toJson(), - "errorResponses": errorResponses, - }; + "response": response == null ? null : response!.toJson(), + "errorResponses": errorResponses == null ? null : List.from(errorResponses!.map((x) => x.toJson())), + }; } class Response { @@ -51,28 +50,48 @@ class Response { String? encryptedUserName; factory Response.fromJson(Map json) => Response( - id: json["id"] == null ? null : json["id"], - userName: json["userName"] == null ? null : json["userName"], - email: json["email"] == null ? null : json["email"], - phone: json["phone"] == null ? null : json["phone"], - title: json["title"] == null ? null : json["title"], - token: json["token"] == null ? null : json["token"], - isDomainUser: json["isDomainUser"] == null ? null : json["isDomainUser"], - isActiveCode: json["isActiveCode"] == null ? null : json["isActiveCode"], - encryptedUserId: json["encryptedUserId"] == null ? null : json["encryptedUserId"], - encryptedUserName: json["encryptedUserName"] == null ? null : json["encryptedUserName"], - ); + id: json["id"] == null ? null : json["id"], + userName: json["userName"] == null ? null : json["userName"], + email: json["email"] == null ? null : json["email"], + phone: json["phone"] == null ? null : json["phone"], + title: json["title"] == null ? null : json["title"], + token: json["token"] == null ? null : json["token"], + isDomainUser: json["isDomainUser"] == null ? null : json["isDomainUser"], + isActiveCode: json["isActiveCode"] == null ? null : json["isActiveCode"], + encryptedUserId: json["encryptedUserId"] == null ? null : json["encryptedUserId"], + encryptedUserName: json["encryptedUserName"] == null ? null : json["encryptedUserName"], + ); + + Map toJson() => { + "id": id == null ? null : id, + "userName": userName == null ? null : userName, + "email": email == null ? null : email, + "phone": phone == null ? null : phone, + "title": title == null ? null : title, + "token": token == null ? null : token, + "isDomainUser": isDomainUser == null ? null : isDomainUser, + "isActiveCode": isActiveCode == null ? null : isActiveCode, + "encryptedUserId": encryptedUserId == null ? null : encryptedUserId, + "encryptedUserName": encryptedUserName == null ? null : encryptedUserName, + }; +} + +class ErrorResponse { + ErrorResponse({ + this.fieldName, + this.message, + }); + + String? fieldName; + String? message; + + factory ErrorResponse.fromJson(Map json) => ErrorResponse( + fieldName: json["fieldName"] == null ? null : json["fieldName"], + message: json["message"] == null ? null : json["message"], + ); Map toJson() => { - "id": id == null ? null : id, - "userName": userName == null ? null : userName, - "email": email == null ? null : email, - "phone": phone == null ? null : phone, - "title": title == null ? null : title, - "token": token == null ? null : token, - "isDomainUser": isDomainUser == null ? null : isDomainUser, - "isActiveCode": isActiveCode == null ? null : isActiveCode, - "encryptedUserId": encryptedUserId == null ? null : encryptedUserId, - "encryptedUserName": encryptedUserName == null ? null : encryptedUserName, - }; + "fieldName": fieldName == null ? null : fieldName, + "message": message == null ? null : message, + }; } diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index 5b9f8f1..b38536c 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -7,6 +7,7 @@ import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/main.dart'; +import 'package:mohem_flutter_app/models/chat/chat_count_conversation_model.dart'; import 'package:mohem_flutter_app/models/dashboard/drawer_menu_item_model.dart'; import 'package:mohem_flutter_app/models/dashboard/get_accrual_balances_list_model.dart'; import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart'; @@ -34,6 +35,10 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { bool isWorkListLoading = true; int workListCounter = 0; + //Chat + bool isChatCounterLoding = true; + int chatUConvCounter = 0; + //Misssing Swipe bool isMissingSwipeLoading = true; int missingSwipeCounter = 0; @@ -91,6 +96,9 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { accrualList = null; leaveBalanceAccrual = null; + isChatCounterLoding = true; + chatUConvCounter = 0; + ticketBalance = 0; isServicesMenusLoading = true; homeMenus = null; @@ -266,7 +274,19 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { return res; } - + void fetchChatCounts() async { + print("----------------------- Fetch Count ____________________________________"); + try { + ChatUnreadCovnCountModel response = await DashboardApiClient().getChatCount(); + chatUConvCounter = response.singleChatCount!; + isChatCounterLoding = false; + notifyListeners(); + } catch (ex) { + logger.wtf(ex); + notifyListeners(); + Utils.handleException(ex, null, null); + } + } void notify() { notifyListeners(); diff --git a/lib/ui/chat/call/chat_call_screen.dart b/lib/ui/chat/call/chat_call_screen.dart index 0bec1f0..3fce65b 100644 --- a/lib/ui/chat/call/chat_call_screen.dart +++ b/lib/ui/chat/call/chat_call_screen.dart @@ -255,6 +255,7 @@ class _IncomingCallState extends State with SingleTickerProviderSt // backToHome(); // final roomModel = RoomModel(name: widget.incomingCallData.name, token: widget.incomingCallData.sessionId, identity: widget.incomingCallData.identity); await _controller?.dispose(); + // changeCallStatusAPI(4); // if (_session != null && _signaling != null) { @@ -300,6 +301,7 @@ class _IncomingCallState extends State with SingleTickerProviderSt // final connected = await signaling.declineCall(widget.incomingCallData.callerID, widget.incomingCallData.receiverID); // LandingPage.isOpenCallPage = false; // _signaling + _animationController!.dispose(); // player.stop(); // changeCallStatusAPI(3); // _signaling.bye(_session, callRejected: true); diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 6ddd19e..2ef61f0 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -34,15 +34,25 @@ class _ChatDetailScreenState extends State { void getMoreChat() async { if (userDetails != null) { data.paginationVal = data.paginationVal + 10; - data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true, isNewChat: false); + if (userDetails != null) + data.getSingleUserChatHistory( + senderUID: AppState().chatDetails!.response!.id.toString(), + receiverUID: userDetails["targetUser"].id, + loadMore: true, + isNewChat: false, + ); } - await Future.delayed(const Duration(milliseconds: 1000)); + await Future.delayed( + const Duration( + milliseconds: 1000, + ), + ); _rc.loadComplete(); } @override - void initState() { - super.initState(); + Widget build(BuildContext context) { + userDetails = ModalRoute.of(context)!.settings.arguments; data = Provider.of(context, listen: false); if (userDetails != null) data.getSingleUserChatHistory( @@ -51,12 +61,6 @@ class _ChatDetailScreenState extends State { loadMore: false, isNewChat: userDetails["isNewChat"], ); - //data.scrollController.addListener(data.scrollListener); - } - - @override - Widget build(BuildContext context) { - userDetails = ModalRoute.of(context)!.settings.arguments; return Scaffold( backgroundColor: const Color(0xFFF8F8F8), appBar: AppBarWidget(context, @@ -66,7 +70,7 @@ class _ChatDetailScreenState extends State { actions: [ IconButton( onPressed: () { - makeCall("AUDIO"); + // makeCall("AUDIO"); }, icon: SvgPicture.asset( "assets/images/call.svg", @@ -76,7 +80,7 @@ class _ChatDetailScreenState extends State { ), IconButton( onPressed: () { - makeCall("VIDEO"); + // makeCall("VIDEO"); }, icon: SvgPicture.asset( "assets/images/call.svg", diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 738fc17..744188f 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -1,6 +1,9 @@ +import 'dart:convert'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; @@ -31,7 +34,7 @@ class _ChatHomeState extends State { // TODO: implement initState super.initState(); data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().then((value) { + data.getUserAutoLoginToken().then((Object? value) { data.getUserRecentChats(); }); } @@ -39,7 +42,9 @@ class _ChatHomeState extends State { @override void dispose() { data.clearAll(); - data.hubConnection.stop(); + if (data.hubConInitialized) { + data.hubConnection.stop(); + } super.dispose(); } diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index d342072..7453603 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -71,6 +71,7 @@ class _DashboardScreenState extends State { data.fetchLeaveTicketBalance(context, DateTime.now()); data.fetchMenuEntries(); data.getCategoryOffersListAPI(context); + data.fetchChatCounts(); _refreshController.refreshCompleted(); } @@ -268,7 +269,7 @@ class _DashboardScreenState extends State { ).onPress(() { showMyBottomSheet( context, - callBackFunc: (){}, + callBackFunc: () {}, child: MarkAttendanceWidget(model, isFromDashboard: true), ); }), @@ -469,10 +470,32 @@ class _DashboardScreenState extends State { label: LocaleKeys.itemsForSale.tr(), ), BottomNavigationBarItem( - icon: SvgPicture.asset( - "assets/icons/chat/chat.svg", - color: currentIndex == 4 ? MyColors.grey3AColor : MyColors.grey98Color, - ).paddingAll(4), + icon: Stack( + alignment: Alignment.centerLeft, + children: [ + SvgPicture.asset( + "assets/icons/chat/chat.svg", + color: currentIndex == 4 ? MyColors.grey3AColor : MyColors.grey98Color, + ).paddingAll(4), + Consumer( + builder: (BuildContext cxt, DashboardProviderModel data, Widget? child) { + if (data.chatUConvCounter == 0) { + return const SizedBox(); + } + return Positioned( + right: 0, + top: 0, + child: Container( + padding: const EdgeInsets.only(left: 4, right: 4), + alignment: Alignment.center, + decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)), + child: data.chatUConvCounter.toString().toText10(color: Colors.white), + ), + ); + }, + ), + ], + ), label: LocaleKeys.chat.tr(), ), ], diff --git a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart index a30b33d..b88b96f 100644 --- a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart +++ b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart @@ -236,7 +236,7 @@ class _SearchEmployeeBottomSheetState extends State { arguments: {"targetUser": chatUsersList![index], "isNewChat": true}, ); }, - onLongPress: () {}, + ), ); }, From d7c0ef7bfbaef8afb6f82eb21fc7d44634091a82 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Wed, 16 Nov 2022 16:50:34 +0300 Subject: [PATCH 41/62] Chat Count Api / Chat Token Updates / Chat Call UI --- lib/ui/chat/chat_home.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 744188f..ed6b155 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -34,8 +34,11 @@ class _ChatHomeState extends State { // TODO: implement initState super.initState(); data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().then((Object? value) { + data.getUserAutoLoginToken().then((value) { data.getUserRecentChats(); + // var datae = [int.parse(AppState().memberInformationList!.eMPLOYEENUMBER.toString())]; + + // data.hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [int.parse(AppState().memberInformationList!.eMPLOYEENUMBER.toString())]); }); } From 44d76f068781e7ef22665d39fd16f3146025daeb Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 17 Nov 2022 09:26:11 +0300 Subject: [PATCH 42/62] Chat Count Api / Chat Token Updates / Chat Call UI --- lib/api/chat/chat_provider_model.dart | 46 ++++++++++++++++++++++----- lib/ui/chat/chat_detailed_screen.dart | 5 +-- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index cedc158..b336ace 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -109,7 +109,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } - void getSingleUserChatHistory({required String senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false}) async { + Future GetUserChatHistoryNotDeliveredAsync(int userId) async { + await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]); + return ""; + } + + void getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false}) async { isLoading = true; if (isNewChat) userChatHistory = []; if (!loadMore) paginationVal = 0; @@ -134,9 +139,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } isLoading = false; + await GetUserChatHistoryNotDeliveredAsync(senderUID); notifyListeners(); } + void updateUserChatHistoryStatusAsync(List data) { + hubConnection.invoke("UpdateUserChatHistoryStatusAsync", args: [data]); + } + List getSingleUserChatModel(String str) => List.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); ChatUserModel userToList(String str) => ChatUserModel.fromJson(json.decode(str)); @@ -170,7 +180,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { .withAutomaticReconnect( retryDelays: [2000, 5000, 10000, 20000], ) - .configureLogging(Logger("Loggin")) + .configureLogging( + Logger("Loggin"), + ) .build(); hubConnection.onclose( ({Exception? error}) {}, @@ -188,11 +200,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { // hubConnection.on("OnSeenChatUserAsync", onChatSeen); //hubConnection.on("OnUserTypingAsync", onUserTyping); - // hubConnection.on("OnUserCountAsync", userCountAsync); + hubConnection.on("OnUserCountAsync", userCountAsync); hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); - } } @@ -223,6 +234,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void userCountAsync(List? args) { dynamic items = args!.toList(); + // logger.d(items); //logger.d("---------------------------------User Count Async -------------------------------------"); //logger.d(items); // for (var user in searchedChats!) { @@ -247,10 +259,17 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void chatNotDelivered(List? args) { dynamic items = args!.toList(); - if (kDebugMode) { - print("--------------------------------- Chat Not Delivered Windows Async -------------------------------------"); + for (dynamic item in items[0]) { + dynamic data = [ + { + "userChatHistoryId": item["userChatHistoryId"], + "TargetUserId": item["targetUserId"], + "isDelivered": true, + "isSeen": true, + } + ]; + updateUserChatHistoryStatusAsync(data); } - logger.d(items); // for (var user in searchedChats!) { // if (user.id == items.first["id"]) { // user.userStatus = items.first["userStatus"]; @@ -289,7 +308,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } Future onMsgReceived(List? parameters) async { - print("msg Received"); List data = []; List temp = []; for (dynamic msg in parameters!) { @@ -307,6 +325,18 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { // element.unreadMessageCount = val! + 1; // } // }); + logger.d(jsonEncode(data)); + + var list = [ + { + "userChatHistoryId": data.first.userChatHistoryId, + "TargetUserId": data.first.targetUserId, + "isDelivered": true, + "isSeen": isChatScreenActive ? true : false, + } + ]; + updateUserChatHistoryStatusAsync(list); + notifyListeners(); // if (isChatScreenActive) scrollToBottom(); } diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 2ef61f0..71a95b5 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -36,7 +36,7 @@ class _ChatDetailScreenState extends State { data.paginationVal = data.paginationVal + 10; if (userDetails != null) data.getSingleUserChatHistory( - senderUID: AppState().chatDetails!.response!.id.toString(), + senderUID: AppState().chatDetails!.response!.id!.toInt(), receiverUID: userDetails["targetUser"].id, loadMore: true, isNewChat: false, @@ -56,11 +56,12 @@ class _ChatDetailScreenState extends State { data = Provider.of(context, listen: false); if (userDetails != null) data.getSingleUserChatHistory( - senderUID: AppState().chatDetails!.response!.id.toString(), + senderUID: AppState().chatDetails!.response!.id!.toInt(), receiverUID: userDetails["targetUser"].id, loadMore: false, isNewChat: userDetails["isNewChat"], ); + return Scaffold( backgroundColor: const Color(0xFFF8F8F8), appBar: AppBarWidget(context, From 5aa56450d9db89aa4660e38802cca8ba0ded2ba3 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 15 Nov 2022 16:04:19 +0300 Subject: [PATCH 43/62] Chat Fixes --- lib/api/chat/chat_provider_model.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index b336ace..bf4c33a 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -270,6 +270,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ]; updateUserChatHistoryStatusAsync(data); } + logger.d(items); // for (var user in searchedChats!) { // if (user.id == items.first["id"]) { // user.userStatus = items.first["userStatus"]; @@ -308,6 +309,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } Future onMsgReceived(List? parameters) async { + print("msg Received"); List data = []; List temp = []; for (dynamic msg in parameters!) { @@ -428,11 +430,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future sendChatToServer( {required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { Uuid uuid = const Uuid(); - String msg = message.text; SingleUserChatModel data = SingleUserChatModel( chatEventId: chatEventId, chatSource: 1, - contant: msg, + contant: message.text, contantNo: uuid.v4(), conversationId: uuid.v4(), createdDate: DateTime.now(), From 33609ea773dd77c2123b02b0a8fadd0688426d89 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 17 Nov 2022 09:49:31 +0300 Subject: [PATCH 44/62] Chat Fixes --- lib/api/chat/chat_provider_model.dart | 4 +++- lib/ui/chat/chat_detailed_screen.dart | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index bf4c33a..ff02c4d 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -50,6 +50,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { { "employeeNumber": int.parse( AppState().memberInformationList!.eMPLOYEENUMBER.toString(), + // "" ), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" }, @@ -430,10 +431,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future sendChatToServer( {required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { Uuid uuid = const Uuid(); + var msg = message.text; SingleUserChatModel data = SingleUserChatModel( chatEventId: chatEventId, chatSource: 1, - contant: message.text, + contant: msg, contantNo: uuid.v4(), conversationId: uuid.v4(), createdDate: DateTime.now(), diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 71a95b5..ff661f1 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -71,7 +71,7 @@ class _ChatDetailScreenState extends State { actions: [ IconButton( onPressed: () { - // makeCall("AUDIO"); + makeCall("AUDIO"); }, icon: SvgPicture.asset( "assets/images/call.svg", @@ -81,7 +81,7 @@ class _ChatDetailScreenState extends State { ), IconButton( onPressed: () { - // makeCall("VIDEO"); + makeCall("VIDEO"); }, icon: SvgPicture.asset( "assets/images/call.svg", From 3cac5eebbc7fbc92f675600b7596a890b96d8c45 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 17 Nov 2022 10:49:37 +0300 Subject: [PATCH 45/62] Chat Fixes --- assets/icons/chat/call.svg | 3 + assets/icons/chat/video_call.svg | 6 + lib/api/chat/chat_provider_model.dart | 4 +- lib/classes/consts.dart | 4 +- lib/provider/dashboard_provider_model.dart | 1 - ...en.dart => chat_incoming_call_screen.dart} | 1 + .../chat/call/chat_outgoing_call_screen.dart | 470 ++++++++++++++++++ lib/ui/chat/chat_bubble.dart | 12 +- lib/ui/chat/chat_detailed_screen.dart | 22 +- 9 files changed, 502 insertions(+), 21 deletions(-) create mode 100644 assets/icons/chat/call.svg create mode 100644 assets/icons/chat/video_call.svg rename lib/ui/chat/call/{chat_call_screen.dart => chat_incoming_call_screen.dart} (99%) create mode 100644 lib/ui/chat/call/chat_outgoing_call_screen.dart diff --git a/assets/icons/chat/call.svg b/assets/icons/chat/call.svg new file mode 100644 index 0000000..843daf4 --- /dev/null +++ b/assets/icons/chat/call.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/chat/video_call.svg b/assets/icons/chat/video_call.svg new file mode 100644 index 0000000..2fceee6 --- /dev/null +++ b/assets/icons/chat/video_call.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index ff02c4d..f5d896c 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -49,8 +49,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { "${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", { "employeeNumber": int.parse( - AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - // "" + //AppState().memberInformationList!.eMPLOYEENUMBER.toString(), + "210919" ), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" }, diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index c5788f9..ede22e3 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index b38536c..948e5b4 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -275,7 +275,6 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } void fetchChatCounts() async { - print("----------------------- Fetch Count ____________________________________"); try { ChatUnreadCovnCountModel response = await DashboardApiClient().getChatCount(); chatUConvCounter = response.singleChatCount!; diff --git a/lib/ui/chat/call/chat_call_screen.dart b/lib/ui/chat/call/chat_incoming_call_screen.dart similarity index 99% rename from lib/ui/chat/call/chat_call_screen.dart rename to lib/ui/chat/call/chat_incoming_call_screen.dart index 3fce65b..923a4bd 100644 --- a/lib/ui/chat/call/chat_call_screen.dart +++ b/lib/ui/chat/call/chat_incoming_call_screen.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:ui'; import 'package:camera/camera.dart'; diff --git a/lib/ui/chat/call/chat_outgoing_call_screen.dart b/lib/ui/chat/call/chat_outgoing_call_screen.dart new file mode 100644 index 0000000..b5a47a6 --- /dev/null +++ b/lib/ui/chat/call/chat_outgoing_call_screen.dart @@ -0,0 +1,470 @@ +import 'dart:ui'; + +import 'package:camera/camera.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/models/chat/call.dart'; + +class OutGoingCall extends StatefulWidget { + IncomingCallData OutGoingCallData; + bool? isVideoCall; + + OutGoingCall({Key? key, required this.OutGoingCallData, this.isVideoCall}) : super(key: key); + + @override + _OutGoingCallState createState() => _OutGoingCallState(); +} + +class _OutGoingCallState extends State with SingleTickerProviderStateMixin { + AnimationController? _animationController; + CameraController? _controller; + Future? _initializeControllerFuture; + bool isCameraReady = false; + bool isMicOff = false; + bool isLoudSpeaker = false; + bool isCamOff = false; + + @override + void initState() { + _animationController = AnimationController( + vsync: this, + duration: const Duration( + milliseconds: 500, + ), + ); + //_runAnimation(); + // connectSignaling(); + WidgetsBinding.instance.addPostFrameCallback( + (_) => _runAnimation(), + ); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: FutureBuilder( + future: _initializeControllerFuture, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return Stack( + alignment: FractionalOffset.center, + children: [ + if (widget.isVideoCall!) + Positioned.fill( + child: AspectRatio( + aspectRatio: _controller!.value.aspectRatio, + child: CameraPreview( + _controller!, + ), + ), + ), + Positioned.fill( + child: ClipRect( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), + child: Container( + decoration: BoxDecoration( + color: MyColors.grey57Color.withOpacity( + 0.7, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + 40.height, + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + margin: const EdgeInsets.all(21.0), + child: Container( + margin: const EdgeInsets.only( + left: 10.0, + right: 10.0, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + SvgPicture.asset( + "assets/images/user.svg", + height: 70, + width: 70, + fit: BoxFit.cover, + ), + 10.height, + Text( + "Aamir Saleem Ahmad", + style: TextStyle( + fontSize: 21, + fontWeight: FontWeight.bold, + color: MyColors.white, + letterSpacing: -1.26, + height: 23 / 12, + ), + ), + Text( + "Ringing...", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color( + 0xffC6C6C6, + ), + letterSpacing: -0.48, + height: 23 / 24, + ), + ), + SizedBox( + height: 2, + ), + ], + ), + ), + ), + ], + ), + // Container( + // margin: const EdgeInsets.all(21.0), + // width: MediaQuery.of(context).size.width, + // decoration: cardRadius(15.0, color: MyColors.black, elevation: null), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisSize: MainAxisSize.min, + // children: [ + // Container( + // padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 6.0), + // child: Text( + // "TranslationBase.of(context).appoInfo", + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.white, letterSpacing: -0.64, height: 23 / 12), + // ), + // ), + // Container( + // padding: const EdgeInsets.only(left: 16.0, right: 16.0), + // child: Text( + // "widget.OutGoingCallData.appointmentdate + widget.OutGoingCallData.appointmenttime", + // style: TextStyle(fontSize: 12.0, letterSpacing: -0.48, color: Color(0xff8E8E8E), fontWeight: FontWeight.w600), + // ), + // ), + // Container( + // padding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 21.0), + // child: Text( + // "widget.OutGoingCallData.clinicname", + // style: TextStyle(fontSize: 12.0, letterSpacing: -0.48, color: Color(0xff8E8E8E), fontWeight: FontWeight.w600), + // ), + // ), + // ], + // ), + // ), + const Spacer(), + Container( + margin: const EdgeInsets.only( + bottom: 70.0, + left: 49, + right: 49, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (widget.isVideoCall!) + RotationTransition( + turns: Tween( + begin: 0.0, + end: -.1, + ) + .chain( + CurveTween( + curve: Curves.elasticIn, + ), + ) + .animate( + _animationController!, + ), + child: RawMaterialButton( + onPressed: () { + _camOff(); + }, + elevation: 2.0, + fillColor: isCamOff ? MyColors.green2DColor : Colors.grey, + padding: const EdgeInsets.all( + 15.0, + ), + shape: const CircleBorder(), + child: Icon( + isCamOff ? Icons.videocam_off : Icons.videocam, + color: MyColors.white, + size: 35.0, + ), + ), + ) + else + RotationTransition( + turns: Tween( + begin: 0.0, + end: -.1, + ) + .chain( + CurveTween( + curve: Curves.elasticIn, + ), + ) + .animate( + _animationController!, + ), + child: RawMaterialButton( + onPressed: () { + _loudOn(); + }, + elevation: 2.0, + fillColor: isLoudSpeaker ? MyColors.green2DColor : Colors.grey, + padding: const EdgeInsets.all( + 15.0, + ), + shape: const CircleBorder(), + child: const Icon( + Icons.volume_up, + color: MyColors.white, + size: 35.0, + ), + ), + ), + RotationTransition( + turns: Tween( + begin: 0.0, + end: -.1, + ) + .chain( + CurveTween( + curve: Curves.elasticIn, + ), + ) + .animate( + _animationController!, + ), + child: RawMaterialButton( + onPressed: () { + _micOff(); + }, + elevation: 2.0, + fillColor: isMicOff ? MyColors.green2DColor : Colors.grey, + padding: const EdgeInsets.all( + 15.0, + ), + shape: const CircleBorder(), + child: Icon( + isMicOff ? Icons.mic_off : Icons.mic, + color: MyColors.white, + size: 35.0, + ), + ), + ), + RawMaterialButton( + onPressed: () { + backToHome(); + }, + elevation: 2.0, + fillColor: MyColors.redA3Color, + padding: const EdgeInsets.all( + 15.0, + ), + shape: const CircleBorder(), + child: const Icon( + Icons.call_end, + color: MyColors.white, + size: 35.0, + ), + ), + ], + ), + ), + ], + ), + ), + ), + ), + ), + ], + ); + } else { + return const Center( + child: CircularProgressIndicator(), + ); + } + }, + ), + ); + } + + void _runAnimation() async { + List cameras = await availableCameras(); + CameraDescription firstCamera = cameras[1]; + _controller = CameraController( + firstCamera, + ResolutionPreset.medium, + ); + _initializeControllerFuture = _controller!.initialize(); + setState(() {}); + // setAudioFile(); + for (int i = 0; i < 100; i++) { + await _animationController!.forward(); + await _animationController!.reverse(); + } + } + + void _micOff() { + setState(() { + isMicOff = !isMicOff; + }); + } + + void _camOff() { + setState(() { + isCamOff = !isCamOff; + }); + } + + void _loudOn() { + setState(() { + isLoudSpeaker = !isLoudSpeaker; + }); + } + + Future _submit() async { + try { + // backToHome(); + // final roomModel = RoomModel(name: widget.OutGoingCallData.name, token: widget.OutGoingCallData.sessionId, identity: widget.OutGoingCallData.identity); + await _controller?.dispose(); + + // changeCallStatusAPI(4); + + // if (_session != null && _signaling != null) { + // await Navigator.of(context).pushReplacement( + // MaterialPageRoute( + // // fullscreenDialog: true, + // builder: (BuildContext context) { + // // if (widget.OutGoingCallData.isWebRTC == "true") { + // return StartVideoCall(signaling: _signaling, session: _session); + // + // // else { + // // return OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: widget.OutGoingCallData.sessionId, token: widget.OutGoingCallData.token); + // // } + // + // // return VideoCallWebPage(receiverId: widget.OutGoingCallData.receiverID, callerId: widget.OutGoingCallData.callerID); // Web WebRTC VideoCall + // + // // return CallHomePage(receiverId: widget.OutGoingCallData.receiverID, callerId: widget.OutGoingCallData.callerID); // App WebRTC VideoCall + // }, + // ), + // ); + // } else { + // // Invalid Params/Data + // Utils.showToast("Failed to establish connection with server"); + // } + } catch (err) { + print(err); + // await PlatformExceptionAlertDialog( + // exception: err, + // ).show(context); + + Utils.showToast(err.toString()); + } + } + + // void changeCallStatusAPI(int sessionStatus) { + // LiveCareService service = new LiveCareService(); + // service.endCallAPI(widget.OutGoingCallData.sessionId, sessionStatus, context).then((res) {}).catchError((err) { + // print(err); + // }); + // } + + void backToHome() async { + // final connected = await signaling.declineCall(widget.OutGoingCallData.callerID, widget.OutGoingCallData.receiverID); + // LandingPage.isOpenCallPage = false; + // _signaling + _animationController!.dispose(); + // player.stop(); + // changeCallStatusAPI(3); + // _signaling.bye(_session, callRejected: true); + // _signaling.callDisconnected(_session, callRejected: true); + Navigator.of(context).pop(); + } + + // + // void 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"); + // } + // } + // + // void connectSignaling({@required bool iAmCaller = false}) async { + // print("----------------- + Signaling Connection Started ---------------------------"); + // var caller = widget.OutGoingCallData.callerID; + // var receiver = widget.OutGoingCallData.receiverID; + // var host = widget.OutGoingCallData.server; + // + // var selfRole = iAmCaller ? "Caller" : "Receiver"; + // var selfId = iAmCaller ? caller : receiver; + // var selfUser = SocketUser(id: selfId, name: "$selfRole-$selfId", userAgent: DeviceInfo.userAgent, moreInfo: {}); + // + // var remoteRole = !iAmCaller ? "Caller" : "Receiver"; + // var remoteId = !iAmCaller ? caller : receiver; + // var remoteUser = SocketUser(id: remoteId, name: "$remoteRole-$remoteId", userAgent: DeviceInfo.userAgent, moreInfo: {}); + // + // var sessionId = "$caller-$receiver"; + // _session = SessionOneToOne(id: sessionId, local_user: selfUser, remote_user: remoteUser); + // + // _signaling = Signaling(host, session: _session); + // await _signaling.connect(); + // + // if (_signaling.state == SignalingState.Open) { + // return; + // } + // } + + BoxDecoration cardRadius(double radius, {required Color color, double? elevation}) { + return BoxDecoration( + shape: BoxShape.rectangle, + color: color ?? Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(radius), + ), + boxShadow: [ + BoxShadow( + color: const Color( + 0xff000000, + ).withOpacity( + .05, + ), + //spreadRadius: 5, + blurRadius: elevation ?? 27, + offset: const Offset( + -2, + 3, + ), + ), + ], + ); + } +} diff --git a/lib/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index c638b34..6dcd6d2 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -91,12 +91,12 @@ class ChatBubble extends StatelessWidget { children: [ dateTime.toText12(color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7),), if (isCurrentUser) 5.width, - if (isCurrentUser) - Icon( - isDelivered ? Icons.done_all : Icons.done_all, - color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor, - size: 14, - ), + // if (isCurrentUser) + // Icon( + // isDelivered ? Icons.done_all : Icons.done_all, + // color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor, + // size: 14, + // ), ], ), ], diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index ff661f1..2c8b2d8 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -6,11 +6,12 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.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/chat/call.dart'; -import 'package:mohem_flutter_app/ui/chat/call/chat_call_screen.dart'; +import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart'; import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; @@ -71,12 +72,12 @@ class _ChatDetailScreenState extends State { actions: [ IconButton( onPressed: () { - makeCall("AUDIO"); + makeCall("AUDIO"); }, icon: SvgPicture.asset( - "assets/images/call.svg", - width: 25, - height: 25, + "assets/icons/chat/call.svg", + width: 22, + height: 22, ), ), IconButton( @@ -84,11 +85,12 @@ class _ChatDetailScreenState extends State { makeCall("VIDEO"); }, icon: SvgPicture.asset( - "assets/images/call.svg", - width: 25, - height: 25, + "assets/icons/chat/video_call.svg", + width: 20, + height: 20, ), ), + 10.width, ]), body: Consumer( builder: (BuildContext context, ChatProviderModel m, Widget? child) { @@ -355,9 +357,9 @@ class _ChatDetailScreenState extends State { await Navigator.push( context, MaterialPageRoute( - builder: (BuildContext context) => IncomingCall( - incomingCallData: incomingCallData, + builder: (BuildContext context) => OutGoingCall( isVideoCall: callType == "VIDEO" ? true : false, + OutGoingCallData: incomingCallData, ), ), ); From 451b381acf34370470ac8636c96c29f6e7e8051b Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 17 Nov 2022 10:52:08 +0300 Subject: [PATCH 46/62] Chat Count Api / Chat Token Updates / Chat Call UI --- lib/api/chat/chat_provider_model.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index f5d896c..bf69d58 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -49,8 +49,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { "${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", { "employeeNumber": int.parse( - //AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "210919" + AppState().memberInformationList!.eMPLOYEENUMBER.toString(), ), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" }, From 5ec6fbdf421fb5304cbcf2172817d9de29b25601 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 17 Nov 2022 11:07:43 +0300 Subject: [PATCH 47/62] Chat Fixes --- .gitignore | 1 - lib/api/chat/chat_provider_model.dart | 4 ++-- lib/classes/consts.dart | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 034a5be..a841580 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,6 @@ pubspec.lock /build/ # Web related -lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index f5d896c..7227c99 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -49,8 +49,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { "${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", { "employeeNumber": int.parse( - //AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "210919" + AppState().memberInformationList!.eMPLOYEENUMBER.toString(), + //"210919" ), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" }, diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index ede22e3..c5788f9 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/"; From c6cd550dbced3b1462a69d247be0687556d925c3 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 17 Nov 2022 11:32:10 +0300 Subject: [PATCH 48/62] Chat Fixes --- ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme | 2 +- lib/ui/chat/chat_detailed_screen.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c87d15a..ac88fca 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -40,7 +40,7 @@ { actions: [ IconButton( onPressed: () { - makeCall("AUDIO"); + // makeCall("AUDIO"); }, icon: SvgPicture.asset( "assets/icons/chat/call.svg", @@ -82,7 +82,7 @@ class _ChatDetailScreenState extends State { ), IconButton( onPressed: () { - makeCall("VIDEO"); + // makeCall("VIDEO"); }, icon: SvgPicture.asset( "assets/icons/chat/video_call.svg", From 2546fb52a9100987b2ffe40033f4da1dba7b4646 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 17 Nov 2022 11:32:24 +0300 Subject: [PATCH 49/62] Chat Count Api / Chat Token Updates / Chat Call UI --- lib/classes/consts.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index ede22e3..c5788f9 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local 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/"; From 5913452a439d135dec80841635c821ec60f88afc Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 17 Nov 2022 11:34:54 +0300 Subject: [PATCH 50/62] Chat Count Api / Chat Token Updates / Chat Call UI --- lib/api/chat/chat_provider_model.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 7227c99..7439b98 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -50,7 +50,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { { "employeeNumber": int.parse( AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - //"210919" ), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" }, @@ -310,7 +309,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } Future onMsgReceived(List? parameters) async { - print("msg Received"); List data = []; List temp = []; for (dynamic msg in parameters!) { @@ -328,7 +326,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { // element.unreadMessageCount = val! + 1; // } // }); - logger.d(jsonEncode(data)); var list = [ { From efce6dbd0f0e7b1142737a043e9fed1b39dffb84 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 17 Nov 2022 11:50:37 +0300 Subject: [PATCH 51/62] Chat Count Api / Chat Token Updates / Chat Call UI --- ios/Runner/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 2ac7a44..2797543 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -44,6 +44,8 @@ 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. UIBackgroundModes remote-notification From 4d35767784b2d1264bdf3125883c09e00e2dcf50 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 17 Nov 2022 12:37:03 +0300 Subject: [PATCH 52/62] Revert "Chat Count Api / Chat Token Updates / Chat Call UI" This reverts commit 826c39bafc72f27eceb7a2fbb975740e2a18c7db. --- ios/Runner/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 2ac7a44..2797543 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -44,6 +44,8 @@ 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. UIBackgroundModes remote-notification From e2a1eb3c812686767225f3e59cdf958da6d90466 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 17 Nov 2022 15:05:49 +0300 Subject: [PATCH 53/62] Chat Count Api / Chat Token Updates / Chat Call UI --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a841580..4a374d7 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release +/ios/ From 8cb5d9a0610f397ea0dcb8a3d9e563f6ccb928e5 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 17 Nov 2022 15:15:33 +0300 Subject: [PATCH 54/62] Chat Count Api / Chat Token Updates / Chat Call UI --- lib/ui/chat/chat_detailed_screen.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index be34d7a..2c8b2d8 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -72,7 +72,7 @@ class _ChatDetailScreenState extends State { actions: [ IconButton( onPressed: () { - // makeCall("AUDIO"); + makeCall("AUDIO"); }, icon: SvgPicture.asset( "assets/icons/chat/call.svg", @@ -82,7 +82,7 @@ class _ChatDetailScreenState extends State { ), IconButton( onPressed: () { - // makeCall("VIDEO"); + makeCall("VIDEO"); }, icon: SvgPicture.asset( "assets/icons/chat/video_call.svg", From 42287f24d18b4a63377c0d62a09a17334de1bfc4 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 17 Nov 2022 15:16:16 +0300 Subject: [PATCH 55/62] Chat Count Api / Chat Token Updates / Chat Call UI --- ios/Runner/Info.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 2797543..2ac7a44 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -44,8 +44,6 @@ 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. UIBackgroundModes remote-notification From 1fcb6250f5264612c7062c3c9a9f13a234dd12a0 Mon Sep 17 00:00:00 2001 From: Aamir Saleem Ahmad Date: Thu, 17 Nov 2022 12:22:59 +0000 Subject: [PATCH 56/62] Revert "Chat Fixes" This reverts commit c6cd550dbced3b1462a69d247be0687556d925c3 --- ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index ac88fca..c87d15a 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -40,7 +40,7 @@ Date: Thu, 17 Nov 2022 12:24:46 +0000 Subject: [PATCH 57/62] Revert "Chat Count Api / Chat Token Updates / Chat Call UI" This reverts commit 42287f24d18b4a63377c0d62a09a17334de1bfc4 --- ios/Runner/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 2ac7a44..2797543 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -44,6 +44,8 @@ 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. UIBackgroundModes remote-notification From 06e7a913dae9f92a531074dd8bd5079742cf86c6 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 17 Nov 2022 15:57:29 +0300 Subject: [PATCH 58/62] Chat Count Api / Chat Token Updates / Chat Call UI --- .../chat/call/chat_outgoing_call_screen.dart | 2 +- lib/ui/chat/chat_bubble.dart | 65 +++++++++++++--- lib/ui/chat/chat_detailed_screen.dart | 46 ++++++++++-- lib/ui/chat/chat_home.dart | 22 ++++-- lib/ui/chat/chat_home_screen.dart | 74 +++++++++++++++---- lib/ui/chat/favorite_users_screen.dart | 21 ++++-- 6 files changed, 180 insertions(+), 50 deletions(-) diff --git a/lib/ui/chat/call/chat_outgoing_call_screen.dart b/lib/ui/chat/call/chat_outgoing_call_screen.dart index b5a47a6..f049059 100644 --- a/lib/ui/chat/call/chat_outgoing_call_screen.dart +++ b/lib/ui/chat/call/chat_outgoing_call_screen.dart @@ -82,7 +82,7 @@ class _OutGoingCallState extends State with SingleTickerProviderSt Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, - children: [ + children: [ Container( margin: const EdgeInsets.all(21.0), child: Container( diff --git a/lib/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index 6dcd6d2..1696a49 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -30,7 +30,11 @@ class ChatBubble extends StatelessWidget { Widget build(BuildContext context) { return Padding( // padding: EdgeInsets.zero, - padding: EdgeInsets.only(left: isCurrentUser ? 110 : 20, right: isCurrentUser ? 20 : 110, bottom: 9), + padding: EdgeInsets.only( + left: isCurrentUser ? 110 : 20, + right: isCurrentUser ? 20 : 110, + bottom: 9, + ), child: Align( alignment: isCurrentUser ? Alignment.centerRight : Alignment.centerLeft, @@ -40,7 +44,9 @@ class ChatBubble extends StatelessWidget { gradient: isCurrentUser ? null : const LinearGradient( - transform: GradientRotation(.46), + transform: GradientRotation( + .46, + ), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ @@ -48,21 +54,33 @@ class ChatBubble extends StatelessWidget { MyColors.gradiantStartColor, ], ), - borderRadius: BorderRadius.circular(10), + borderRadius: BorderRadius.circular( + 10, + ), ), child: Padding( - padding: EdgeInsets.only(top: isReplied ? 8 : 5, right: 8, left: 8, bottom: 5), + padding: EdgeInsets.only( + top: isReplied ? 8 : 5, + right: 8, + left: 8, + bottom: 5, + ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ if (isReplied) ClipRRect( - borderRadius: BorderRadius.circular(5.0), + borderRadius: BorderRadius.circular( + 5.0, + ), child: Container( decoration: BoxDecoration( border: Border( - left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white), + left: BorderSide( + width: 6, + color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white, + ), ), color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30), ), @@ -72,10 +90,29 @@ class ChatBubble extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - (userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5), + (userName) + .toText12( + color: MyColors.gradiantStartColor, + isBold: false, + ) + .paddingOnly( + right: 5, + top: 5, + bottom: 0, + left: 5, + ), replyText - .toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4) - .paddingOnly(right: 5, top: 5, bottom: 8, left: 5), + .toText10( + color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), + isBold: false, + maxlines: 4, + ) + .paddingOnly( + right: 5, + top: 5, + bottom: 8, + left: 5, + ), ], ), ), @@ -84,12 +121,16 @@ class ChatBubble extends StatelessWidget { ), ), if (isReplied) 8.height, - text.toText12(color: isCurrentUser ? MyColors.grey57Color : MyColors.white), + text.toText12( + color: isCurrentUser ? MyColors.grey57Color : MyColors.white, + ), Row( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, - children: [ - dateTime.toText12(color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7),), + children: [ + dateTime.toText12( + color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7), + ), if (isCurrentUser) 5.width, // if (isCurrentUser) // Icon( diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 2c8b2d8..347c573 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -132,7 +132,9 @@ class _ChatDetailScreenState extends State { userName: AppState().chatDetails!.response!.userName == m.userChatHistory[i].currentUserName.toString() ? "You" : m.userChatHistory[i].currentUserName.toString(), ), onRightSwipe: () { - m.chatReply(m.userChatHistory[i]); + m.chatReply( + m.userChatHistory[i], + ); }, ); }, @@ -156,7 +158,10 @@ class _ChatDetailScreenState extends State { ? "You" : m.repliedMsg.first.currentUserName.toString().replaceAll(".", " ")) .toText14(color: MyColors.lightGreenColor), - subtitle: (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(color: MyColors.white, maxLine: 2), + subtitle: (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12( + color: MyColors.white, + maxLine: 2, + ), trailing: GestureDetector( onTap: m.closeMe, child: Container( @@ -183,7 +188,12 @@ class _ChatDetailScreenState extends State { margin: EdgeInsets.zero, elevation: 0, child: Padding( - padding: const EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 0), + padding: const EdgeInsets.only( + left: 20, + right: 20, + top: 20, + bottom: 0, + ), child: Card( margin: EdgeInsets.zero, shape: RoundedRectangleBorder( @@ -217,13 +227,21 @@ class _ChatDetailScreenState extends State { controller: m.message, decoration: InputDecoration( hintText: m.isFileSelected ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(), - hintStyle: TextStyle(color: m.isFileSelected ? MyColors.darkTextColor : MyColors.grey98Color, fontSize: 14), + hintStyle: TextStyle( + color: m.isFileSelected ? MyColors.darkTextColor : MyColors.grey98Color, + fontSize: 14, + ), border: InputBorder.none, focusedBorder: InputBorder.none, enabledBorder: InputBorder.none, errorBorder: InputBorder.none, disabledBorder: InputBorder.none, - contentPadding: EdgeInsets.only(left: m.sFileType.isNotEmpty ? 10 : 20, right: m.sFileType.isNotEmpty ? 0 : 5, top: 20, bottom: 20), + contentPadding: EdgeInsets.only( + left: m.sFileType.isNotEmpty ? 10 : 20, + right: m.sFileType.isNotEmpty ? 0 : 5, + top: 20, + bottom: 20, + ), prefixIcon: m.sFileType.isNotEmpty ? Row( mainAxisSize: MainAxisSize.min, @@ -267,7 +285,13 @@ class _ChatDetailScreenState extends State { color: MyColors.white, ), ), - ("Clear").toText11(color: MyColors.redA3Color).paddingOnly(left: 4), + ("Clear") + .toText11( + color: MyColors.redA3Color, + ) + .paddingOnly( + left: 4, + ), ], ), onPressed: () async { @@ -299,12 +323,18 @@ class _ChatDetailScreenState extends State { width: 26, ), onPressed: () { - m.sendChatMessage(userDetails["targetUser"].id, userDetails["targetUser"].userName, context); + m.sendChatMessage( + userDetails["targetUser"].id, + userDetails["targetUser"].userName, + context, + ); }, ) ], ), - ).paddingOnly(right: 20), + ).paddingOnly( + right: 20, + ), ), ), ), diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index ed6b155..9884d59 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -34,11 +34,8 @@ class _ChatHomeState extends State { // TODO: implement initState super.initState(); data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().then((value) { + data.getUserAutoLoginToken().then((Object? value) { data.getUserRecentChats(); - // var datae = [int.parse(AppState().memberInformationList!.eMPLOYEENUMBER.toString())]; - - // data.hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [int.parse(AppState().memberInformationList!.eMPLOYEENUMBER.toString())]); }); } @@ -73,14 +70,17 @@ class _ChatHomeState extends State { transform: GradientRotation(.83), begin: Alignment.topRight, end: Alignment.bottomLeft, - colors: [ + colors: [ MyColors.gradiantEndColor, MyColors.gradiantStartColor, ], ), ), child: Row( - children: [myTab(LocaleKeys.mychats.tr(), 0), myTab(LocaleKeys.favorite.tr(), 1)], + children: [ + myTab(LocaleKeys.mychats.tr(), 0), + myTab(LocaleKeys.favorite.tr(), 1), + ], ), ), PageView( @@ -91,7 +91,10 @@ class _ChatHomeState extends State { tabIndex = pageIndex; }); }, - children: [ChatHomeScreen(), ChatFavoriteUsersScreen()], + children: [ + ChatHomeScreen(), + ChatFavoriteUsersScreen(), + ], ).expanded, ], ), @@ -104,7 +107,10 @@ class _ChatHomeState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ - title.toText12(color: isSelected ? MyColors.white : MyColors.white.withOpacity(.74), isCenter: true), + title.toText12( + color: isSelected ? MyColors.white : MyColors.white.withOpacity(.74), + isCenter: true, + ), 4.height, Container( height: 8, diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index a22c7e0..05623f7 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -40,21 +40,41 @@ class _ChatHomeScreenState extends State { physics: const AlwaysScrollableScrollPhysics(), children: [ Padding( - padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20), + padding: const EdgeInsets.symmetric( + vertical: 20, + horizontal: 20, + ), child: TextField( controller: m.search, onChanged: (String val) { m.filter(val); }, decoration: InputDecoration( - border: fieldBorder(radius: 5, color: 0xFFE5E5E5), - focusedBorder: fieldBorder(radius: 5, color: 0xFFE5E5E5), - enabledBorder: fieldBorder(radius: 5, color: 0xFFE5E5E5), - contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), + border: fieldBorder( + radius: 5, + color: 0xFFE5E5E5, + ), + focusedBorder: fieldBorder( + radius: 5, + color: 0xFFE5E5E5, + ), + enabledBorder: fieldBorder( + radius: 5, + color: 0xFFE5E5E5, + ), + contentPadding: const EdgeInsets.symmetric( + horizontal: 15, + vertical: 10, + ), hintText: LocaleKeys.searchfromchat.tr(), - hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic), + hintStyle: const TextStyle( + color: MyColors.lightTextColor, + fontStyle: FontStyle.italic, + ), filled: true, - fillColor: const Color(0xFFF7F7F7), + fillColor: const Color( + 0xFFF7F7F7, + ), suffixIcon: m.search.text.isNotEmpty ? IconButton( onPressed: () { @@ -73,7 +93,9 @@ class _ChatHomeScreenState extends State { if (m.searchedChats != null) ListView.separated( itemCount: m.searchedChats!.length, - padding: const EdgeInsets.only(bottom: 80), + padding: const EdgeInsets.only( + bottom: 80, + ), shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (BuildContext context, int index) { @@ -136,15 +158,26 @@ class _ChatHomeScreenState extends State { child: IconButton( alignment: Alignment.centerRight, padding: EdgeInsets.zero, - icon: Icon(m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == false ? Icons.star_sharp : Icons.star_sharp), + icon: Icon( + m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == false ? Icons.star_sharp : Icons.star_sharp, + ), color: m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == true ? MyColors.yellowColor : MyColors.grey35Color, onPressed: () { if (m.searchedChats![index].isFav == null || m.searchedChats![index].isFav == false) { - m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + m.favoriteUser( + userID: AppState().chatDetails!.response!.id!, + targetUserID: m.searchedChats![index].id!, + ); } else if (m.searchedChats![index].isFav == true) { - m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + m.unFavoriteUser( + userID: AppState().chatDetails!.response!.id!, + targetUserID: m.searchedChats![index].id!, + ); } else { - m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + m.favoriteUser( + userID: AppState().chatDetails!.response!.id!, + targetUserID: m.searchedChats![index].id!, + ); } }, ), @@ -167,9 +200,14 @@ class _ChatHomeScreenState extends State { ); }, separatorBuilder: (BuildContext context, int index) => const Padding( - padding: EdgeInsets.only(right: 10, left: 70), + padding: EdgeInsets.only( + right: 10, + left: 70, + ), child: Divider( - color: Color(0xFFE5E5E5), + color: Color( + 0xFFE5E5E5, + ), ), ), ), @@ -217,9 +255,13 @@ class _ChatHomeScreenState extends State { OutlineInputBorder fieldBorder({required double radius, required int color}) { return OutlineInputBorder( - borderRadius: BorderRadius.circular(radius), + borderRadius: BorderRadius.circular( + radius, + ), borderSide: BorderSide( - color: Color(color), + color: Color( + color, + ), ), ); } diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart index fd118de..7ef0f84 100644 --- a/lib/ui/chat/favorite_users_screen.dart +++ b/lib/ui/chat/favorite_users_screen.dart @@ -34,7 +34,7 @@ class ChatFavoriteUsersScreen extends StatelessWidget { height: 55, child: ListTile( leading: Stack( - children: [ + children: [ SvgPicture.asset( "assets/images/user.svg", height: 48, @@ -56,14 +56,22 @@ class ChatFavoriteUsersScreen extends StatelessWidget { ) ], ), - title: (m.favUsersList![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor), + title: (m.favUsersList![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14( + color: MyColors.darkTextColor, + ), trailing: IconButton( alignment: Alignment.centerRight, padding: EdgeInsets.zero, - icon: Icon(m.favUsersList![index].isFav! ? Icons.star : Icons.star_border), + icon: Icon( + m.favUsersList![index].isFav! ? Icons.star : Icons.star_border, + ), color: m.favUsersList![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, onPressed: () { - if (m.favUsersList![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.favUsersList![index].id!); + if (m.favUsersList![index].isFav!) + m.unFavoriteUser( + userID: AppState().chatDetails!.response!.id!, + targetUserID: m.favUsersList![index].id!, + ); }, ), minVerticalPadding: 0, @@ -82,7 +90,10 @@ class ChatFavoriteUsersScreen extends StatelessWidget { ); }, separatorBuilder: (BuildContext context, int index) => const Padding( - padding: EdgeInsets.only(right: 10, left: 70), + padding: EdgeInsets.only( + right: 10, + left: 70, + ), child: Divider( color: Color( 0xFFE5E5E5, From a64ae80a4ae76f8b4d48b47e828c765c0eaf0d7e Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Sun, 20 Nov 2022 10:10:08 +0300 Subject: [PATCH 59/62] Chat Updates --- .../chat/call/chat_outgoing_call_screen.dart | 116 ++++++------------ lib/ui/landing/dashboard_screen.dart | 6 +- 2 files changed, 42 insertions(+), 80 deletions(-) diff --git a/lib/ui/chat/call/chat_outgoing_call_screen.dart b/lib/ui/chat/call/chat_outgoing_call_screen.dart index f049059..25bc05d 100644 --- a/lib/ui/chat/call/chat_outgoing_call_screen.dart +++ b/lib/ui/chat/call/chat_outgoing_call_screen.dart @@ -102,7 +102,7 @@ class _OutGoingCallState extends State with SingleTickerProviderSt fit: BoxFit.cover, ), 10.height, - Text( + const Text( "Aamir Saleem Ahmad", style: TextStyle( fontSize: 21, @@ -112,7 +112,7 @@ class _OutGoingCallState extends State with SingleTickerProviderSt height: 23 / 12, ), ), - Text( + const Text( "Ringing...", style: TextStyle( fontSize: 16, @@ -124,7 +124,7 @@ class _OutGoingCallState extends State with SingleTickerProviderSt height: 23 / 24, ), ), - SizedBox( + const SizedBox( height: 2, ), ], @@ -177,96 +177,54 @@ class _OutGoingCallState extends State with SingleTickerProviderSt mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (widget.isVideoCall!) - RotationTransition( - turns: Tween( - begin: 0.0, - end: -.1, - ) - .chain( - CurveTween( - curve: Curves.elasticIn, - ), - ) - .animate( - _animationController!, - ), - child: RawMaterialButton( - onPressed: () { - _camOff(); - }, - elevation: 2.0, - fillColor: isCamOff ? MyColors.green2DColor : Colors.grey, - padding: const EdgeInsets.all( - 15.0, - ), - shape: const CircleBorder(), - child: Icon( - isCamOff ? Icons.videocam_off : Icons.videocam, - color: MyColors.white, - size: 35.0, - ), + RawMaterialButton( + onPressed: () { + _camOff(); + }, + elevation: 2.0, + fillColor: isCamOff ? MyColors.green2DColor : Colors.grey, + padding: const EdgeInsets.all( + 15.0, ), - ) - else - RotationTransition( - turns: Tween( - begin: 0.0, - end: -.1, - ) - .chain( - CurveTween( - curve: Curves.elasticIn, - ), - ) - .animate( - _animationController!, - ), - child: RawMaterialButton( - onPressed: () { - _loudOn(); - }, - elevation: 2.0, - fillColor: isLoudSpeaker ? MyColors.green2DColor : Colors.grey, - padding: const EdgeInsets.all( - 15.0, - ), - shape: const CircleBorder(), - child: const Icon( - Icons.volume_up, - color: MyColors.white, - size: 35.0, - ), + shape: const CircleBorder(), + child: Icon( + isCamOff ? Icons.videocam_off : Icons.videocam, + color: MyColors.white, + size: 35.0, ), - ), - RotationTransition( - turns: Tween( - begin: 0.0, - end: -.1, ) - .chain( - CurveTween( - curve: Curves.elasticIn, - ), - ) - .animate( - _animationController!, - ), - child: RawMaterialButton( + else + RawMaterialButton( onPressed: () { - _micOff(); + _loudOn(); }, elevation: 2.0, - fillColor: isMicOff ? MyColors.green2DColor : Colors.grey, + fillColor: isLoudSpeaker ? MyColors.green2DColor : Colors.grey, padding: const EdgeInsets.all( 15.0, ), shape: const CircleBorder(), - child: Icon( - isMicOff ? Icons.mic_off : Icons.mic, + child: const Icon( + Icons.volume_up, color: MyColors.white, size: 35.0, ), ), + RawMaterialButton( + onPressed: () { + _micOff(); + }, + elevation: 2.0, + fillColor: isMicOff ? MyColors.green2DColor : Colors.grey, + padding: const EdgeInsets.all( + 15.0, + ), + shape: const CircleBorder(), + child: Icon( + isMicOff ? Icons.mic_off : Icons.mic, + color: MyColors.white, + size: 35.0, + ), ), RawMaterialButton( onPressed: () { diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 7453603..a6c08c3 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -13,6 +13,7 @@ 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/main.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/ui/landing/widget/app_drawer.dart'; @@ -515,7 +516,10 @@ class _DashboardScreenState extends State { } else if (index == 3) { Navigator.pushNamed(context, AppRoutes.itemsForSale); } else if (index == 4) { - Navigator.pushNamed(context, AppRoutes.chat); + Navigator.pushNamed(context, AppRoutes.chat).then((Object? value) { + logger.d("Again Api Call"); + data.fetchChatCounts(); + }); } }, ), From 5708c93ae5972c67c2b34513b81c8b5171466009 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Sun, 20 Nov 2022 10:20:46 +0300 Subject: [PATCH 60/62] Chat Updates --- lib/ui/landing/dashboard_screen.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index a6c08c3..c568e6f 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -480,9 +480,6 @@ class _DashboardScreenState extends State { ).paddingAll(4), Consumer( builder: (BuildContext cxt, DashboardProviderModel data, Widget? child) { - if (data.chatUConvCounter == 0) { - return const SizedBox(); - } return Positioned( right: 0, top: 0, @@ -517,7 +514,6 @@ class _DashboardScreenState extends State { Navigator.pushNamed(context, AppRoutes.itemsForSale); } else if (index == 4) { Navigator.pushNamed(context, AppRoutes.chat).then((Object? value) { - logger.d("Again Api Call"); data.fetchChatCounts(); }); } From 4f88f30368740e8e671a78cda2738b675d060eb9 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 20 Nov 2022 10:26:14 +0300 Subject: [PATCH 61/62] updates --- lib/ui/landing/dashboard_screen.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 165793b..45eea24 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -479,9 +479,9 @@ class _DashboardScreenState extends State { ).paddingAll(4), Consumer( builder: (BuildContext cxt, DashboardProviderModel data, Widget? child) { - if (data.chatUConvCounter == 0) { - return const SizedBox(); - } + // if (data.chatUConvCounter == 0) { + // return const SizedBox(); + // } return Positioned( right: 0, top: 0, From ba1a5c66ef76a24acc701b7fe0132d15395bb6d1 Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Sun, 20 Nov 2022 12:34:32 +0300 Subject: [PATCH 62/62] fix issues --- lib/api/my_attendance_api_client.dart | 30 +++++++++++++++---- lib/models/generic_response_model.dart | 4 +-- .../dynamic_screens/dynamic_input_screen.dart | 21 ++++++++----- .../dynamic_listview_screen.dart | 7 +++-- .../services_menu_list_screen.dart | 8 +++-- lib/ui/my_team/create_request.dart | 5 ++-- lib/ui/my_team/team_members.dart | 6 ++-- .../dynamic_input_basic_details_screen.dart | 22 ++++++++++---- .../dynamic_listview_screen.dart | 7 +++-- 9 files changed, 77 insertions(+), 33 deletions(-) diff --git a/lib/api/my_attendance_api_client.dart b/lib/api/my_attendance_api_client.dart index 72d9bcb..c11885c 100644 --- a/lib/api/my_attendance_api_client.dart +++ b/lib/api/my_attendance_api_client.dart @@ -18,47 +18,59 @@ class MyAttendanceApiClient { factory MyAttendanceApiClient() => _instance; - Future?> getEitTransaction(String pFunctionName) async { + Future?> getEitTransaction(String pFunctionName, String? empID) async { String url = "${ApiConsts.erpRest}GET_EIT_TRANSACTIONS"; Map postParams = {"P_PAGE_LIMIT": 50, "P_PAGE_NUM": 1, "P_SELECTED_RESP_ID": -999, "P_MENU_TYPE": "E", "P_FUNCTION_NAME": pFunctionName}; postParams.addAll(AppState().postParamsJson); + // postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID; + if('P_SELECTED_EMPLOYEE_NUMBER'.isNotEmpty){ + postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID; + // AppState().postParamsJson['P_SELECTED_EMPLOYEE_NUMBER'] = empID; + print(empID); + } return await ApiClient().postJsonForObject((json) { GenericResponseModel? responseData = GenericResponseModel.fromJson(json); return responseData.getEITTransactionList ?? []; }, url, postParams); } - Future getEitDffStructure(String pFunctionName) async { + Future getEitDffStructure(String pFunctionName, String? empID) async { String url = "${ApiConsts.erpRest}GET_EIT_DFF_STRUCTURE"; Map postParams = {"P_SELECTED_RESP_ID": -999, "P_MENU_TYPE": "E", "P_FUNCTION_NAME": pFunctionName}; postParams.addAll(AppState().postParamsJson); + if('P_SELECTED_EMPLOYEE_NUMBER'.isNotEmpty) { + postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID; + } return await ApiClient().postJsonForObject((json) { GenericResponseModel? responseData = GenericResponseModel.fromJson(json); return responseData; }, url, postParams); } - Future> getValueSetValues(String pSegmentName, String pDescFlexContextCode, String pDescFlexName, List> list) async { + Future> getValueSetValues(String pSegmentName, String pDescFlexContextCode, String pDescFlexName, List> list,{ String? empID, String? parentValue}) async { String url = "${ApiConsts.erpRest}GET_VALUE_SET_VALUES"; Map postParams = { "P_SELECTED_RESP_ID": -999, "P_MENU_TYPE": "E", "P_PAGE_LIMIT": 1000, "P_PAGE_NUM": 1, - "P_PARENT_VALUE": null, + "P_PARENT_VALUE": empID!.isNotEmpty? parentValue : null, "P_SEGMENT_NAME": pSegmentName, "P_DESC_FLEX_CONTEXT_CODE": pDescFlexContextCode, "P_DESC_FLEX_NAME": pDescFlexName, "GetValueSetValuesTBL": list, }; postParams.addAll(AppState().postParamsJson); + if('P_SELECTED_EMPLOYEE_NUMBER'.isNotEmpty) { + postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID; + } return await ApiClient().postJsonForObject((json) { GenericResponseModel? responseData = GenericResponseModel.fromJson(json); return responseData.getValueSetValuesList ?? []; }, url, postParams); } - Future getDefaultValue(String pSegmentName, String pDescFlexContextCode, String pDescFlexName, List> list) async { + Future getDefaultValue(String pSegmentName, String pDescFlexContextCode, String pDescFlexName, List> list, String? empID) async { String url = "${ApiConsts.erpRest}GET_DEFAULT_VALUE"; Map postParams = { "P_SELECTED_RESP_ID": -999, @@ -70,13 +82,16 @@ class MyAttendanceApiClient { "GetValueSetValuesTBL": list, }; postParams.addAll(AppState().postParamsJson); + if('P_SELECTED_EMPLOYEE_NUMBER'.isNotEmpty) { + postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID; + } return await ApiClient().postJsonForObject((json) { GenericResponseModel? responseData = GenericResponseModel.fromJson(json); return ESERVICESDV.fromJson(responseData.getDefaultValueList!.toJson()); }, url, postParams); } - Future validateEitTransaction(String pDescFlexContextCode, String pFunctionName, List> list) async { + Future validateEitTransaction(String pDescFlexContextCode, String pFunctionName, List> list, { String? empID}) async { String url = "${ApiConsts.erpRest}VALIDATE_EIT_TRANSACTION"; Map postParams = { "P_SELECTED_RESP_ID": -999, @@ -86,6 +101,9 @@ class MyAttendanceApiClient { "EITTransactionTBL": list, }; postParams.addAll(AppState().postParamsJson); + if('P_SELECTED_EMPLOYEE_NUMBER'.isNotEmpty) { + postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID; + } return await ApiClient().postJsonForObject((json) { GenericResponseModel? responseData = GenericResponseModel.fromJson(json); return responseData; //ESERVICESDV.fromJson(responseData.getDefaultValueList!.toJson()); diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index 5cfc4aa..cd7043c 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -334,7 +334,7 @@ class GenericResponseModel { String? sFHGetPrNotificationBodyList; StartAbsenceApprovalProccess? startAbsenceApprovalProccess; StartAddressApprovalProcess? startAddressApprovalProcessList; - String? startBasicDetApprProcessList; + StartAddressApprovalProcess? startBasicDetApprProcessList; String? startCeiApprovalProcess; String? startContactApprovalProcessList; StartEitApprovalProcess? startEitApprovalProcess; @@ -1294,7 +1294,7 @@ class GenericResponseModel { startAbsenceApprovalProccess = json['StartAbsenceApprovalProccess'] != null ? StartAbsenceApprovalProccess.fromJson(json['StartAbsenceApprovalProccess']) : null; startAddressApprovalProcessList = json['StartAddressApprovalProcessList'] != null ? StartAddressApprovalProcess.fromJson(json['StartAddressApprovalProcessList']) : null; - startBasicDetApprProcessList = json['StartBasicDetApprProcessList']; + startBasicDetApprProcessList = json['StartAddressApprovalProcessList'] != null ? StartAddressApprovalProcess.fromJson(json['StartAddressApprovalProcessList']) : null; startCeiApprovalProcess = json['StartCeiApprovalProcess']; startContactApprovalProcessList = json['StartContactApprovalProcessList']; 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 519bb6c..6cda072 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -5,6 +5,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/api/leave_balance_api_client.dart'; import 'package:mohem_flutter_app/api/my_attendance_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.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'; @@ -43,7 +44,8 @@ class _DynamicInputScreenState extends State { void getTransactionsStructure() async { try { Utils.showLoading(context); - genericResponseModel = await MyAttendanceApiClient().getEitDffStructure(dynamicParams!.dynamicId); + + genericResponseModel = await MyAttendanceApiClient().getEitDffStructure(dynamicParams!.dynamicId, dynamicParams!.selectedEmp); dESCFLEXCONTEXTCODE = genericResponseModel!.pDESCFLEXCONTEXTCODE ?? ""; descFlexConTextTitle = genericResponseModel!.pDESCFLEXCONTEXTNAME ?? ""; getEitDffStructureList = genericResponseModel?.getEITDFFStructureList ?? []; @@ -90,7 +92,7 @@ class _DynamicInputScreenState extends State { values.add(ValidateEitTransactionModel(dATEVALUE: null, nAME: "PEI_EXTRA_INFO_ID", nUMBERVALUE: -1, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: null).toJson()); values.add(ValidateEitTransactionModel(dATEVALUE: null, nAME: "PEI_OBJECT_VERSION_NUMBER", nUMBERVALUE: 0, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: null).toJson()); - genericResponseModel = await MyAttendanceApiClient().validateEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values); + genericResponseModel = await MyAttendanceApiClient().validateEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID:dynamicParams!.selectedEmp ??''); SubmitEITTransactionList submitEITTransactionList = await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values); Utils.hideLoading(context); await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, @@ -112,14 +114,14 @@ class _DynamicInputScreenState extends State { Utils.showLoading(context); String segmentId = structureList.cHILDSEGMENTSVS!; if (dESCFLEXCONTEXTCODE.isEmpty) dESCFLEXCONTEXTCODE = structureList.dESCFLEXCONTEXTCODE!; - List filteredList = getEitDffStructureList?.where((element) => element.cHILDSEGMENTSVSSplited!.contains(segmentId)).toList() ?? []; - List> values = filteredList + List> values = filteredList .map((e) => GetSetValuesRequestModel( sEGMENTNAME: e.sEGMENTNAME, vALUECOLUMNNAME: e.eSERVICESDV!.pVALUECOLUMNNAME, dESCRIPTION: "", iDCOLUMNNAME: e.eSERVICESDV!.pIDCOLUMNNAME, fLEXVALUESETNAME: e.fLEXVALUESETNAME) .toJson()) .toList(); - List eServicesResponseModel = await MyAttendanceApiClient().getValueSetValues(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, values); + List eServicesResponseModel = await MyAttendanceApiClient().getValueSetValues(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, + values, empID:dynamicParams!.selectedEmp ??'', parentValue: structureList.eSERVICESDV!.pVALUECOLUMNNAME ); List abc = genericResponseModel?.getEITDFFStructureList ?? []; getEitDffStructureList = abc; int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == structureList.cHILDSEGMENTSVS); @@ -155,7 +157,7 @@ class _DynamicInputScreenState extends State { List> getSetList = getDefaultValuesIonicLogic(parent); if (getSetList.isNotEmpty) { - ESERVICESDV defaultValue = await MyAttendanceApiClient().getDefaultValue(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, getSetList); + ESERVICESDV defaultValue = await MyAttendanceApiClient().getDefaultValue(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, getSetList, dynamicParams!.selectedEmp); int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId); getEitDffStructureList![index].eSERVICESDV = defaultValue; } @@ -340,7 +342,7 @@ class _DynamicInputScreenState extends State { String? text = data?.pVALUECOLUMNNAME; String? val = data?.pIDCOLUMNNAME; - if ((val ?? "").isEmpty && parentsList[i].IsRequired == "REQUIRED") { + if ((val ?? "").isEmpty && parentsList[i].isRequired == "REQUIRED") { //alert(parentsList[i].Name +" Is required"); return []; } else {} @@ -362,7 +364,7 @@ class _DynamicInputScreenState extends State { String? text = data?.pVALUECOLUMNNAME; String? val = data?.pIDCOLUMNNAME; - if ((val ?? "").isEmpty && parentsList[i].IsRequired == "REQUIRED") { + if ((val ?? "").isEmpty && parentsList[i].isRequired == "REQUIRED") { //alert(parentsList[i].Name +" Is required"); return []; } else {} @@ -392,6 +394,9 @@ class _DynamicInputScreenState extends State { Widget build(BuildContext context) { if (dynamicParams == null) { dynamicParams = ModalRoute.of(context)!.settings.arguments as DynamicListViewParams; + if(dynamicParams!.selectedEmp.isNotEmpty){ + AppState().postParamsJson['P_SELECTED_EMPLOYEE_NUMBER'] = dynamicParams!.selectedEmp; + } getTransactionsStructure(); } return Scaffold( diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart index ec52304..5c4053c 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart @@ -18,9 +18,11 @@ class DynamicListViewParams { String requestID; String colsURL; bool isUpdate; + List? collectionNotificationList; + final String selectedEmp; - DynamicListViewParams(this.title, this.dynamicId, {this.uRL = 'GET_EIT_DFF_STRUCTURE', this.requestID = '', this.colsURL = '', this.isUpdate = false, this.collectionNotificationList}); + DynamicListViewParams(this.title, this.dynamicId, {this.selectedEmp ='', this.uRL = 'GET_EIT_DFF_STRUCTURE', this.requestID = '', this.colsURL = '', this.isUpdate = false, this.collectionNotificationList}); } class DynamicListViewScreen extends StatefulWidget { @@ -35,6 +37,7 @@ class DynamicListViewScreen extends StatefulWidget { class _DynamicListViewScreenState extends State { List? getEITTransactionList; DynamicListViewParams? dynamicParams; + // String? empId; @override void initState() { @@ -44,7 +47,7 @@ class _DynamicListViewScreenState extends State { void getTransactions() async { try { Utils.showLoading(context); - getEITTransactionList = await MyAttendanceApiClient().getEitTransaction(dynamicParams!.dynamicId); + getEITTransactionList = await MyAttendanceApiClient().getEitTransaction(dynamicParams!.dynamicId, dynamicParams!.selectedEmp); getEITTransactionList?.forEach((element) { element.collectionTransaction = element.collectionTransaction?.where((elemen) => elemen.dISPLAYFLAG == "Y").toList() ?? []; }); diff --git a/lib/ui/my_attendance/services_menu_list_screen.dart b/lib/ui/my_attendance/services_menu_list_screen.dart index c05e035..cd76132 100644 --- a/lib/ui/my_attendance/services_menu_list_screen.dart +++ b/lib/ui/my_attendance/services_menu_list_screen.dart @@ -8,6 +8,7 @@ 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/models/dashboard/menu_entries.dart'; +import 'package:mohem_flutter_app/models/my_team/get_employee_subordinates_list.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; @@ -16,8 +17,9 @@ import 'package:provider/provider.dart'; class ServicesMenuListScreenParams { final String title; final List list; - - ServicesMenuListScreenParams(this.title, this.list); + final String selectedEmp; + GetEmployeeSubordinatesList? getEmployeeSubordinates; + ServicesMenuListScreenParams(this.title, this.list, {this.selectedEmp =''}); } class ServicesMenuListScreen extends StatelessWidget { @@ -56,7 +58,7 @@ class ServicesMenuListScreen extends StatelessWidget { return; } if (servicesMenuData.list[index].requestType == "EIT") { - Navigator.pushNamed(context, AppRoutes.dynamicScreen, arguments: DynamicListViewParams(servicesMenuData.list[index].prompt!, servicesMenuData.list[index].functionName!)); + Navigator.pushNamed(context, AppRoutes.dynamicScreen, arguments: DynamicListViewParams(servicesMenuData.list[index].prompt!, servicesMenuData.list[index].functionName!, selectedEmp: servicesMenuData.selectedEmp)); } else { if (servicesMenuData.list[index].requestType == "TERMINATION") { Navigator.pushNamed(context, AppRoutes.endEmploymentScreen, diff --git a/lib/ui/my_team/create_request.dart b/lib/ui/my_team/create_request.dart index a4c6c83..53205c9 100644 --- a/lib/ui/my_team/create_request.dart +++ b/lib/ui/my_team/create_request.dart @@ -65,13 +65,14 @@ class _CreateRequestState extends State { return menus; } - void handleOnPress(context, Menus menu) { + void handleOnPress(context, Menus menu) { + if (menu.menuEntry.menuEntryType == "FUNCTION") { if (menu.menuEntry.requestType == "EIT") { Navigator.pushNamed(context, AppRoutes.dynamicScreen, arguments: DynamicListViewParams(menu.menuEntry.prompt!, menu.menuEntry.functionName!)); } else {} } else { - Navigator.pushNamed(context, AppRoutes.servicesMenuListScreen, arguments: ServicesMenuListScreenParams(menu.menuEntry.prompt!, menu.menuEntiesList)); + Navigator.pushNamed(context, AppRoutes.servicesMenuListScreen, arguments: ServicesMenuListScreenParams(menu.menuEntry.prompt!, menu.menuEntiesList, selectedEmp: getEmployeeSubordinates?.eMPLOYEENUMBER??'')); } return; } diff --git a/lib/ui/my_team/team_members.dart b/lib/ui/my_team/team_members.dart index 50bf7e7..e7336bb 100644 --- a/lib/ui/my_team/team_members.dart +++ b/lib/ui/my_team/team_members.dart @@ -14,7 +14,8 @@ import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:url_launcher/url_launcher.dart'; class TeamMembers extends StatefulWidget { - const TeamMembers({Key? key}) : super(key: key); + final String? selectedEmp; + const TeamMembers({this.selectedEmp, Key? key}) : super(key: key); @override _TeamMembersState createState() => _TeamMembersState(); @@ -25,6 +26,7 @@ class _TeamMembersState extends State { String searchEmpName =""; String searchEmpNo = ""; String? empId; + List getEmployeeSubordinatesList = []; GetEmployeeSubordinatesList? getEmployeeSubordinates; @@ -37,7 +39,7 @@ class _TeamMembersState extends State { try { Utils.showLoading(context); getEmployeeSubordinatesList = await MyTeamApiClient().getEmployeeSubordinates(searchEmpEmail.toString(), searchEmpName.toString(), searchEmpNo.toString()); - getEmployeeSubordinatesList = await MyTeamApiClient().employeeSubordinates(searchEmpEmail.toString(), searchEmpName.toString(), searchEmpNo.toString(),getEmployeeSubordinates?.eMPLOYEENUMBER); + // getEmployeeSubordinatesList = await MyTeamApiClient().employeeSubordinates(searchEmpEmail.toString(), searchEmpName.toString(), searchEmpNo.toString(),getEmployeeSubordinates?.eMPLOYEENUMBER); Utils.hideLoading(context); setState(() {}); } catch (ex) { diff --git a/lib/ui/profile/dynamic_screens/dynamic_input_basic_details_screen.dart b/lib/ui/profile/dynamic_screens/dynamic_input_basic_details_screen.dart index 3127bec..444b83e 100644 --- a/lib/ui/profile/dynamic_screens/dynamic_input_basic_details_screen.dart +++ b/lib/ui/profile/dynamic_screens/dynamic_input_basic_details_screen.dart @@ -80,11 +80,23 @@ class _DynamicInputScreenState extends State { } }); } else { - getBasicDetDffStructureList?.forEach((element) { - element.userBasicDetail = new GetEmployeeBasicDetailsList(); + // getBasicDetDffStructureList?.forEach((element) { + // element.userBasicDetail = new GetEmployeeBasicDetailsList(); + // }); + // getBasicDetColsStructureList?.forEach((element) { + // element.userBasicDetail = GetEmployeeBasicDetailsList(); + // }); + getBasicDetDffStructureList?.forEach((GetBasicDetDffStructureList element) { + element.userBasicDetail = + dynamicParams!.getEmployeeBasicDetailsList!.singleWhere((GetEmployeeBasicDetailsList userDetail) => userDetail.aPPLICATIONCOLUMNNAME == element.aPPLICATIONCOLUMNNAME); }); - getBasicDetColsStructureList?.forEach((element) { - element.userBasicDetail = GetEmployeeBasicDetailsList(); + getBasicDetColsStructureList?.forEach((GetBasicDetColsStructureList element) { + element.userBasicDetail = + dynamicParams!.getEmployeeBasicDetailsList!.singleWhere((GetEmployeeBasicDetailsList userDetail) => userDetail.aPPLICATIONCOLUMNNAME == element.aPPLICATIONCOLUMNNAME); + if (element.objectValuesList != null) { + ObjectValuesList dropDownListValue = element.objectValuesList!.singleWhere((ObjectValuesList dropdown) => dropdown.cODE == element.userBasicDetail!.vARCHAR2VALUE); + element.userBasicDetail!.sEGMENTVALUEDSP = dropDownListValue.mEANING; + } }); } @@ -369,7 +381,7 @@ class _DynamicInputScreenState extends State { //values.add(ValidateEitTransactionModel(dATEVALUE: null, nAME: "PEI_OBJECT_VERSION_NUMBER", nUMBERVALUE: 0, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: null).toJson()); List> valuesCols = getBasicDetColsStructureList!.map((e) { if (e.dATATYPE == 'NUMBER') { - numberValue = e.userBasicDetail!.nUMBERVALUE!; + numberValue = e.userBasicDetail!.nUMBERVALUE ?? 0; } return ValidateEitTransactionModel( dATEVALUE: e.userBasicDetail!.dATEVALUE ?? "", nAME: e.aPPLICATIONCOLUMNNAME, nUMBERVALUE: numberValue, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: e.userBasicDetail!.vARCHAR2VALUE ?? "") diff --git a/lib/ui/profile/dynamic_screens/dynamic_listview_screen.dart b/lib/ui/profile/dynamic_screens/dynamic_listview_screen.dart index ed35527..dce4662 100644 --- a/lib/ui/profile/dynamic_screens/dynamic_listview_screen.dart +++ b/lib/ui/profile/dynamic_screens/dynamic_listview_screen.dart @@ -17,7 +17,8 @@ class DynamicListViewParams { String dynamicId; String uRL; String requestID; - DynamicListViewParams(this.title, this.dynamicId, {this.uRL = 'GET_EIT_DFF_STRUCTURE', this.requestID = ''}); + final String selectedEmp; + DynamicListViewParams(this.title, this.dynamicId, {this.selectedEmp ='', this.uRL = 'GET_EIT_DFF_STRUCTURE', this.requestID = ''}); } class DynamicListViewScreen extends StatefulWidget { @@ -38,9 +39,9 @@ class _DynamicListViewScreenState extends State { } void getTransactions() async { - try { + try { Utils.showLoading(context); - getEITTransactionList = await MyAttendanceApiClient().getEitTransaction(dynamicParams!.dynamicId); + getEITTransactionList = await MyAttendanceApiClient().getEitTransaction(dynamicParams!.dynamicId, dynamicParams!.selectedEmp); Utils.hideLoading(context); setState(() {}); } catch (ex) {