From bd10bb4f1d036980d3309781249f53bd04e50422 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 8 Jan 2023 16:43:09 +0300 Subject: [PATCH 01/11] Push notifications handler implemented --- lib/api/chat/chat_api_client.dart | 2 + lib/app_state/app_state.dart | 6 ++ lib/classes/push-notification-handler.dart | 59 +++++++++++++++++++ lib/ui/login/login_screen.dart | 9 ++- .../widgets/marathon_details_card.dart | 2 +- lib/widgets/mark_attendance_widget.dart | 9 +++ 6 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 lib/classes/push-notification-handler.dart diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index 87e684e..c4bba3a 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -30,6 +30,8 @@ class ChatApiClient { { "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", + "isMobile": true, + "deviceToken": AppState().getDeviceToken, }, ); if (!kReleaseMode) { diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index e43c774..b3a4a32 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -17,6 +17,12 @@ class AppState { factory AppState() => _instance; + String? deviceToken = ""; + + set setDeviceToken(v) => deviceToken = v; + + String? get getDeviceToken => deviceToken; + bool isAuthenticated = false; set setIsAuthenticated(v) => isAuthenticated = v; diff --git a/lib/classes/push-notification-handler.dart b/lib/classes/push-notification-handler.dart new file mode 100644 index 0000000..b95ceb2 --- /dev/null +++ b/lib/classes/push-notification-handler.dart @@ -0,0 +1,59 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; + +// |--> Push Notification Background +Future backgroundMessageHandler(message) async { + print("Firebase backgroundMessageHandler!!!"); +} + +class PushNotificationHandler { + final BuildContext context; + static PushNotificationHandler? _instance; + + PushNotificationHandler(this.context) { + PushNotificationHandler._instance = this; + } + + static PushNotificationHandler getInstance() => _instance!; + + void init() async { + FirebaseMessaging.onMessage.listen((RemoteMessage message) async { + if (Platform.isIOS) { + await Future.delayed(Duration(milliseconds: 3000)).then((value) { + newMessage(message); + }); + } else { + newMessage(message); + } + }); + + FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async { + if (Platform.isIOS) { + await Future.delayed(Duration(milliseconds: 3000)).then((value) { + newMessage(message); + }); + } else { + newMessage(message); + } + }); + + FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) { + print("Push Notification onTokenRefresh: " + fcm_token); + AppState().setDeviceToken = fcm_token; + }); + + FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); + } + + void newMessage(RemoteMessage remoteMessage) async { + print("Remote Message: " + remoteMessage.data.toString()); + if (remoteMessage.data.isEmpty) { + return; + } + } +} diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 7ba82e4..26e9f3e 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -12,6 +12,7 @@ import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:mohem_flutter_app/classes/push-notification-handler.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'; @@ -91,8 +92,15 @@ class _LoginScreenState extends State { try { Utils.showLoading(context); await Firebase.initializeApp(); + await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( + alert: true, + badge: true, + sound: true, + ); + PushNotificationHandler(context).init(); _firebaseMessaging = FirebaseMessaging.instance; firebaseToken = await _firebaseMessaging.getToken(); + AppState().setDeviceToken = firebaseToken; loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); if (loginInfo == null) { await checkPrefs(); @@ -171,7 +179,6 @@ class _LoginScreenState extends State { } if (isAppOpenBySystem!) checkFirebaseToken(); } - // username.text = "15444"; return Scaffold( diff --git a/lib/ui/marathon/widgets/marathon_details_card.dart b/lib/ui/marathon/widgets/marathon_details_card.dart index dda7ef8..267d2d3 100644 --- a/lib/ui/marathon/widgets/marathon_details_card.dart +++ b/lib/ui/marathon/widgets/marathon_details_card.dart @@ -57,7 +57,7 @@ class MarathonDetailsCard extends StatelessWidget { children: marathonDetailModel.sponsors!.first.sponsorPrizes! .map( (SponsorPrizes prizes) => - "${AppState().isArabic(context) ? prizes.marathonPrizeAr : prizes.marathonPrizeAr}".toText16(color: MyColors.greenColor, isBold: true).paddingOnly(right: 5), + "${AppState().isArabic(context) ? prizes.marathonPrizeAr : prizes.marathonPrizeEn}".toText16(color: MyColors.greenColor, isBold: true).paddingOnly(right: 5), ) .toList(), ), diff --git a/lib/widgets/mark_attendance_widget.dart b/lib/widgets/mark_attendance_widget.dart index dfe3b79..59681b7 100644 --- a/lib/widgets/mark_attendance_widget.dart +++ b/lib/widgets/mark_attendance_widget.dart @@ -218,6 +218,15 @@ class _MarkAttendanceWidgetState extends State { Utils.showLoading(context); bool isConnected = await WiFiForIoTPlugin.connect(AppState().getMohemmWifiSSID ?? "", password: AppState().getMohemmWifiPassword ?? "", joinOnce: Platform.isIOS ? false : true, security: NetworkSecurity.WPA, withInternet: false); + // + // print("CURRENT SSID: ${await WiFiForIoTPlugin.getSSID()}"); + + if (await WiFiForIoTPlugin.getSSID() == AppState().getMohemmWifiSSID) { + isConnected = true; + } else { + isConnected = false; + } + if (isConnected) { if (Platform.isIOS) { await closeWifiRequest(); From c8f98262669a68dce0cc55377281a5e1a15dd365 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Wed, 18 Jan 2023 11:34:50 +0300 Subject: [PATCH 02/11] Permission Issue --- android/app/src/main/AndroidManifest.xml | 10 ++- ios/Runner/AppDelegate.swift | 9 +++ lib/api/chat/chat_api_client.dart | 11 ++- lib/app_state/app_state.dart | 9 +++ lib/classes/notifications.dart | 61 +++++++++++++++ lib/provider/chat_provider_model.dart | 52 ++++++++++++- lib/ui/chat/chat_bubble.dart | 98 +++++++++++------------- lib/ui/chat/chat_detailed_screen.dart | 12 ++- lib/ui/landing/dashboard_screen.dart | 3 +- lib/ui/login/login_screen.dart | 6 ++ pubspec.yaml | 5 ++ 11 files changed, 211 insertions(+), 65 deletions(-) create mode 100644 lib/classes/notifications.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 30555e1..8331694 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,11 +7,13 @@ + + + + + + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 70693e4..7d74b94 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,5 +1,7 @@ import UIKit import Flutter +import flutter_local_notifications + @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { @@ -7,6 +9,13 @@ import Flutter _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { + FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in + GeneratedPluginRegistrant.register(with: registry) + } + + if #available(iOS 10.0, *) { + UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate + } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index 87e684e..efd7af9 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -30,10 +30,19 @@ class ChatApiClient { { "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", + "isMobile": true, + "deviceToken": AppState().deviceNotificationToken }, ); + + print({ + "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), + "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", + "isMobile": true, + "deviceToken": AppState().deviceNotificationToken + }); if (!kReleaseMode) { - logger.i("res: " + response.body); + logger.i("login-res: " + response.body); } if (response.statusCode == 200) { userLoginResponse = user.userAutoLoginModelFromJson(response.body); diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index e43c774..8d09d2d 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -173,4 +173,13 @@ class AppState { } bool cancelRequestTrancsection = true; + + + String? _deviceNotificationToken; + + String? get deviceNotificationToken => _deviceNotificationToken; + + set deviceNotificationToken(String? deviceNotificationToken) { + _deviceNotificationToken = deviceNotificationToken; + } } diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart new file mode 100644 index 0000000..26bb70d --- /dev/null +++ b/lib/classes/notifications.dart @@ -0,0 +1,61 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/main.dart'; +import 'package:permission_handler/permission_handler.dart'; + +final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); + + +class AppNotifications { + static final AppNotifications _instance = AppNotifications._internal(); + + AppNotifications._internal(); + + factory AppNotifications() => _instance; + + Future requestPermissions() async { + if (Platform.isIOS) { + await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); + } else if (Platform.isAndroid) { + AndroidFlutterLocalNotificationsPlugin? androidImplementation = flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation(); + bool? granted = await androidImplementation?.requestPermission(); + if (granted == false) { + print("-------------------- Permission Granted ------------------------"); + print(granted); + await Permission.notification.request(); + } + } + } + + Future isAndroidPermGranted() async { + if (Platform.isAndroid) { + bool granted = await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.areNotificationsEnabled() ?? false; + } + } + + void initNotification(String? firebaseToken) async { + // await requestPermissions(); + AppState().deviceNotificationToken = firebaseToken; + // await Permission.notification.isDenied.then((value) { + // if (value) { + // Permission.notification.request(); + // } + // }); + RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage(); + if (initialMessage != null) _handleMessage(initialMessage); + + FirebaseMessaging.onMessage.listen((RemoteMessage message) { + if (message.notification != null) _handleMessage(message); + }); + FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage); + } + + void _handleMessage(RemoteMessage message) { + print("Handle Message"); + logger.w(json.encode(message)); + } +} diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index 460a338..c0a16c0 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; - import 'package:audio_waveforms/audio_waveforms.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; @@ -32,6 +31,7 @@ import 'package:permission_handler/permission_handler.dart'; import 'package:signalr_netcore/hub_connection.dart'; import 'package:signalr_netcore/signalr_client.dart'; import 'package:uuid/uuid.dart'; +import 'package:flutter/material.dart' as Material; class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ScrollController scrollController = ScrollController(); @@ -66,6 +66,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List getEmployeeSubordinatesList = []; List teamMembersList = []; + Material.TextDirection textDirection = Material.TextDirection.ltr; + //Chat Home Page Counter int chatUConvCounter = 0; @@ -99,7 +101,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { HubConnection hub; HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); hub = HubConnectionBuilder() - .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp) + .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Desktop&access_token=${AppState().chatDetails!.response!.token}", options: httpOp) .withAutomaticReconnect(retryDelays: [2000, 5000, 10000, 20000]).build(); return hub; } @@ -1409,4 +1411,50 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { isLoading = false; notifyListeners(); } + + void inputBoxDirection(String val) { + if (val.isNotEmpty) { + isTextMsg = true; + } else { + isTextMsg = false; + } + RegExp exp = RegExp("[a-zA-Z]"); + if (exp.hasMatch(val.substring(val.length - 1)) && val.substring(val.length - 1) != " ") { + textDirection = Material.TextDirection.ltr; + notifyListeners(); + } else if (val.substring(val.length - 1) != " " && !exp.hasMatch(val.substring(val.length - 1))) { + textDirection = Material.TextDirection.rtl; + notifyListeners(); + } + } + + Material.TextDirection getTextDirection(String v) { + String str = v.trim(); + if (str.isEmpty) return Material.TextDirection.ltr; + int firstUnit = str.codeUnitAt(0); + if (firstUnit > 0x0600 && firstUnit < 0x06FF || + firstUnit > 0x0750 && firstUnit < 0x077F || + firstUnit > 0x07C0 && firstUnit < 0x07EA || + firstUnit > 0x0840 && firstUnit < 0x085B || + firstUnit > 0x08A0 && firstUnit < 0x08B4 || + firstUnit > 0x08E3 && firstUnit < 0x08FF || + firstUnit > 0xFB50 && firstUnit < 0xFBB1 || + firstUnit > 0xFBD3 && firstUnit < 0xFD3D || + firstUnit > 0xFD50 && firstUnit < 0xFD8F || + firstUnit > 0xFD92 && firstUnit < 0xFDC7 || + firstUnit > 0xFDF0 && firstUnit < 0xFDFC || + firstUnit > 0xFE70 && firstUnit < 0xFE74 || + firstUnit > 0xFE76 && firstUnit < 0xFEFC || + firstUnit > 0x10800 && firstUnit < 0x10805 || + firstUnit > 0x1B000 && firstUnit < 0x1B0FF || + firstUnit > 0x1D165 && firstUnit < 0x1D169 || + firstUnit > 0x1D16D && firstUnit < 0x1D172 || + firstUnit > 0x1D17B && firstUnit < 0x1D182 || + firstUnit > 0x1D185 && firstUnit < 0x1D18B || + firstUnit > 0x1D1AA && firstUnit < 0x1D1AD || + firstUnit > 0x1D242 && firstUnit < 0x1D244) { + return Material.TextDirection.rtl; + } + return Material.TextDirection.ltr; + } } diff --git a/lib/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index 6d1e2eb..1e91a79 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -32,6 +32,8 @@ class ChatBubble extends StatelessWidget { bool isReplied = false; + bool isVoice = false; + int? fileTypeID; String? fileTypeName; @@ -50,6 +52,7 @@ class ChatBubble extends StatelessWidget { isCurrentUser = cItem.currentUserId == AppState().chatDetails!.response!.id ? true : false; isSeen = cItem.isSeen == true ? true : false; isReplied = cItem.userChatReplyResponse != null ? true : false; + // isVoice = cItem.fileTypeId == 13 && cItem.voiceController != null ? true : false; fileTypeID = cItem.fileTypeId; fileTypeName = cItem.fileTypeResponse != null ? cItem.fileTypeResponse!.fileTypeName : ""; fileTypeDescription = cItem.fileTypeResponse != null ? cItem.fileTypeResponse!.fileTypeDescription : ""; @@ -57,18 +60,6 @@ class ChatBubble extends StatelessWidget { userName = AppState().chatDetails!.response!.userName == cItem.currentUserName.toString() ? "You" : cItem.currentUserName.toString(); } - Future getCurrentUrl(String url)async{ - if(Platform.isIOS){ - String a = url.substring(url.indexOf("Documents/") + 10, url.length) ; - Directory dir = await getApplicationDocumentsDirectory(); - a = "${dir.path}/$a"; - return a; - } - else{ - return url; - } - } - void playVoice( BuildContext context, { required SingleUserChatModel data, @@ -91,36 +82,30 @@ class ChatBubble extends StatelessWidget { } else { Utils.showLoading(context); Uint8List encodedString = await ChatApiClient().downloadURL(fileName: data.contant!, fileTypeDescription: provider.getFileTypeDescription(data.fileTypeResponse!.fileTypeName ?? "")); - // try { - File sFile = await provider.downChatVoice(encodedString, data.fileTypeResponse!.fileTypeName ?? "", data); - if(sFile.path.isEmpty){ - logger.d("Path Is Emptyyyyyyy"); - }else{ - logger.d("Path Exsists"); - } - data.voice = sFile; - if (Platform.isIOS) { - logger.d("isIOS"); - Duration? duration = await data.voiceController!.setAudioSource(MyCustomStream(data.voice!.readAsBytesSync())); - await data.voiceController!.seek(duration); - await data.voiceController!.setLoopMode(LoopMode.off); - await data.voiceController!.setVolume(1.0); + // try { + File sFile = await provider.downChatVoice(encodedString, data.fileTypeResponse!.fileTypeName ?? "", data); + if (sFile.path.isEmpty) { + logger.d("Path Is Emptyyyyyyy"); + } else { + logger.d("Path Exsists"); + } + data.voice = sFile; + if (Platform.isIOS) { + logger.d("isIOS"); + Duration? duration = await data.voiceController!.setAudioSource(MyCustomStream(data.voice!.readAsBytesSync())); + await data.voiceController!.seek(duration); + await data.voiceController!.setLoopMode(LoopMode.off); + await data.voiceController!.setVolume(1.0); await data.voiceController!.load(); - Utils.hideLoading(context); - data.voiceController!.play(); - } else { - Duration? duration = await data.voiceController!.setFilePath(sFile.path); - await data.voiceController!.setLoopMode(LoopMode.off); - await data.voiceController!.seek(duration); - - Utils.hideLoading(context); - await data.voiceController!.play(); - } - - // } catch (e) { - // Utils.hideLoading(context); - // Utils.showToast(e.toString()); - // } + Utils.hideLoading(context); + data.voiceController!.play(); + } else { + Duration? duration = await data.voiceController!.setFilePath(sFile.path); + await data.voiceController!.setLoopMode(LoopMode.off); + await data.voiceController!.seek(duration); + Utils.hideLoading(context); + await data.voiceController!.play(); + } } } @@ -168,9 +153,12 @@ class ChatBubble extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ (userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5), - (cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : "") - .toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4) - .paddingOnly(right: 5, top: 5, bottom: 8, left: 5), + Directionality( + textDirection: provider.getTextDirection(cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : ""), + child: (cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : "") + .toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4) + .paddingOnly(right: 5, top: 5, bottom: 8, left: 5), + ), ], ).expanded, if (cItem.userChatReplyResponse != null) @@ -215,7 +203,7 @@ class ChatBubble extends StatelessWidget { // || fileTypeID == 2 ) SvgPicture.asset(provider.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 0, right: 10), - (cItem.contant ?? "").toText12().expanded, + Directionality(textDirection: provider.getTextDirection(cItem.contant ?? ""), child: (cItem.contant ?? "").toText12().expanded), if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 //|| fileTypeID == 2 ) @@ -269,9 +257,12 @@ class ChatBubble extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ (userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5), - (cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : "") - .toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4) - .paddingOnly(right: 5, top: 5, bottom: 8, left: 5), + Directionality( + textDirection: provider.getTextDirection(cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : ""), + child: (cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : "") + .toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4) + .paddingOnly(right: 5, top: 5, bottom: 8, left: 5), + ), ], ).expanded, if (cItem.userChatReplyResponse != null) @@ -317,7 +308,7 @@ class ChatBubble extends StatelessWidget { // || fileTypeID == 2 ) SvgPicture.asset(provider.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 0, right: 10), - (cItem.contant ?? "").toText12(color: Colors.white).expanded, + Directionality(textDirection: provider.getTextDirection(cItem.contant ?? ""), child: (cItem.contant ?? "").toText12(color: Colors.white).expanded), if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 //|| fileTypeID == 2 ) @@ -335,6 +326,10 @@ class ChatBubble extends StatelessWidget { ).paddingOnly(right: MediaQuery.of(context).size.width * 0.3); } + Widget voiceMsg(BuildContext context) { + return Container(); + } + Widget showImage({required bool isReplyPreview, required String fileName, required String fileTypeDescription}) { if (cItem.isImageLoaded! && cItem.image != null) { return Image.memory( @@ -455,7 +450,7 @@ class ChatBubble extends StatelessWidget { playVoice(context, data: modelData); }); } else if (processingState != ProcessingState.completed) { - return Icon( + return const Icon( Icons.pause, size: 30, color: MyColors.lightGreenColor, @@ -463,7 +458,7 @@ class ChatBubble extends StatelessWidget { pausePlaying(context, data: modelData); }); } else { - return Icon( + return const Icon( Icons.replay, size: 30, color: MyColors.lightGreenColor, @@ -476,7 +471,6 @@ class ChatBubble extends StatelessWidget { } } -// Feed your own stream of bytes into the player class MyCustomStream extends StreamAudioSource { final Uint8List bytes; diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 3e02d96..1bbae82 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -42,6 +42,7 @@ class _ChatDetailScreenState extends State { final RefreshController _rc = RefreshController(initialRefresh: false); late ChatProviderModel data; ChatDetailedScreenParams? params; + var textDirection = TextDirection.RTL; void getMoreChat() async { if (params != null) { @@ -202,8 +203,7 @@ class _ChatDetailScreenState extends State { WaveBubble( playerController: m.playerController, isPlaying: m.playerController.playerState == PlayerState.playing, - onTap: () { - }, + onTap: () {}, ).expanded else AudioWaveforms( @@ -253,6 +253,7 @@ class _ChatDetailScreenState extends State { Row( children: [ TextField( + textDirection: m.textDirection, controller: m.message, decoration: InputDecoration( hintText: m.isAttachmentMsg ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(), @@ -275,11 +276,8 @@ class _ChatDetailScreenState extends State { : null, ), onChanged: (String val) { - if (val.isNotEmpty) { - m.isTextMsg = true; - } else { - m.isTextMsg = false; - } + m.inputBoxDirection(val); + m.userTypingInvoke(currentUser: AppState().chatDetails!.response!.id!, reciptUser: params!.chatUser!.id!); }, ).expanded, diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 98bf976..5d5549d 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -58,7 +58,7 @@ class _DashboardScreenState extends State { data = Provider.of(context, listen: false); marathonProvider = Provider.of(context, listen: false); cProvider = Provider.of(context, listen: false); - + _bHubCon(); _onRefresh(); }); } @@ -80,7 +80,6 @@ class _DashboardScreenState extends State { void _onRefresh() async { data.initProvider(); - _bHubCon(); // data.getITGNotification().then((value) { // print("--------------------detail_1-----------------"); // print(value!.result!.data!.notificationMasterId); diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 7ba82e4..0028505 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; @@ -12,12 +13,14 @@ import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:mohem_flutter_app/classes/notifications.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart'; import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; @@ -25,6 +28,7 @@ import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'package:mohem_flutter_app/models/privilege_list_model.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:safe_device/safe_device.dart'; class LoginScreen extends StatefulWidget { @@ -93,6 +97,7 @@ class _LoginScreenState extends State { await Firebase.initializeApp(); _firebaseMessaging = FirebaseMessaging.instance; firebaseToken = await _firebaseMessaging.getToken(); + AppNotifications().initNotification(firebaseToken); loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); if (loginInfo == null) { await checkPrefs(); @@ -154,6 +159,7 @@ class _LoginScreenState extends State { } } + @override Widget build(BuildContext context) { if (isAppOpenBySystem == null) { diff --git a/pubspec.yaml b/pubspec.yaml index 3167dcd..6f277f5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -92,6 +92,7 @@ dependencies: swipe_to: ^1.0.2 flutter_webrtc: ^0.9.16 camera: ^0.10.0+4 + flutter_local_notifications: any #Chat Voice Message Recoding & Play audio_waveforms: ^0.1.5+1 @@ -106,6 +107,10 @@ dependencies: flutter_layout_grid: ^2.0.1 +dependency_overrides: + firebase_core_platform_interface: 4.5.1 + + dev_dependencies: flutter_test: sdk: flutter From a9bf383164c68fa7fecddcdf7993ab68108a267a Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 18 Jan 2023 12:53:43 +0300 Subject: [PATCH 03/11] Updates & fixes --- android/app/build.gradle | 22 ++++++++++++++----- android/app/src/main/AndroidManifest.xml | 1 + ios/Runner/Info.plist | 16 ++++++++------ .../items_for_sale_api_client.dart | 2 +- lib/api/offers_and_discounts_api_client.dart | 2 +- lib/app_state/app_state.dart | 2 +- lib/classes/consts.dart | 4 ++-- lib/ui/login/login_screen.dart | 9 ++++++++ lib/widgets/mark_attendance_widget.dart | 12 +++++----- pubspec.yaml | 4 ++-- 10 files changed, 49 insertions(+), 25 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 9cd8b0e..198bc87 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -21,6 +21,12 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } +def keystoreProperties = new Properties() +def keystorePropertiesFile = rootProject.file('key.properties') +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} + apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'com.google.gms.google-services' @@ -44,18 +50,24 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.cloudSolutions.mohemmtest" + applicationId "hmg.cloudSolutions.mohem" minSdkVersion 21 - targetSdkVersion 32 + targetSdkVersion 33 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } + signingConfigs { + release { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword keystoreProperties['storePassword'] + } + } buildTypes { release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug + signingConfig signingConfigs.release } } } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 30555e1..bd112a0 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,6 +7,7 @@ + CFBundleInfoDictionaryVersion 6.0 CFBundleName - mohem_flutter_app + MOHEMM CFBundlePackageType APPL CFBundleShortVersionString @@ -42,10 +42,10 @@ This App requires access to your location to mark your attendance. NSLocationWhenInUseUsageDescription This App requires access to your location to mark your attendance. - NSPhotoLibraryUsageDescription - This app requires photo library access to select image as document & upload it. NSMicrophoneUsageDescription This app requires microphone access to for call. + NSPhotoLibraryUsageDescription + This app requires photo library access to select image as document & upload it. UIBackgroundModes remote-notification @@ -69,13 +69,15 @@ UIViewControllerBasedStatusBarAppearance - com.apple.developer.nfc.readersession.formats - - TAG - com.apple.developer.nfc.readersession.felica.systemcodes 0000 + ITSAppUsesNonExemptEncryption + + com.apple.developer.nfc.readersession.formats + + TAG + diff --git a/lib/api/items_for_sale/items_for_sale_api_client.dart b/lib/api/items_for_sale/items_for_sale_api_client.dart index eae6ffb..a04651e 100644 --- a/lib/api/items_for_sale/items_for_sale_api_client.dart +++ b/lib/api/items_for_sale/items_for_sale_api_client.dart @@ -32,7 +32,7 @@ class ItemsForSaleApiClient { getSaleCategoriesListObj.titleAr = "الجميع"; getSaleCategoriesListObj.isActive = true; getSaleCategoriesListObj.content = - ''; + ' '; getSaleCategoriesList.add(getSaleCategoriesListObj); diff --git a/lib/api/offers_and_discounts_api_client.dart b/lib/api/offers_and_discounts_api_client.dart index 6189612..1d3153c 100644 --- a/lib/api/offers_and_discounts_api_client.dart +++ b/lib/api/offers_and_discounts_api_client.dart @@ -30,7 +30,7 @@ class OffersAndDiscountsApiClient { getSaleCategoriesListObj.categoryNameAr = "الجميع"; getSaleCategoriesListObj.isActive = true; getSaleCategoriesListObj.content = - ''; + ' '; getSaleCategoriesList.add(getSaleCategoriesListObj); diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index b3a4a32..6f4e698 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -76,7 +76,7 @@ class AppState { bool get getIsDemoMarathon => _isDemoMarathon; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 3.8, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 3.9, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 6679cbb..56b0008 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - // static String baseUrl = "https://hmgwebservices.com"; // Live server + // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 26e9f3e..0d14e99 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -26,6 +26,7 @@ import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'package:mohem_flutter_app/models/privilege_list_model.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:safe_device/safe_device.dart'; class LoginScreen extends StatefulWidget { @@ -92,6 +93,14 @@ class _LoginScreenState extends State { try { Utils.showLoading(context); await Firebase.initializeApp(); + if(Platform.isIOS) { + await FirebaseMessaging.instance.requestPermission(); + } else { + await Permission.notification.request().then((value) { + }).catchError((err) { + print(err); + }); + } await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( alert: true, badge: true, diff --git a/lib/widgets/mark_attendance_widget.dart b/lib/widgets/mark_attendance_widget.dart index 59681b7..6b89c42 100644 --- a/lib/widgets/mark_attendance_widget.dart +++ b/lib/widgets/mark_attendance_widget.dart @@ -218,13 +218,13 @@ class _MarkAttendanceWidgetState extends State { Utils.showLoading(context); bool isConnected = await WiFiForIoTPlugin.connect(AppState().getMohemmWifiSSID ?? "", password: AppState().getMohemmWifiPassword ?? "", joinOnce: Platform.isIOS ? false : true, security: NetworkSecurity.WPA, withInternet: false); - // - // print("CURRENT SSID: ${await WiFiForIoTPlugin.getSSID()}"); - if (await WiFiForIoTPlugin.getSSID() == AppState().getMohemmWifiSSID) { - isConnected = true; - } else { - isConnected = false; + if (Platform.isIOS) { + if (await WiFiForIoTPlugin.getSSID() == AppState().getMohemmWifiSSID) { + isConnected = true; + } else { + isConnected = false; + } } if (isConnected) { diff --git a/pubspec.yaml b/pubspec.yaml index 3167dcd..db3f4ed 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 3.6.0+300060 +version: 3.2.0+300020 environment: sdk: ">=2.16.0 <3.0.0" @@ -40,7 +40,7 @@ dependencies: provider: ^6.0.1 easy_localization: ^3.0.0 http: ^0.13.4 - permission_handler: ^9.2.0 + permission_handler: ^10.2.0 flutter_svg: any sizer: ^2.0.15 local_auth: ^1.1.9 From 7152b0d57bee13d19be15fbc3fa720424c67ca0e Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 19 Jan 2023 11:24:51 +0300 Subject: [PATCH 04/11] Chat Fix --- lib/api/chat/chat_api_client.dart | 4 ++-- lib/app_state/app_state.dart | 2 +- lib/classes/notifications.dart | 22 ++++++++++------------ lib/ui/chat/chat_detailed_screen.dart | 1 - pubspec.yaml | 4 ++-- 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index efd7af9..b525efd 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -38,8 +38,8 @@ class ChatApiClient { print({ "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", - "isMobile": true, - "deviceToken": AppState().deviceNotificationToken + // "isMobile": true, + // "deviceToken": AppState().deviceNotificationToken }); if (!kReleaseMode) { logger.i("login-res: " + response.body); diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 8d09d2d..4a2bd7e 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -70,7 +70,7 @@ class AppState { bool get getIsDemoMarathon => _isDemoMarathon; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 3.8, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 3.9, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index 26bb70d..649b757 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -1,13 +1,11 @@ import 'dart:convert'; import 'dart:io'; - import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/main.dart'; import 'package:permission_handler/permission_handler.dart'; -final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); +//final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); class AppNotifications { @@ -19,21 +17,21 @@ class AppNotifications { Future requestPermissions() async { if (Platform.isIOS) { - await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); + // await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); } else if (Platform.isAndroid) { - AndroidFlutterLocalNotificationsPlugin? androidImplementation = flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation(); - bool? granted = await androidImplementation?.requestPermission(); - if (granted == false) { - print("-------------------- Permission Granted ------------------------"); - print(granted); - await Permission.notification.request(); - } + // AndroidFlutterLocalNotificationsPlugin? androidImplementation = flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation(); + // bool? granted = await androidImplementation?.requestPermission(); + // if (granted == false) { + // print("-------------------- Permission Granted ------------------------"); + // print(granted); + // await Permission.notification.request(); + // } } } Future isAndroidPermGranted() async { if (Platform.isAndroid) { - bool granted = await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.areNotificationsEnabled() ?? false; + // bool granted = await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.areNotificationsEnabled() ?? false; } } diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 1bbae82..da547cf 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -277,7 +277,6 @@ class _ChatDetailScreenState extends State { ), onChanged: (String val) { m.inputBoxDirection(val); - m.userTypingInvoke(currentUser: AppState().chatDetails!.response!.id!, reciptUser: params!.chatUser!.id!); }, ).expanded, diff --git a/pubspec.yaml b/pubspec.yaml index 6f277f5..c343421 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -92,7 +92,7 @@ dependencies: swipe_to: ^1.0.2 flutter_webrtc: ^0.9.16 camera: ^0.10.0+4 - flutter_local_notifications: any + #flutter_local_notifications: any #Chat Voice Message Recoding & Play audio_waveforms: ^0.1.5+1 @@ -108,7 +108,7 @@ dependencies: dependency_overrides: - firebase_core_platform_interface: 4.5.1 + #firebase_core_platform_interface: 4.5.1 dev_dependencies: From 03ae216b695499a99e18fac7de685ce01ca8e893 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 19 Jan 2023 11:31:33 +0300 Subject: [PATCH 05/11] Chat fix --- lib/api/chat/chat_api_client.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index b525efd..b408362 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -29,15 +29,15 @@ class ChatApiClient { "${ApiConsts.chatLoginTokenUrl}externaluserlogin", { "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", - "isMobile": true, - "deviceToken": AppState().deviceNotificationToken + "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" + // "isMobile": true, + // "deviceToken": AppState().deviceNotificationToken }, ); print({ "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", + "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" // "isMobile": true, // "deviceToken": AppState().deviceNotificationToken }); From f8ae5b0987f8167e42ad333871c66fb19bd8a140 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 19 Jan 2023 15:53:49 +0300 Subject: [PATCH 06/11] mark attendance session expire fixed --- lib/api/chat/chat_api_client.dart | 6 ------ lib/provider/chat_provider_model.dart | 16 ++++++++-------- lib/ui/chat/chat_detailed_screen.dart | 5 ++++- pubspec.yaml | 2 +- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index b408362..210106e 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -35,12 +35,6 @@ class ChatApiClient { }, ); - print({ - "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" - // "isMobile": true, - // "deviceToken": AppState().deviceNotificationToken - }); if (!kReleaseMode) { logger.i("login-res: " + response.body); } diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index c0a16c0..71d7ccb 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -1415,17 +1415,17 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void inputBoxDirection(String val) { if (val.isNotEmpty) { isTextMsg = true; + RegExp exp = RegExp("[a-zA-Z]"); + if (exp.hasMatch(val.substring(val.length - 1)) && val.substring(val.length - 1) != " ") { + textDirection = Material.TextDirection.ltr; + notifyListeners(); + } else if (val.substring(val.length - 1) != " " && !exp.hasMatch(val.substring(val.length - 1))) { + textDirection = Material.TextDirection.rtl; + notifyListeners(); + } } else { isTextMsg = false; } - RegExp exp = RegExp("[a-zA-Z]"); - if (exp.hasMatch(val.substring(val.length - 1)) && val.substring(val.length - 1) != " ") { - textDirection = Material.TextDirection.ltr; - notifyListeners(); - } else if (val.substring(val.length - 1) != " " && !exp.hasMatch(val.substring(val.length - 1))) { - textDirection = Material.TextDirection.rtl; - notifyListeners(); - } } Material.TextDirection getTextDirection(String v) { diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index da547cf..a72e12b 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -256,7 +256,10 @@ class _ChatDetailScreenState extends State { textDirection: m.textDirection, controller: m.message, decoration: InputDecoration( - hintText: m.isAttachmentMsg ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(), + hintTextDirection: m.textDirection, + hintText: m.isAttachmentMsg + ? m.selectedFile.path.split("/").last + : m.textDirection.name == "rtl" ? "اكتب هنا للرد" :LocaleKeys.typeheretoreply.tr(), hintStyle: TextStyle(color: m.isAttachmentMsg ? MyColors.darkTextColor : MyColors.grey98Color, fontSize: 14), border: InputBorder.none, focusedBorder: InputBorder.none, diff --git a/pubspec.yaml b/pubspec.yaml index c343421..b3d6c4c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -108,7 +108,7 @@ dependencies: dependency_overrides: - #firebase_core_platform_interface: 4.5.1 + firebase_core_platform_interface: 4.5.1 dev_dependencies: From 33da1a103d23431017e19a20b114b8806e721a0a Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 19 Jan 2023 16:28:44 +0300 Subject: [PATCH 07/11] mark attendance session expire fixed --- ios/Runner/AppDelegate.swift | 10 ++------ ios/Runner/Info.plist | 14 +++++++----- lib/api/chat/chat_api_client.dart | 6 ++--- lib/classes/notifications.dart | 38 +++++++++++++++---------------- 4 files changed, 32 insertions(+), 36 deletions(-) diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 7d74b94..c1c9fd9 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,6 +1,6 @@ import UIKit import Flutter -import flutter_local_notifications +import Firebase @UIApplicationMain @@ -9,13 +9,7 @@ import flutter_local_notifications _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in - GeneratedPluginRegistrant.register(with: registry) - } - - if #available(iOS 10.0, *) { - UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate - } + FirebaseApp.configure() GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index f8d7b49..15e0a0c 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -42,14 +42,16 @@ This App requires access to your location to mark your attendance. NSLocationWhenInUseUsageDescription This App requires access to your location to mark your attendance. - NSPhotoLibraryUsageDescription - This app requires photo library access to select image as document & upload it. NSMicrophoneUsageDescription This app requires microphone access to for call. + NSPhotoLibraryUsageDescription + This app requires photo library access to select image as document & upload it. UIBackgroundModes remote-notification + FirebaseAppDelegateProxyEnabled + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -69,13 +71,13 @@ UIViewControllerBasedStatusBarAppearance - com.apple.developer.nfc.readersession.formats - - TAG - com.apple.developer.nfc.readersession.felica.systemcodes 0000 + com.apple.developer.nfc.readersession.formats + + TAG + diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index 210106e..3ad0ed7 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -29,9 +29,9 @@ class ChatApiClient { "${ApiConsts.chatLoginTokenUrl}externaluserlogin", { "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" - // "isMobile": true, - // "deviceToken": AppState().deviceNotificationToken + "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", + "isMobile": true, + "deviceToken": AppState().deviceNotificationToken }, ); diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index 649b757..b7d7988 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -15,25 +15,25 @@ class AppNotifications { factory AppNotifications() => _instance; - Future requestPermissions() async { - if (Platform.isIOS) { - // await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); - } else if (Platform.isAndroid) { - // AndroidFlutterLocalNotificationsPlugin? androidImplementation = flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation(); - // bool? granted = await androidImplementation?.requestPermission(); - // if (granted == false) { - // print("-------------------- Permission Granted ------------------------"); - // print(granted); - // await Permission.notification.request(); - // } - } - } - - Future isAndroidPermGranted() async { - if (Platform.isAndroid) { - // bool granted = await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.areNotificationsEnabled() ?? false; - } - } + // Future requestPermissions() async { + // if (Platform.isIOS) { + // await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); + // } else if (Platform.isAndroid) { + // AndroidFlutterLocalNotificationsPlugin? androidImplementation = flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation(); + // bool? granted = await androidImplementation?.requestPermission(); + // if (granted == false) { + // print("-------------------- Permission Granted ------------------------"); + // print(granted); + // await Permission.notification.request(); + // } + // } + // } + + // Future isAndroidPermGranted() async { + // if (Platform.isAndroid) { + // bool granted = await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.areNotificationsEnabled() ?? false; + // } + // } void initNotification(String? firebaseToken) async { // await requestPermissions(); From 7f9c82d165659d873e117c05231a271a9421382c Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 19 Jan 2023 16:30:58 +0300 Subject: [PATCH 08/11] ChatFix --- lib/api/chat/chat_api_client.dart | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index b408362..d029866 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -29,18 +29,13 @@ class ChatApiClient { "${ApiConsts.chatLoginTokenUrl}externaluserlogin", { "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" - // "isMobile": true, - // "deviceToken": AppState().deviceNotificationToken + "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", + "isMobile": true, + "deviceToken": AppState().deviceNotificationToken }, ); - print({ - "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" - // "isMobile": true, - // "deviceToken": AppState().deviceNotificationToken - }); + if (!kReleaseMode) { logger.i("login-res: " + response.body); } From 81a060012ee91b4349b8887056e17b8f883bb7f2 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 19 Jan 2023 16:44:06 +0300 Subject: [PATCH 09/11] Chat Fix --- lib/ui/login/login_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 0ec0bdb..6253002 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -12,6 +12,7 @@ import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:mohem_flutter_app/classes/notifications.dart'; import 'package:mohem_flutter_app/classes/push-notification-handler.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; @@ -96,7 +97,6 @@ class _LoginScreenState extends State { await Firebase.initializeApp(); _firebaseMessaging = FirebaseMessaging.instance; firebaseToken = await _firebaseMessaging.getToken(); - AppState().setDeviceToken = firebaseToken; AppNotifications().initNotification(firebaseToken); loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); if (loginInfo == null) { From 0f84f9ae65d53c765ca771bcac93b19677238750 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 23 Jan 2023 15:28:20 +0300 Subject: [PATCH 10/11] app life cycle added. file attachment option added on dynamic form. & improvements --- assets/langs/ar-SA.json | 2 +- assets/langs/en-US.json | 2 +- lib/generated/codegen_loader.g.dart | 2085 ++++++++++++------------ lib/generated/locale_keys.g.dart | 2 +- lib/ui/landing/dashboard_screen.dart | 23 +- lib/ui/misc/request_submit_screen.dart | 2 +- 6 files changed, 1076 insertions(+), 1040 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index b4cf456..a2f0aa1 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -520,6 +520,6 @@ "noUpcoming": "لا يوجد قادم", "fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية", "noWinner": "حزين! لم يفز أحد اليوم.", - "myTeam" : "فريقي" + "myTeam" : "فريقي", "youCanPlayDemo": "لكن يمكنك لعب العرض" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 3d37c1b..2e6703a 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -520,6 +520,6 @@ "noUpcoming": "There is no upcoming", "fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.", "noWinner": "Sad! No one won today.", - "myTeam" : "My Team" + "myTeam" : "My Team", "youCanPlayDemo": "But you can play demo" } \ No newline at end of file diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index f01aa0d..1563767 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -6,1048 +6,1063 @@ import 'dart:ui'; import 'package:easy_localization/easy_localization.dart' show AssetLoader; -class CodegenLoader extends AssetLoader { +class CodegenLoader extends AssetLoader{ const CodegenLoader(); @override - Future> load(String fullPath, Locale locale) { + Future> load(String fullPath, Locale locale ) { return Future.value(mapLocales[locale.toString()]); } - static const Map ar_SA = { - "mohemm": "Mohemm", - "english": "English", - "arabic": "عربي", - "login": "تسجيل الدخول", - "pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول", - "username": "اسم المستخدم", - "password": "كلمة المرور", - "welcomeBack": "مرحبا بعودتك", - "wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟", - "lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:", - "verificationType": "نوع التحقق:", - "pleaseVerify": "ارجوك تحقق", - "pleaseVerifyForBio": "الرجاء التحقق من تسجيل الدخول باستخدام أحد هذه الخيارات", - "verifyThroughFace": "تحقق من خلال الوجه", - "verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع", - "verifyThroughSMS": "تحقق من خلال الرسائل القصيرة", - "verifyThroughWhatsapp": "تحقق من خلال Whatsapp", - "useAnotherAccount": "استخدم حسابا آخر", - "pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ", - "theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ", - "goodMorning": "صباح الخير", - "markAttendance": "علامة الحضور", - "timeLeftToday": "الوقت المتبقي اليوم", - "checkIn": "تحقق في", - "workList": "قائمة العمل", - "leaveBalance": "رصيد الاجازات", - "missingSwipes": "تسجيل بصمة حضور", - "ticketBalance": "رصيد التذكرة", - "other": "آخر", - "services": "خدمات", - "viewAllServices": "عرض جميع الخدمات", - "monthlyAttendance": "الحضور الشهري", - "vacationRule": "قاعدة الاجازات", - "vacationType": "نوع الاجازة", - "startDateT": "تاريخ البدء", - "endDateT": "تاريخ الانتهاء", - "workFromHome": "العمل من المنزل", - "ticketRequest": "طلب تذكرة", - "viewAllOffers": "مشاهدة جميع العروض", - "offers": "عروض & ", - "discounts": "الخصومات", - "newString": "جديد", - "setTheNewPassword": "قم بتعيين كلمة المرور الجديدة", - "typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه", - "confirmPassword": "تأكيد كلمة المرور", - "update": "تحديث", - "title": "عنوان", - "home": "الرئيسية", - "mySalary": "راتبي", - "createRequest": "إنشاء طلب", - "forgotPassword": "هل نسيت كلمة السر", - "employeeId": "هوية الموظف", - "loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول", - "changePassword": "تغيير كلمة المرور", - "ok": "موافق", - "confirm": "تؤكد", - "passwordChangedSuccessfully": "تم تغيير الرقم السري بنجاح", - "itemsForSale": "سلع للبيع", - "attendanceDetails": "تفاصيل الحضور", - "order": "الطلبات", - "earlyOut": "الخروج مبكرا", - "shortage": "ساعات التقصير", - "excess": "فائض", - "lateIn": "القدوم المتاخر", - "approvedCheckOut": "اعتماد وقت الخروج", - "approvedCheckIn": "اعتماد وقت الدخول", - "actualCheckOut": "وقت الخروج", - "actualCheckIn": "وقت الدخول", - "present": "حضور", - "pres": "حضور", - "shiftTime": "وقت التناوب", - "absent": "غياب", - "attendance": "الحضور", - "scheduleDays": "ايام العمل", - "offDays": "ايام الراحه", - "nonAnalyzed": "لايوجد تحليل", - "shortageHour": "ساعات التقصير", - "stats": "الحاله", - "completed": "تم اكمال", - "msg": "Hello {} in the {} world ", - "msg_named": "{} are written in the {lang} language", - "clickMe": "Click me", - "doNotUseRecentPassword": "لا تستخدم كلمة مرور حديثة", - "atLeastOneLowercase": "حرف صغير واحد على الأقل", - "atLeastOneUppercase": "حرف كبير واحد على الأقل", - "atLeastOneNumeric": "رقم واحد على الأقل", - "minimum8Characters": "8 أحرف على الأقل", - "doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة", - "itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص", - "confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور", - "sms": "رسالة قصيرة", - "fingerPrint": "بصمة", - "face": "التعرف على الوجه", - "whatsapp": "واتس اب", - "reject": "يرفض", - "approve": "يوافق", - "cancel": "إلغاء", - "requestedItems": "العناصر المطلوبة", - "request": "طلب", - "myRequest": "طلبي", - "actions": "أجراءات", - "delegate": "مندوب", - "request_info": "اطلب معلومات", - "attachments": "المرفقات", - "info": "معلومات", - "employeeNumber": "رقم الموظف", - "assignmentNumber": "رقم الواجب", - "employeeName": "اسم الموظف", - "scheduleDate": "تاريخ الجدول الزمني", - "shiftType": "نوع التحول", - "shift": "يحول", - "breakText": "استراحة", - "actualSwipeStart": "بدء التمرير الفعلي", - "actualSwipeEnd": "التمرير الفعلي للنهاية", - "approvedSwipeStart": "وافق انتقاد البدء", - "approvedSwipeStartReason": "تمت الموافقة على سبب بدء التمرير السريع", - "approvedSwipeEnd": "تمت الموافقة على تمرير النهاية", - "approvedSwipeEndReason": "الموافقة على سبب إنهاء التمرير", - "from": "من", - "to": "ل", - "sent": "أرسلت", - "closed": "مغلق", - "id": "هوية شخصية", - "responder": "المستجيب", - "jobTitle": "عنوان وظيفي", - "grade": "درجة", - "jobCategory": "تصنيف الوظيفة", - "category": "فئة", - "employeeEmailAddress": "عنوان البريد الإلكتروني للموظف", - "payrollBranch": "فرع الرواتب", - "yourChangeHasBeenSavedSuccessfully": "تم حفظ التغيير الخاص بك بنجاح", - "code": "شفرة", - "unit": "وحدة", - "quantity": "كمية", - "dateRequired": "التاريخ مطلوب", - "lineStatus": "حالة الخط", - "statusDate": "تاريخ الحالة", - "transactionType": "نوع المعاملة", - "operatingUnit": "وحدة التشغيل", - "organizationCode": "كود المنظمة", - "organization": "منظمة", - "fromSubInventory": "من الجرد الفرعي", - "fromLocator": "من محدد المواقع", - "toSubInventory": "إلى الجرد الفرعي", - "toLocator": "إلى محدد المواقع", - "shipToLocator": "شحن إلى محدد المواقع", - "itemHistory": "تاريخ العنصر", - "mfg": "مبدع", - "lineType": "نوع الخط", - "price": "السعر", - "lineAmount": "مبلغ الخط", - "lineDiscount": "خصم الخط٪", - "needByDate": "القادمة إلى الأمام", - "promisedDate": "التسجيل وعد", - "deliverToLocation": "تسليم إلى الموقع", - "requisitionNumber": "رقم الطلب", - "requester": "مقدم الطلب", - "quotationAnalysis": "تحليل الاقتباس", - "subject": "موضوعات", - "description": "وصف", - "supplier": "المورد", - "site": "موقع", - "buyer": "مشتر", - "preparer": "معد", - "creationDate": "تاريخ الإنشاء", - "shipToLocation": "الشحن الى الموقع", - "quotationNumber": "رقم الإقتباس", - "quotationDate": "تاريخ الاقتباس", - "paymentTerms": "شروط الدفع", - "currency": "عملة", - "grossAmount": "المبلغ الإجمالي", - "discountAmount": "مقدار الخصم", - "customDuty": "الرسوم الجمركية", - "shipHandle": "مقبض السفينة", - "otherCharges": "رسوم أخرى", - "totalPOAmountWithVAT": "إجمالي مبلغ الشراء مع ضريبة القيمة المضافة", - "totalPOAmountInWords": "إجمالي مبلغ أمر الشراء بالكلمات", - "requestNumber": "رقم الطلب", - "uom": "UOM", - "operatingCode": "كود التشغيل", - "poNumber": "PO عدد", - "revision": "مراجعة", - "quantityOrdered": "الكمية المطلوبة", - "quantityReceived": "الكمية المستلمة", - "bonusQuantity": "كمية المكافأة", - "purchasePrice": "سعر الشراء", - "discountPer": "خصم ٪", - "balanceQuantity": "كمية التوازن", - "netPrice": "السعر الصافي", - "closureStatus": "حالة الإغلاق", - "quotationNetPrice": "صافي سعر الاقتباس", - "quotationUOM": "اقتباس UOM", - "quotationQty": "اقتباس الكمية", - "itemCode": "رمز الصنف", - "vendorName": "اسم البائع", - "quotationMFGPartNumber": "رقم الجزء MFG الاقتباس", - "quotationDeliveryDate": "تاريخ تسليم عرض الأسعار", - "quotationBonusQuantity": "كمية مكافأة الاقتباس", - "quotationLineTotal": "مجموع خط الاقتباس", - "rfqUOM": "RFQ UOM", - "rfqQty": "RFQ الكمية", - "rfqNumber": "رقم RFQ", - "human": "بشري", - "resources": "موارد", - "details": "تفاصيل", - "noDataAvailable": "لا تتوافر بيانات", - "productName": "اسم المنتج", - "productDescription": "وصف المنتج", - "unitPrice": "سعر الوحده", - "manufacturerName": "اسم المصنع", - "manufacturerPartName": "اسم جزء الشركة المصنعة", - "supplierName": "اسم المورد", - "supplierContact": "الاتصال بالمورد", - "chargeToPatient": "المسؤول عن المريض", - "justification": "التبرير", - "itemDescription": "وصف السلعة", - "groupCode": "كود المجموعة", - "primaryUOM": "UOM الابتدائية", - "subgroupDescription": "وصف المجموعة الفرعية", - "subgroupCode": "رمز المجموعة الفرعية", - "groupDescription": "وصف المجموعة", - "templateName": "اسم القالب", - "itemCreationStatus": "حالة إنشاء العنصر", - "standardizationApprovalStatus": "حالة الموافقة على التقييس", - "standardizationApprovalRejectionReason": "سبب رفض الموافقة على التقييس", - "analyzedBy": "تحليل بواسطة", - "approvedDate": "تاريخ الموافقة", - "itemType": "نوع العنصر", - "relatedTo": "متعلق ب", - "requestDate": "تاريخ الطلب", - "analyzedDate": "تاريخ التحليل", - "urgent": "العاجلة", - "requestDetails": "طلب تفاصيل", - "approvalLevel": "مستوى الموافقة", - "requesterDetails": "تفاصيل مقدم الطلب", - "myAttendance": "حضوري", - "workOnBreak": "التعويض عن العمل اثناءالاستراحه", - "next": "التالي", - "apply": "يتقدم", - "mobile": "التليفون المحمول", - "completingYear": "نحن نقدر لك لاستكمال خدمة", - "year": "سنة", - "month": "شهر", - "day": "يوم", - "address": "العنوان", - "phoneNumber": "رقم الجوال", - "businessGroup": "مجموعة العمل", - "Payroll": "الراتب", - "civilIdentityNumber": "رقم الهويه", - "dateOfBirth": "تاريخ الميلاد", - "maritalStatus ": "الحالة الاجتماعية", - "fullName": "الأسم الكامل", - "remove": "حذف", - "submit": "ارسال", - "areYouSureYouWantToSubmit": "هل أنت متأكد أنك تريد أن تقدم؟", - "comments": "تعليقات", - "writeComment": "أكتب تعليقا", - "approversList": "قائمة الموافقين", - "yourRequestHasBeenSubmittedForApprovals": "تم تقديم طلبك للموافقات", - "monthlyPaySlip": "قسيمة الراتب الشهرية", - "particular": "خاص", - "earnings": "أرباح", - "deductions": "الخصومات", - "paymentMethodName": "اسم طريقة الدفع", - "bankName": "اسم البنك", - "branchCode": "رمز الفرع", - "accountNo": "رقم الحساب", - "summaryOfInformation": "ملخص المعلومات", - "totalPayAmount": "المبلغ الإجمالي للدفع", - "paymentInformation": "معلومات الدفع", - "performance": "تقييم الاداء", - "performanceEvaluation": "تقييم الأداء في", - "performanceEvaluationIn": "تقييم أدائك في", - "valuationIn": "تقييم الأداء في", - "amount": "مقدار", - "correctCurrentDatails": "تعديل او اكمال التفاصيل الحالية", - "selectType": " حدد نوع التغيير الذي تريد القيام به", - "enterNewInfo": " أدخل معلومات جديدة بسبب تغيير حقيقي في التفاصيل الحالية (على سبيل المثال بسبب تغيير في الحالة الاجتماعية", - "endDate": "تاريخ الانتهاء", - "removeThisMember": "هل انت متأكد تريد ازالة هذا العضو؟", - "wantUpdateThisMember ": "هل انت متأكد تريد تحديث بيانات هذا العضو؟", - "addNewFamilyMember": "اضافة عضو جديد", - "addRow": "اضافة صف جديد", - "pleaseSelect": "الرجاء اختيار", - "delete": "حذف", - "edit": "تعديل", - "add": "اضافه", - "myProfile": "معلوماتي", - "mowadhafhi": "موظفي", - "searchAnnouncements": "بحث الاعلانات", - "announcements": "اعلانات", - "swipeRequest": "طلب تسجيل حضور", - "serviceType": "نوع الخدمه", - "departmentName": "اسم القسم", - "selectDepartment": "اختر القسم", - "relatedSection": "قسم ذو صله", - "selectSection": "اختيار القسم", - "relatedTopic": "عنوان ذو صله", - "selectTopic": "اختر العنوان", - "supportingDocument": "ارفاق مستند", - "mowadhafhiRequest": "طلب موظفي", - "ticketReference": "مرجع التذكره", - "section": "القسم", - "topic": "العنوان", - "actionBy": "الرد بواسطة", - "pending": "معلق", - "pendingTransactions": "المعاملات المعلقه", - "selectRequestType": "الرجاء اختيار نوع الطلب", - "dateFrom": "من تاريخ", - "dateTo": "الى تاريخ", - "requestName": "اسم الطلب", - "createdFor": "انشاء لأجل", - "requestCreatedSuccessfully": "تم انشاء الطلب بنجاح", - "search": "بحث", - "wantToReject": "هل انت متأكد تريد الرفض", - "requestType": "نوع الطلب", - "employeeDigitalID": "هويةالموظف الرقمية", - "businessCard": "بطاقة العمل", - "viewBusinessCard": "عرض بطاقة العمل", - "logout": "تسجيل خروج", - "checkOut": "وقت الخروج", - "regular": "منتظم", - "mark": "علامة", - "selectMethodOfAttendance": "اختر طريقة تسجيل الحضور", - "comeNearHMGWifi": "HMG wifi من فضلك اقترب من", - "deliverNotificationToMeRegardless": "تسليم الإخطارات إلي بغض النظر عن أي قواعد عامة", - "close": "أغلق", - "respond": "يرد", - "vacationRuleAdded": "تمت إضافة قاعدة الإجازة", - "selectTypeT": "اختر صنف", - "notification": "تنبيه", - "selectNotification": "حدد إعلام", - "ifAllSelectedYouWillSkip": "* إذا تم تحديد الكل ، فستنتقل إلى الخطوة 3", - "applyForVacationRule": "التقدم بطلب للحصول على قانون الإجازة", - "step1": "الخطوة 1", - "step2": "الخطوة 2", - "step3": "الخطوه 3", - "message": "رسالة", - "writeAMessage": "اكتب رسالة", - "notificationReassign": "إعادة تعيين الإخطار", - "selectEmployee": "حدد الموظف", - "searchEmployeeForReplacement": "ابحث عن موظف بديل", - "searchForEmployee": "ابحث عن موظف", - "pleaseSpecifyEndTime": "الرجاء تحديد وقت الانتهاء", - "pleaseSelectNotificationReassign": "يرجى تحديد إعادة تعيين الإخطار", - "pleaseSelectEmployeeForReplacement": "الرجاء تحديد موظف للاستبدال", - "pleaseSelectAction": "الرجاء تحديد الإجراء", - "pleaseSelectDate": "الرجاء تحديد التاريخ", - "todayAttendance": "حضور اليوم", - "viewAttendance": "عرض الحضور", - "teamMembers": "اعضاءالفريق", - "profileDetails": "الملف الشخصي", - "noResultsFound": "لايوجد نتائج", - "searchBy": "بحث بواسطة", - "myTeamMembers": "اعضاء فريقي", - "save": "حفظ", - "TurnNotificationsFor": "تفعيل الاشعارات", - "worklistSettings": "اعدادات الاشعارات", - "absenceType": "نوع الغياب", - "absenceCategory": "فئة الغياب", - "days": "أيام", - "hours": "ساعات", - "approvalStatus": "حالة القبول", - "absenceStatus": "حالة الغياب", - "subordinateLeave": "إجازة التابعيين", - "numberDays": "عدد الأيام", - "poweredBy": "مشغل بواسطة", - "cloudSolutions": "حلول السحابة", - "selectTemplate": "حدد قالب", - "myPostedAds": "إعلاناتي المنشورة", - "browseCategories": "تصفح الفئات", - "searchItems": "عناصر البحث", - "offerAndDiscounts": "العروض والخصومات", - "offerValid": "العرض صالح", - "offerExpired": "انتهى العرض", - "whatAreYouOffering": "ما الذي تعرضه؟", - "selectCategory": "اختر الفئة", - "inProgress": "في تَقَدم", - "locked": "مقفل", - "addDetails": "أضف التفاصيل", - "reviewAndSell": "مراجعة وبيع", - "itemTitle": "عنوان البند", - "itemCondition": "حالة السلعة", - "used": "تستخدم", - "region": "منطقة", - "selectRegion": "اختر المنطقة", - "itemPrice": "سعر السلعة", - "itemPhotos": "صور البند", - "itemInfo": "معلومات العنصر", - "uploadAttachment": "تحميل المرفق", - "selectFromGalleryOrOpenCamera": "اختر من المعرض أو فتح الكاميرا", - "openCamera": "فتح\nالكاميرا", - "uploadFromGallery": "تحميل من\nملفات الجهاز", - "name": "الأسم", - "email": "ايميل", - "noHistoryAvailable": "لايوجد سجل بيانات سابقة ", - "purchaseRequisition": "طلب شراء", - "moveOrder": "طلب تغيير", - "humanResource": "الموارد البشريه", - "purchaseOrder": "امر شراء", - "ITGForms": "ITG نماذج", - "itemCreation": "أنشاء عنصر", - "stamp": "ختم", - "addFavoriteList": "هل تريد اضافة {name} لقائمة المفضله", - "feedbackUserExperience": "هذا للحصول على تعليقات حول تجربة المستخدم", - "rateUI": ".1 كيف تريد تقييم التطبيق", - "submitSurvey": "ارسال الاستبيان", - "typeHere": "اكتب هنا", - "infoDetail": "تفاصيل المعلومات", - "amount_detail": "تفاصيل المبلغ", - "currentBalance": "الرصيد الحالي", - "currentLeaveBalance": "رصيد الاجازات الحالي", - "calculatedDays": "الايام المحسوبه", - "totalDays": "مجموع الأيام", - "usedBalance": "المستخدم", - "infants": "رضيع", - "child": "طفل", - "adult": "بالغ", - "updateMember": "هل انت متأكد تريد تحديث بيانات هذا العضو؟", - "fieldIsEmpty": "'{data}' الحقل فارغ. الرجاء التحديد", - "pleaseEnterComments": "الرجاء إدخال التعليقات", - "skip": "يتخطى", - "typeCurrentPasswordBelow": "اكتب كلمة المرور الحاليه", - "currentPassword": "كلمة المرور الحاليه", - "concurrentReports": "التقارير المتزامنه", - "EnterNewAddressMoved": "أدخل عنوان جديد إذا كنت قد انتقلت", - "CorrectAddress": "تصحيح أو تعديل هذا العنوان", - "SelectChangeWantToMake": " حدد نوع التغيير الذي تريد القيام به.", - "profile": { - "reset_password": {"label": "Reset Password", "username": "Username", "password": "password"}, - "profileCompletionPer": "استكمال الملف الشخصي", - "completeProfile": "الملف الشخصي الكامل", - "personalInformation": "معلومات شخصية", - "basicDetails": "تفاصيل أساسية", - "address": "العنوان", - "contactDetails": "بيانات التواصل", - "familyDetails": "تفاصيل عائلية", - "effectiveDate": "تاريخ النفاذ", - "country": "دولة" - }, - "clicked": { - "zero": "You clicked {} times!", - "one": "You clicked {} time!", - "two": "You clicked {} times!", - "few": "You clicked {} times!", - "many": "You clicked {} times!", - "other": "You clicked {} times!" + static const Map ar_SA = { + "mohemm": "Mohemm", + "english": "English", + "arabic": "عربي", + "login": "تسجيل الدخول", + "pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول", + "username": "اسم المستخدم", + "password": "كلمة المرور", + "welcomeBack": "مرحبا بعودتك", + "wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟", + "lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:", + "verificationType": "نوع التحقق:", + "pleaseVerify": "ارجوك تحقق", + "pleaseVerifyForBio": "الرجاء التحقق من تسجيل الدخول باستخدام أحد هذه الخيارات", + "verifyThroughFace": "تحقق من خلال الوجه", + "verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع", + "verifyThroughSMS": "تحقق من خلال الرسائل القصيرة", + "verifyThroughWhatsapp": "تحقق من خلال Whatsapp", + "useAnotherAccount": "استخدم حسابا آخر", + "pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ", + "theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ", + "goodMorning": "صباح الخير", + "markAttendance": "علامة الحضور", + "timeLeftToday": "الوقت المتبقي اليوم", + "checkIn": "تحقق في", + "workList": "قائمة العمل", + "leaveBalance": "رصيد الاجازات", + "missingSwipes": "تسجيل بصمة حضور", + "ticketBalance": "رصيد التذكرة", + "other": "آخر", + "services": "خدمات", + "viewAllServices": "عرض جميع الخدمات", + "monthlyAttendance": "الحضور الشهري", + "vacationRule": "قاعدة الاجازات", + "vacationType": "نوع الاجازة", + "startDateT": "تاريخ البدء", + "endDateT": "تاريخ الانتهاء", + "workFromHome": "العمل من المنزل", + "ticketRequest": "طلب تذكرة", + "viewAllOffers": "مشاهدة جميع العروض", + "offers": "عروض & ", + "discounts": "الخصومات", + "newString": "جديد", + "setTheNewPassword": "قم بتعيين كلمة المرور الجديدة", + "typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه", + "confirmPassword": "تأكيد كلمة المرور", + "update": "تحديث", + "title": "عنوان", + "home": "الرئيسية", + "mySalary": "راتبي", + "createRequest": "إنشاء طلب", + "forgotPassword": "هل نسيت كلمة السر", + "employeeId": "هوية الموظف", + "loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول", + "changePassword": "تغيير كلمة المرور", + "ok": "موافق", + "confirm": "تؤكد", + "passwordChangedSuccessfully": "تم تغيير الرقم السري بنجاح", + "itemsForSale": "سلع للبيع", + "attendanceDetails": "تفاصيل الحضور", + "order": "الطلبات", + "earlyOut": "الخروج مبكرا", + "shortage": "ساعات التقصير", + "excess": "فائض", + "lateIn": "القدوم المتاخر", + "approvedCheckOut": "اعتماد وقت الخروج", + "approvedCheckIn": "اعتماد وقت الدخول", + "actualCheckOut": "وقت الخروج", + "actualCheckIn": "وقت الدخول", + "present": "حضور", + "pres": "حضور", + "shiftTime": "وقت التناوب", + "absent": "غياب", + "attendance": "الحضور", + "scheduleDays": "ايام العمل", + "offDays": "ايام الراحه", + "nonAnalyzed": "لايوجد تحليل", + "shortageHour": "ساعات التقصير", + "stats": "الحاله", + "completed": "تم اكمال", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "Click me", + "doNotUseRecentPassword": "لا تستخدم كلمة مرور حديثة", + "atLeastOneLowercase": "حرف صغير واحد على الأقل", + "atLeastOneUppercase": "حرف كبير واحد على الأقل", + "atLeastOneNumeric": "رقم واحد على الأقل", + "minimum8Characters": "8 أحرف على الأقل", + "doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة", + "itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص", + "confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور", + "sms": "رسالة قصيرة", + "fingerPrint": "بصمة", + "face": "التعرف على الوجه", + "whatsapp": "واتس اب", + "reject": "يرفض", + "approve": "يوافق", + "cancel": "إلغاء", + "requestedItems": "العناصر المطلوبة", + "request": "طلب", + "myRequest": "طلبي", + "actions": "أجراءات", + "delegate": "مندوب", + "request_info": "اطلب معلومات", + "attachments": "المرفقات", + "info": "معلومات", + "employeeNumber": "رقم الموظف", + "assignmentNumber": "رقم الواجب", + "employeeName": "اسم الموظف", + "scheduleDate": "تاريخ الجدول الزمني", + "shiftType": "نوع التحول", + "shift": "يحول", + "breakText": "استراحة", + "actualSwipeStart": "بدء التمرير الفعلي", + "actualSwipeEnd": "التمرير الفعلي للنهاية", + "approvedSwipeStart": "وافق انتقاد البدء", + "approvedSwipeStartReason": "تمت الموافقة على سبب بدء التمرير السريع", + "approvedSwipeEnd": "تمت الموافقة على تمرير النهاية", + "approvedSwipeEndReason": "الموافقة على سبب إنهاء التمرير", + "from": "من", + "to": "ل", + "sent": "أرسلت", + "closed": "مغلق", + "id": "هوية شخصية", + "responder": "المستجيب", + "jobTitle": "عنوان وظيفي", + "grade": "درجة", + "jobCategory": "تصنيف الوظيفة", + "category": "فئة", + "employeeEmailAddress": "عنوان البريد الإلكتروني للموظف", + "payrollBranch": "فرع الرواتب", + "yourChangeHasBeenSavedSuccessfully": "تم حفظ التغيير الخاص بك بنجاح", + "code": "شفرة", + "unit": "وحدة", + "quantity": "كمية", + "dateRequired": "التاريخ مطلوب", + "lineStatus": "حالة الخط", + "statusDate": "تاريخ الحالة", + "transactionType": "نوع المعاملة", + "operatingUnit": "وحدة التشغيل", + "organizationCode": "كود المنظمة", + "organization": "منظمة", + "fromSubInventory": "من الجرد الفرعي", + "fromLocator": "من محدد المواقع", + "toSubInventory": "إلى الجرد الفرعي", + "toLocator": "إلى محدد المواقع", + "shipToLocator": "شحن إلى محدد المواقع", + "itemHistory": "تاريخ العنصر", + "mfg": "مبدع", + "lineType": "نوع الخط", + "price": "السعر", + "lineAmount": "مبلغ الخط", + "lineDiscount": "خصم الخط٪", + "needByDate": "القادمة إلى الأمام", + "promisedDate": "التسجيل وعد", + "deliverToLocation": "تسليم إلى الموقع", + "requisitionNumber": "رقم الطلب", + "requester": "مقدم الطلب", + "quotationAnalysis": "تحليل الاقتباس", + "subject": "موضوعات", + "description": "وصف", + "supplier": "المورد", + "site": "موقع", + "buyer": "مشتر", + "preparer": "معد", + "creationDate": "تاريخ الإنشاء", + "shipToLocation": "الشحن الى الموقع", + "quotationNumber": "رقم الإقتباس", + "quotationDate": "تاريخ الاقتباس", + "paymentTerms": "شروط الدفع", + "currency": "عملة", + "grossAmount": "المبلغ الإجمالي", + "discountAmount": "مقدار الخصم", + "customDuty": "الرسوم الجمركية", + "shipHandle": "مقبض السفينة", + "otherCharges": "رسوم أخرى", + "totalPOAmountWithVAT": "إجمالي مبلغ الشراء مع ضريبة القيمة المضافة", + "totalPOAmountInWords": "إجمالي مبلغ أمر الشراء بالكلمات", + "requestNumber": "رقم الطلب", + "uom": "UOM", + "operatingCode": "كود التشغيل", + "poNumber": "PO عدد", + "revision": "مراجعة", + "quantityOrdered": "الكمية المطلوبة", + "quantityReceived": "الكمية المستلمة", + "bonusQuantity": "كمية المكافأة", + "purchasePrice": "سعر الشراء", + "discountPer": "خصم ٪", + "balanceQuantity": "كمية التوازن", + "netPrice": "السعر الصافي", + "closureStatus": "حالة الإغلاق", + "quotationNetPrice": "صافي سعر الاقتباس", + "quotationUOM": "اقتباس UOM", + "quotationQty": "اقتباس الكمية", + "itemCode": "رمز الصنف", + "vendorName": "اسم البائع", + "quotationMFGPartNumber": "رقم الجزء MFG الاقتباس", + "quotationDeliveryDate": "تاريخ تسليم عرض الأسعار", + "quotationBonusQuantity": "كمية مكافأة الاقتباس", + "quotationLineTotal": "مجموع خط الاقتباس", + "rfqUOM": "RFQ UOM", + "rfqQty": "RFQ الكمية", + "rfqNumber": "رقم RFQ", + "human": "بشري", + "resources": "موارد", + "details": "تفاصيل", + "noDataAvailable": "لا تتوافر بيانات", + "productName": "اسم المنتج", + "productDescription": "وصف المنتج", + "unitPrice": "سعر الوحده", + "manufacturerName": "اسم المصنع", + "manufacturerPartName": "اسم جزء الشركة المصنعة", + "supplierName": "اسم المورد", + "supplierContact": "الاتصال بالمورد", + "chargeToPatient": "المسؤول عن المريض", + "justification": "التبرير", + "itemDescription": "وصف السلعة", + "groupCode": "كود المجموعة", + "primaryUOM": "UOM الابتدائية", + "subgroupDescription": "وصف المجموعة الفرعية", + "subgroupCode": "رمز المجموعة الفرعية", + "groupDescription": "وصف المجموعة", + "templateName": "اسم القالب", + "itemCreationStatus": "حالة إنشاء العنصر", + "standardizationApprovalStatus": "حالة الموافقة على التقييس", + "standardizationApprovalRejectionReason": "سبب رفض الموافقة على التقييس", + "analyzedBy": "تحليل بواسطة", + "approvedDate": "تاريخ الموافقة", + "itemType": "نوع العنصر", + "relatedTo": "متعلق ب", + "requestDate": "تاريخ الطلب", + "analyzedDate": "تاريخ التحليل", + "urgent": "العاجلة", + "requestDetails": "طلب تفاصيل", + "approvalLevel": "مستوى الموافقة", + "requesterDetails": "تفاصيل مقدم الطلب", + "myAttendance": "حضوري", + "workOnBreak": "التعويض عن العمل اثناءالاستراحه", + "next": "التالي", + "apply": "يتقدم", + "mobile": "التليفون المحمول", + "completingYear": "نحن نقدر لك لاستكمال خدمة", + "year": "سنة", + "month": "شهر", + "day": "يوم", + "address": "العنوان", + "phoneNumber": "رقم الجوال", + "businessGroup": "مجموعة العمل", + "Payroll": "الراتب", + "civilIdentityNumber": "رقم الهويه", + "dateOfBirth": "تاريخ الميلاد", + "maritalStatus ": "الحالة الاجتماعية", + "fullName": "الأسم الكامل", + "remove": "حذف", + "submit": "ارسال", + "areYouSureYouWantToSubmit": "هل أنت متأكد أنك تريد أن تقدم؟", + "comments": "تعليقات", + "writeComment": "أكتب تعليقا", + "approversList": "قائمة الموافقين", + "yourRequestHasBeenSubmittedForApprovals": "تم تقديم طلبك للموافقات", + "monthlyPaySlip": "قسيمة الراتب الشهرية", + "particular": "خاص", + "earnings": "أرباح", + "deductions": "الخصومات", + "paymentMethodName": "اسم طريقة الدفع", + "bankName": "اسم البنك", + "branchCode": "رمز الفرع", + "accountNo": "رقم الحساب", + "summaryOfInformation": "ملخص المعلومات", + "totalPayAmount": "المبلغ الإجمالي للدفع", + "paymentInformation": "معلومات الدفع", + "performance": "تقييم الاداء", + "performanceEvaluation": "تقييم الأداء في", + "performanceEvaluationIn": "تقييم أدائك في", + "valuationIn": "تقييم الأداء في", + "amount": "مقدار", + "correctCurrentDatails": "تعديل او اكمال التفاصيل الحالية", + "selectType": " حدد نوع التغيير الذي تريد القيام به", + "enterNewInfo": " أدخل معلومات جديدة بسبب تغيير حقيقي في التفاصيل الحالية (على سبيل المثال بسبب تغيير في الحالة الاجتماعية", + "endDate": "تاريخ الانتهاء", + "removeThisMember": "هل انت متأكد تريد ازالة هذا العضو؟", + "wantUpdateThisMember ": "هل انت متأكد تريد تحديث بيانات هذا العضو؟", + "addNewFamilyMember": "اضافة عضو جديد", + "addRow": "اضافة صف جديد", + "pleaseSelect": "الرجاء اختيار", + "delete": "حذف", + "edit": "تعديل", + "add": "اضافه", + "myProfile": "معلوماتي", + "mowadhafhi": "موظفي", + "searchAnnouncements": "بحث الاعلانات", + "announcements": "اعلانات", + "swipeRequest": "طلب تسجيل حضور", + "serviceType": "نوع الخدمه", + "departmentName": "اسم القسم", + "selectDepartment": "اختر القسم", + "relatedSection": "قسم ذو صله", + "selectSection": "اختيار القسم", + "relatedTopic": "عنوان ذو صله", + "selectTopic": "اختر العنوان", + "supportingDocument": "ارفاق مستند", + "mowadhafhiRequest": "طلب موظفي", + "ticketReference": "مرجع التذكره", + "section": "القسم", + "topic": "العنوان", + "actionBy": "الرد بواسطة", + "pending": "معلق", + "pendingTransactions": "المعاملات المعلقه", + "selectRequestType": "الرجاء اختيار نوع الطلب", + "dateFrom": "من تاريخ", + "dateTo": "الى تاريخ", + "requestName": "اسم الطلب", + "createdFor": "انشاء لأجل", + "requestCreatedSuccessfully": "تم انشاء الطلب بنجاح", + "search": "بحث", + "wantToReject": "هل انت متأكد تريد الرفض", + "requestType": "نوع الطلب", + "employeeDigitalID": "هويةالموظف الرقمية", + "businessCard": "بطاقة العمل", + "viewBusinessCard": "عرض بطاقة العمل", + "logout": "تسجيل خروج", + "checkOut": "وقت الخروج", + "regular": "منتظم", + "mark": "علامة", + "selectMethodOfAttendance": "اختر طريقة تسجيل الحضور", + "comeNearHMGWifi": "HMG wifi من فضلك اقترب من", + "deliverNotificationToMeRegardless": "تسليم الإخطارات إلي بغض النظر عن أي قواعد عامة", + "close": "أغلق", + "respond": "يرد", + "vacationRuleAdded": "تمت إضافة قاعدة الإجازة", + "selectTypeT": "اختر صنف", + "notification": "تنبيه", + "selectNotification": "حدد إعلام", + "ifAllSelectedYouWillSkip": "* إذا تم تحديد الكل ، فستنتقل إلى الخطوة 3", + "applyForVacationRule": "التقدم بطلب للحصول على قانون الإجازة", + "step1": "الخطوة 1", + "step2": "الخطوة 2", + "step3": "الخطوه 3", + "message": "رسالة", + "writeAMessage": "اكتب رسالة", + "notificationReassign": "إعادة تعيين الإخطار", + "selectEmployee": "حدد الموظف", + "searchEmployeeForReplacement": "ابحث عن موظف بديل", + "searchForEmployee": "ابحث عن موظف", + "pleaseSpecifyEndTime": "الرجاء تحديد وقت الانتهاء", + "pleaseSelectNotificationReassign": "يرجى تحديد إعادة تعيين الإخطار", + "pleaseSelectEmployeeForReplacement": "الرجاء تحديد موظف للاستبدال", + "pleaseSelectAction": "الرجاء تحديد الإجراء", + "pleaseSelectDate": "الرجاء تحديد التاريخ", + "todayAttendance": "حضور اليوم", + "viewAttendance": "عرض الحضور", + "teamMembers": "اعضاءالفريق", + "profileDetails": "الملف الشخصي", + "noResultsFound": "لايوجد نتائج", + "searchBy": "بحث بواسطة", + "myTeamMembers": "اعضاء فريقي", + "save": "حفظ", + "TurnNotificationsFor": "تفعيل الاشعارات", + "worklistSettings": "اعدادات الاشعارات", + "absenceType": "نوع الغياب", + "absenceCategory": "فئة الغياب", + "days": "أيام", + "hours": "ساعات", + "approvalStatus": "حالة القبول", + "absenceStatus": "حالة الغياب", + "subordinateLeave": "إجازة التابعيين", + "numberDays": "عدد الأيام", + "poweredBy": "مشغل بواسطة", + "cloudSolutions": "حلول السحابة", + "selectTemplate": "حدد قالب", + "myPostedAds": "إعلاناتي المنشورة", + "browseCategories": "تصفح الفئات", + "searchItems": "عناصر البحث", + "offerAndDiscounts": "العروض والخصومات", + "offerValid": "العرض صالح", + "offerExpired": "انتهى العرض", + "whatAreYouOffering": "ما الذي تعرضه؟", + "selectCategory": "اختر الفئة", + "inProgress": "في تَقَدم", + "locked": "مقفل", + "addDetails": "أضف التفاصيل", + "reviewAndSell": "مراجعة وبيع", + "itemTitle": "عنوان البند", + "itemCondition": "حالة السلعة", + "used": "تستخدم", + "region": "منطقة", + "selectRegion": "اختر المنطقة", + "itemPrice": "سعر السلعة", + "itemPhotos": "صور البند", + "itemInfo": "معلومات العنصر", + "uploadAttachment": "تحميل المرفق", + "selectFromGalleryOrOpenCamera": "اختر من المعرض أو فتح الكاميرا", + "openCamera": "فتح\nالكاميرا", + "uploadFromGallery": "تحميل من\nملفات الجهاز", + "name": "الأسم", + "email": "ايميل", + "noHistoryAvailable": "لايوجد سجل بيانات سابقة ", + "purchaseRequisition": "طلب شراء", + "moveOrder": "طلب تغيير", + "humanResource": "الموارد البشريه", + "purchaseOrder": "امر شراء", + "ITGForms": "ITG نماذج", + "itemCreation": "أنشاء عنصر", + "stamp": "ختم", + "addFavoriteList": "هل تريد اضافة {name} لقائمة المفضله", + "feedbackUserExperience": "هذا للحصول على تعليقات حول تجربة المستخدم", + "rateUI": ".1 كيف تريد تقييم التطبيق", + "submitSurvey": "ارسال الاستبيان", + "typeHere": "اكتب هنا", + "infoDetail": "تفاصيل المعلومات", + "amount_detail": "تفاصيل المبلغ", + "currentBalance": "الرصيد الحالي", + "currentLeaveBalance": "رصيد الاجازات الحالي", + "calculatedDays": "الايام المحسوبه", + "totalDays": "مجموع الأيام", + "usedBalance": "المستخدم", + "infants": "رضيع", + "child": "طفل", + "adult": "بالغ", + "updateMember": "هل انت متأكد تريد تحديث بيانات هذا العضو؟", + "fieldIsEmpty": "'{data}' الحقل فارغ. الرجاء التحديد", + "pleaseEnterComments": "الرجاء إدخال التعليقات", + "skip": "يتخطى", + "typeCurrentPasswordBelow": "اكتب كلمة المرور الحاليه", + "currentPassword": "كلمة المرور الحاليه", + "concurrentReports": "التقارير المتزامنه", + "EnterNewAddressMoved": "أدخل عنوان جديد إذا كنت قد انتقلت", + "CorrectAddress": "تصحيح أو تعديل هذا العنوان", + "SelectChangeWantToMake": " حدد نوع التغيير الذي تريد القيام به.", + "profile": { + "reset_password": { + "label": "Reset Password", + "username": "Username", + "password": "password" }, - "gender": { - "male": "Hi man ;) ", - "female": "Hello girl :)", - "with_arg": {"male": "Hi man ;) {}", "female": "Hello girl :) {}"} + "profileCompletionPer": "استكمال الملف الشخصي", + "completeProfile": "الملف الشخصي الكامل", + "personalInformation": "معلومات شخصية", + "basicDetails": "تفاصيل أساسية", + "address": "العنوان", + "contactDetails": "بيانات التواصل", + "familyDetails": "تفاصيل عائلية", + "effectiveDate": "تاريخ النفاذ", + "country": "دولة" + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": { + "male": "Hi man ;) {}", + "female": "Hello girl :) {}" + } + }, + "reset_locale": "إعادة ضبط اللغة", + "chat": "دردشة", + "mychats": "دردشاتي", + "advancedSearch": "بحث متقدم", + "openNot": "التبليغات المفتوحة", + "fyi": "تبليغات للعلم", + "toDo": "تبليغات الأعمال", + "all": "كل التبليغات", + "meNot": "تبليغات صادرة مني", + "view": "عرض", + "fromUserName": "من", + "sentDate": "تاريخ الإرسال", + "itemTypeDisplayName": "اسم العرض", + "none": "بدون", + "createNewChat": "إنشاء محادثة جديدة", + "brainMarathon": "ماراثون الدماغ", + "contestTopicAbout": "سيكون موضوع المسابقة حول:", + "gameDate": "تاريخ اللعبة:", + "gameTime": "وقت اللعب:", + "joinMarathon": "انضم إلى ماراثون", + "joinDemoMarathon": "انضم إلى الماراثون التجريبي", + "demo": "تجريبي", + "minutes": "الدقائق", + "seconds": "ثواني", + "note": "ملحوظة:", + "demoMarathonNoteP1": "يمكنك لعب ماراثون العرض لتتعلم كيف يعمل. يمكنك الانضمام إلى ماراثون", + "demoMarathonNoteP2": "خمس دقائق", + "demoMarathonNoteP3": "قبل الوقت الفعلي.", + "sponsoredBy": "برعاية:", + "question": "سؤال", + "marathoners": "الماراثون", + "marathoner": "ماراثونر", + "prize": "جائزة:", + "winnerSelection": "اختيار الفائز", + "qualifiers": "تصفيات", + "qualifier": "المؤهل", + "getReadyForContest": "استعد للمسابقة القادمة:", + "winnerSelectedRandomly": "سيتم اختيار الفائز عشوائياً من بين التصفيات.", + "fingersCrossed": "تشابك الاصابع!!!", + "congrats": "مبروك !!!", + "allQuestionsCorrect": "لقد أجبت على جميع الأسئلة بشكل صحيح.", + "otp": "OTP", + "verification": "تَحَقّق", + "resend": "إعادة إرسال", + "codeExpire": "انتهت صلاحية رمز التحقق", + "typeheretoreply": "اكتب هنا للرد", + "favorite": "مفضلتي", + "searchfromchat": "البحث من الدردشة", + "yourAnswerCorrect": "إجابتك صحيحة", + "youMissedTheQuestion": "نفد منك الوقت. أنت خارج اللعبة. لكن يمكنك الاستمرار وكمشاهد.", + "wrongAnswer": "إجابتك غير صحيحة. أنت خارج اللعبة. لكن يمكنك الاستمرار وكمشاهد.", + "oops": "أوه!!!", + "winner": "الفائز", + "youWantToLeaveMarathon": "هل أنت متأكد أنك تريد العودة؟ سوف تخرج من المسابقة.", + "ourSponsor": "راعينا:", + "startingIn": "يبدأ في", + "youAreOutOfContest": "أنت خارج المسابقة.", + "winners": "الفائزين!!!", + "noUpcoming": "لا يوجد قادم", + "fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية", + "noWinner": "حزين! لم يفز أحد اليوم.", + "myTeam": "فريقي", + "youCanPlayDemo": "لكن يمكنك لعب العرض" +}; +static const Map en_US = { + "mohemm": "Mohemm", + "english": "English", + "arabic": "عربي", + "login": "Login", + "pleaseEnterLoginDetails": "Please enter the detail below to login", + "username": "Username", + "password": "Password", + "welcomeBack": "Welcome back", + "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", + "lastLoginDetails": "Last Login Details:", + "verificationType": "Verification Type:", + "pleaseVerify": "Please Verify", + "pleaseVerifyForBio": "Please verify login with one of the following options", + "verifyThroughFace": "Verify Through Face", + "verifyThroughFingerprint": "Verify Through Fingerprint", + "verifyThroughSMS": "Verify Through SMS", + "verifyThroughWhatsapp": "Verify Through Whatsapp", + "useAnotherAccount": "Use Another Account", + "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", + "theVerificationCodeWillExpireIn": "The verification code will expire in ", + "goodMorning": "Good Morning", + "markAttendance": "Mark Attendance", + "timeLeftToday": "Time Left Today", + "checkIn": "Check In", + "workList": "Work List", + "leaveBalance": "Leave Balance", + "missingSwipes": "Missing Swipes", + "ticketBalance": "Ticket Balance", + "other": "Other", + "services": "Services", + "viewAllServices": "View All Services", + "monthlyAttendance": "Monthly Attendance", + "vacationRule": "Vacation Rule", + "vacationType": "Vacation Type", + "startDateT": "Start Date", + "endDateT": "End Date", + "workFromHome": "Work From Home", + "ticketRequest": "Ticket Request", + "viewAllOffers": "View All Offers", + "offers": "Offers & ", + "discounts": "Discounts", + "newString": "New", + "setTheNewPassword": "Set the new password", + "typeYourNewPasswordBelow": "Type your new password below", + "confirmPassword": "Confirm Password", + "update": "Update", + "title": "Title", + "home": "Home", + "mySalary": "My Salary", + "createRequest": "Create Request", + "forgotPassword": "Forgot Password", + "employeeId": "Employee ID", + "loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number", + "changePassword": "Change Password", + "ok": "OK", + "confirm": "Confirm", + "passwordChangedSuccessfully": "Password changed successfully", + "itemsForSale": "Items for Sale", + "attendanceDetails": "Attendance Details", + "order": "order", + "earlyOut": "Early Out", + "shortage": "Shortage", + "excess": "Excess", + "lateIn": "Late In", + "approvedCheckOut": "Approved Check Out", + "approvedCheckIn": "Approved Check In", + "actualCheckOut": "Actual Check Out", + "actualCheckIn": "Actual Check In", + "present": "PRESENT", + "pres": "present", + "shiftTime": "Shift Time", + "absent": "ABSENT", + "attendance": "Attendance", + "scheduleDays": "Schedule\nDays", + "offDays": "Off\nDays", + "nonAnalyzed": "Non\nAnalyzed", + "shortageHour": "Shortage\nHour", + "stats": "Stats", + "completed": "Completed", + "doNotUseRecentPassword": "Do not use recent password", + "atLeastOneLowercase": "At least one lowercase", + "atLeastOneUppercase": "At least one uppercase", + "atLeastOneNumeric": "At least one numeric", + "minimum8Characters": "Minimum 8 characters", + "doNotAddRepeatingLetters": "Do not add repeating letters", + "itShouldContainSpecialCharacter": "It should contain special character", + "confirmPasswordMustMatch": "Confirm password must match", + "sms": "SMS", + "fingerPrint": "Fingerprint", + "face": "Face", + "whatsapp": "Whatsapp", + "reject": "Reject", + "approve": "Approve", + "cancel": "Cancel", + "requestedItems": "Requested Items", + "request": "Request", + "myRequest": "My Request", + "actions": "Actions", + "delegate": "Delegate", + "request_info": "Request Info", + "attachments": "Attachments", + "info": "Info.", + "employeeNumber": "Employee Number", + "assignmentNumber": "Assignment Number", + "employeeName": "Employee Name", + "scheduleDate": "Schedule Date", + "shiftType": "Shift Type", + "shift": "Shift", + "breakText": "Break", + "actualSwipeStart": "Actual Swipe Start", + "actualSwipeEnd": "Actual Swipe End", + "approvedSwipeStart": "Approved Swipe Start", + "approvedSwipeStartReason": "Approved Swipe Start Reason", + "approvedSwipeEnd": "Approved Swipe End", + "approvedSwipeEndReason": "Approved Swipe End Reason", + "from": "From", + "to": "To", + "sent": "Sent", + "closed": "Closed", + "id": "ID", + "responder": "Responder", + "jobTitle": "Job Title", + "grade": "Grade", + "jobCategory": "Job Category", + "category": "Category", + "employeeEmailAddress": "Employee Email Address", + "payrollBranch": "Payroll Branch", + "yourChangeHasBeenSavedSuccessfully": "Your change has been saved successfully", + "code": "Code", + "unit": "Unit", + "quantity": "Quantity", + "dateRequired": "Date Required", + "lineStatus": "Line Status", + "statusDate": "Status Date", + "transactionType": "Transaction Type", + "operatingUnit": "Operating Unit", + "organizationCode": "Organization Code", + "organization": "Organization", + "fromSubInventory": "From Sub Inventory", + "fromLocator": "From Locator", + "toSubInventory": "To Sub Inventory", + "toLocator": "To Locator", + "shipToLocator": "Ship To Locator", + "itemHistory": "Item History", + "mfg": "MFG", + "lineType": "Line Type", + "price": "Price", + "lineAmount": "Line Amount", + "lineDiscount": "Line Discount %", + "needByDate": "Need By Date", + "promisedDate": "Promised Date", + "deliverToLocation": "Deliver To Location", + "requisitionNumber": "Requisition Number", + "requester": "Requester", + "subject": "Subject", + "quotationAnalysis": "Quotation Analysis", + "description": "Description", + "supplier": "Supplier", + "site": "Site", + "buyer": "Buyer", + "preparer": "Preparer", + "creationDate": "Creation Date", + "shipToLocation": "Ship To Location", + "quotationNumber": "Quotation Number", + "quotationDate": "Quotation Date", + "paymentTerms": "Payment Terms", + "currency": "Currency", + "grossAmount": "Gross Amount", + "discountAmount": "Discount Amount", + "customDuty": "Custom Duty", + "shipHandle": "Ship Handle", + "otherCharges": "Other Charges", + "totalPOAmountWithVAT": "Total PO Amount With VAT", + "totalPOAmountInWords": "Total PO Amount In Words", + "requestNumber": "Request Number", + "uom": "UOM", + "operatingCode": "Operating Code", + "poNumber": "PO Number", + "revision": "Revision", + "quantityOrdered": "Quantity Ordered", + "quantityReceived": "Quantity Received", + "bonusQuantity": "Bonus Quantity", + "purchasePrice": "Purchase Price", + "discountPer": "Discount %", + "balanceQuantity": "Balance Quantity", + "netPrice": "Net Price", + "closureStatus": "Closure Status", + "quotationNetPrice": "Quotation Net Price", + "quotationUOM": "Quotation UOM", + "quotationQty": "Quotation Qty", + "itemCode": "item Code", + "vendorName": "Vendor Name", + "quotationMFGPartNumber": "Quotation MFG Part Number", + "quotationDeliveryDate": "Quotation Delivery Date", + "quotationBonusQuantity": "Quotation Bonus Quantity", + "quotationLineTotal": "Quotation Line Total", + "rfqUOM": "RFQ UOM", + "rfqQty": "RFQ Qty", + "rfqNumber": "RFQ Number", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "Click me", + "human": "Human", + "resources": "Resources", + "details": "Details", + "noDataAvailable": "No Data Available", + "productName": "Product Name", + "productDescription": "Product Description", + "unitPrice": "Unit Price", + "manufacturerName": "Manufacturer Name", + "manufacturerPartName": "Manufacturer Part Name", + "supplierName": "Supplier Name", + "supplierContact": "Supplier Contact", + "chargeToPatient": "Charge To Patient", + "justification": "Justification", + "itemDescription": "Item Description", + "groupCode": "Group Code", + "primaryUOM": "Primary UOM", + "subgroupDescription": "Subgroup Description", + "subgroupCode": "Subgroup Code", + "groupDescription": "Group Description", + "templateName": "Template Name", + "itemCreationStatus": "Item Creation Status", + "standardizationApprovalStatus": "Standardization Approval Status", + "standardizationApprovalRejectionReason": "Standardization Approval Rejection Reason", + "analyzedBy": "Analyzed By", + "approvedDate": "Approved Date", + "itemType": "Item Type", + "relatedTo": "Related To", + "requestDate": "Request Date", + "analyzedDate": "Analyzed Date", + "urgent": "Urgent", + "requestDetails": "Request Details", + "approvalLevel": "Approval Level", + "requesterDetails": "Requester Details", + "myAttendance": "My Attendance", + "workOnBreak": "Work On Break", + "next": "Next", + "apply": "Apply", + "mobile": "Mobile", + "year": "Year", + "month": "Month", + "day": "Day", + "completingYear": "We appreciate you for completing the service of", + "address": "Address", + "phoneNumber": "Phone Number", + "businessGroup": "Business", + "Payroll": "Payroll", + "civilIdentityNumber": "Civil Identity Number", + "dateOfBirth": "Date of Birth", + "maritalStatus ": "Marital Status ", + "fullName": "Full Name", + "remove": "Remove", + "Attendance": "Attendance", + "submit": "Submit", + "areYouSureYouWantToSubmit": "Are you sure you want to submit?", + "comments": "Comments", + "writeComment": "Write a comment", + "approversList": "Approvers List", + "yourRequestHasBeenSubmittedForApprovals": "Your request has been submitted for approvals", + "monthlyPaySlip": "Monthly Pay Slip", + "particular": "Particular", + "earnings": "Earnings", + "deductions": "Deductions", + "paymentMethodName": "Payment Method Name", + "bankName": "Bank Name", + "branchCode": "Branch Code", + "accountNo": "Account No", + "summaryOfInformation": "Summary of Information", + "totalPayAmount": "Total Pay Amount", + "paymentInformation": "Payment Information", + "amount": "Amount", + "correctCurrentDatails": "correct or complete the current details", + "selectType": "Select the type of change you want to make", + "enterNewInfo": "Enter new Information because of a real change to the current details (e.g because of a change in marital status)", + "endDate": "*End Date", + "removeThisMember": "Are You Sure You Want to Remove this Member?", + "wantUpdateThisMember": "Are You Sure You Want to Update this Member?", + "addNewFamilyMember": "Add New Family Member", + "addRow": "Add new row", + "pleaseSelect": "Please Select *", + "delete": "delete", + "add": "Add", + "edit": "Edit", + "myProfile": "My Profile", + "mowadhafhi": "Mowadhafi", + "searchAnnouncements": "Search Announcements", + "announcements": "Announcements", + "swipeRequest": "Swipe Request", + "serviceType": "Service Type", + "departmentName": "Department Name", + "selectDepartment": "Select Department", + "relatedSection": "Related Section", + "selectSection": "Select Section", + "relatedTopic": "Related Topic", + "selectTopic": "Select Topic", + "supportingDocument": "Supporting Document", + "mowadhafhiRequest": "Mowadhafi Request", + "ticketReference": "Ticket Reference", + "section": "Section", + "topic": "Topic", + "actionBy": "Action By", + "pendingTransactions": "Pending Transactions", + "selectRequestType": "Please select request type", + "dateFrom": "Date From", + "dateTo": "Date To", + "requestName": "Request Name", + "createdFor": "Created For", + "requestType": "Request Type", + "requestCreatedSuccessfully": "Request created successfully", + "search": "Search", + "wantToReject": "Are you sure want to reject?", + "employeeDigitalID": "Employee Digital ID", + "businessCard": "Business Card", + "checkOut": "Check Out", + "regular": "Regular", + "mark": "Mark", + "performance": "Performance Evaluation", + "performanceEvaluationIn": "Your performance Evaluation in", + "valuationIn": "Performance Evaluation in", + "viewBusinessCard": "View Business Card", + "performanceEvaluation": "Performance Evaluation", + "logout": "Logout", + "selectMethodOfAttendance": "Select the method to mark the attendance", + "comeNearHMGWifi": "Please come near to HMG wifi", + "deliverNotificationToMeRegardless": "Deliver notifications to me regardless of any general rules", + "close": "Close", + "respond": "Respond", + "vacationRuleAdded": "Vacation rule added", + "selectTypeT": "Select Type", + "notification": "Notification", + "selectNotification": "Select Notification", + "ifAllSelectedYouWillSkip": "*If All is selected, you will skip to step 3", + "applyForVacationRule": "Apply for Vacation Rule", + "step1": "Step 1", + "step2": "Step 2", + "step3": "Step 3", + "message": "Message", + "writeAMessage": "Write a message", + "notificationReassign": "Notification Reassign", + "selectEmployee": "Select Employee", + "searchEmployeeForReplacement": "Search employee for replacement", + "searchForEmployee": "Search for Employee", + "pleaseSpecifyEndTime": "Please specify End Time", + "pleaseSelectNotificationReassign": "Please select notification reassign", + "pleaseSelectEmployeeForReplacement": "Please select employee for replacement", + "pleaseSelectAction": "Please select action", + "pleaseSelectDate": "Please select date", + "todayAttendance": "Today's Attendance", + "viewAttendance": "View Attendance", + "teamMembers": "Team Members", + "profileDetails": "Profile Details", + "noResultsFound": "No Results Found", + "searchBy": "Search by", + "myTeamMembers": "My Team Members", + "save": "Save", + "TurnNotificationsFor": "Turn on notifications for", + "worklistSettings": "Worklist Settings", + "absenceType": "Absence Type", + "absenceCategory": "Absence Category", + "days": "Days", + "hours": "Hours", + "approvalStatus": "Approval Status", + "absenceStatus": "Absence Status", + "poweredBy": "Powered By", + "cloudSolutions": "Cloud Solutions", + "subordinateLeave": "Subordinate Leave", + "numberDays": "Number of days", + "selectTemplate": "Select Template", + "myPostedAds": "My posted ads", + "browseCategories": "Browse Categories", + "searchItems": "Search Items", + "offerAndDiscounts": "Offer & Discounts", + "offerValid": "Offer Valid", + "offerExpired": "Offer Expired", + "whatAreYouOffering": "What are you offering?", + "selectCategory": "Select Category", + "inProgress": "InProgress", + "locked": "Locked", + "addDetails": "Add Details", + "reviewAndSell": "Review & Sell", + "itemTitle": "Item Title", + "itemCondition": "Item Condition", + "used": "Used", + "region": "Region", + "selectRegion": "Select Region", + "itemPrice": "Item Price", + "itemPhotos": "Item Photos", + "itemInfo": "Item Info", + "uploadAttachment": "Upload Attachment", + "selectFromGalleryOrOpenCamera": "Select from gallery or open camera", + "openCamera": "Open\nCamera", + "uploadFromGallery": "Upload from\nGallery", + "name": "Name", + "email": "Email", + "noHistoryAvailable": "No History Available", + "purchaseRequisition": "Purchase Requisition", + "moveOrder": "Move Order", + "humanResource": "Human Resource", + "purchaseOrder": "Purchase Order", + "ITGForms": "ITG Forms", + "itemCreation": "Item Creation", + "stamp": "Stamp", + "addFavoriteList": "Do you want to add {name} in your favorite list", + "feedbackUserExperience": "This is to get the feedback about the user experience", + "rateUI": "1. How would you rate this UI?", + "submitSurvey": "Submit Survey", + "typeHere": "Type here", + "infoDetail": "Info Detail", + "amount_detail": "Amount Detail", + "currentBalance": "Current Balance", + "currentLeaveBalance": "Current Leave Balance", + "calculatedDays": "Calculated Days", + "totalDays": "Total Days", + "usedBalance": "Used", + "infants": "Infants", + "child": "Child", + "adult": "Adult", + "updateMember": "Are You Sure You Want to Update this Member?", + "fieldIsEmpty": "'{data}' Field is empty. Please select", + "pleaseEnterComments": "Please enter comments", + "skip": "Skip", + "typeCurrentPasswordBelow": "Type Your Current password below", + "currentPassword": "Current password", + "concurrentReports": "Concurrent Reports", + "EnterNewAddressMoved": "Enter a new address if you have moved", + "CorrectAddress": "Correct or amend this address", + "SelectChangeWantToMake": "Select the type of change you want to make", + "profile": { + "reset_password": { + "label": "Reset Password", + "username": "Username", + "password": "password" }, - "reset_locale": "إعادة ضبط اللغة", - "chat": "دردشة", - "mychats": "دردشاتي", - "advancedSearch": "بحث متقدم", - "openNot": "التبليغات المفتوحة", - "fyi": "تبليغات للعلم", - "toDo": "تبليغات الأعمال", - "all": "كل التبليغات", - "meNot": "تبليغات صادرة مني", - "view": "عرض", - "fromUserName": "من", - "sentDate": "تاريخ الإرسال", - "itemTypeDisplayName": "اسم العرض", - "none": "بدون", - "createNewChat": "إنشاء محادثة جديدة", - "brainMarathon": "ماراثون الدماغ", - "contestTopicAbout": "سيكون موضوع المسابقة حول:", - "gameDate": "تاريخ اللعبة:", - "gameTime": "وقت اللعب:", - "joinMarathon": "انضم إلى ماراثون", - "joinDemoMarathon": "انضم إلى الماراثون التجريبي", - "demo":"تجريبي", - "minutes": "الدقائق", - "seconds": "ثواني", - "note": "ملحوظة:", - "demoMarathonNoteP1": "يمكنك لعب ماراثون العرض لتتعلم كيف يعمل. يمكنك الانضمام إلى ماراثون", - "demoMarathonNoteP2": "خمس دقائق", - "demoMarathonNoteP3": "قبل الوقت الفعلي.", - "sponsoredBy": "برعاية:", - "question": "سؤال", - "marathoners": "الماراثون", - "marathoner": "ماراثونر", - "prize": "جائزة:", - "winnerSelection": "اختيار الفائز", - "qualifiers": "تصفيات", - "qualifier": "المؤهل", - "getReadyForContest": "استعد للمسابقة القادمة:", - "winnerSelectedRandomly": "سيتم اختيار الفائز عشوائياً من بين التصفيات.", - "fingersCrossed": "تشابك الاصابع!!!", - "congrats": "مبروك !!!", - "allQuestionsCorrect": "لقد أجبت على جميع الأسئلة بشكل صحيح.", - "otp": "OTP", - "verification": "تَحَقّق", - "resend": "إعادة إرسال", - "codeExpire": "انتهت صلاحية رمز التحقق", - "typeheretoreply": "اكتب هنا للرد", - "favorite": "مفضلتي", - "searchfromchat": "البحث من الدردشة", - "yourAnswerCorrect": "إجابتك صحيحة", - "youMissedTheQuestion": "نفد منك الوقت. أنت خارج اللعبة. لكن يمكنك الاستمرار وكمشاهد.", - "wrongAnswer": "إجابتك غير صحيحة. أنت خارج اللعبة. لكن يمكنك الاستمرار وكمشاهد.", - "oops": "أوه!!!", - "winner": "الفائز", - "youWantToLeaveMarathon": "هل أنت متأكد أنك تريد العودة؟ سوف تخرج من المسابقة.", - "ourSponsor": "راعينا:", - "startingIn": "يبدأ في", - "youAreOutOfContest": "أنت خارج المسابقة.", - "winners": "الفائزين!!!", - "noUpcoming": "لا يوجد قادم", - "fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية", - "noWinner": "حزين! لم يفز أحد اليوم.", - "youCanPlayDemo": "لكن يمكنك لعب العرض" - }; - static const Map en_US = { - "mohemm": "Mohemm", - "english": "English", - "arabic": "عربي", - "login": "Login", - "pleaseEnterLoginDetails": "Please enter the detail below to login", - "username": "Username", - "password": "Password", - "welcomeBack": "Welcome back", - "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", - "lastLoginDetails": "Last Login Details:", - "verificationType": "Verification Type:", - "pleaseVerify": "Please Verify", - "pleaseVerifyForBio": "Please verify login with one of the following options", - "verifyThroughFace": "Verify Through Face", - "verifyThroughFingerprint": "Verify Through Fingerprint", - "verifyThroughSMS": "Verify Through SMS", - "verifyThroughWhatsapp": "Verify Through Whatsapp", - "useAnotherAccount": "Use Another Account", - "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", - "theVerificationCodeWillExpireIn": "The verification code will expire in ", - "goodMorning": "Good Morning", - "markAttendance": "Mark Attendance", - "timeLeftToday": "Time Left Today", - "checkIn": "Check In", - "workList": "Work List", - "leaveBalance": "Leave Balance", - "missingSwipes": "Missing Swipes", - "ticketBalance": "Ticket Balance", - "other": "Other", - "services": "Services", - "viewAllServices": "View All Services", - "monthlyAttendance": "Monthly Attendance", - "vacationRule": "Vacation Rule", - "vacationType": "Vacation Type", - "startDateT": "Start Date", - "endDateT": "End Date", - "workFromHome": "Work From Home", - "ticketRequest": "Ticket Request", - "viewAllOffers": "View All Offers", - "offers": "Offers & ", - "discounts": "Discounts", - "newString": "New", - "setTheNewPassword": "Set the new password", - "typeYourNewPasswordBelow": "Type your new password below", - "confirmPassword": "Confirm Password", - "update": "Update", - "title": "Title", - "home": "Home", - "mySalary": "My Salary", - "createRequest": "Create Request", - "forgotPassword": "Forgot Password", - "employeeId": "Employee ID", - "loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number", - "changePassword": "Change Password", - "ok": "OK", - "confirm": "Confirm", - "passwordChangedSuccessfully": "Password changed successfully", - "itemsForSale": "Items for Sale", - "attendanceDetails": "Attendance Details", - "order": "order", - "earlyOut": "Early Out", - "shortage": "Shortage", - "excess": "Excess", - "lateIn": "Late In", - "approvedCheckOut": "Approved Check Out", - "approvedCheckIn": "Approved Check In", - "actualCheckOut": "Actual Check Out", - "actualCheckIn": "Actual Check In", - "present": "PRESENT", - "pres": "present", - "shiftTime": "Shift Time", - "absent": "ABSENT", - "attendance": "Attendance", - "scheduleDays": "Schedule\nDays", - "offDays": "Off\nDays", - "nonAnalyzed": "Non\nAnalyzed", - "shortageHour": "Shortage\nHour", - "stats": "Stats", - "completed": "Completed", - "doNotUseRecentPassword": "Do not use recent password", - "atLeastOneLowercase": "At least one lowercase", - "atLeastOneUppercase": "At least one uppercase", - "atLeastOneNumeric": "At least one numeric", - "minimum8Characters": "Minimum 8 characters", - "doNotAddRepeatingLetters": "Do not add repeating letters", - "itShouldContainSpecialCharacter": "It should contain special character", - "confirmPasswordMustMatch": "Confirm password must match", - "sms": "SMS", - "fingerPrint": "Fingerprint", - "face": "Face", - "whatsapp": "Whatsapp", - "reject": "Reject", - "approve": "Approve", - "cancel": "Cancel", - "requestedItems": "Requested Items", - "request": "Request", - "myRequest": "My Request", - "actions": "Actions", - "delegate": "Delegate", - "request_info": "Request Info", - "attachments": "Attachments", - "info": "Info.", - "employeeNumber": "Employee Number", - "assignmentNumber": "Assignment Number", - "employeeName": "Employee Name", - "scheduleDate": "Schedule Date", - "shiftType": "Shift Type", - "shift": "Shift", - "breakText": "Break", - "actualSwipeStart": "Actual Swipe Start", - "actualSwipeEnd": "Actual Swipe End", - "approvedSwipeStart": "Approved Swipe Start", - "approvedSwipeStartReason": "Approved Swipe Start Reason", - "approvedSwipeEnd": "Approved Swipe End", - "approvedSwipeEndReason": "Approved Swipe End Reason", - "from": "From", - "to": "To", - "sent": "Sent", - "closed": "Closed", - "id": "ID", - "responder": "Responder", - "jobTitle": "Job Title", - "grade": "Grade", - "jobCategory": "Job Category", - "category": "Category", - "employeeEmailAddress": "Employee Email Address", - "payrollBranch": "Payroll Branch", - "yourChangeHasBeenSavedSuccessfully": "Your change has been saved successfully", - "code": "Code", - "unit": "Unit", - "quantity": "Quantity", - "dateRequired": "Date Required", - "lineStatus": "Line Status", - "statusDate": "Status Date", - "transactionType": "Transaction Type", - "operatingUnit": "Operating Unit", - "organizationCode": "Organization Code", - "organization": "Organization", - "fromSubInventory": "From Sub Inventory", - "fromLocator": "From Locator", - "toSubInventory": "To Sub Inventory", - "toLocator": "To Locator", - "shipToLocator": "Ship To Locator", - "itemHistory": "Item History", - "mfg": "MFG", - "lineType": "Line Type", - "price": "Price", - "lineAmount": "Line Amount", - "lineDiscount": "Line Discount %", - "needByDate": "Need By Date", - "promisedDate": "Promised Date", - "deliverToLocation": "Deliver To Location", - "requisitionNumber": "Requisition Number", - "requester": "Requester", - "subject": "Subject", - "quotationAnalysis": "Quotation Analysis", - "description": "Description", - "supplier": "Supplier", - "site": "Site", - "buyer": "Buyer", - "preparer": "Preparer", - "creationDate": "Creation Date", - "shipToLocation": "Ship To Location", - "quotationNumber": "Quotation Number", - "quotationDate": "Quotation Date", - "paymentTerms": "Payment Terms", - "currency": "Currency", - "grossAmount": "Gross Amount", - "discountAmount": "Discount Amount", - "customDuty": "Custom Duty", - "shipHandle": "Ship Handle", - "otherCharges": "Other Charges", - "totalPOAmountWithVAT": "Total PO Amount With VAT", - "totalPOAmountInWords": "Total PO Amount In Words", - "requestNumber": "Request Number", - "uom": "UOM", - "operatingCode": "Operating Code", - "poNumber": "PO Number", - "revision": "Revision", - "quantityOrdered": "Quantity Ordered", - "quantityReceived": "Quantity Received", - "bonusQuantity": "Bonus Quantity", - "purchasePrice": "Purchase Price", - "discountPer": "Discount %", - "balanceQuantity": "Balance Quantity", - "netPrice": "Net Price", - "closureStatus": "Closure Status", - "quotationNetPrice": "Quotation Net Price", - "quotationUOM": "Quotation UOM", - "quotationQty": "Quotation Qty", - "itemCode": "item Code", - "vendorName": "Vendor Name", - "quotationMFGPartNumber": "Quotation MFG Part Number", - "quotationDeliveryDate": "Quotation Delivery Date", - "quotationBonusQuantity": "Quotation Bonus Quantity", - "quotationLineTotal": "Quotation Line Total", - "rfqUOM": "RFQ UOM", - "rfqQty": "RFQ Qty", - "rfqNumber": "RFQ Number", - "msg": "Hello {} in the {} world ", - "msg_named": "{} are written in the {lang} language", - "clickMe": "Click me", - "human": "Human", - "resources": "Resources", - "details": "Details", - "noDataAvailable": "No Data Available", - "productName": "Product Name", - "productDescription": "Product Description", - "unitPrice": "Unit Price", - "manufacturerName": "Manufacturer Name", - "manufacturerPartName": "Manufacturer Part Name", - "supplierName": "Supplier Name", - "supplierContact": "Supplier Contact", - "chargeToPatient": "Charge To Patient", - "justification": "Justification", - "itemDescription": "Item Description", - "groupCode": "Group Code", - "primaryUOM": "Primary UOM", - "subgroupDescription": "Subgroup Description", - "subgroupCode": "Subgroup Code", - "groupDescription": "Group Description", - "templateName": "Template Name", - "itemCreationStatus": "Item Creation Status", - "standardizationApprovalStatus": "Standardization Approval Status", - "standardizationApprovalRejectionReason": "Standardization Approval Rejection Reason", - "analyzedBy": "Analyzed By", - "approvedDate": "Approved Date", - "itemType": "Item Type", - "relatedTo": "Related To", - "requestDate": "Request Date", - "analyzedDate": "Analyzed Date", - "urgent": "Urgent", - "requestDetails": "Request Details", - "approvalLevel": "Approval Level", - "requesterDetails": "Requester Details", - "myAttendance": "My Attendance", - "workOnBreak": "Work On Break", - "next": "Next", - "apply": "Apply", - "mobile": "Mobile", - "year": "Year", - "month": "Month", - "day": "Day", - "completingYear": "We appreciate you for completing the service of", + "profileCompletionPer": "Profile Completion", + "completeProfile": "Complete Profile", + "personalInformation": "Personal Information", + "basicDetails": "Basic Details", "address": "Address", - "phoneNumber": "Phone Number", - "businessGroup": "Business", - "Payroll": "Payroll", - "civilIdentityNumber": "Civil Identity Number", - "dateOfBirth": "Date of Birth", - "maritalStatus ": "Marital Status ", - "fullName": "Full Name", - "remove": "Remove", - "Attendance": "Attendance", - "submit": "Submit", - "areYouSureYouWantToSubmit": "Are you sure you want to submit?", - "comments": "Comments", - "writeComment": "Write a comment", - "approversList": "Approvers List", - "yourRequestHasBeenSubmittedForApprovals": "Your request has been submitted for approvals", - "monthlyPaySlip": "Monthly Pay Slip", - "particular": "Particular", - "earnings": "Earnings", - "deductions": "Deductions", - "paymentMethodName": "Payment Method Name", - "bankName": "Bank Name", - "branchCode": "Branch Code", - "accountNo": "Account No", - "summaryOfInformation": "Summary of Information", - "totalPayAmount": "Total Pay Amount", - "paymentInformation": "Payment Information", - "amount": "Amount", - "correctCurrentDatails": "correct or complete the current details", - "selectType": "Select the type of change you want to make", - "enterNewInfo": "Enter new Information because of a real change to the current details (e.g because of a change in marital status)", - "endDate": "*End Date", - "removeThisMember": "Are You Sure You Want to Remove this Member?", - "wantUpdateThisMember": "Are You Sure You Want to Update this Member?", - "addNewFamilyMember": "Add New Family Member", - "addRow": "Add new row", - "pleaseSelect": "Please Select *", - "delete": "delete", - "add": "Add", - "edit": "Edit", - "myProfile": "My Profile", - "mowadhafhi": "Mowadhafi", - "searchAnnouncements": "Search Announcements", - "announcements": "Announcements", - "swipeRequest": "Swipe Request", - "serviceType": "Service Type", - "departmentName": "Department Name", - "selectDepartment": "Select Department", - "relatedSection": "Related Section", - "selectSection": "Select Section", - "relatedTopic": "Related Topic", - "selectTopic": "Select Topic", - "supportingDocument": "Supporting Document", - "mowadhafhiRequest": "Mowadhafi Request", - "ticketReference": "Ticket Reference", - "section": "Section", - "topic": "Topic", - "actionBy": "Action By", - "pendingTransactions": "Pending Transactions", - "selectRequestType": "Please select request type", - "dateFrom": "Date From", - "dateTo": "Date To", - "requestName": "Request Name", - "createdFor": "Created For", - "requestType": "Request Type", - "requestCreatedSuccessfully": "Request created successfully", - "search": "Search", - "wantToReject": "Are you sure want to reject?", - "employeeDigitalID": "Employee Digital ID", - "businessCard": "Business Card", - "checkOut": "Check Out", - "regular": "Regular", - "mark": "Mark", - "performance": "Performance Evaluation", - "performanceEvaluationIn": "Your performance Evaluation in", - "valuationIn": "Performance Evaluation in", - "viewBusinessCard": "View Business Card", - "performanceEvaluation": "Performance Evaluation", - "logout": "Logout", - "selectMethodOfAttendance": "Select the method to mark the attendance", - "comeNearHMGWifi": "Please come near to HMG wifi", - "deliverNotificationToMeRegardless": "Deliver notifications to me regardless of any general rules", - "close": "Close", - "respond": "Respond", - "vacationRuleAdded": "Vacation rule added", - "selectTypeT": "Select Type", - "notification": "Notification", - "selectNotification": "Select Notification", - "ifAllSelectedYouWillSkip": "*If All is selected, you will skip to step 3", - "applyForVacationRule": "Apply for Vacation Rule", - "step1": "Step 1", - "step2": "Step 2", - "step3": "Step 3", - "message": "Message", - "writeAMessage": "Write a message", - "notificationReassign": "Notification Reassign", - "selectEmployee": "Select Employee", - "searchEmployeeForReplacement": "Search employee for replacement", - "searchForEmployee": "Search for Employee", - "pleaseSpecifyEndTime": "Please specify End Time", - "pleaseSelectNotificationReassign": "Please select notification reassign", - "pleaseSelectEmployeeForReplacement": "Please select employee for replacement", - "pleaseSelectAction": "Please select action", - "pleaseSelectDate": "Please select date", - "todayAttendance": "Today's Attendance", - "viewAttendance": "View Attendance", - "teamMembers": "Team Members", - "profileDetails": "Profile Details", - "noResultsFound": "No Results Found", - "searchBy": "Search by", - "myTeamMembers": "My Team Members", - "save": "Save", - "TurnNotificationsFor": "Turn on notifications for", - "worklistSettings": "Worklist Settings", - "absenceType": "Absence Type", - "absenceCategory": "Absence Category", - "days": "Days", - "hours": "Hours", - "approvalStatus": "Approval Status", - "absenceStatus": "Absence Status", - "poweredBy": "Powered By", - "cloudSolutions": "Cloud Solutions", - "subordinateLeave": "Subordinate Leave", - "numberDays": "Number of days", - "selectTemplate": "Select Template", - "myPostedAds": "My posted ads", - "browseCategories": "Browse Categories", - "searchItems": "Search Items", - "offerAndDiscounts": "Offer & Discounts", - "offerValid": "Offer Valid", - "offerExpired": "Offer Expired", - "whatAreYouOffering": "What are you offering?", - "selectCategory": "Select Category", - "inProgress": "InProgress", - "locked": "Locked", - "addDetails": "Add Details", - "reviewAndSell": "Review & Sell", - "itemTitle": "Item Title", - "itemCondition": "Item Condition", - "used": "Used", - "region": "Region", - "selectRegion": "Select Region", - "itemPrice": "Item Price", - "itemPhotos": "Item Photos", - "itemInfo": "Item Info", - "uploadAttachment": "Upload Attachment", - "selectFromGalleryOrOpenCamera": "Select from gallery or open camera", - "openCamera": "Open\nCamera", - "uploadFromGallery": "Upload from\nGallery", - "name": "Name", - "email": "Email", - "noHistoryAvailable": "No History Available", - "purchaseRequisition": "Purchase Requisition", - "moveOrder": "Move Order", - "humanResource": "Human Resource", - "purchaseOrder": "Purchase Order", - "ITGForms": "ITG Forms", - "itemCreation": "Item Creation", - "stamp": "Stamp", - "addFavoriteList": "Do you want to add {name} in your favorite list", - "feedbackUserExperience": "This is to get the feedback about the user experience", - "rateUI": "1. How would you rate this UI?", - "submitSurvey": "Submit Survey", - "typeHere": "Type here", - "infoDetail": "Info Detail", - "amount_detail": "Amount Detail", - "currentBalance": "Current Balance", - "currentLeaveBalance": "Current Leave Balance", - "calculatedDays": "Calculated Days", - "totalDays": "Total Days", - "usedBalance": "Used", - "infants": "Infants", - "child": "Child", - "adult": "Adult", - "updateMember": "Are You Sure You Want to Update this Member?", - "fieldIsEmpty": "'{data}' Field is empty. Please select", - "pleaseEnterComments": "Please enter comments", - "skip": "Skip", - "typeCurrentPasswordBelow": "Type Your Current password below", - "currentPassword": "Current password", - "concurrentReports": "Concurrent Reports", - "EnterNewAddressMoved": "Enter a new address if you have moved", - "CorrectAddress": "Correct or amend this address", - "SelectChangeWantToMake": "Select the type of change you want to make", - "profile": { - "reset_password": {"label": "Reset Password", "username": "Username", "password": "password"}, - "profileCompletionPer": "Profile Completion", - "completeProfile": "Complete Profile", - "personalInformation": "Personal Information", - "basicDetails": "Basic Details", - "address": "Address", - "contactDetails": "Contact Details", - "familyDetails": "Family Members", - "effectiveDate": "Effective Date", - "country": "Country" - }, - "clicked": { - "zero": "You clicked {} times!", - "one": "You clicked {} time!", - "two": "You clicked {} times!", - "few": "You clicked {} times!", - "many": "You clicked {} times!", - "other": "You clicked {} times!" - }, - "gender": { - "male": "Hi man ;) ", - "female": "Hello girl :)", - "with_arg": {"male": "Hi man ;) {}", "female": "Hello girl :) {}"} - }, - "reset_locale": "Reset Language", - "chat": "Chat", - "mychats": "My Chats", - "createNewChat": "Create New Chat", - "brainMarathon": "Brain Marathon", - "contestTopicAbout": "Contest Topic will be about:", - "gameDate": "Game Date:", - "gameTime": "Game Time:", - "joinMarathon": "Join Marathon", - "joinDemoMarathon": "Join Demo Marathon", - "demo":"Demo", - "minutes": "Minutes", - "seconds": "Seconds", - "note": "Note:", - "demoMarathonNoteP1": "You can play the demo_questions_marathon.json Marathon to learn how it works. You can join the Marathon", - "demoMarathonNoteP2": "5 Minutes", - "demoMarathonNoteP3": "before the actual time.", - "sponsoredBy": "Sponsored By:", - "question": "Question", - "marathoners": "Marathoners", - "marathoner": "Marathoner", - "prize": "Prize:", - "advancedSearch": "Advanced Search", - "openNot": "Open Notifications", - "fyi": "FYI Notifications", - "toDo": "To Do Notifications", - "all": "All Notifications", - "meNot": "Notifications from Me", - "view": "View", - "fromUserName": "From User Name", - "sentDate": "Sent Date", - "itemTypeDisplayName": "Item Type Display Name", - "none": "None", - "winnerSelection": "Winner Selection", - "qualifiers": "Qualifiers", - "qualifier": "Qualifier", - "getReadyForContest": "Get Ready for the coming contest:", - "winnerSelectedRandomly": "The winner will be selected randomly among the qualifiers.", - "fingersCrossed": "Fingers Crossed!!!", - "congrats": "Congratulations!!!", - "otp": "OTP", - "verification": "Verification", - "resend": "Resend", - "codeExpire": "The verification code has been expired", - "allQuestionsCorrect": "You have answered all questions correct", - "typeheretoreply": "Type here to reply", - "favorite": "My Favorites", - "searchfromchat": "Search from chat", - "yourAnswerCorrect": "Your answer is correct", - "youMissedTheQuestion": "You ran out of time. You are out of the game. But you can continue as a viewer.", - "wrongAnswer": "Your answer is Incorrect. You are out of the game. But you can continue as a viewer.", - "oops": "Ooopsss!!!!", - "winner": "WINNER", - "youWantToLeaveMarathon": "Are you sure you want to go back? You will be out of the contest.", - "ourSponsor": "Our Sponsor:", - "startingIn": "Starting in", - "youAreOutOfContest": "You are out of the contest.", - "winners": "WINNERS!!!", - "noUpcoming": "There is no upcoming", - "fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.", - "noWinner": "Sad! No one won today.", - "youCanPlayDemo": "But you can play demo" - - }; - static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; + "contactDetails": "Contact Details", + "familyDetails": "Family Members", + "effectiveDate": "Effective Date", + "country": "Country" + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": { + "male": "Hi man ;) {}", + "female": "Hello girl :) {}" + } + }, + "reset_locale": "Reset Language", + "chat": "Chat", + "mychats": "My Chats", + "createNewChat": "Create New Chat", + "brainMarathon": "Brain Marathon", + "contestTopicAbout": "Contest Topic will be about:", + "gameDate": "Game Date:", + "gameTime": "Game Time:", + "joinMarathon": "Join Marathon", + "joinDemoMarathon": "Join Demo Marathon", + "demo": "Demo", + "minutes": "Minutes", + "seconds": "Seconds", + "note": "Note:", + "demoMarathonNoteP1": "You can play the demo Marathon to learn how it works. You can join the Marathon", + "demoMarathonNoteP2": "5 Minutes", + "demoMarathonNoteP3": "before the actual time.", + "sponsoredBy": "Sponsored By:", + "question": "Question", + "marathoners": "Marathoners", + "marathoner": "Marathoner", + "prize": "Prize:", + "advancedSearch": "Advanced Search", + "openNot": "Open Notifications", + "fyi": "FYI Notifications", + "toDo": "To Do Notifications", + "all": "All Notifications", + "meNot": "Notifications from Me", + "view": "View", + "fromUserName": "From User Name", + "sentDate": "Sent Date", + "itemTypeDisplayName": "Item Type Display Name", + "none": "None", + "winnerSelection": "Winner Selection", + "qualifiers": "Qualifiers", + "qualifier": "Qualifier", + "getReadyForContest": "Get Ready for the coming contest:", + "winnerSelectedRandomly": "The winner will be selected randomly among the qualifiers.", + "fingersCrossed": "Fingers Crossed!!!", + "congrats": "Congratulations!!!", + "otp": "OTP", + "verification": "Verification", + "resend": "Resend", + "codeExpire": "The verification code has been expired", + "allQuestionsCorrect": "You have answered all questions correct", + "typeheretoreply": "Type here to reply", + "favorite": "My Favorites", + "searchfromchat": "Search from chat", + "yourAnswerCorrect": "Your answer is correct", + "youMissedTheQuestion": "You ran out of time. You are out of the game. But you can continue as a viewer.", + "wrongAnswer": "Your answer is Incorrect. You are out of the game. But you can continue as a viewer.", + "oops": "Ooopsss!!!!", + "winner": "WINNER", + "youWantToLeaveMarathon": "Are you sure you want to go back? You will be out of the contest.", + "ourSponsor": "Our Sponsor:", + "startingIn": "Starting in", + "youAreOutOfContest": "You are out of the contest.", + "winners": "WINNERS!!!", + "noUpcoming": "There is no upcoming", + "fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.", + "noWinner": "Sad! No one won today.", + "myTeam": "My Team", + "youCanPlayDemo": "But you can play demo" +}; +static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index aa61124..1671b72 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -506,7 +506,7 @@ abstract class LocaleKeys { static const noUpcoming = 'noUpcoming'; static const fakeLocation = 'fakeLocation'; static const noWinner = 'noWinner'; - static const youCanPlayDemo = 'youCanPlayDemo'; static const myTeam = 'myTeam'; + static const youCanPlayDemo = 'youCanPlayDemo'; } diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 98bf976..b4ccb0a 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -6,6 +6,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; @@ -41,7 +42,7 @@ class DashboardScreen extends StatefulWidget { } } -class _DashboardScreenState extends State { +class _DashboardScreenState extends State with WidgetsBindingObserver { late DashboardProviderModel data; late MarathonProvider marathonProvider; late ChatProviderModel cProvider; @@ -53,6 +54,7 @@ class _DashboardScreenState extends State { @override void initState() { + WidgetsBinding.instance.addObserver(this); super.initState(); scheduleMicrotask(() { data = Provider.of(context, listen: false); @@ -63,8 +65,27 @@ class _DashboardScreenState extends State { }); } + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + if (state == AppLifecycleState.resumed) { + checkSession(); + } + } + + void checkSession() async { + try { + Utils.showLoading(context); + await DashboardApiClient().getOpenMissingSwipes(); + Utils.hideLoading(context); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } + @override void dispose() { + WidgetsBinding.instance.removeObserver(this); super.dispose(); chatHubConnection.stop(); } diff --git a/lib/ui/misc/request_submit_screen.dart b/lib/ui/misc/request_submit_screen.dart index 91cd2b1..d1264fd 100644 --- a/lib/ui/misc/request_submit_screen.dart +++ b/lib/ui/misc/request_submit_screen.dart @@ -261,7 +261,7 @@ class _RequestSubmitScreenState extends State { title.toText16().expanded, 6.width, SimpleButton(LocaleKeys.add.tr(), () async { - ImageOptions.showImageOptionsNew(context, false, (String image, File file) { + ImageOptions.showImageOptionsNew(context, true, (String image, File file) { setState(() { attachmentFiles.add(file); attachments.add(image); From dd6627f2162045aa50bbf63a2ebb1af32d4a1da0 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 24 Jan 2023 09:45:50 +0300 Subject: [PATCH 11/11] firebase notification token issue fix. --- lib/classes/notifications.dart | 2 +- lib/ui/login/login_screen.dart | 2 +- pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index b7d7988..336b87c 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -37,7 +37,7 @@ class AppNotifications { void initNotification(String? firebaseToken) async { // await requestPermissions(); - AppState().deviceNotificationToken = firebaseToken; + AppState().setDeviceToken = firebaseToken; // await Permission.notification.isDenied.then((value) { // if (value) { // Permission.notification.request(); diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 6253002..1c10bb6 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -112,7 +112,7 @@ class _LoginScreenState extends State { } } catch (ex) { Utils.hideLoading(context); - Utils.handleException(ex, context, (errorMsg) {}); + Utils.handleException(ex, context, null); } } diff --git a/pubspec.yaml b/pubspec.yaml index 189128d..f8748e6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -49,7 +49,7 @@ dependencies: flutter_calendar_carousel: ^2.1.0 pie_chart: ^5.1.0 shared_preferences: ^2.0.12 - firebase_messaging: ^11.2.8 + firebase_messaging: ^13.0.4 shimmer: ^2.0.0 logger: ^1.1.0 flutter_countdown_timer: ^4.1.0