diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 85b7deca..3d8089b0 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -11,8 +11,8 @@ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 764494E530A33DE800D090BE /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; 76AE113C28E078EA00513112 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 76AE113B28E078EA00513112 /* GoogleService-Info.plist */; }; - 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; @@ -59,6 +59,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 764494E530A33DE800D090BE /* FlutterGeneratedPluginSwiftPackage in Frameworks */, 0AD79F8B1905C17FADC8B42C /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -147,7 +148,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, C4CFBC4C5CAC00182015ACD5 /* [CP] Embed Pods Frameworks */, - EF29CE25BB57F5AA48CE1136 /* [CP] Copy Pods Resources */, + 7556BD102EECD90C90102DA6 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -251,6 +252,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 7556BD102EECD90C90102DA6 /* [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; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -283,23 +301,6 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - D9FFC0F21D4146458615A992 /* [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; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -400,12 +401,12 @@ ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.7.95; + MARKETING_VERSION = 3.9.10; PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -539,12 +540,12 @@ ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.7.95; + MARKETING_VERSION = 3.9.10; PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -570,12 +571,12 @@ ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.7.95; + MARKETING_VERSION = 3.9.10; PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index cf19ad37..42cabfcb 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,27 +2,6 @@ - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - UISceneConfigurations - - UIWindowSceneSessionRoleApplication - - - UISceneClassName - UIWindowScene - UISceneDelegateClassName - FlutterSceneDelegate - UISceneConfigurationName - flutter - UISceneStoryboardFile - Main - - - - CADisableMinimumFrameDurationOnPhone CFBundleDevelopmentRegion @@ -88,11 +67,30 @@ NSPhotoLibraryUsageDescription This app requires photo library access to select image as document & upload it. NSSpeechRecognitionUsageDescription - This app requires speech recognition to convert your voice to text. + This app requires speech recognition access to access voice command features. + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + FlutterSceneDelegate + UISceneStoryboardFile + Main + + + + UIApplicationSupportsIndirectInputEvents - NSSpeechRecognitionUsageDescription - This app requires speech recognition access to access voice command features. UIBackgroundModes fetch diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements index 98a55e2d..304aa000 100644 --- a/ios/Runner/Runner.entitlements +++ b/ios/Runner/Runner.entitlements @@ -20,7 +20,6 @@ com.apple.developer.nfc.readersession.formats - NDEF TAG com.apple.developer.ubiquity-container-identifiers diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index 6576100c..5af1730e 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -7,6 +7,7 @@ import 'package:android_id/android_id.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:http/http.dart' as http; import 'package:device_info_plus/device_info_plus.dart'; +import 'package:mobile_device_identifier/mobile_device_identifier.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'; @@ -276,7 +277,7 @@ class DashboardApiClient { String QRValue = "", String payrollCode = "", }) async { - + var _mobileDeviceIdentifierPlugin = MobileDeviceIdentifier(); Codec stringToBase64 = utf8.fuse(base64); String url = "${ApiConsts.swpRest}AuthenticateAndSwipeUserSupportNFC"; Uuid uuid = Uuid(); @@ -292,8 +293,16 @@ class DashboardApiClient { deviceId = deviceId.length >= 50 ? deviceId.substring(0, 48) : deviceId; } else if (Platform.isIOS) { IosDeviceInfo iosInfo = await DeviceInfoPlugin().iosInfo; - deviceId = iosInfo.identifierForVendor; + try { + deviceId = await _mobileDeviceIdentifierPlugin.getDeviceId() ?? + "Unknown"; + } catch (ex) { + deviceId = iosInfo.identifierForVendor; + } } + + print("the DeviceID is $deviceId"); + Map postParams = { "UID": deviceId, //uuid.v4(), //Mobile Id // "UID": uuid.v4(), //Mobile Id diff --git a/lib/api/offers_and_discounts_api_client.dart b/lib/api/offers_and_discounts_api_client.dart index 5c1eaab8..34a5709b 100644 --- a/lib/api/offers_and_discounts_api_client.dart +++ b/lib/api/offers_and_discounts_api_client.dart @@ -68,7 +68,7 @@ class OffersAndDiscountsApiClient { String url = "${ApiConsts.cocRest}GetOfferDiscountsConfigData"; Map postParams = { - "EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER, + "EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER ?? "217869", "ItgPageSize": pageSize, "ItgPageNo": 1, "ItgCategoryID": categoryID, diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 0d01d44c..59d69046 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -92,7 +92,7 @@ class AppState { String get getHuaweiPushToken => _huaweiPushToken; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 10.3, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 10.4, mobileType: Platform.isAndroid ? "android" : "ios"); PostParamsModel get postParamsInitConfig { if (_postParamsInitConfig.pLegislationCode == null) { diff --git a/lib/ui/mazaya/mazaya_discover_screen.dart b/lib/ui/mazaya/mazaya_discover_screen.dart index 34c3df41..0c67dea7 100644 --- a/lib/ui/mazaya/mazaya_discover_screen.dart +++ b/lib/ui/mazaya/mazaya_discover_screen.dart @@ -4,6 +4,7 @@ import 'dart:convert'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/api/offers_and_discounts_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; @@ -11,6 +12,7 @@ import 'package:mohem_flutter_app/classes/consts.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/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/wala_plus_category_model.dart'; @@ -48,7 +50,7 @@ class _MazayaDiscoverScreenState extends State { bool _isLoadingCategories = true; List _categories = []; - + bool _hasRegisteredMobileLoginInfo = false; bool _isLoadingExclusiveOffers = true; List _exclusiveOffers = []; @@ -70,6 +72,7 @@ class _MazayaDiscoverScreenState extends State { _fetchCategories(); _fetchExclusiveOffers(); _initCityAndFetchSections(); + _registerMobileLoginInfo(); } Future _initCityAndFetchSections() async { @@ -101,10 +104,63 @@ class _MazayaDiscoverScreenState extends State { super.dispose(); } - // Only drives the benefits strip now - Travel Essentials/Home & Kitchen/Latest on Mazaya each - // fetch independently (see _fetchCategorySection/_fetchLatestOnMazaya). Still fetched in - // parallel with those though, since it also feeds each fixed-category section's title (the - // top-level categories list is the primary source there - see _sectionTitle). + Future _registerMobileLoginInfo() async { + if (_hasRegisteredMobileLoginInfo) return; + if (!ApiConsts.isDependetLogin) return; + _hasRegisteredMobileLoginInfo = true; + + try { + int loginType = AppState().dependentLoginType ?? 1; + String nationalId = AppState().getUserName ?? ""; + String dob = AppState().dependentDob ?? ""; + String name = AppState().dependentName ?? ""; + String mobile = AppState().postParamsObject?.mobileNumber ?? ""; + String tokenID = + (AppState().postParamsObject?.tokenID != null && + AppState().postParamsObject!.tokenID!.isNotEmpty) + ? AppState().postParamsObject!.tokenID! + : (AppState().authenticationTokenID ?? ""); + if (tokenID.isEmpty) { + tokenID = await Utils.getStringFromPrefs("P_DEP_TOKEN_ID"); + } + int sessionId = AppState().postParamsObject?.pSessionId ?? 0; + String email = AppState().postParamsObject?.pEmailAddress ?? ""; + String deviceToken = + AppState().getIsHuawei + ? AppState().getHuaweiPushToken + : ((AppState().getDeviceToken != null && + AppState().getDeviceToken!.isNotEmpty && + AppState().getDeviceToken != "null") + ? AppState().getDeviceToken! + : ""); + if (deviceToken.isEmpty || deviceToken == "null") { + String savedToken = await Utils.getStringFromPrefs( + "P_DEP_DEVICE_TOKEN", + ); + if (savedToken.isNotEmpty && savedToken != "null") { + deviceToken = savedToken; + } + } + + await LoginApiClient().insertMobileLoginInfoDependent( + loginType: loginType, + nationalId: nationalId, + dob: dob, + dependentName: name, + mobileNumber: mobile, + tokenID: tokenID, + sessionId: sessionId, + email: email, + deviceToken: deviceToken, + channel: AppState().postParamsObject?.channel, + context: context, + ); + } catch (e) { + // if (kDebugMode) { + print("Error calling insertMobileLoginInfoDependent: $e"); + // } + } + } Future _fetchCategories() async { setState(() => _isLoadingCategories = true); try { @@ -458,7 +514,7 @@ class _MazayaDiscoverScreenState extends State { appBar: AppBarWidget( context, title: LocaleKeys.mazayaDeals.tr(), - showHomeButton: true, + showHomeButton: ApiConsts.isDependetLogin ? false : true, // Discover is the dependent-login landing page - no back button there (logout is still // reachable via the explicit logout action below). Employees reaching Discover from the // regular dashboard can still pop back normally. @@ -1023,7 +1079,7 @@ class _MazayaDiscoverScreenState extends State { title.toText20( color: const Color(0xFF202F32), weight: FontWeight.w600, - ), + ).toShimmer(isShow: isLoading), InkWell( onTap: onSeeAll, child: Row( @@ -1055,7 +1111,7 @@ class _MazayaDiscoverScreenState extends State { subtitle.toText11( color: const Color(0xFF78817F), weight: FontWeight.w400, - ), + ).toShimmer(isShow: isLoading), ], ), ), diff --git a/lib/ui/mazaya/retailers_list_screen.dart b/lib/ui/mazaya/retailers_list_screen.dart index 64156e3a..e39f9b85 100644 --- a/lib/ui/mazaya/retailers_list_screen.dart +++ b/lib/ui/mazaya/retailers_list_screen.dart @@ -100,7 +100,7 @@ class _RetailersListScreenState extends State { WidgetsBinding.instance.addPostFrameCallback((_) async { if (mounted) { await _saveDependentSessionToPrefs(); - await _registerMobileLoginInfo(); + await fetchCategories(); } }); diff --git a/lib/ui/mazaya/widgets/mazaya_bottom_nav.dart b/lib/ui/mazaya/widgets/mazaya_bottom_nav.dart index 898478a3..f6d85c01 100644 --- a/lib/ui/mazaya/widgets/mazaya_bottom_nav.dart +++ b/lib/ui/mazaya/widgets/mazaya_bottom_nav.dart @@ -105,13 +105,13 @@ class MazayaBottomNav extends StatelessWidget { context, tab: MazayaTab.discover, svgAsset: "assets/icons/mazaya_compass.svg", - label: LocaleKeys.discover.tr(), + label: LocaleKeys.discover.tr(context: context), ), _buildItem( context, tab: MazayaTab.saved, svgAsset: "assets/icons/mazaya_heart_outline.svg", - label: LocaleKeys.saved.tr(), + label: LocaleKeys.saved.tr(context: context), ), // My Family lets the account holder manage their dependents' Mazaya access - not // applicable (and not shown) when a dependent is the one logged in. @@ -120,7 +120,7 @@ class MazayaBottomNav extends StatelessWidget { context, tab: MazayaTab.myFamily, svgAsset: "assets/icons/mazaya_user_round.svg", - label: LocaleKeys.myFamily.tr(), + label: LocaleKeys.myFamily.tr(context: context), ), ], ), diff --git a/pubspec.yaml b/pubspec.yaml index 1e8527a7..761e6c81 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,8 +17,8 @@ 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.8.0+300090 -#version: 3.9.3+1 +version: 3.8.1+300091 +#version: 3.9.10+1 environment: sdk: ^3.7.0 @@ -151,6 +151,7 @@ dependencies: speech_to_text: ^7.3.0 sms_otp_auto_verify: ^2.2.0 + mobile_device_identifier: ^0.1.0 # saf: ^1.0.3+4