diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 91e7ba3..546a7f9 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,4 +1,5 @@ @@ -8,6 +9,16 @@ + + + + + + + + @@ -27,6 +38,17 @@ android:usesCleartextTraffic="true" android:networkSecurityConfig="@xml/network_security_config" android:roundIcon="@mipmap/ic_launcher_round"> + + + + + + + \ No newline at end of file diff --git a/assets/json/demo_upcoming_marathon b/assets/json/demo_upcoming_marathon index 2fdabf0..f08cb22 100644 --- a/assets/json/demo_upcoming_marathon +++ b/assets/json/demo_upcoming_marathon @@ -16,7 +16,7 @@ "projects": { "id": "b1cd3fa3-bb27-422e-a4c1-08dac09254df", "nameEn": "Cloud Solutions", - "nameAr": "333شركة حلول السحابة للاتصالات وتقنية المعلومات", + "nameAr": "شركة حلول السحابة للاتصالات وتقنية المعلومات", "projectCode": "CS" }, "sponsors": [ @@ -42,5 +42,6 @@ "totalQuestions": 10, "cancelReason": null, "marathonBufferTime": 30, - "currentTime": "2022-12-28T08:03:24.3671803Z" + "currentTime": "2022-12-28T08:03:24.3671803Z", + "displayCorrectAnswer": true } diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 43841a1..e734dc5 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -144,7 +144,6 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, C4CFBC4C5CAC00182015ACD5 /* [CP] Embed Pods Frameworks */, - 1C704830960BB41251F31356 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -204,23 +203,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 1C704830960BB41251F31356 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; 2D06B7AD3B87C9C9059E4168 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -245,6 +227,7 @@ }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -259,6 +242,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -382,17 +366,18 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest; + MARKETING_VERSION = 3.7.8; + PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -519,17 +504,18 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest; + MARKETING_VERSION = 3.7.8; + PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -548,17 +534,18 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest; + MARKETING_VERSION = 3.7.8; + PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index 318a383..88cbc6d 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -1,7 +1,9 @@ import 'dart:convert'; import 'dart:io'; +import 'dart:typed_data'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; @@ -27,12 +29,14 @@ class ChatApiClient { Future getUserLoginToken() async { user.UserAutoLoginModel userLoginResponse = user.UserAutoLoginModel(); + String? deviceToken = AppState().getIsHuawei ? AppState().getHuaweiPushToken : AppState().getDeviceToken; Response response = await ApiClient().postJsonForResponse( "${ApiConsts.chatLoginTokenUrl}externaluserlogin", { "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", "isMobile": true, + "platform": Platform.isIOS ? "ios" : "android", "deviceToken": AppState().getIsHuawei ? AppState().getHuaweiPushToken : AppState().getDeviceToken, "isHuaweiDevice": AppState().getIsHuawei, "platform": Platform.isIOS ? "ios" : "android", // ios, android diff --git a/lib/api/mowadhafhi/mowadhafhi_api_client.dart b/lib/api/mowadhafhi/mowadhafhi_api_client.dart index e5ecc4b..d724c67 100644 --- a/lib/api/mowadhafhi/mowadhafhi_api_client.dart +++ b/lib/api/mowadhafhi/mowadhafhi_api_client.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + 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'; @@ -10,6 +12,7 @@ import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_details.dart'; import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_transactions.dart'; import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_types.dart'; import 'package:mohem_flutter_app/models/mowadhafhi/get_tickets_list.dart'; +import 'package:mohem_flutter_app/models/mowadhafhi/get_transaction_attachment_model.dart'; class MowadhafhiApiClient { static final MowadhafhiApiClient _instance = MowadhafhiApiClient._internal(); @@ -51,6 +54,18 @@ class MowadhafhiApiClient { }, url, postParams); } + Future getTransactionAttachments(int? attachmentID) async { + String url = "${ApiConsts.cocRest}Mohemm_ITG_GetTicketAttachment"; + Map postParams = {"EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER, "ItgAttachmentId": attachmentID}; + + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel? responseData = GenericResponseModel.fromJson(json); + var jsonDecodedData = jsonDecode(responseData.mohemmITGResponseItem!); + return GetTransactionAttachmentModel.fromJson(jsonDecodedData); + }, url, postParams); + } + Future> getTicketTypes() async { String url = "${ApiConsts.cocRest}Mohemm_ITG_GetTicketTypes"; Map postParams = {"EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER}; diff --git a/lib/api/worklist/worklist_api_client.dart b/lib/api/worklist/worklist_api_client.dart index 29805ec..611bcf4 100644 --- a/lib/api/worklist/worklist_api_client.dart +++ b/lib/api/worklist/worklist_api_client.dart @@ -24,6 +24,7 @@ import 'package:mohem_flutter_app/models/get_user_item_type_list.dart'; import 'package:mohem_flutter_app/models/itg_forms_models/itg_request_model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; +import 'package:mohem_flutter_app/models/termination/termination_notification_body.dart'; import 'package:mohem_flutter_app/models/update_user_item_type_list.dart'; import 'package:mohem_flutter_app/models/worklist/GetRFCEmployeeList.dart'; import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart'; @@ -550,6 +551,22 @@ class WorkListApiClient { }, url, postParams); } + Future?> getTerminationNotificationBodyList(int? notificationId) async { + String url = "${ApiConsts.erpRest}GET_TERM_NOTIFICATION_BODY"; + Map postParams = { + "P_NOTIFICATION_ID": notificationId, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getTermNotificationBodyList; + }, url, postParams); + } + + + Future?> getFavoriteReplacementWithoutImage() async { String url = "${ApiConsts.erpRest}Mohemm_GetFavoriteReplacementsWithoutImage"; Map postParams = {}; diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 55f9448..847d282 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -90,7 +90,7 @@ class AppState { String get getHuaweiPushToken => _huaweiPushToken; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 5.3, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 5.7, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 9b85bb9..f0e19ab 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - static String baseUrl = "https://hmgwebservices.com"; // Live server + static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver + // 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/"; @@ -55,7 +55,6 @@ class ApiConsts { static String marathonGetMarathonersCount = marathonBaseUrl + "Participant/GetRemainingParticipants"; //DummyCards for the UI - static CardContent dummyQuestion = const CardContent(); static int tabletMinLength = 500; } @@ -73,3 +72,5 @@ class SharedPrefsConsts { static String mohemmWifiPassword = "mohemmWifiPassword"; static String editItemForSale = "editItemForSale"; } + + diff --git a/lib/classes/decorations_helper.dart b/lib/classes/decorations_helper.dart index b313673..fd6d4f7 100644 --- a/lib/classes/decorations_helper.dart +++ b/lib/classes/decorations_helper.dart @@ -30,7 +30,6 @@ class MyDecorations { return getContainersDecoration(MyColors.greenColor); case QuestionsOptionStatus.wrong: return getContainersDecoration(MyColors.redColor); - case QuestionsOptionStatus.selected: return getContainersDecoration(MyColors.yellowColorII); case QuestionsOptionStatus.unSelected: diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index 5188b2c..893b5b9 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -92,6 +92,7 @@ import 'package:mohem_flutter_app/models/submit_term_transaction_list_model.dart import 'package:mohem_flutter_app/models/subordinates_on_leaves_model.dart'; import 'package:mohem_flutter_app/models/termination/get_term_cols_structure_list_model.dart'; import 'package:mohem_flutter_app/models/termination/get_term_dff_structure_list_model.dart'; +import 'package:mohem_flutter_app/models/termination/termination_notification_body.dart'; import 'package:mohem_flutter_app/models/update_item_type_success_list.dart'; import 'package:mohem_flutter_app/models/update_user_item_type_list.dart'; import 'package:mohem_flutter_app/models/vacation_rule/create_vacation_rule_list_model.dart'; @@ -223,7 +224,6 @@ class GenericResponseModel { List? getOrganizationsSalariesList; List? getPaymentInformationList; List? getPayslipList; - // List? getPendingReqDetailsList; // List? getPendingReqFunctionsList; List? getPerformanceAppraisalList; @@ -254,7 +254,7 @@ class GenericResponseModel { List? getSwipesList; List? getTermColsStructureList; List? getTermDffStructureList; - List? getTermNotificationBodyList; + List? getTermNotificationBodyList; List? getTimeCardSummaryList; List? getTicketsByEmployeeList; List? getTicketDetailsByEmployee; @@ -680,6 +680,7 @@ class GenericResponseModel { successMsg = json['SuccessMsg']; successMsgN = json['SuccessMsgN']; vidaUpdatedResponse = json['VidaUpdatedResponse']; + if (json['AddAttSuccessList'] != null) { addAttSuccessList = []; json['AddAttSuccessList'].forEach((v) { @@ -693,6 +694,14 @@ class GenericResponseModel { businessCardPrivilege = json['BusinessCardPrivilege']; calculateAbsenceDuration = json['CalculateAbsenceDuration'] != null ? new CalculateAbsenceDuration.fromJson(json['CalculateAbsenceDuration']) : null; cancelHRTransactionLIst = json['CancelHRTransactionLIst'] != null ? new CancelHRTransactionLIst.fromJson(json['CancelHRTransactionLIst']) : null; + + if (json['GetTermNotificationBodyList'] != null) { + getTermNotificationBodyList = []; + json['GetTermNotificationBodyList'].forEach((v) { + getTermNotificationBodyList!.add(TerminationNotificationBody.fromJson(v)); + }); + } + chatEmployeeLoginList = json['Chat_EmployeeLoginList']; companyBadge = json['CompanyBadge']; companyImage = json['CompanyImage']; @@ -1090,7 +1099,7 @@ class GenericResponseModel { }); } - getTermNotificationBodyList = json['GetTermNotificationBodyList']; + if (json['GetTimeCardSummaryList'] != null) { getTimeCardSummaryList = []; @@ -1612,6 +1621,9 @@ class GenericResponseModel { data['GetNotificationReassignModeList'] = getNotificationReassignModeList!.map((v) => v.toJson()).toList(); } + if(getTermNotificationBodyList !=null){ + data['GetTermNotificationBodyList'] = getTermNotificationBodyList!.map((v) => v.toJson()).toList(); + } data['GetObjectValuesList'] = this.getObjectValuesList; data['GetOpenMissingSwipesList'] = this.getOpenMissingSwipesList; data['GetOpenNotificationsList'] = this.getOpenNotificationsList; @@ -1688,7 +1700,6 @@ class GenericResponseModel { data['GetTermDffStructureList'] = this.getTermDffStructureList!.map((v) => v.toJson()).toList(); } - data['GetTermNotificationBodyList'] = this.getTermNotificationBodyList; if (this.getTimeCardSummaryList != null) { data['GetTimeCardSummaryList'] = this.getTimeCardSummaryList!.map((v) => v.toJson()).toList(); } diff --git a/lib/models/leave_balance/calculate_absence_duration_model.dart b/lib/models/leave_balance/calculate_absence_duration_model.dart index 0f0a48b..cf32a0e 100644 --- a/lib/models/leave_balance/calculate_absence_duration_model.dart +++ b/lib/models/leave_balance/calculate_absence_duration_model.dart @@ -1,6 +1,6 @@ class CalculateAbsenceDuration { - num? pABSENCEDAYS; - num? pABSENCEHOURS; + double? pABSENCEDAYS; + double? pABSENCEHOURS; String? pRETURNMSG; String? pRETURNSTATUS; diff --git a/lib/models/marathon/marathon_model.dart b/lib/models/marathon/marathon_model.dart index d86ffc7..934b73b 100644 --- a/lib/models/marathon/marathon_model.dart +++ b/lib/models/marathon/marathon_model.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + class MarathonDetailModel { String? id; String? titleEn; @@ -17,6 +19,7 @@ class MarathonDetailModel { List? questions; int? totalQuestions; int? marathonBufferTime; + bool? displayCorrectAnswer; MarathonDetailModel({ id, @@ -37,6 +40,7 @@ class MarathonDetailModel { questions, totalQuestions, marathonBufferTime, + displayCorrectAnswer, }); MarathonDetailModel.fromJson(Map json) { @@ -68,6 +72,7 @@ class MarathonDetailModel { } totalQuestions = json["totalQuestions"]; marathonBufferTime = json["marathonBufferTime"]; + displayCorrectAnswer = json["displayCorrectAnswer"]; } Map toJson() { diff --git a/lib/models/mowadhafhi/get_ticket_transactions.dart b/lib/models/mowadhafhi/get_ticket_transactions.dart index be793ca..3cb0ce1 100644 --- a/lib/models/mowadhafhi/get_ticket_transactions.dart +++ b/lib/models/mowadhafhi/get_ticket_transactions.dart @@ -1,24 +1,24 @@ class GetTicketTransactions { String? actionBy; String? actionDate; + List? attachments; String? comments; String? statusDisplayText; String? statusName; String? ticketId; int? ticketTransactionId; - GetTicketTransactions( - {this.actionBy, - this.actionDate, - this.comments, - this.statusDisplayText, - this.statusName, - this.ticketId, - this.ticketTransactionId}); + GetTicketTransactions({this.actionBy, this.actionDate, this.attachments, this.comments, this.statusDisplayText, this.statusName, this.ticketId, this.ticketTransactionId}); GetTicketTransactions.fromJson(Map json) { actionBy = json['actionBy']; actionDate = json['actionDate']; + if (json['attachments'] != null) { + attachments = []; + json['attachments'].forEach((v) { + attachments!.add(new Attachments.fromJson(v)); + }); + } comments = json['comments']; statusDisplayText = json['statusDisplayText']; statusName = json['statusName']; @@ -27,9 +27,12 @@ class GetTicketTransactions { } Map toJson() { - Map data = new Map(); + Map data = Map(); data['actionBy'] = this.actionBy; data['actionDate'] = this.actionDate; + if (this.attachments != null) { + data['attachments'] = this.attachments!.map((v) => v.toJson()).toList(); + } data['comments'] = this.comments; data['statusDisplayText'] = this.statusDisplayText; data['statusName'] = this.statusName; @@ -38,3 +41,22 @@ class GetTicketTransactions { return data; } } + +class Attachments { + int? attachmentId; + String? fileName; + + Attachments({this.attachmentId, this.fileName}); + + Attachments.fromJson(Map json) { + attachmentId = json['attachmentId']; + fileName = json['fileName']; + } + + Map toJson() { + Map data = Map(); + data['attachmentId'] = this.attachmentId; + data['fileName'] = this.fileName; + return data; + } +} diff --git a/lib/models/mowadhafhi/get_transaction_attachment_model.dart b/lib/models/mowadhafhi/get_transaction_attachment_model.dart new file mode 100644 index 0000000..1234946 --- /dev/null +++ b/lib/models/mowadhafhi/get_transaction_attachment_model.dart @@ -0,0 +1,52 @@ +class GetTransactionAttachmentModel { + int? attachmentId; + String? fileName; + String? contentType; + dynamic attachFileStream; + String? base64String; + dynamic isActive; + dynamic referenceItemId; + dynamic content; + dynamic filePath; + int? languageId; + + GetTransactionAttachmentModel( + {this.attachmentId, + this.fileName, + this.contentType, + this.attachFileStream, + this.base64String, + this.isActive, + this.referenceItemId, + this.content, + this.filePath, + this.languageId}); + + GetTransactionAttachmentModel.fromJson(Map json) { + attachmentId = json['attachmentId']; + fileName = json['fileName']; + contentType = json['contentType']; + attachFileStream = json['attachFileStream']; + base64String = json['base64String']; + isActive = json['isActive']; + referenceItemId = json['referenceItemId']; + content = json['content']; + filePath = json['filePath']; + languageId = json['languageId']; + } + + Map toJson() { + Map data = Map(); + data['attachmentId'] = this.attachmentId; + data['fileName'] = this.fileName; + data['contentType'] = this.contentType; + data['attachFileStream'] = this.attachFileStream; + data['base64String'] = this.base64String; + data['isActive'] = this.isActive; + data['referenceItemId'] = this.referenceItemId; + data['content'] = this.content; + data['filePath'] = this.filePath; + data['languageId'] = this.languageId; + return data; + } +} diff --git a/lib/models/termination/termination_notification_body.dart b/lib/models/termination/termination_notification_body.dart new file mode 100644 index 0000000..2c2c709 --- /dev/null +++ b/lib/models/termination/termination_notification_body.dart @@ -0,0 +1,18 @@ +class TerminationNotificationBody { + String? sEGMENTPROMPT; + String? sEGMENTVALUEDSP; + + TerminationNotificationBody({this.sEGMENTPROMPT, this.sEGMENTVALUEDSP}); + + TerminationNotificationBody.fromJson(Map json) { + sEGMENTPROMPT = json['SEGMENT_PROMPT']; + sEGMENTVALUEDSP = json['SEGMENT_VALUE_DSP']; + } + + Map toJson() { + Map data = new Map(); + data['SEGMENT_PROMPT'] = this.sEGMENTPROMPT; + data['SEGMENT_VALUE_DSP'] = this.sEGMENTVALUEDSP; + return data; + } +} diff --git a/lib/ui/leave_balance/add_leave_balance_screen.dart b/lib/ui/leave_balance/add_leave_balance_screen.dart index a16e81d..830ca85 100644 --- a/lib/ui/leave_balance/add_leave_balance_screen.dart +++ b/lib/ui/leave_balance/add_leave_balance_screen.dart @@ -40,7 +40,7 @@ class _AddLeaveBalanceScreenState extends State { GetAbsenceAttendanceTypesList? selectedAbsenceType; DateTime? startDateTime; DateTime? endDateTime; - int? totalDays; + double? totalDays; String comment = ""; ReplacementList? selectedReplacementEmployee; String? selectedEmp; @@ -90,7 +90,7 @@ class _AddLeaveBalanceScreenState extends State { Utils.showLoading(context); CalculateAbsenceDuration duration = await LeaveBalanceApiClient() .calculateAbsenceDuration(selectedAbsenceType!.aBSENCEATTENDANCETYPEID!, Utils.getMonthNamedFormat(startDateTime!), Utils.getMonthNamedFormat(endDateTime!), -999, empID: selectedEmp); - totalDays = duration.pABSENCEDAYS?.toInt(); + totalDays = duration.pABSENCEDAYS?.toDouble(); Utils.hideLoading(context); setState(() {}); } catch (ex) { @@ -232,7 +232,7 @@ class _AddLeaveBalanceScreenState extends State { isInputTypeNum: true, isEnable: false, onChange: (input) { - totalDays = int.parse(input); + totalDays = double.tryParse(input); }, ), 12.height, diff --git a/lib/ui/marathon/marathon_provider.dart b/lib/ui/marathon/marathon_provider.dart index 544aad3..ed241af 100644 --- a/lib/ui/marathon/marathon_provider.dart +++ b/lib/ui/marathon/marathon_provider.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:developer'; import 'package:appinio_swiper/appinio_swiper.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -414,13 +415,16 @@ class MarathonProvider extends ChangeNotifier { notifyListeners(); } - void updateCurrentQuestionOptionStatus(QuestionsOptionStatus status, int index) { + void updateCurrentQuestionOptionStatus({required QuestionsOptionStatus status, required int selectedOptIndex, required int correctOptionIndex}) { for (int i = 0; i < currentQuestion.questionOptions!.length; i++) { currentQuestion.questionOptions![i].optionStatus = QuestionsOptionStatus.unSelected; } - currentQuestion.questionOptions![index].optionStatus = status; - selectedOptionId = currentQuestion.questionOptions![index].id; - selectedOptionIndex = index; + if (status == QuestionsOptionStatus.wrong) { + currentQuestion.questionOptions![correctOptionIndex].optionStatus = QuestionsOptionStatus.correct; // if person's answer is wrong we have to show him the actual right answer + } + currentQuestion.questionOptions![selectedOptIndex].optionStatus = status; + selectedOptionId = currentQuestion.questionOptions![selectedOptIndex].id; + selectedOptionIndex = selectedOptIndex; notifyListeners(); } @@ -435,22 +439,30 @@ class MarathonProvider extends ChangeNotifier { } void getCorrectAnswerAndUpdateAnswerColor() { + log("correctOptionIndex"); + callCountThreshold = 1; + int correctOptionIndex = -1; + if (demoMarathonDetailModel.displayCorrectAnswer ?? false) { + correctOptionIndex = currentQuestion.questionOptions!.indexWhere((QuestionOptions element) => element.isCorrectOption ?? false); + log("correctOptionIndex: $correctOptionIndex"); + } + if (selectedOptionIndex != null) { scheduleMicrotask(() async { if (AppState().getIsDemoMarathon) { if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) { - updateCurrentQuestionOptionStatus(QuestionsOptionStatus.correct, selectedOptionIndex!); + updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.correct, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex); } else { - updateCurrentQuestionOptionStatus(QuestionsOptionStatus.wrong, selectedOptionIndex!); + updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.wrong, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex); } } else { await callSubmitOptionApi().then((bool value) async { updateIsUserOutOfGame = !value; if (value) { - updateCurrentQuestionOptionStatus(QuestionsOptionStatus.correct, selectedOptionIndex!); + updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.correct, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex); } else { - updateCurrentQuestionOptionStatus(QuestionsOptionStatus.wrong, selectedOptionIndex!); + updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.wrong, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex); } }); } @@ -551,7 +563,6 @@ class MarathonProvider extends ChangeNotifier { notifyListeners(); isPrivilegedWithMarathon = checkIfPrivilegedForMarathon(); demoMarathonDetailModel = await DemoMarathonRepo().getDemoMarathonDetails(); - if (isPrivilegedWithMarathon) { marathonDetailModel = await MarathonApiClient().getMarathonDetails(); updateTotalSecondsToWaitForMarathon = marathonDetailModel.marathonBufferTime ?? 30; diff --git a/lib/ui/marathon/widgets/question_card.dart b/lib/ui/marathon/widgets/question_card.dart index 8aa76bd..0965c9d 100644 --- a/lib/ui/marathon/widgets/question_card.dart +++ b/lib/ui/marathon/widgets/question_card.dart @@ -133,7 +133,7 @@ class AnswerContent extends StatelessWidget { if (provider.totalCurrentQuestionTime - provider.currentGapTime <= 0) { null; } else { - provider.updateCurrentQuestionOptionStatus(QuestionsOptionStatus.selected, index); + provider.updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.selected, selectedOptIndex: index, correctOptionIndex: -1); // } }, ); diff --git a/lib/ui/screens/mowadhafhi/request_details.dart b/lib/ui/screens/mowadhafhi/request_details.dart index aa22bdd..b2371ab 100644 --- a/lib/ui/screens/mowadhafhi/request_details.dart +++ b/lib/ui/screens/mowadhafhi/request_details.dart @@ -1,3 +1,8 @@ +import 'dart:convert'; +import 'dart:io'; +import 'dart:io' as Io; +import 'dart:typed_data'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/api/mowadhafhi/mowadhafhi_api_client.dart'; @@ -6,9 +11,14 @@ 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/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_details.dart'; import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_transactions.dart'; +import 'package:mohem_flutter_app/models/mowadhafhi/get_transaction_attachment_model.dart'; +import 'package:mohem_flutter_app/ui/screens/mowadhafhi/view_transaction_attachment.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; +import 'package:open_file/open_file.dart'; +import 'package:path_provider/path_provider.dart'; class MowadhafhiRequestDetails extends StatefulWidget { const MowadhafhiRequestDetails({Key? key}) : super(key: key); @@ -21,6 +31,9 @@ class _RequestDetailsState extends State { String? itgTicketID; List getTicketsByEmployeeList = []; List getTicketTransactionsList = []; + GetTransactionAttachmentModel? getTransactionAttachmentModel; + + late File imageFile; @override void initState() { @@ -43,7 +56,7 @@ class _RequestDetailsState extends State { backgroundColor: Colors.white, appBar: AppBarWidget( context, - title: LocaleKeys.mowadhafhiRequest.tr(), + title: LocaleKeys.mowadhafhiRequest.tr(), ), body: SingleChildScrollView( child: getTicketsByEmployeeList.length != 0 @@ -76,16 +89,16 @@ class _RequestDetailsState extends State { ], ), 8.height, - LocaleKeys.ticketReference.tr().toText12(color: MyColors.grey98Color), + LocaleKeys.ticketReference.tr().toText12(color: MyColors.grey98Color), getTicketsByEmployeeList![0].ticketReferenceNo!.toText14(color: MyColors.grey57Color), 8.height, - LocaleKeys.section.tr().toText12(color: MyColors.grey98Color), + LocaleKeys.section.tr().toText12(color: MyColors.grey98Color), getTicketsByEmployeeList![0].sectionName!.toText14(color: MyColors.grey57Color), 8.height, - LocaleKeys.topic.tr().toText12(color: MyColors.grey98Color), + LocaleKeys.topic.tr().toText12(color: MyColors.grey98Color), getTicketsByEmployeeList![0].topicName!.toText14(color: MyColors.grey57Color), 8.height, - LocaleKeys.description.tr().toText12(color: MyColors.grey98Color), + LocaleKeys.description.tr().toText12(color: MyColors.grey98Color), getTicketsByEmployeeList![0].description!.toText14(color: MyColors.grey57Color), ], ), @@ -128,15 +141,31 @@ class _RequestDetailsState extends State { Row( children: [ LocaleKeys.actionBy.tr().toText14(color: MyColors.grey57Color), + ": ".toText14(), getTicketTransactionsList![index].actionBy!.toText14(color: MyColors.grey57Color), ], ), + Row( + children: [ + LocaleKeys.actions.tr().toText14(color: MyColors.grey57Color), + ": ".toText14(), + getTicketTransactionsList![index].statusDisplayText!.toText14(color: MyColors.grey57Color), + ], + ), getTicketTransactionsList![index].comments!.toText14(color: MyColors.grey98Color), 12.height, + if (getTicketTransactionsList[index].attachments != null) + InkWell( + onTap: () { + print(getTicketTransactionsList[index].attachments![0].attachmentId); + getTransactionAttachment(getTicketTransactionsList[index].attachments![0].attachmentId!); + }, + child: LocaleKeys.attachments.tr().toText14(color: MyColors.gradiantEndColor, isUnderLine: true), + ), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - getTicketTransactionsList![0].actionDate!.split(" ")[0].toText12(color: MyColors.grey70Color), + getTicketTransactionsList![index].actionDate!.split(" ")[0].toText12(color: MyColors.grey70Color), ], ), ], @@ -212,4 +241,42 @@ class _RequestDetailsState extends State { Utils.handleException(ex, context, null); } } + + void getTransactionAttachment(int attachmentID) async { + try { + Utils.showLoading(context); + getTransactionAttachmentModel = await MowadhafhiApiClient().getTransactionAttachments(attachmentID); + Utils.hideLoading(context); + handleTransactionAttachment(); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } + + Future _createFileFromString(String encodedStr, String ext) async { + Uint8List bytes = base64.decode(encodedStr); + String dir = (await getApplicationDocumentsDirectory()).path; + File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext); + await file.writeAsBytes(bytes); + return file.path; + } + + void handleTransactionAttachment() async { + String ext = ''; + String? rFile = getTransactionAttachmentModel!.base64String; + String? rFileExt = getTransactionAttachmentModel!.fileName; + + ext = rFileExt!.split(".").last.toLowerCase(); + + try { + String path = await _createFileFromString(rFile!.split("base64,").last ?? "", ext ?? ""); + debugPrint(path); + + print(" file here: ${File(path).existsSync()}"); + await OpenFile.open(path); + } catch (ex) { + Utils.showToast("Cannot open file."); + } + } } diff --git a/lib/ui/screens/mowadhafhi/view_transaction_attachment.dart b/lib/ui/screens/mowadhafhi/view_transaction_attachment.dart new file mode 100644 index 0000000..e6ef8bc --- /dev/null +++ b/lib/ui/screens/mowadhafhi/view_transaction_attachment.dart @@ -0,0 +1,34 @@ +import 'dart:io'; + +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; + +class ViewTransactionAttachment extends StatelessWidget { + final File imageFile; + + const ViewTransactionAttachment({Key? key, required this.imageFile}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBarWidget( + context, + title: LocaleKeys.mowadhafhiRequest.tr(), + ), + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.file(imageFile), + 50.height, + ], + ), + ), + ); + } +} diff --git a/lib/ui/work_list/worklist_detail_screen.dart b/lib/ui/work_list/worklist_detail_screen.dart index 0a4f8cc..c80f1b4 100644 --- a/lib/ui/work_list/worklist_detail_screen.dart +++ b/lib/ui/work_list/worklist_detail_screen.dart @@ -44,6 +44,8 @@ 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/accept_reject_input_dialog.dart'; import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; +import 'package:mohem_flutter_app/models/termination/termination_notification_body.dart'; + class WorkListDetailScreen extends StatefulWidget { WorkListDetailScreen({Key? key}) : super(key: key); @@ -80,6 +82,8 @@ class _WorkListDetailScreenState extends State { List? getAbsenceCollectionNotificationBodyList = []; GetContactNotificationBodyList? getContactNotificationBodyList; List? getAddressNotificationBodyList = []; + List? getTerminationNotificationBodyList = []; + GenericResponseModel? getBasicNTFBody; GenericResponseModel? getICBody; @@ -121,6 +125,7 @@ class _WorkListDetailScreenState extends State { getItemCreationNtfBody?.itemCreationHeader!.clear(); getPhonesNotificationBodyList!.clear(); getBasicDetNtfBodyList!.clear(); + getTerminationNotificationBodyList!.clear(); getAbsenceCollectionNotificationBodyList!.clear(); getContactNotificationBodyList = null; getAddressNotificationBodyList!.clear(); @@ -147,6 +152,8 @@ class _WorkListDetailScreenState extends State { getContactNotificationBody(); } else if (workListData!.rEQUESTTYPE == "ADDRESS") { getAddressNotificationBody(); + } else if(workListData!.rEQUESTTYPE =='TERMINATION'){ + getTerminationNotificationBody(); } } if (workListData!.iTEMTYPE == "STAMP") { @@ -257,6 +264,7 @@ class _WorkListDetailScreenState extends State { getAbsenceCollectionNotificationBodyList: getAbsenceCollectionNotificationBodyList, getContactNotificationBodyList: getContactNotificationBodyList, getPrNotificationBodyList: getPrNotificationBody, + getTerminationNotificationBodyList:getTerminationNotificationBodyList ), (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") ? DetailFragment(workListData, memberInformationListModel) @@ -854,6 +862,25 @@ class _WorkListDetailScreenState extends State { Utils.handleException(ex, context, null); } } + void getTerminationNotificationBody() async { + try { + if (apiCallCount == 0) + apiCallCount++; + getTerminationNotificationBodyList = await WorkListApiClient().getTerminationNotificationBodyList(workListData!.nOTIFICATIONID); + Utils.hideLoading(context); + apiCallCount--; + if (apiCallCount == 0) { + + setState(() {}); + } + } catch (ex) { + apiCallCount--; + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } + + void getStampNotificationBody() async { try { diff --git a/lib/ui/work_list/worklist_fragments/actions_fragment.dart b/lib/ui/work_list/worklist_fragments/actions_fragment.dart index 1d88129..10d027a 100644 --- a/lib/ui/work_list/worklist_fragments/actions_fragment.dart +++ b/lib/ui/work_list/worklist_fragments/actions_fragment.dart @@ -167,10 +167,14 @@ class ActionsFragment extends StatelessWidget { 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 + 1].nOTIFICATIONDATE!); - Duration duration = dateTimeTo.difference(dateTimeFrom); - return "Action duration: " + DateUtil.formatDuration(duration); + if (actionHistoryList[index + 1].nOTIFICATIONDATE!.isEmpty) { + return ""; + } else { + DateTime dateTimeTo = DateUtil.convertSimpleStringDateToDate(actionHistoryList[index].nOTIFICATIONDATE!); + DateTime dateTimeFrom = DateUtil.convertSimpleStringDateToDate(actionHistoryList[index + 1].nOTIFICATIONDATE!); + Duration duration = dateTimeTo.difference(dateTimeFrom); + return "Action duration: " + DateUtil.formatDuration(duration); + } } } diff --git a/lib/ui/work_list/worklist_fragments/info_fragments.dart b/lib/ui/work_list/worklist_fragments/info_fragments.dart index 5edb6f1..7e1cd1c 100644 --- a/lib/ui/work_list/worklist_fragments/info_fragments.dart +++ b/lib/ui/work_list/worklist_fragments/info_fragments.dart @@ -20,6 +20,8 @@ import 'package:mohem_flutter_app/models/worklist/hr/get_phones_notification_bod import 'package:mohem_flutter_app/models/worklist_response_model.dart'; import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart'; +import 'package:mohem_flutter_app/models/termination/termination_notification_body.dart'; + class InfoFragment extends StatelessWidget { WorkListResponseModel? workListData; List poHeaderList; @@ -33,7 +35,7 @@ class InfoFragment extends StatelessWidget { GetContactNotificationBodyList? getContactNotificationBodyList; GetPrNotificationBodyList? getPrNotificationBodyList; List? getAddressNotificationBodyList = []; - + List? getTerminationNotificationBodyList =[]; InfoFragment( {this.workListData, this.poHeaderList = const [], @@ -46,7 +48,9 @@ class InfoFragment extends StatelessWidget { this.getAbsenceCollectionNotificationBodyList, this.getContactNotificationBodyList, this.getPrNotificationBodyList, - this.getAddressNotificationBodyList}); + this.getAddressNotificationBodyList, + this.getTerminationNotificationBodyList + }); double itemHeight = 0; double itemWidth = 0; @@ -93,6 +97,7 @@ class InfoFragment extends StatelessWidget { if (getAbsenceCollectionNotificationBodyList?.isNotEmpty ?? false) getAbsenceCollectionNotificationBodyListWidget(getAbsenceCollectionNotificationBodyList ?? []), if (getContactNotificationBodyList != null) getContactNotificationBodyListWidget(getContactNotificationBodyList ?? GetContactNotificationBodyList()).objectContainerView(), if (getAddressNotificationBodyList?.isNotEmpty ?? false) getAddressNotificationBodyListWidget(getAddressNotificationBodyList!), + if (getTerminationNotificationBodyList?.isNotEmpty ?? false) getTerminationNotificationBodyListWidget(getTerminationNotificationBodyList!), ]; return Container( width: double.infinity, @@ -499,6 +504,39 @@ class InfoFragment extends StatelessWidget { ).objectContainerView(); } + + Widget getTerminationNotificationBodyListWidget(List getterminationNotificationBodyList) { + bool isOdd = false; + try { + if (getterminationNotificationBodyList.length % 2 != 0) { + isOdd = true; + getterminationNotificationBodyList.add(TerminationNotificationBody(sEGMENTPROMPT: "--", sEGMENTVALUEDSP: "--")); + } + } catch (e) {} + + return GridView.builder( + itemCount: getterminationNotificationBodyList!.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) => ItemDetailViewGridItem( + index, + getterminationNotificationBodyList[index].sEGMENTPROMPT, + getterminationNotificationBodyList[index].sEGMENTVALUEDSP, + isNeedToShowEmptyDivider: (getterminationNotificationBodyList.length == index + 1) + ? isOdd + ? true + : false + : false, + ), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: (itemWidth / itemHeight), + ), + ).objectContainerView(); + } + + + List getPRHeaderValues() { List pRHeaders = []; getPrNotificationBodyList!.pRHeader!.forEach((element) { diff --git a/lib/widgets/image_picker.dart b/lib/widgets/image_picker.dart index ef04f84..19b1e00 100644 --- a/lib/widgets/image_picker.dart +++ b/lib/widgets/image_picker.dart @@ -8,6 +8,8 @@ import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheets/attachment_options.dart'; +import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; +import 'package:permission_handler/permission_handler.dart'; class ImageOptions { static void showImageOptionsNew(BuildContext context, bool showFilesOption, Function(String, File) image) { @@ -43,24 +45,42 @@ class ImageOptions { } }, onFilesTap: () async { - FilePickerResult? result = await FilePicker.platform.pickFiles( - type: FileType.custom, - allowedExtensions: [ - 'jpg', - 'jpeg ', - 'pdf', - 'txt', - 'docx', - 'doc', - 'pptx', - 'xlsx', - 'png', - 'rar', - 'zip', - ], - ); - List files = result!.paths.map((path) => File(path!)).toList(); - image(result.files.first.path.toString(), files.first); + Permission.storage.isGranted.then((isGranted) { + if (!isGranted) { + Permission.manageExternalStorage.request().then((granted) async { + if (granted == PermissionStatus.granted) { + FilePickerResult? result = await FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: [ + 'jpg', + 'jpeg ', + 'pdf', + 'txt', + 'docx', + 'doc', + 'pptx', + 'xlsx', + 'png', + 'rar', + 'zip', + ], + ); + List files = result!.paths.map((path) => File(path!)).toList(); + image(result.files.first.path.toString(), files.first); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to give storage permission to upload files.", + onTap: () { + Navigator.pop(context); + }, + ), + ); + } + }); + } + }); }, ), ); diff --git a/pubspec.yaml b/pubspec.yaml index 2039c7a..ddbe513 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html #version: 3.3.01+300040 -version: 3.7.7+1 +version: 3.3.6+300046 environment: sdk: ">=2.16.0 <3.0.0" @@ -60,7 +60,7 @@ dependencies: # android_id: ^0.1.3+1 platform_device_id: ^1.0.1 image_picker: ^0.8.5+3 - file_picker: ^4.6.1 + file_picker: 5.2.5 geolocator: ^9.0.2 month_year_picker: any month_picker_dialog: ^2.0.2 @@ -128,6 +128,8 @@ dependencies: in_app_update: 3.0.0 flutter_ios_voip_kit: ^0.1.0 +# saf: ^1.0.3+4 + dependency_overrides: firebase_core_platform_interface: 4.5.1