diff --git a/android/app/agconnect-services.json b/android/app/agconnect-services.json
new file mode 100644
index 0000000..20a7546
--- /dev/null
+++ b/android/app/agconnect-services.json
@@ -0,0 +1,57 @@
+{
+ "agcgw_all":{
+ "CN":"connect-drcn.dbankcloud.cn",
+ "CN_back":"connect-drcn.hispace.hicloud.com",
+ "DE":"connect-dre.dbankcloud.cn",
+ "DE_back":"connect-dre.hispace.hicloud.com",
+ "RU":"connect-drru.hispace.dbankcloud.ru",
+ "RU_back":"connect-drru.hispace.dbankcloud.cn",
+ "SG":"connect-dra.dbankcloud.cn",
+ "SG_back":"connect-dra.hispace.hicloud.com"
+ },
+ "websocketgw_all":{
+ "CN":"connect-ws-drcn.hispace.dbankcloud.cn",
+ "CN_back":"connect-ws-drcn.hispace.dbankcloud.com",
+ "DE":"connect-ws-dre.hispace.dbankcloud.cn",
+ "DE_back":"connect-ws-dre.hispace.dbankcloud.com",
+ "RU":"connect-ws-drru.hispace.dbankcloud.ru",
+ "RU_back":"connect-ws-drru.hispace.dbankcloud.cn",
+ "SG":"connect-ws-dra.hispace.dbankcloud.cn",
+ "SG_back":"connect-ws-dra.hispace.dbankcloud.com"
+ },
+ "client":{
+ "cp_id":"2640966000002322881",
+ "product_id":"737518067793559971",
+ "client_id":"715996003571874624",
+ "client_secret":"B5B89A56A53847C6BB9D216A8747E75952760DF9A8232239D8744CD847A8FFDA",
+ "project_id":"737518067793559971",
+ "app_id":"104737117",
+ "api_key":"DAEDACKDrYgyco9mjPV9ZUjCSh1kCr/GBV0nseHH0z2mnxlZ41RksOKmyTi+PUTwmGEPK+VxCup4F9oUf4VbDnCsjB7aNBShYcjR+g==",
+ "package_name":"hmg.cloudSolutions.mohem"
+ },
+ "oauth_client":{
+ "client_id":"104737117",
+ "client_type":1
+ },
+ "app_info":{
+ "app_id":"104737117",
+ "package_name":"hmg.cloudSolutions.mohem"
+ },
+ "configuration_version":"3.0",
+ "appInfos":[
+ {
+ "package_name":"hmg.cloudSolutions.mohem",
+ "client":{
+ "app_id":"104737117"
+ },
+ "app_info":{
+ "package_name":"hmg.cloudSolutions.mohem",
+ "app_id":"104737117"
+ },
+ "oauth_client":{
+ "client_type":1,
+ "client_id":"104737117"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 198bc87..80eb644 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -31,6 +31,7 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+apply plugin: 'com.huawei.agconnect'
android {
compileSdkVersion 33
@@ -58,6 +59,12 @@ android {
}
signingConfigs {
+// debug {
+// keyAlias keystoreProperties['keyAlias']
+// keyPassword keystoreProperties['keyPassword']
+// storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
+// storePassword keystoreProperties['storePassword']
+// }
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
@@ -68,6 +75,9 @@ android {
buildTypes {
release {
signingConfig signingConfigs.release
+ minifyEnabled true
+ shrinkResources true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index f187ebd..5b3b2ba 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -7,7 +7,15 @@
-
+
+
+
+
+
+
+
+
+
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+ NSAllowsArbitraryLoadsForMedia
+
+ NSAllowsArbitraryLoadsInWebContent
+
+
CADisableMinimumFrameDurationOnPhone
CFBundleDevelopmentRegion
@@ -33,7 +42,7 @@
NFCReaderUsageDescription
This App requires access to NFC to mark your attendance.
NSCameraUsageDescription
- This app requires camera access to capture & upload pictures.
+ This app requires camera access to capture & upload picture as profile image.
NSFaceIDUsageDescription
This app requires Face ID to allow biometric authentication for app login.
NSLocationAlwaysAndWhenInUseUsageDescription
@@ -46,15 +55,13 @@
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
- fetch
+ fetch
remote-notification
FirebaseAppDelegateProxyEnabled
-
+
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
@@ -80,14 +87,9 @@
ITSAppUsesNonExemptEncryption
-
com.apple.developer.nfc.readersession.formats
TAG
- com.apple.developer.nfc.readersession.felica.systemcodes
-
- 0000
-
diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart
index ea7b85e..32d713c 100644
--- a/lib/app_state/app_state.dart
+++ b/lib/app_state/app_state.dart
@@ -1,7 +1,6 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
-import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart';
import 'package:mohem_flutter_app/models/itg_forms_models/request_detail_model.dart';
import 'package:mohem_flutter_app/models/member_information_list_model.dart';
@@ -77,7 +76,19 @@ class AppState {
bool get getIsDemoMarathon => _isDemoMarathon;
- final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.0, mobileType: Platform.isAndroid ? "android" : "ios");
+ bool _isHuawei = false;
+
+ set setIsHuawei(bool value) => _isHuawei = value;
+
+ bool get getIsHuawei => _isHuawei;
+
+ String _huaweiPushToken = "";
+
+ set setHuaweiPushToken(String value) => _huaweiPushToken = value;
+
+ String get getHuaweiPushToken => _huaweiPushToken;
+
+ final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.1, mobileType: Platform.isAndroid ? "android" : "ios");
void setPostParamsInitConfig() {
isAuthenticated = false;
@@ -180,5 +191,4 @@ class AppState {
}
bool cancelRequestTrancsection = true;
-
}
diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart
index 96fd4b0..7740624 100644
--- a/lib/classes/consts.dart
+++ b/lib/classes/consts.dart
@@ -1,12 +1,10 @@
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://uathrmsys.moenergy.gov.sa"; //MOE UAT
+ // static String baseUrl = "https://hrmsys.moenergy.gov.sa"; // MOE ;LIVE
+
static String baseUrlServices = baseUrl + "/Services/"; // server
- // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/";
static String erpRest = baseUrlServices + "ERP.svc/REST/";
static String swpRest = baseUrlServices + "SWP.svc/REST/";
diff --git a/lib/classes/date_uitl.dart b/lib/classes/date_uitl.dart
index 3cae1cd..89e237d 100644
--- a/lib/classes/date_uitl.dart
+++ b/lib/classes/date_uitl.dart
@@ -60,13 +60,13 @@ class DateUtil {
}
}
date = date + " $hours:$mins:$secs";
- DateTime returnDate = DateFormat("MM/dd/yyyy HH:mm:ss").parse(date);
+ DateTime returnDate = DateFormat("MM/dd/yyyy HH:mm:ss", "en_US").parse(date);
return returnDate;
}
static DateTime convertSimpleStringDateToDateddMMyyyy(String date) {
- return DateFormat("MM/dd/yyyy hh:mm:ss").parse(date);
+ return DateFormat("MM/dd/yyyy hh:mm:ss", "en_US").parse(date);
}
static DateTime convertStringToDateNoTimeZone(String date) {
@@ -123,7 +123,7 @@ class DateUtil {
}
static String formatDateToTime(DateTime date) {
- return DateFormat('hh:mm a').format(date);
+ return DateFormat('hh:mm a', "en_US").format(date);
}
static String yearMonthDay(DateTime dateTime) {
@@ -419,7 +419,7 @@ class DateUtil {
/// [dateTime] convert DateTime to data formatted
static String getDayMonthDateFormatted(DateTime dateTime) {
if (dateTime != null)
- return DateFormat('dd/MM').format(dateTime);
+ return DateFormat('dd/MM', "en_US").format(dateTime);
else
return "";
}
@@ -466,7 +466,7 @@ class DateUtil {
/// [dateTime] convert DateTime to data formatted
static String getDayMonthYearHourMinuteDateFormatted(DateTime dateTime) {
if (dateTime != null)
- return dateTime.day.toString() + "/" + dateTime.month.toString() + "/" + dateTime.year.toString() + " " + DateFormat('HH:mm').format(dateTime);
+ return dateTime.day.toString() + "/" + dateTime.month.toString() + "/" + dateTime.year.toString() + " " + DateFormat('HH:mm', "en_US").format(dateTime);
else
return "";
}
@@ -491,11 +491,11 @@ class DateUtil {
}
static String getFormattedDate(DateTime dateTime, String formattedString) {
- return DateFormat(formattedString).format(dateTime);
+ return DateFormat(formattedString, "en_US").format(dateTime);
}
static String convertISODateToJsonDate(String isoDate) {
- return "/Date(" + DateFormat('mm-dd-yyy').parse(isoDate).millisecondsSinceEpoch.toString() + ")/";
+ return "/Date(" + DateFormat('mm-dd-yyy', "en_US").parse(isoDate).millisecondsSinceEpoch.toString() + ")/";
}
// static String getDay(DayOfWeek dayOfWeek) {
diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart
index 0773575..2d46642 100644
--- a/lib/classes/notifications.dart
+++ b/lib/classes/notifications.dart
@@ -1,13 +1,14 @@
-import 'dart:convert';
import 'dart:io';
+
+import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
+import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
+import 'package:huawei_push/huawei_push.dart' as huawei_push;
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
-import 'package:mohem_flutter_app/main.dart';
import 'package:permission_handler/permission_handler.dart';
-import 'package:firebase_core/firebase_core.dart';
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
@@ -18,6 +19,10 @@ class AppNotifications {
factory AppNotifications() => _instance;
+ late HmsApiAvailability hmsApiAvailability;
+
+ String _huaweiToken = '';
+
Future requestPermissions() async {
if (Platform.isIOS) {
await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true);
@@ -35,6 +40,7 @@ class AppNotifications {
}
void init(String? firebaseToken) async {
+ hmsApiAvailability = HmsApiAvailability();
await requestPermissions();
AppState().setDeviceToken = firebaseToken;
await Permission.notification.isDenied.then((bool value) {
@@ -57,6 +63,48 @@ class AppNotifications {
FirebaseMessaging.instance.onTokenRefresh.listen((String token) {
AppState().setDeviceToken = token;
});
+
+ if (Platform.isAndroid) {
+ await hmsApiAvailability.isHMSAvailable().then((value) async {
+ if (value == 0) {
+ huawei_push.Push.enableLogger();
+ var result = await huawei_push.Push.setAutoInitEnabled(true);
+
+ huawei_push.Push.onNotificationOpenedApp.listen((message) {
+ // newMessage(toFirebaseRemoteMessage(message));
+ }, onError: (e) => print(e.toString()));
+
+ huawei_push.Push.onMessageReceivedStream.listen((message) {
+ // newMessage(toFirebaseRemoteMessage(message));
+ }, onError: (e) => print(e.toString()));
+ }
+ }).catchError((err) {
+ print(err);
+ });
+ }
+ }
+
+ void initHuaweiPush(Function loginCallback) {
+ AppState().setIsHuawei = true;
+ initTokenStream(loginCallback);
+ huawei_push.Push.getToken("");
+ }
+
+ // HUAWEI PUSH TOKEN IMPLEMENTATION
+ void _onTokenEvent(String event) {
+ _huaweiToken = event;
+ AppState().setHuaweiPushToken = _huaweiToken;
+ debugPrint("HUAWEI PUSH TOKEN: $_huaweiToken");
+ }
+
+ void _onTokenError(Object error) {}
+
+ Future initTokenStream(Function loginCallback) async {
+ huawei_push.Push.getTokenStream.listen(_onTokenEvent, onError: _onTokenError).onData((data) {
+ AppState().setHuaweiPushToken = data;
+ debugPrint("HUAWEI PUSH TOKEN: $data");
+ loginCallback();
+ });
}
void _handleMessage(RemoteMessage message) {
diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart
index 2c36694..8822123 100644
--- a/lib/classes/utils.dart
+++ b/lib/classes/utils.dart
@@ -98,7 +98,8 @@ class Utils {
static void handleException(dynamic exception, cxt, Function(String)? onErrorMessage) {
String errorMessage;
- if (exception.error.errorType != null && exception.error.errorType == 4) {
+ print("exception:$exception");
+ if (exception?.error?.errorType != null && exception.error.errorType == 4) {
Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.appUpdateScreen, (_) => false, arguments: exception.error?.errorMessage);
} else {
if (exception is APIException) {
@@ -266,7 +267,7 @@ class Utils {
static String getMonthNamedFormat(DateTime date) {
/// it will return like "29-Sep-2022"
- return DateFormat('dd-MMM-yyyy').format(date);
+ return DateFormat('dd-MMM-yyyy', "en_US").format(date);
}
static String reverseFormatDate(String date) {
@@ -336,9 +337,9 @@ class Utils {
return date;
} else {
if (date.toLowerCase().split("-")[1].length == 3) {
- return DateFormat('dd-MM-yyyy').format(DateFormat('dd-MMM-yyyy').parseLoose(date));
+ return DateFormat('dd-MM-yyyy', "en_US").format(DateFormat('dd-MMM-yyyy', "en_US").parseLoose(date));
} else {
- return DateFormat('dd-MM-yyyy').format(DateFormat('yyyy-MM-dd').parseLoose(date));
+ return DateFormat('dd-MM-yyyy', "en_US").format(DateFormat('yyyy-MM-dd', "en_US").parseLoose(date));
}
// return DateFormat('yyyy-MM-dd').format(DateFormat('dd-MM-yyyy').parseLoose(date));
}
diff --git a/lib/config/app_feature_config.dart b/lib/config/app_feature_config.dart
new file mode 100644
index 0000000..058d971
--- /dev/null
+++ b/lib/config/app_feature_config.dart
@@ -0,0 +1 @@
+var json = {};
diff --git a/lib/config/env.dart b/lib/config/env.dart
index b78c5e4..38fa108 100644
--- a/lib/config/env.dart
+++ b/lib/config/env.dart
@@ -1,9 +1,8 @@
// ignore_for_file: prefer_single_quotes, lines_longer_than_80_chars final
-Map env = {
- "appConfig": "lib/config/config_en.json",
-
- // Worklist (Dynamic ListView, Dynamic Forms, Dynamic Submission)
+// link to generate dart class https://www.webinovers.com/web-tools/json-to-dart-convertor
+Map _env = {
+ "appConfig": "lib/config/config_en.json",
"login": {
"verification": true,
"verificationMethod": {
@@ -21,6 +20,7 @@ Map env = {
"monthlyAttendance": false,
"vocationRules": false,
},
+ "itg": false,
"marathon": false,
"offersDiscount": false,
"myTeams": false,
@@ -32,4 +32,175 @@ Map env = {
"chat": false,
"monthlyAttendance": false,
"vocationRules": false,
+ "canEdit": false,
};
+
+Env env = Env.fromJson(_env);
+
+class Env {
+ Env({
+ required this.appConfig,
+ required this.login,
+ required this.bottomBar,
+ required this.dashboard,
+ required this.itg,
+ required this.marathon,
+ required this.offersDiscount,
+ required this.myTeams,
+ required this.modifiy,
+ required this.myRequest,
+ required this.pendingTransactions,
+ required this.myProfile,
+ required this.itemsForSale,
+ required this.chat,
+ required this.monthlyAttendance,
+ required this.vocationRules,
+ required this.canEdit,
+ });
+
+ late final String appConfig;
+ late final Login login;
+ late final bool bottomBar;
+ late final Dashboard dashboard;
+ late final bool itg;
+ late final bool marathon;
+ late final bool offersDiscount;
+ late final bool myTeams;
+ late final bool modifiy;
+ late final bool myRequest;
+ late final bool pendingTransactions;
+ late final bool myProfile;
+ late final bool itemsForSale;
+ late final bool chat;
+ late final bool monthlyAttendance;
+ late final bool vocationRules;
+ late final bool canEdit;
+
+ Env.fromJson(Map json) {
+ appConfig = json['appConfig'];
+ login = Login.fromJson(json['login']);
+ bottomBar = json['bottomBar'];
+ dashboard = Dashboard.fromJson(json['dashboard']);
+ marathon = json['marathon'];
+ itg = json['itg'];
+ offersDiscount = json['offersDiscount'];
+ myTeams = json['myTeams'];
+ modifiy = json['modifiy'];
+ myRequest = json['myRequest'];
+ pendingTransactions = json['pendingTransactions'];
+ myProfile = json['myProfile'];
+ itemsForSale = json['itemsForSale'];
+ chat = json['chat'];
+ monthlyAttendance = json['monthlyAttendance'];
+ vocationRules = json['vocationRules'];
+ canEdit = json['canEdit'];
+ }
+
+ Map toJson() {
+ var _data = {};
+ _data['appConfig'] = appConfig;
+ _data['login'] = login.toJson();
+ _data['bottomBar'] = bottomBar;
+ _data['dashboard'] = dashboard.toJson();
+ _data['marathon'] = marathon;
+ _data['itg'] = itg;
+ _data['offersDiscount'] = offersDiscount;
+ _data['myTeams'] = myTeams;
+ _data['modifiy'] = modifiy;
+ _data['myRequest'] = myRequest;
+ _data['pendingTransactions'] = pendingTransactions;
+ _data['myProfile'] = myProfile;
+ _data['itemsForSale'] = itemsForSale;
+ _data['chat'] = chat;
+ _data['monthlyAttendance'] = monthlyAttendance;
+ _data['vocationRules'] = vocationRules;
+ _data['canEdit'] = canEdit;
+ return _data;
+ }
+}
+
+class Login {
+ Login({
+ required this.verification,
+ required this.verificationMethod,
+ required this.forgetPassword,
+ });
+
+ late final bool verification;
+ late final VerificationMethod verificationMethod;
+ late final bool forgetPassword;
+
+ Login.fromJson(Map json) {
+ verification = json['verification'];
+ verificationMethod = VerificationMethod.fromJson(json['verificationMethod']);
+ forgetPassword = json['forgetPassword'];
+ }
+
+ Map toJson() {
+ var _data = {};
+ _data['verification'] = verification;
+ _data['verificationMethod'] = verificationMethod.toJson();
+ _data['forgetPassword'] = forgetPassword;
+ return _data;
+ }
+}
+
+class VerificationMethod {
+ VerificationMethod({
+ required this.whatsapp,
+ });
+
+ late final bool whatsapp;
+
+ VerificationMethod.fromJson(Map json) {
+ whatsapp = json['whatsapp'];
+ }
+
+ Map toJson() {
+ var _data = {};
+ _data['whatsapp'] = whatsapp;
+ return _data;
+ }
+}
+
+class Dashboard {
+ Dashboard({
+ required this.attendance,
+ required this.worklist,
+ required this.ticketBalance,
+ required this.leaveBalance,
+ required this.missingSwipe,
+ required this.monthlyAttendance,
+ required this.vocationRules,
+ });
+
+ late final bool attendance;
+ late final bool worklist;
+ late final bool ticketBalance;
+ late final bool leaveBalance;
+ late final bool missingSwipe;
+ late final bool monthlyAttendance;
+ late final bool vocationRules;
+
+ Dashboard.fromJson(Map json) {
+ attendance = json['attendance'];
+ worklist = json['worklist'];
+ ticketBalance = json['ticketBalance'];
+ leaveBalance = json['leaveBalance'];
+ missingSwipe = json['missingSwipe'];
+ monthlyAttendance = json['monthlyAttendance'];
+ vocationRules = json['vocationRules'];
+ }
+
+ Map toJson() {
+ var _data = {};
+ _data['attendance'] = attendance;
+ _data['worklist'] = worklist;
+ _data['ticketBalance'] = ticketBalance;
+ _data['leaveBalance'] = leaveBalance;
+ _data['missingSwipe'] = missingSwipe;
+ _data['monthlyAttendance'] = monthlyAttendance;
+ _data['vocationRules'] = vocationRules;
+ return _data;
+ }
+}
diff --git a/lib/dialogs/otp_dialog.dart b/lib/dialogs/otp_dialog.dart
index 9158b94..9f7c82e 100644
--- a/lib/dialogs/otp_dialog.dart
+++ b/lib/dialogs/otp_dialog.dart
@@ -9,7 +9,6 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/otp_widget.dart';
-import 'package:sizer/sizer.dart';
final ValueNotifier otpFieldClear = ValueNotifier("");
diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart
index 53b70a5..54ffe20 100644
--- a/lib/extensions/string_extensions.dart
+++ b/lib/extensions/string_extensions.dart
@@ -221,7 +221,7 @@ extension EmailValidator on String {
String date = this.split("T")[0];
String time = this.split("T")[1];
var dates = date.split("-");
- return "${dates[2]} ${getMonth(int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a').format(DateFormat('hh:mm:ss').parse(time))}";
+ return "${dates[2]} ${getMonth(int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a', "en_US").format(DateFormat('hh:mm:ss', "en_US").parse(time))}";
}
String getMonth(int month) {
diff --git a/lib/main.dart b/lib/main.dart
index d7b9646..b00609b 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -6,9 +6,11 @@ import 'package:flutter/services.dart';
import 'package:logger/logger.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
+import 'package:mohem_flutter_app/config/env.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/codegen_loader.g.dart';
import 'package:mohem_flutter_app/models/post_params_model.dart';
+import 'package:mohem_flutter_app/provider/chat_call_provider.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/provider/eit_provider_model.dart';
@@ -25,7 +27,6 @@ Logger logger = Logger(
),
);
-
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
@@ -62,12 +63,17 @@ Future main() async {
ChangeNotifierProvider(
create: (_) => EITProviderModel(),
),
- ChangeNotifierProvider(
- create: (_) => ChatProviderModel(),
- ),
- ChangeNotifierProvider(
- create: (_) => MarathonProvider(),
- )
+ if (env.chat)
+ ChangeNotifierProvider(
+ create: (_) => ChatProviderModel(),
+ ),
+ if (env.marathon)
+ ChangeNotifierProvider(
+ create: (_) => MarathonProvider(),
+ ),
+ // ChangeNotifierProvider(
+ // create: (_) => ChatCallProvider(),
+ // ),
],
child: const MyApp(),
),
@@ -259,5 +265,3 @@ class MyApp extends StatelessWidget {
// });
// }
// }
-
-
diff --git a/lib/models/chat/call.dart b/lib/models/chat/call.dart
index 7f8f6eb..ce58ae3 100644
--- a/lib/models/chat/call.dart
+++ b/lib/models/chat/call.dart
@@ -7,127 +7,191 @@ import 'dart:convert';
class CallDataModel {
CallDataModel({
this.callerId,
- this.callReceiverID,
- this.notificationForeground,
- this.message,
+ this.callerDetails,
+ this.receiverId,
+ this.receiverDetails,
this.title,
- this.type,
- this.identity,
- this.name,
- this.isCall,
- this.isWebrtc,
- this.contant,
- this.contantNo,
- this.chatEventId,
- this.fileTypeId,
- this.currentUserId,
- this.chatSource,
- this.userChatHistoryLineRequestList,
- this.server,
+ this.calltype,
});
String? callerId;
- String? callReceiverID;
- String? notificationForeground;
- String? message;
- String? title;
- String? type;
- String? identity;
- String? name;
- String? isCall;
- String? isWebrtc;
- String? contant;
- String? contantNo;
- String? chatEventId;
- dynamic? fileTypeId;
- String? currentUserId;
- String? chatSource;
- List? userChatHistoryLineRequestList;
- String? server;
+ CallerDetails? callerDetails;
+ String? receiverId;
+ ReceiverDetails? receiverDetails;
+ dynamic title;
+ String? calltype;
factory CallDataModel.fromRawJson(String str) => CallDataModel.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory CallDataModel.fromJson(Map json) => CallDataModel(
- callerId: json["callerID"] == null ? null : json["callerID"],
- callReceiverID: json["callReceiverID"] == null ? null : json["callReceiverID"],
- notificationForeground: json["notification_foreground"] == null ? null : json["notification_foreground"],
- message: json["message"] == null ? null : json["message"],
- title: json["title"] == null ? null : json["title"],
- type: json["type"] == null ? null : json["type"],
- identity: json["identity"] == null ? null : json["identity"],
- name: json["name"] == null ? null : json["name"],
- isCall: json["is_call"] == null ? null : json["is_call"],
- isWebrtc: json["is_webrtc"] == null ? null : json["is_webrtc"],
- contant: json["contant"] == null ? null : json["contant"],
- contantNo: json["contantNo"] == null ? null : json["contantNo"],
- chatEventId: json["chatEventId"] == null ? null : json["chatEventId"],
- fileTypeId: json["fileTypeId"],
- currentUserId: json["currentUserId"] == null ? null : json["currentUserId"],
- chatSource: json["chatSource"] == null ? null : json["chatSource"],
- userChatHistoryLineRequestList: json["userChatHistoryLineRequestList"] == null
- ? null
- : List.from(
- json["userChatHistoryLineRequestList"].map(
- (x) => UserChatHistoryLineRequestList.fromJson(x),
- ),
- ),
- server: json["server"] == null ? null : json["server"],
- );
+ callerId: json["callerID"],
+ callerDetails: json["callerDetails"] == null ? null : CallerDetails.fromJson(json["callerDetails"]),
+ receiverId: json["receiverID"],
+ receiverDetails: json["receiverDetails"] == null ? null : ReceiverDetails.fromJson(json["receiverDetails"]),
+ title: json["title"],
+ calltype: json["calltype"],
+ );
+
+ Map toJson() => {
+ "callerID": callerId,
+ "callerDetails": callerDetails?.toJson(),
+ "receiverID": receiverId,
+ "receiverDetails": receiverDetails?.toJson(),
+ "title": title,
+ "calltype": calltype,
+ };
+}
+
+class CallerDetails {
+ CallerDetails({
+ this.response,
+ this.errorResponses,
+ });
+
+ Response? response;
+ dynamic errorResponses;
+
+ factory CallerDetails.fromRawJson(String str) => CallerDetails.fromJson(json.decode(str));
+
+ String toRawJson() => json.encode(toJson());
+
+ factory CallerDetails.fromJson(Map json) => CallerDetails(
+ response: json["response"] == null ? null : Response.fromJson(json["response"]),
+ errorResponses: json["errorResponses"],
+ );
Map toJson() => {
- "callerID": callerId == null ? null : callerId,
- "callReceiverID": callReceiverID == null ? null : callReceiverID,
- "notification_foreground": notificationForeground == null ? null : notificationForeground,
- "message": message == null ? null : message,
- "title": title == null ? null : title,
- "type": type == null ? null : type,
- "identity": identity == null ? null : identity,
- "name": name == null ? null : name,
- "is_call": isCall == null ? null : isCall,
- "is_webrtc": isWebrtc == null ? null : isWebrtc,
- "contant": contant == null ? null : contant,
- "contantNo": contantNo == null ? null : contantNo,
- "chatEventId": chatEventId == null ? null : chatEventId,
- "fileTypeId": fileTypeId,
- "currentUserId": currentUserId == null ? null : currentUserId,
- "chatSource": chatSource == null ? null : chatSource,
- "userChatHistoryLineRequestList": userChatHistoryLineRequestList == null
- ? null
- : List.from(
- userChatHistoryLineRequestList!.map(
- (x) => x.toJson(),
- ),
- ),
- "server": server == null ? null : server,
- };
+ "response": response?.toJson(),
+ "errorResponses": errorResponses,
+ };
}
-class UserChatHistoryLineRequestList {
- UserChatHistoryLineRequestList({
- this.isSeen,
- this.isDelivered,
- this.targetUserId,
- this.targetUserStatus,
+class Response {
+ Response({
+ this.id,
+ this.userName,
+ this.email,
+ this.phone,
+ this.title,
+ this.token,
+ this.isDomainUser,
+ this.isActiveCode,
+ this.encryptedUserId,
+ this.encryptedUserName,
});
- bool? isSeen;
- bool? isDelivered;
- int? targetUserId;
- int? targetUserStatus;
+ int? id;
+ String? userName;
+ String? email;
+ dynamic phone;
+ String? title;
+ String? token;
+ bool? isDomainUser;
+ bool? isActiveCode;
+ String? encryptedUserId;
+ String? encryptedUserName;
+
+ factory Response.fromRawJson(String str) => Response.fromJson(json.decode(str));
+
+ String toRawJson() => json.encode(toJson());
+
+ factory Response.fromJson(Map json) => Response(
+ id: json["id"],
+ userName: json["userName"],
+ email: json["email"],
+ phone: json["phone"],
+ title: json["title"],
+ token: json["token"],
+ isDomainUser: json["isDomainUser"],
+ isActiveCode: json["isActiveCode"],
+ encryptedUserId: json["encryptedUserId"],
+ encryptedUserName: json["encryptedUserName"],
+ );
+
+ Map toJson() => {
+ "id": id,
+ "userName": userName,
+ "email": email,
+ "phone": phone,
+ "title": title,
+ "token": token,
+ "isDomainUser": isDomainUser,
+ "isActiveCode": isActiveCode,
+ "encryptedUserId": encryptedUserId,
+ "encryptedUserName": encryptedUserName,
+ };
+}
+
+class ReceiverDetails {
+ ReceiverDetails({
+ this.id,
+ this.userName,
+ this.email,
+ this.phone,
+ this.title,
+ this.userStatus,
+ this.image,
+ this.unreadMessageCount,
+ this.userAction,
+ this.isPin,
+ this.isFav,
+ this.isAdmin,
+ this.rKey,
+ this.totalCount,
+ });
+
+ int? id;
+ String? userName;
+ String? email;
+ dynamic phone;
+ dynamic title;
+ int? userStatus;
+ String? image;
+ int? unreadMessageCount;
+ dynamic userAction;
+ bool? isPin;
+ bool? isFav;
+ bool? isAdmin;
+ String? rKey;
+ int? totalCount;
+
+ factory ReceiverDetails.fromRawJson(String str) => ReceiverDetails.fromJson(json.decode(str));
+
+ String toRawJson() => json.encode(toJson());
- factory UserChatHistoryLineRequestList.fromJson(Map json) => UserChatHistoryLineRequestList(
- isSeen: json["isSeen"] == null ? null : json["isSeen"],
- isDelivered: json["isDelivered"] == null ? null : json["isDelivered"],
- targetUserId: json["targetUserId"] == null ? null : json["targetUserId"],
- targetUserStatus: json["targetUserStatus"] == null ? null : json["targetUserStatus"],
- );
+ factory ReceiverDetails.fromJson(Map json) => ReceiverDetails(
+ id: json["id"],
+ userName: json["userName"],
+ email: json["email"],
+ phone: json["phone"],
+ title: json["title"],
+ userStatus: json["userStatus"],
+ image: json["image"],
+ unreadMessageCount: json["unreadMessageCount"],
+ userAction: json["userAction"],
+ isPin: json["isPin"],
+ isFav: json["isFav"],
+ isAdmin: json["isAdmin"],
+ rKey: json["rKey"],
+ totalCount: json["totalCount"],
+ );
Map toJson() => {
- "isSeen": isSeen == null ? null : isSeen,
- "isDelivered": isDelivered == null ? null : isDelivered,
- "targetUserId": targetUserId == null ? null : targetUserId,
- "targetUserStatus": targetUserStatus == null ? null : targetUserStatus,
- };
+ "id": id,
+ "userName": userName,
+ "email": email,
+ "phone": phone,
+ "title": title,
+ "userStatus": userStatus,
+ "image": image,
+ "unreadMessageCount": unreadMessageCount,
+ "userAction": userAction,
+ "isPin": isPin,
+ "isFav": isFav,
+ "isAdmin": isAdmin,
+ "rKey": rKey,
+ "totalCount": totalCount,
+ };
}
diff --git a/lib/models/get_eit_dff_structure_list_model.dart b/lib/models/get_eit_dff_structure_list_model.dart
index 3aed98c..c659cc2 100644
--- a/lib/models/get_eit_dff_structure_list_model.dart
+++ b/lib/models/get_eit_dff_structure_list_model.dart
@@ -31,6 +31,7 @@ class GetEITDFFStructureList {
List? pARENTSEGMENTSVSSplitedVS;
String? rEADONLY;
String? rEQUIREDFLAG;
+ String? rEQCOLTIP;
String? sEGMENTNAME;
String? sEGMENTPROMPT;
int? sEGMENTSEQNUM;
@@ -73,6 +74,7 @@ class GetEITDFFStructureList {
this.pARENTSEGMENTSVSSplitedVS,
this.rEADONLY,
this.rEQUIREDFLAG,
+ this.rEQCOLTIP,
this.sEGMENTNAME,
this.sEGMENTPROMPT,
this.sEGMENTSEQNUM,
@@ -132,7 +134,6 @@ class GetEITDFFStructureList {
});
}
pARENTSEGMENTSVS = json['PARENT_SEGMENTS_VS'];
-
if (json['PARENT_SEGMENTS_VS_SplitedVS'] != null) {
pARENTSEGMENTSVSSplitedVS = [];
json['PARENT_SEGMENTS_VS_SplitedVS'].forEach((v) {
@@ -141,6 +142,7 @@ class GetEITDFFStructureList {
}
rEADONLY = json['READ_ONLY'];
rEQUIREDFLAG = json['REQUIRED_FLAG'];
+ rEQCOLTIP = json['REQ_COL_TIP'];
sEGMENTNAME = json['SEGMENT_NAME'];
sEGMENTPROMPT = json['SEGMENT_PROMPT'];
sEGMENTSEQNUM = json['SEGMENT_SEQ_NUM'];
@@ -171,9 +173,6 @@ class GetEITDFFStructureList {
if (this.eSERVICESVS != null) {
data['E_SERVICES_VS'] = this.eSERVICESVS!.map((v) => v.toJson()).toList();
}
- // if (this.eSERVICESVS != null) {
- // data['E_SERVICES_VS'] = this.eSERVICESVS!.toList();
- // }
data['FLEX_VALUE_SET_NAME'] = this.fLEXVALUESETNAME;
data['FORMAT_TYPE'] = this.fORMATTYPE;
data['FORMAT_TYPE_DSP'] = this.fORMATTYPEDSP;
@@ -193,9 +192,9 @@ class GetEITDFFStructureList {
if (this.pARENTSEGMENTSVSSplitedVS != null) {
data['PARENT_SEGMENTS_VS_SplitedVS'] = this.pARENTSEGMENTSVSSplitedVS!.map((v) => v.toJson()).toList();
}
-
data['READ_ONLY'] = this.rEADONLY;
data['REQUIRED_FLAG'] = this.rEQUIREDFLAG;
+ data['REQ_COL_TIP'] = this.rEQCOLTIP;
data['SEGMENT_NAME'] = this.sEGMENTNAME;
data['SEGMENT_PROMPT'] = this.sEGMENTPROMPT;
data['SEGMENT_SEQ_NUM'] = this.sEGMENTSEQNUM;
diff --git a/lib/models/get_mobile_login_info_list_model.dart b/lib/models/get_mobile_login_info_list_model.dart
index a2f7799..d544ef5 100644
--- a/lib/models/get_mobile_login_info_list_model.dart
+++ b/lib/models/get_mobile_login_info_list_model.dart
@@ -1,6 +1,6 @@
class GetMobileLoginInfoListModel {
int? iD;
- int? employeeID;
+ String? employeeID;
int? channelID;
int? companyID;
String? deviceType;
diff --git a/lib/provider/chat_call_provider.dart b/lib/provider/chat_call_provider.dart
new file mode 100644
index 0000000..45205df
--- /dev/null
+++ b/lib/provider/chat_call_provider.dart
@@ -0,0 +1,187 @@
+import 'dart:convert';
+import 'dart:ui';
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter_webrtc/flutter_webrtc.dart';
+import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
+
+class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
+ ///////////////////// Web RTC Video Calling //////////////////////
+ // Video Call
+ late RTCPeerConnection _peerConnection;
+ RTCVideoRenderer _localVideoRenderer = RTCVideoRenderer();
+ final RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
+
+ MediaStream? _localStream;
+ MediaStream? _remoteStream;
+
+ void initCallListeners() {
+ chatHubConnection.on("OnCallAcceptedAsync", onCallAcceptedAsync);
+ chatHubConnection.on("OnIceCandidateAsync", onIceCandidateAsync);
+ chatHubConnection.on("OnOfferAsync", onOfferAsync);
+ chatHubConnection.on("OnAnswerOffer", onAnswerOffer);
+ chatHubConnection.on("OnHangUpAsync", onHangUpAsync);
+ chatHubConnection.on("OnCallDeclinedAsync", onCallDeclinedAsync);
+ }
+
+ //Video Constraints
+ var videoConstraints = {
+ "video": {
+ "mandatory": {
+ "width": {"min": 320},
+ "height": {"min": 180}
+ },
+ "optional": [
+ {
+ "width": {"max": 1280}
+ },
+ {"frameRate": 25},
+ {"facingMode": "user"}
+ ]
+ },
+ "frameRate": 25,
+ "width": 420, //420,//640,//1280,
+ "height": 240 //240//480//720
+ };
+
+ // Audio Constraints
+ var audioConstraints = {
+ "sampleRate": 8000,
+ "sampleSize": 16,
+ "channelCount": 2,
+ "echoCancellation": true,
+ "audio": true,
+ };
+
+ Future _createPeerConnection() async {
+ // {"url": "stun:stun.l.google.com:19302"},
+ Map configuration = {
+ "iceServers": [
+ {"urls": 'stun:15.185.116.59:3478'},
+ {"urls": "turn:15.185.116.59:3479", "username": "admin", "credential": "admin"}
+ ]
+ };
+
+ Map offerSdpConstraints = {
+ "mandatory": {
+ "OfferToReceiveAudio": true,
+ "OfferToReceiveVideo": true,
+ },
+ "optional": [],
+ };
+
+ RTCPeerConnection pc = await createPeerConnection(configuration, offerSdpConstraints);
+ // if (pc != null) print(pc);
+ //pc.addStream(widget.localStream);
+
+ pc.onIceCandidate = (e) {
+ if (e.candidate != null) {
+ print(json.encode({
+ 'candidate': e.candidate.toString(),
+ 'sdpMid': e.sdpMid.toString(),
+ 'sdpMlineIndex': e.sdpMLineIndex,
+ }));
+ }
+ };
+ pc.onIceConnectionState = (e) {
+ print(e);
+ };
+ pc.onAddStream = (stream) {
+ print('addStream: ' + stream.id);
+ _remoteRenderer.srcObject = stream;
+ };
+ return pc;
+ }
+
+ void init() {
+ initRenderers();
+ _createPeerConnection().then((pc) {
+ _peerConnection = pc;
+ // _setRemoteDescription(widget.info);
+ });
+ }
+
+ void initRenderers() {
+ _localVideoRenderer.initialize();
+ _remoteRenderer.initialize();
+ initLocalCamera();
+ }
+
+ void initLocalCamera() async {
+ _localStream = await navigator.mediaDevices.getUserMedia({'video': true, 'audio': true});
+ _localVideoRenderer.srcObject = _localStream;
+ // _localVideoRenderer.srcObject = await navigator.mediaDevices
+ // .getUserMedia({'video': true, 'audio': true});
+ print('this source Object');
+ print('this suarce ${_localVideoRenderer.srcObject != null}');
+ notifyListeners();
+ }
+
+ void startCall({required String callType}) {}
+
+ void endCall() {}
+
+ void checkCall(Map message) {
+ switch (message["callStatus"]) {
+ case 'connected':
+ {}
+ break;
+ case 'offer':
+ {}
+ break;
+ case 'accept':
+ {}
+ break;
+ case 'candidate':
+ {}
+ break;
+ case 'bye':
+ {}
+ break;
+ case 'leave':
+ {}
+ break;
+ }
+ }
+
+ //// Listeners Methods ////
+
+ void onCallAcceptedAsync(List