Merge branch 'master' into faiz_cs

# Conflicts:
#	lib/classes/consts.dart
merge-requests/89/head
Faiz Hashmi 3 years ago
commit f31db58a76

@ -9,6 +9,7 @@ import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/exceptions/api_exception.dart'; import 'package:mohem_flutter_app/exceptions/api_exception.dart';
import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/chat_user_image_model.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as user; import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as user;
import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav;
@ -28,9 +29,7 @@ class ChatApiClient {
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
}, },
); );
user.UserAutoLoginModel userLoginResponse = user.userAutoLoginModelFromJson( user.UserAutoLoginModel userLoginResponse = user.userAutoLoginModelFromJson(response.body);
response.body,
);
return userLoginResponse; return userLoginResponse;
} }
@ -42,9 +41,7 @@ class ChatApiClient {
return searchUserJsonModel(response.body); return searchUserJsonModel(response.body);
} }
List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from( List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from(json.decode(str).map((x) => ChatUser.fromJson(x)));
json.decode(str).map((x) => ChatUser.fromJson(x)),
);
Future<ChatUserModel> getRecentChats() async { Future<ChatUserModel> getRecentChats() async {
try { try {
@ -58,7 +55,6 @@ class ChatApiClient {
} catch (e) { } catch (e) {
e as APIException; e as APIException;
if (e.message == "api_common_unauthorized") { if (e.message == "api_common_unauthorized") {
logger.d("Token Generated On APIIIIII");
user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken(); user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) { if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse; AppState().setchatUserDetails = userLoginResponse;
@ -98,9 +94,7 @@ class ChatApiClient {
AppState().setchatUserDetails = userLoginResponse; AppState().setchatUserDetails = userLoginResponse;
getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore, paginationVal: paginationVal); getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore, paginationVal: paginationVal);
} else { } else {
Utils.showToast( Utils.showToast(userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr");
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
} }
} }
throw e; throw e;
@ -108,13 +102,7 @@ class ChatApiClient {
} }
Future<fav.FavoriteChatUser> favUser({required int userID, required int targetUserID}) async { Future<fav.FavoriteChatUser> favUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient().postJsonForResponse( Response response = await ApiClient().postJsonForResponse("${ApiConsts.chatFavUser}addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token);
"${ApiConsts.chatFavUser}addFavUser",
{
"targetUserId": targetUserID,
"userId": userID,
},
token: AppState().chatDetails!.response!.token);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser; return favoriteChatUser;
} }
@ -137,9 +125,7 @@ class ChatApiClient {
AppState().setchatUserDetails = userLoginResponse; AppState().setchatUserDetails = userLoginResponse;
unFavUser(userID: userID, targetUserID: targetUserID); unFavUser(userID: userID, targetUserID: targetUserID);
} else { } else {
Utils.showToast( Utils.showToast(userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr");
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
} }
} }
throw e; throw e;
@ -147,7 +133,7 @@ class ChatApiClient {
} }
Future<StreamedResponse> uploadMedia(String userId, File file) async { Future<StreamedResponse> uploadMedia(String userId, File file) async {
dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatServerBaseApiUrl}upload')); dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatMediaImageUploadUrl}upload'));
request.fields.addAll({'userId': userId, 'fileSource': '1'}); request.fields.addAll({'userId': userId, 'fileSource': '1'});
request.files.add(await MultipartFile.fromPath('files', file.path)); request.files.add(await MultipartFile.fromPath('files', file.path));
request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'}); request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'});
@ -167,16 +153,12 @@ class ChatApiClient {
return data; return data;
} }
Future getUsersImages({required List encryptedEmails}) async { Future<List<ChatUserImageModel>> getUsersImages({required List<String> encryptedEmails}) async {
Response response = await ApiClient().postJsonForResponse( Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatUserImages}images", "${ApiConsts.chatUserImages}images",
{ {"encryptedEmails": encryptedEmails, "fromClient": false},
"encryptedEmails": ["/g8Rc+s6eEOdci41PwJuV5dX+gXe51G9OTHzb9ahcVlHCmVvNhxReirudF79+hdxVSkCnQ6wC5DBFV8xnJlC74X6157PxF7mNYrAYuHRgp4="],
"fromClient": true
},
token: AppState().chatDetails!.response!.token, token: AppState().chatDetails!.response!.token,
); );
logger.d(response.body); return chatUserImageModelFromJson(response.body);
// Uint8List data = Uint8List.fromList(response.body);
} }
} }

@ -66,6 +66,41 @@ class ItemsForSaleApiClient {
}, url, postParams); }, url, postParams);
} }
Future<dynamic> updateItemsForSale(int itemSaleID) async {
List<GetItemsForSaleList> getItemsForSaleList = [];
String url = "${ApiConsts.cocRest}Mohemm_ITG_UpdateItemForSale";
// request.fields['itemSaleID'] = itemSaleID.toString();
// request.fields['Channel'] = "31";
// request.fields['isActive'] = "false";
// request.fields['LogInToken'] = loginTokenID!;
// request.fields['Token'] = tokenID!;
// request.fields['MobileNo'] = empMobNum!;
// request.fields['EmployeeNumber'] = empNum!;
// request.fields['employeeNumber'] = empNum;
Map<String, dynamic> postParams = {
"EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER,
"employeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER,
"MobileNo": AppState().memberInformationList?.eMPLOYEEMOBILENUMBER,
"itemSaleID": itemSaleID.toString(),
"Channel": "31",
"isActive": "false",
"Token": AppState().postParamsObject?.tokenID
};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((response) {
var body = json.decode(response['Mohemm_ITG_ResponseItem']);
// body['result']['data'].forEach((v) {
// getItemsForSaleList.add(new GetItemsForSaleList.fromJson(v));
// });
return getItemsForSaleList;
}, url, postParams);
}
Future<List<EmployeePostedAds>> getEmployeePostedAds() async { Future<List<EmployeePostedAds>> getEmployeePostedAds() async {
List<EmployeePostedAds> employeePostedAdsList = []; List<EmployeePostedAds> employeePostedAdsList = [];

@ -70,7 +70,7 @@ class MyAttendanceApiClient {
}, url, postParams); }, url, postParams);
} }
Future<ESERVICESDV> getDefaultValue(String pSegmentName, String pDescFlexContextCode, String pDescFlexName, List<Map<String, dynamic>> list, String? empID) async { Future<ESERVICESDV> getDefaultValue(String pSegmentName, String pDescFlexContextCode, String pDescFlexName, List<Map<String, dynamic>> list, {String? empID}) async {
String url = "${ApiConsts.erpRest}GET_DEFAULT_VALUE"; String url = "${ApiConsts.erpRest}GET_DEFAULT_VALUE";
Map<String, dynamic> postParams = { Map<String, dynamic> postParams = {
"P_SELECTED_RESP_ID": -999, "P_SELECTED_RESP_ID": -999,
@ -82,7 +82,7 @@ class MyAttendanceApiClient {
"GetValueSetValuesTBL": list, "GetValueSetValuesTBL": list,
}; };
postParams.addAll(AppState().postParamsJson); postParams.addAll(AppState().postParamsJson);
if (empID!.isNotEmpty) { if (empID != null && empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID; postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
} }
return await ApiClient().postJsonForObject((json) { return await ApiClient().postJsonForObject((json) {

@ -62,4 +62,5 @@ class MyColors {
static const Color grey9DColor = Color(0xff9D9D9D); static const Color grey9DColor = Color(0xff9D9D9D);
static const Color darkDigitColor = Color(0xff2D2F39); static const Color darkDigitColor = Color(0xff2D2F39);
static const Color grey71Color = Color(0xff717171); static const Color grey71Color = Color(0xff717171);
static const Color darkGrey3BColor = Color(0xff3B3B3B);
} }

@ -2,8 +2,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
class ApiConsts { class ApiConsts {
//static String baseUrl = "http://10.200.204.20:2801/"; // Local server //static String baseUrl = "http://10.200.204.20:2801/"; // Local server
static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server
// static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrlServices = baseUrl + "/Services/"; // server static String baseUrlServices = baseUrl + "/Services/"; // server
// static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/";
@ -12,8 +12,6 @@ class ApiConsts {
static String user = baseUrlServices + "api/User/"; static String user = baseUrlServices + "api/User/";
static String cocRest = baseUrlServices + "COCWS.svc/REST/"; static String cocRest = baseUrlServices + "COCWS.svc/REST/";
// todo @aamir move api end point last repo to concerned method.
//Chat //Chat
static String chatServerBaseUrl = "https://apiderichat.hmg.com/"; static String chatServerBaseUrl = "https://apiderichat.hmg.com/";
static String chatServerBaseApiUrl = chatServerBaseUrl + "api/"; static String chatServerBaseApiUrl = chatServerBaseUrl + "api/";
@ -25,6 +23,19 @@ class ApiConsts {
static String chatSingleUserHistoryUrl = chatServerBaseApiUrl + "UserChatHistory/"; static String chatSingleUserHistoryUrl = chatServerBaseApiUrl + "UserChatHistory/";
static String chatMediaImageUploadUrl = chatServerBaseApiUrl + "shared/"; static String chatMediaImageUploadUrl = chatServerBaseApiUrl + "shared/";
static String chatFavUser = chatServerBaseApiUrl + "FavUser/"; static String chatFavUser = chatServerBaseApiUrl + "FavUser/";
static String chatUserImages = chatServerBaseUrl + "empservice/api/employee/";
//Brain Marathon Constants
static String marathonBaseUrl = "https://marathoon.com/service/";
static String marathonParticipantLoginUrl = marathonBaseUrl + "api/auth/participantlogin";
static String marathonProjectGetUrl = marathonBaseUrl + "api/Project/Project_Get";
static String marathonUpcomingUrl = marathonBaseUrl + "api/marathon/upcoming/";
static String marathonHubConnectionUrl = marathonBaseUrl + "MarathonBroadCast";
//DummyCards for the UI
static CardContent dummyQuestion = const CardContent();
static String chatUserImages = chatServerBaseUrl + "empservice/api/employee/"; static String chatUserImages = chatServerBaseUrl + "empservice/api/employee/";
//Brain Marathon Constants //Brain Marathon Constants

@ -40,7 +40,7 @@ class DateUtil {
} }
static DateTime convertSimpleStringDateToDate(String date) { static DateTime convertSimpleStringDateToDate(String date) {
return DateFormat("MM/dd/yyyy hh:mm:ss a").parse(date); return DateFormat("MM/dd/yyyy hh:mm:ss").parse(date);
} }
static DateTime convertSimpleStringDateToDateddMMyyyy(String date) { static DateTime convertSimpleStringDateToDateddMMyyyy(String date) {

@ -0,0 +1,26 @@
import 'dart:convert';
import 'package:flutter/services.dart';
class EmailImageEncryption {
static final EmailImageEncryption _instance = EmailImageEncryption._internal();
static const MethodChannel _channel = MethodChannel('flutter_des');
static const key = "PeShVmYp";
static const iv = "j70IbWYn";
EmailImageEncryption._internal();
factory EmailImageEncryption() => _instance;
Future<String> encrypt({required String val}) async {
Uint8List? crypt = await _channel.invokeMethod('encrypt', [val, key, iv]);
String enc = base64Encode(crypt!.toList());
return enc;
}
Future<String> decrypt({required String encodedVal}) async {
Uint8List deco = base64Decode(encodedVal);
String? decCrypt = await _channel.invokeMethod('decrypt', [deco, key, iv]);
return decCrypt!;
}
}

@ -9,6 +9,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/date_uitl.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/exceptions/api_exception.dart'; import 'package:mohem_flutter_app/exceptions/api_exception.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -20,6 +21,7 @@ import 'package:mohem_flutter_app/widgets/loading_dialog.dart';
import 'package:nfc_manager/nfc_manager.dart'; import 'package:nfc_manager/nfc_manager.dart';
import 'package:nfc_manager/platform_tags.dart'; import 'package:nfc_manager/platform_tags.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
// ignore_for_file: avoid_annotating_with_dynamic // ignore_for_file: avoid_annotating_with_dynamic
class Utils { class Utils {
@ -289,7 +291,7 @@ class Utils {
String formattedDate; String formattedDate;
if (date.isNotEmpty) { if (date.isNotEmpty) {
formattedDate = date.split('T')[0]; formattedDate = date.split('T')[0];
if(!formattedDate.contains("00:00:00")) { if (!formattedDate.contains("00:00:00")) {
formattedDate = formattedDate + ' 00:00:00'; formattedDate = formattedDate + ' 00:00:00';
} }
} else { } else {
@ -298,6 +300,10 @@ class Utils {
return formattedDate; return formattedDate;
} }
static String formatDateDefault(String date) {
return DateFormat('yyyy-MM-dd').format(DateFormat('dd-MMM-yyyy').parseLoose(date));
}
static Future<DateTime> selectDate(BuildContext context, DateTime selectedDate) async { static Future<DateTime> selectDate(BuildContext context, DateTime selectedDate) async {
if (!Platform.isIOS) { if (!Platform.isIOS) {
await showCupertinoModalPopup( await showCupertinoModalPopup(
@ -326,8 +332,7 @@ class Utils {
return selectedDate; return selectedDate;
} }
static void readNFc({required Function(String) onRead}) { static void readNFc({required Function(String) onRead}) {
NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
print(tag.data); print(tag.data);
var f; var f;

@ -0,0 +1,33 @@
// To parse this JSON data, do
//
// final chatUserImageModel = chatUserImageModelFromJson(jsonString);
import 'dart:convert';
List<ChatUserImageModel> chatUserImageModelFromJson(String str) => List<ChatUserImageModel>.from(json.decode(str).map((x) => ChatUserImageModel.fromJson(x)));
String chatUserImageModelToJson(List<ChatUserImageModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class ChatUserImageModel {
ChatUserImageModel({
this.email,
this.profilePicture,
this.mobileNumber,
});
String? email;
String? profilePicture;
String? mobileNumber;
factory ChatUserImageModel.fromJson(Map<String, dynamic> json) => ChatUserImageModel(
email: json["email"] == null ? null : json["email"],
profilePicture: json["profilePicture"] == null ? null : json["profilePicture"],
mobileNumber: json["mobileNumber"] == null ? null : json["mobileNumber"],
);
Map<String, dynamic> toJson() => {
"email": email == null ? null : email,
"profilePicture": profilePicture == null ? null : profilePicture,
"mobileNumber": mobileNumber == null ? null : mobileNumber,
};
}

@ -19,21 +19,23 @@ class ChatUserModel {
} }
class ChatUser { class ChatUser {
ChatUser( ChatUser({
{this.id, this.id,
this.userName, this.userName,
this.email, this.email,
this.phone, this.phone,
this.title, this.title,
this.userStatus, this.userStatus,
this.image, this.image,
this.unreadMessageCount, this.unreadMessageCount,
this.userAction, this.userAction,
this.isPin, this.isPin,
this.isFav, this.isFav,
this.isAdmin, this.isAdmin,
this.isTyping, this.isTyping,
this.isLoadingCounter}); this.isImageLoaded,
this.isImageLoading,
});
int? id; int? id;
String? userName; String? userName;
@ -48,7 +50,8 @@ class ChatUser {
bool? isFav; bool? isFav;
bool? isAdmin; bool? isAdmin;
bool? isTyping; bool? isTyping;
bool? isLoadingCounter; bool? isImageLoaded;
bool? isImageLoading;
factory ChatUser.fromJson(Map<String, dynamic> json) => ChatUser( factory ChatUser.fromJson(Map<String, dynamic> json) => ChatUser(
id: json["id"] == null ? null : json["id"], id: json["id"] == null ? null : json["id"],
@ -64,7 +67,8 @@ class ChatUser {
isFav: json["isFav"] == null ? null : json["isFav"], isFav: json["isFav"] == null ? null : json["isFav"],
isAdmin: json["isAdmin"] == null ? null : json["isAdmin"], isAdmin: json["isAdmin"] == null ? null : json["isAdmin"],
isTyping: false, isTyping: false,
isLoadingCounter: true, isImageLoaded: false,
isImageLoading: true,
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {

@ -1,32 +1,35 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/foundation.dart';
List<SingleUserChatModel> singleUserChatModelFromJson(String str) => List<SingleUserChatModel>.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); List<SingleUserChatModel> singleUserChatModelFromJson(String str) => List<SingleUserChatModel>.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x)));
String singleUserChatModelToJson(List<SingleUserChatModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson()))); String singleUserChatModelToJson(List<SingleUserChatModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class SingleUserChatModel { class SingleUserChatModel {
SingleUserChatModel({ SingleUserChatModel(
this.userChatHistoryId, {this.userChatHistoryId,
this.userChatHistoryLineId, this.userChatHistoryLineId,
this.contant, this.contant,
this.contantNo, this.contantNo,
this.currentUserId, this.currentUserId,
this.currentUserName, this.currentUserName,
this.targetUserId, this.targetUserId,
this.targetUserName, this.targetUserName,
this.encryptedTargetUserId, this.encryptedTargetUserId,
this.encryptedTargetUserName, this.encryptedTargetUserName,
this.chatEventId, this.chatEventId,
this.fileTypeId, this.fileTypeId,
this.isSeen, this.isSeen,
this.isDelivered, this.isDelivered,
this.createdDate, this.createdDate,
this.chatSource, this.chatSource,
this.conversationId, this.conversationId,
this.fileTypeResponse, this.fileTypeResponse,
this.userChatReplyResponse, this.userChatReplyResponse,
this.isReplied, this.isReplied,
}); this.isImageLoaded,
this.image});
int? userChatHistoryId; int? userChatHistoryId;
int? userChatHistoryLineId; int? userChatHistoryLineId;
@ -48,29 +51,32 @@ class SingleUserChatModel {
FileTypeResponse? fileTypeResponse; FileTypeResponse? fileTypeResponse;
UserChatReplyResponse? userChatReplyResponse; UserChatReplyResponse? userChatReplyResponse;
bool? isReplied; bool? isReplied;
bool? isImageLoaded;
Uint8List? image;
factory SingleUserChatModel.fromJson(Map<String, dynamic> json) => SingleUserChatModel( factory SingleUserChatModel.fromJson(Map<String, dynamic> json) => SingleUserChatModel(
userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"], userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"],
userChatHistoryLineId: json["userChatHistoryLineId"] == null ? null : json["userChatHistoryLineId"], userChatHistoryLineId: json["userChatHistoryLineId"] == null ? null : json["userChatHistoryLineId"],
contant: json["contant"] == null ? null : json["contant"], contant: json["contant"] == null ? null : json["contant"],
contantNo: json["contantNo"] == null ? null : json["contantNo"], contantNo: json["contantNo"] == null ? null : json["contantNo"],
currentUserId: json["currentUserId"] == null ? null : json["currentUserId"], currentUserId: json["currentUserId"] == null ? null : json["currentUserId"],
currentUserName: json["currentUserName"] == null ? null : json["currentUserName"], currentUserName: json["currentUserName"] == null ? null : json["currentUserName"],
targetUserId: json["targetUserId"] == null ? null : json["targetUserId"], targetUserId: json["targetUserId"] == null ? null : json["targetUserId"],
targetUserName: json["targetUserName"] == null ? null : json["targetUserName"], targetUserName: json["targetUserName"] == null ? null : json["targetUserName"],
encryptedTargetUserId: json["encryptedTargetUserId"] == null ? null : json["encryptedTargetUserId"], encryptedTargetUserId: json["encryptedTargetUserId"] == null ? null : json["encryptedTargetUserId"],
encryptedTargetUserName: json["encryptedTargetUserName"] == null ? null : json["encryptedTargetUserName"], encryptedTargetUserName: json["encryptedTargetUserName"] == null ? null : json["encryptedTargetUserName"],
chatEventId: json["chatEventId"] == null ? null : json["chatEventId"], chatEventId: json["chatEventId"] == null ? null : json["chatEventId"],
fileTypeId: json["fileTypeId"], fileTypeId: json["fileTypeId"],
isSeen: json["isSeen"] == null ? null : json["isSeen"], isSeen: json["isSeen"] == null ? null : json["isSeen"],
isDelivered: json["isDelivered"] == null ? null : json["isDelivered"], isDelivered: json["isDelivered"] == null ? null : json["isDelivered"],
createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]), createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]),
chatSource: json["chatSource"] == null ? null : json["chatSource"], chatSource: json["chatSource"] == null ? null : json["chatSource"],
conversationId: json["conversationId"] == null ? null : json["conversationId"], conversationId: json["conversationId"] == null ? null : json["conversationId"],
fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]), fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]),
userChatReplyResponse: json["userChatReplyResponse"] == null ? null : UserChatReplyResponse.fromJson(json["userChatReplyResponse"]), userChatReplyResponse: json["userChatReplyResponse"] == null ? null : UserChatReplyResponse.fromJson(json["userChatReplyResponse"]),
isReplied: false, isReplied: false,
); isImageLoaded: false,
image: null);
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId, "userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId,
@ -138,6 +144,8 @@ class UserChatReplyResponse {
this.targetUserId, this.targetUserId,
this.targetUserName, this.targetUserName,
this.fileTypeResponse, this.fileTypeResponse,
this.isImageLoaded,
this.image,
}); });
int? userChatHistoryId; int? userChatHistoryId;
@ -149,18 +157,21 @@ class UserChatReplyResponse {
int? targetUserId; int? targetUserId;
String? targetUserName; String? targetUserName;
FileTypeResponse? fileTypeResponse; FileTypeResponse? fileTypeResponse;
bool? isImageLoaded;
Uint8List? image;
factory UserChatReplyResponse.fromJson(Map<String, dynamic> json) => UserChatReplyResponse( factory UserChatReplyResponse.fromJson(Map<String, dynamic> json) => UserChatReplyResponse(
userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"], userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"],
chatEventId: json["chatEventId"] == null ? null : json["chatEventId"], chatEventId: json["chatEventId"] == null ? null : json["chatEventId"],
contant: json["contant"] == null ? null : json["contant"], contant: json["contant"] == null ? null : json["contant"],
contantNo: json["contantNo"] == null ? null : json["contantNo"], contantNo: json["contantNo"] == null ? null : json["contantNo"],
fileTypeId: json["fileTypeId"], fileTypeId: json["fileTypeId"],
createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]), createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]),
targetUserId: json["targetUserId"] == null ? null : json["targetUserId"], targetUserId: json["targetUserId"] == null ? null : json["targetUserId"],
targetUserName: json["targetUserName"] == null ? null : json["targetUserName"], targetUserName: json["targetUserName"] == null ? null : json["targetUserName"],
fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]), fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]),
); isImageLoaded: false,
image: null);
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId, "userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId,

@ -5,19 +5,20 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:logging/logging.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart'; import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/encryption.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/exceptions/api_exception.dart';
import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/chat_user_image_model.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart'; import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as login; import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as userLoginToken;
import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav;
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/image_picker.dart'; import 'package:mohem_flutter_app/widgets/image_picker.dart';
import 'package:signalr_netcore/hub_connection.dart';
import 'package:signalr_netcore/signalr_client.dart'; import 'package:signalr_netcore/signalr_client.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@ -38,18 +39,58 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
List<ChatUser> favUsersList = []; List<ChatUser> favUsersList = [];
int paginationVal = 0; int paginationVal = 0;
Future<void> getUserAutoLoginToken() async {
userLoginToken.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
}
}
Future<void> buildHubConnection() async {
chatHubConnection = await getHubConnection();
await chatHubConnection.start();
}
Future<HubConnection> getHubConnection() async {
HubConnection hub;
// try {
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)
.withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
// isChatHubLoding = false;
return hub;
// } catch (e) {
// getUserAutoLoginToken().whenComplete(() {
// getHubConnection();
// });
// throw e;
// }
}
void registerEvents() { void registerEvents() {
hubConnection.on("OnUpdateUserStatusAsync", changeStatus); chatHubConnection.on("OnUpdateUserStatusAsync", changeStatus);
hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
// hubConnection.on("OnSeenChatUserAsync", onChatSeen); // hubConnection.on("OnSeenChatUserAsync", onChatSeen);
//hubConnection.on("OnUserTypingAsync", onUserTyping); //hubConnection.on("OnUserTypingAsync", onUserTyping);
hubConnection.on("OnUserCountAsync", userCountAsync); chatHubConnection.on("OnUserCountAsync", userCountAsync);
hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); // hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); chatHubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); chatHubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
} }
void getUserRecentChats() async { void getUserRecentChats() async {
if (chatHubConnection.state != HubConnectionState.Connected) {
getUserAutoLoginToken().whenComplete(() async {
await buildHubConnection();
getUserRecentChats();
});
return;
}
ChatUserModel recentChat = await ChatApiClient().getRecentChats(); ChatUserModel recentChat = await ChatApiClient().getRecentChats();
ChatUserModel favUList = await ChatApiClient().getFavUsers(); ChatUserModel favUList = await ChatApiClient().getFavUsers();
@ -80,10 +121,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
), ),
); );
notifyListeners(); notifyListeners();
getUserImages();
} }
Future invokeUserChatHistoryNotDeliveredAsync({required int userId}) async { Future invokeUserChatHistoryNotDeliveredAsync({required int userId}) async {
await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]); await chatHubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]);
return ""; return "";
} }
@ -92,12 +134,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
if (isNewChat) userChatHistory = []; if (isNewChat) userChatHistory = [];
if (!loadMore) paginationVal = 0; if (!loadMore) paginationVal = 0;
isChatScreenActive = true; isChatScreenActive = true;
Response response = await ChatApiClient().getSingleUserChatHistory( Response response = await ChatApiClient().getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore, paginationVal: paginationVal);
senderUID: senderUID,
receiverUID: receiverUID,
loadMore: loadMore,
paginationVal: paginationVal,
);
if (response.statusCode == 204) { if (response.statusCode == 204) {
if (isNewChat) { if (isNewChat) {
userChatHistory = []; userChatHistory = [];
@ -107,24 +144,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
} else { } else {
if (loadMore) { if (loadMore) {
List<SingleUserChatModel> temp = getSingleUserChatModel( List<SingleUserChatModel> temp = getSingleUserChatModel(response.body).reversed.toList();
response.body, userChatHistory.addAll(temp);
).reversed.toList();
userChatHistory.addAll(
temp,
);
} else { } else {
userChatHistory = getSingleUserChatModel( userChatHistory = getSingleUserChatModel(response.body).reversed.toList();
response.body,
).reversed.toList();
} }
} }
isLoading = false; isLoading = false;
notifyListeners(); notifyListeners();
markRead( markRead(userChatHistory, receiverUID);
userChatHistory,
receiverUID,
);
generateConvId(); generateConvId();
} }
@ -138,75 +166,79 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
for (SingleUserChatModel element in data!) { for (SingleUserChatModel element in data!) {
if (element.isSeen != null) { if (element.isSeen != null) {
if (!element.isSeen!) { if (!element.isSeen!) {
element.isSeen = true;
dynamic data = [ dynamic data = [
{ {
"userChatHistoryId": element.userChatHistoryId, "userChatHistoryId": element.userChatHistoryId,
"TargetUserId": element.targetUserId, "TargetUserId": element.currentUserId == receiverID ? element.currentUserId : element.targetUserId,
"isDelivered": true, "isDelivered": true,
"isSeen": true, "isSeen": true,
} }
]; ];
updateUserChatHistoryStatusAsync(data); updateUserChatHistoryStatusAsync(data);
notifyListeners();
} }
} }
} }
for (ChatUser element in searchedChats!) { for (ChatUser element in searchedChats!) {
if (element.id == receiverID) { if (element.id == receiverID) {
element.unreadMessageCount = 0; element.unreadMessageCount = 0;
notifyListeners(); // notifyListeners();
} }
} }
notifyListeners();
} }
} }
void updateUserChatHistoryStatusAsync(List data) { void updateUserChatHistoryStatusAsync(List data) {
hubConnection.invoke( try {
"UpdateUserChatHistoryStatusAsync", chatHubConnection.invoke("UpdateUserChatHistoryStatusAsync", args: [data]);
args: [data], } catch (e) {
); throw e;
}
} }
List<SingleUserChatModel> getSingleUserChatModel(String str) => List<SingleUserChatModel>.from( void updateUserChatHistoryOnMsg(List data) {
json.decode(str).map( try {
(x) => SingleUserChatModel.fromJson(x), chatHubConnection.invoke("UpdateUserChatHistoryStatusAsync", args: [data]);
), } catch (e) {
); throw e;
}
}
List<SingleUserChatModel> getSingleUserChatModel(String str) => List<SingleUserChatModel>.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x)));
Future<dynamic> uploadAttachments(String userId, File file) async { Future<dynamic> uploadAttachments(String userId, File file) async {
dynamic result; dynamic result;
try { try {
StreamedResponse response = await ChatApiClient().uploadMedia(userId, file); StreamedResponse response = await ChatApiClient().uploadMedia(userId, file);
if (response.statusCode == 200) { if (response.statusCode == 200) {
result = jsonDecode( result = jsonDecode(await response.stream.bytesToString());
await response.stream.bytesToString(),
);
} else { } else {
result = []; result = [];
} }
} catch (e) { } catch (e) {
print(e); throw e;
} }
;
return result; return result;
} }
void updateUserChatStatus(List<Object?>? args) { void updateUserChatStatus(List<Object?>? args) {
dynamic items = args!.toList(); dynamic items = args!.toList();
for (dynamic cItem in items[0]) { for (var cItem in items[0]) {
for (SingleUserChatModel chat in userChatHistory) { for (SingleUserChatModel chat in userChatHistory) {
if (chat.userChatHistoryId.toString() == cItem["userChatHistoryId"].toString()) { if (cItem["contantNo"].toString() == chat.contantNo.toString()) {
chat.isSeen = cItem["isSeen"]; chat.isSeen = cItem["isSeen"];
chat.isDelivered = cItem["isDelivered"]; chat.isDelivered = cItem["isDelivered"];
notifyListeners();
} }
} }
} }
notifyListeners();
} }
void onChatSeen(List<Object?>? args) { void onChatSeen(List<Object?>? args) {
dynamic items = args!.toList(); dynamic items = args!.toList();
logger.d("---------------------------------Chat Seen -------------------------------------");
logger.d(items);
// for (var user in searchedChats!) { // for (var user in searchedChats!) {
// if (user.id == items.first["id"]) { // if (user.id == items.first["id"]) {
// user.userStatus = items.first["userStatus"]; // user.userStatus = items.first["userStatus"];
@ -242,7 +274,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void chatNotDelivered(List<Object?>? args) { void chatNotDelivered(List<Object?>? args) {
dynamic items = args!.toList(); dynamic items = args!.toList();
logger.d(items);
for (dynamic item in items[0]) { for (dynamic item in items[0]) {
searchedChats!.forEach( searchedChats!.forEach(
(ChatUser element) { (ChatUser element) {
@ -250,7 +281,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
int? val = element.unreadMessageCount ?? 0; int? val = element.unreadMessageCount ?? 0;
element.unreadMessageCount = val! + 1; element.unreadMessageCount = val! + 1;
} }
element.isLoadingCounter = false;
}, },
); );
} }
@ -292,17 +322,35 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
data.first.targetUserName = temp.first.currentUserName; data.first.targetUserName = temp.first.currentUserName;
data.first.currentUserId = temp.first.targetUserId; data.first.currentUserId = temp.first.targetUserId;
data.first.currentUserName = temp.first.targetUserName; data.first.currentUserName = temp.first.targetUserName;
if (data.first.fileTypeId == 12 || data.first.fileTypeId == 4 || data.first.fileTypeId == 3) {
data.first.image = await ChatApiClient().downloadURL(fileName: data.first.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg");
}
if (data.first.userChatReplyResponse != null) {
if (data.first.fileTypeResponse != null) {
if (data.first.userChatReplyResponse!.fileTypeId == 12 || data.first.userChatReplyResponse!.fileTypeId == 4 || data.first.userChatReplyResponse!.fileTypeId == 3) {
data.first.userChatReplyResponse!.image =
await ChatApiClient().downloadURL(fileName: data.first.userChatReplyResponse!.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg");
data.first.userChatReplyResponse!.isImageLoaded = true;
}
}
}
} }
userChatHistory.insert(0, data.first); userChatHistory.insert(0, data.first);
var list = [
{ if (searchedChats != null && !isChatScreenActive) {
"userChatHistoryId": data.first.userChatHistoryId, for (ChatUser user in searchedChats!) {
"TargetUserId": data.first.targetUserId, if (user.id == data.first.currentUserId) {
"isDelivered": true, var tempCount = user.unreadMessageCount ?? 0;
"isSeen": isChatScreenActive ? true : false, user.unreadMessageCount = tempCount + 1;
}
} }
}
List list = [
{"userChatHistoryId": data.first.userChatHistoryId, "TargetUserId": temp.first.targetUserId, "isDelivered": true, "isSeen": isChatScreenActive ? true : false}
]; ];
updateUserChatHistoryStatusAsync(list); updateUserChatHistoryOnMsg(list);
notifyListeners(); notifyListeners();
} }
@ -389,34 +437,44 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
Future<void> sendChatToServer( Future<void> sendChatToServer(
{required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { {required int chatEventId,
required fileTypeId,
required int targetUserId,
required String targetUserName,
required chatReplyId,
required bool isAttachment,
required bool isReply,
Uint8List? image,
required bool isImageLoaded}) async {
Uuid uuid = const Uuid(); Uuid uuid = const Uuid();
var contentNo = uuid.v4();
var msg = message.text; var msg = message.text;
SingleUserChatModel data = SingleUserChatModel( SingleUserChatModel data = SingleUserChatModel(
chatEventId: chatEventId, chatEventId: chatEventId,
chatSource: 1, chatSource: 1,
contant: msg, contant: msg,
contantNo: uuid.v4(), contantNo: contentNo,
conversationId: chatCID, conversationId: chatCID,
createdDate: DateTime.now(), createdDate: DateTime.now(),
currentUserId: AppState().chatDetails!.response!.id, currentUserId: AppState().chatDetails!.response!.id,
currentUserName: AppState().chatDetails!.response!.userName, currentUserName: AppState().chatDetails!.response!.userName,
targetUserId: targetUserId, targetUserId: targetUserId,
targetUserName: targetUserName, targetUserName: targetUserName,
isReplied: false, isReplied: false,
fileTypeId: fileTypeId, fileTypeId: fileTypeId,
userChatReplyResponse: isReply ? UserChatReplyResponse.fromJson(repliedMsg.first.toJson()) : null, userChatReplyResponse: isReply ? UserChatReplyResponse.fromJson(repliedMsg.first.toJson()) : null,
fileTypeResponse: isAttachment fileTypeResponse: isAttachment
? FileTypeResponse( ? FileTypeResponse(
fileTypeId: fileTypeId, fileTypeId: fileTypeId,
fileTypeName: getFileType(getFileExtension(selectedFile.path).toString()), fileTypeName: getFileType(getFileExtension(selectedFile.path).toString()),
fileKind: getFileExtension(selectedFile.path), fileKind: getFileExtension(selectedFile.path),
fileName: selectedFile.path.split("/").last, fileName: selectedFile.path.split("/").last,
fileTypeDescription: getFileTypeDescription(getFileExtension(selectedFile.path).toString()), fileTypeDescription: getFileTypeDescription(getFileExtension(selectedFile.path).toString()),
) )
: null, : null,
); image: image,
isImageLoaded: isImageLoaded);
userChatHistory.insert(0, data); userChatHistory.insert(0, data);
isFileSelected = false; isFileSelected = false;
isMsgReply = false; isMsgReply = false;
@ -425,56 +483,75 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners(); notifyListeners();
String chatData = String chatData =
'{"contant":"$msg","contantNo":"${uuid.v4()}","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"$chatCID"}'; '{"contant":"$msg","contantNo":"$contentNo","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"$chatCID"}';
await hubConnection.invoke("AddChatUserAsync", args: <Object>[json.decode(chatData)]); await chatHubConnection.invoke("AddChatUserAsync", args: <Object>[json.decode(chatData)]);
} }
void sendChatMessage(int targetUserId, String targetUserName, BuildContext context) async { void sendChatMessage(int targetUserId, String targetUserName, BuildContext context) async {
dynamic contain = searchedChats!.where((ChatUser element) => element.id == targetUserId); dynamic contain = searchedChats!.where((ChatUser element) => element.id == targetUserId);
if (contain.isEmpty) { if (contain.isEmpty) {
searchedChats!.add( searchedChats!.add(
ChatUser( ChatUser(id: targetUserId, userName: targetUserName, unreadMessageCount: 0),
id: targetUserId,
userName: targetUserName,
unreadMessageCount: 0
),
); );
notifyListeners(); notifyListeners();
} }
if (!isFileSelected && !isMsgReply) { if (!isFileSelected && !isMsgReply) {
print("Normal Text Msg");
if (message.text == null || message.text.isEmpty) { if (message.text == null || message.text.isEmpty) {
return; return;
} }
sendChatToServer(chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: false, chatReplyId: null, isReply: false); sendChatToServer(
} chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: false, chatReplyId: null, isReply: false, isImageLoaded: false, image: null);
} // normal Text msg
if (isFileSelected && !isMsgReply) { if (isFileSelected && !isMsgReply) {
print("Normal Attachment Msg");
Utils.showLoading(context); Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
String? ext = getFileExtension(selectedFile.path); String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context); Utils.hideLoading(context);
sendChatToServer(chatEventId: 2, fileTypeId: getFileType(ext.toString()), targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: true, chatReplyId: null, isReply: false); sendChatToServer(
} chatEventId: 2,
fileTypeId: getFileType(ext.toString()),
targetUserId: targetUserId,
targetUserName: targetUserName,
isAttachment: true,
chatReplyId: null,
isReply: false,
isImageLoaded: true,
image: selectedFile.readAsBytesSync());
} // normal attachemnt msg
if (!isFileSelected && isMsgReply) { if (!isFileSelected && isMsgReply) {
print("Normal Text To Text Reply");
if (message.text == null || message.text.isEmpty) { if (message.text == null || message.text.isEmpty) {
return; return;
} }
sendChatToServer( sendChatToServer(
chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, chatReplyId: repliedMsg.first.userChatHistoryId, isAttachment: false, isReply: true); chatEventId: 1,
} fileTypeId: null,
targetUserId: targetUserId,
targetUserName: targetUserName,
chatReplyId: repliedMsg.first.userChatHistoryId,
isAttachment: false,
isReply: true,
isImageLoaded: repliedMsg.first.isImageLoaded!,
image: repliedMsg.first.image);
} // reply msg over image && normal
if (isFileSelected && isMsgReply) { if (isFileSelected && isMsgReply) {
print("Reply With File");
Utils.showLoading(context); Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
String? ext = getFileExtension(selectedFile.path); String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context); Utils.hideLoading(context);
sendChatToServer( sendChatToServer(
chatEventId: 2, chatEventId: 2,
fileTypeId: getFileType(ext.toString()), fileTypeId: getFileType(ext.toString()),
targetUserId: targetUserId, targetUserId: targetUserId,
targetUserName: targetUserName, targetUserName: targetUserName,
isAttachment: true, isAttachment: true,
chatReplyId: repliedMsg.first.userChatHistoryId, chatReplyId: repliedMsg.first.userChatHistoryId,
isReply: true, isReply: true,
); isImageLoaded: true,
image: selectedFile.readAsBytesSync());
} }
} }
@ -604,7 +681,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
void clearSelections() { void clearSelections() {
print("Hereee i am ");
searchedChats = pChatHistory; searchedChats = pChatHistory;
search.clear(); search.clear();
isChatScreenActive = false; isChatScreenActive = false;
@ -628,50 +704,35 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
sFileType = ""; sFileType = "";
} }
// void scrollListener() { void getUserImages() async {
// _firstAutoscrollExecuted = true; List<String> emails = [];
// if (scrollController.hasClients && scrollController.position.pixels == scrollController.position.maxScrollExtent) { for (ChatUser element in searchedChats!) {
// _shouldAutoscroll = true; emails.add(await EmailImageEncryption().encrypt(val: element.email!));
// } else { }
// _shouldAutoscroll = false; List<ChatUserImageModel> chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails);
// } for (ChatUser user in searchedChats!) {
// } for (ChatUserImageModel uImage in chatImages) {
// if (user.email == uImage.email) {
// void scrollToBottom() { user.image = uImage.profilePicture ?? "";
// scrollController.animateTo( user.isImageLoading = false;
// scrollController.position.maxScrollExtent + 100, user.isImageLoaded = true;
// duration: const Duration(milliseconds: 500), }
// curve: Curves.easeIn, }
// ); }
// } for (ChatUser favUser in favUsersList) {
for (ChatUserImageModel uImage in chatImages) {
void msgScroll() { if (favUser.email == uImage.email) {
scrollController.animateTo( favUser.image = uImage.profilePicture ?? "";
scrollController.position.minScrollExtent - 100, favUser.isImageLoading = false;
duration: const Duration(milliseconds: 500), favUser.isImageLoaded = true;
curve: Curves.easeIn, }
); }
}
notifyListeners();
} }
// Future<void> getDownLoadFile(String fileName) async { ///getUserAutoLoginToken().whenComplete(() {
// var data = await ChatApiClient().downloadURL(fileName: "data"); // buildHubConnection();
// Image.memory(data); // print("After Reconnect State: " + hubConnection.state.toString());
// } // });
// void getUserChatHistoryNotDeliveredAsync({required int userId}) async {
// try {
// await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]);
// } finally {
// hubConnection.off("GetUserChatHistoryNotDeliveredAsync", method: chatNotDelivered);
// }
// }
} }

@ -1,17 +1,13 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/api/offers_and_discounts_api_client.dart'; import 'package:mohem_flutter_app/api/offers_and_discounts_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/chat_count_conversation_model.dart'; import 'package:mohem_flutter_app/models/chat/chat_count_conversation_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart';
import 'package:mohem_flutter_app/models/dashboard/drawer_menu_item_model.dart'; import 'package:mohem_flutter_app/models/dashboard/drawer_menu_item_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_accrual_balances_list_model.dart'; import 'package:mohem_flutter_app/models/dashboard/get_accrual_balances_list_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart'; import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart';
@ -25,7 +21,6 @@ import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/itg/itg_response_model.dart'; import 'package:mohem_flutter_app/models/itg/itg_response_model.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:signalr_netcore/signalr_client.dart';
/// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool /// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool
// ignore: prefer_mixin // ignore: prefer_mixin
@ -42,7 +37,6 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
//Chat //Chat
bool isChatCounterLoding = true; bool isChatCounterLoding = true;
bool isChatHubLoding = true;
int chatUConvCounter = 0; int chatUConvCounter = 0;
//Misssing Swipe //Misssing Swipe
@ -103,7 +97,6 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
leaveBalanceAccrual = null; leaveBalanceAccrual = null;
isChatCounterLoding = true; isChatCounterLoding = true;
isChatHubLoding = true;
chatUConvCounter = 0; chatUConvCounter = 0;
ticketBalance = 0; ticketBalance = 0;
@ -294,26 +287,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
} }
Future<void> getUserAutoLoginToken() async {
UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
}
}
Future<HubConnection> getHubConnection() async {
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)
.withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
isChatHubLoding = false;
return hub;
}
void notify() { void notify() {
notifyListeners(); notifyListeners();
} }

@ -3,161 +3,49 @@ import 'dart:typed_data';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart'; import 'package:mohem_flutter_app/api/chat/chat_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/colors.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.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/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_full_image_preview.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheet.dart';
// todo: @aamir use extension methods, and use correct widgets. // todo: @aamir use extension methods, and use correct widgets.
class ChatBubble extends StatelessWidget { class ChatBubble extends StatelessWidget {
const ChatBubble( ChatBubble({Key? key, required this.dateTime, required this.cItem}) : super(key: key);
{Key? key,
required this.text,
required this.replyText,
required this.isCurrentUser,
required this.isSeen,
required this.isDelivered,
required this.dateTime,
required this.isReplied,
required this.userName,
this.fileTypeID,
this.fileTypeDescription})
: super(key: key);
final String text;
final String replyText;
final bool isCurrentUser;
final bool isSeen;
final bool isDelivered;
final String dateTime; final String dateTime;
final bool isReplied; final SingleUserChatModel cItem;
final String userName;
final int? fileTypeID; bool isCurrentUser = false;
final String? fileTypeDescription; bool isSeen = false;
bool isReplied = false;
int? fileTypeID;
String? fileTypeDescription;
bool isDelivered = false;
String userName = '';
late Offset screenOffset;
void makeAssign() {
isCurrentUser = cItem.currentUserId == AppState().chatDetails!.response!.id ? true : false;
isSeen = cItem.isSeen == true ? true : false;
isReplied = cItem.userChatReplyResponse != null ? true : false;
fileTypeID = cItem.fileTypeId;
fileTypeDescription = cItem.fileTypeResponse != null ? cItem.fileTypeResponse!.fileTypeDescription : "";
isDelivered = cItem.currentUserId == AppState().chatDetails!.response!.id && cItem.isDelivered == true ? true : false;
userName = AppState().chatDetails!.response!.userName == cItem.currentUserName.toString() ? "You" : cItem.currentUserName.toString();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Size windowSize = MediaQuery.of(context).size;
screenOffset = Offset(windowSize.width / 2, windowSize.height / 2);
makeAssign();
return isCurrentUser ? currentUser(context) : receiptUser(context); return isCurrentUser ? currentUser(context) : receiptUser(context);
return Padding(
// padding: EdgeInsets.zero,
padding: EdgeInsets.only(
left: isCurrentUser ? 110 : 20,
right: isCurrentUser ? 20 : 110,
bottom: 9,
),
child: Align(
alignment: isCurrentUser ? Alignment.centerRight : Alignment.centerLeft,
child: DecoratedBox(
decoration: BoxDecoration(
color: MyColors.white,
gradient: isCurrentUser
? null
: const LinearGradient(
transform: GradientRotation(
.46,
),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: <Color>[
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
),
borderRadius: BorderRadius.circular(
10,
),
),
child: Padding(
padding: EdgeInsets.only(
top: isReplied ? 8 : 5,
right: 8,
left: 8,
bottom: 5,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (isReplied)
ClipRRect(
borderRadius: BorderRadius.circular(
5.0,
),
child: Container(
decoration: BoxDecoration(
border: Border(
left: BorderSide(
width: 6,
color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white,
),
),
color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30),
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
(userName)
.toText12(
color: MyColors.gradiantStartColor,
isBold: false,
)
.paddingOnly(
right: 5,
top: 5,
bottom: 0,
left: 5,
),
replyText
.toText10(
color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5),
isBold: false,
maxlines: 4,
)
.paddingOnly(
right: 5,
top: 5,
bottom: 8,
left: 5,
),
],
),
),
],
),
),
),
if (isReplied) 8.height,
text.toText12(
color: isCurrentUser ? MyColors.grey57Color : MyColors.white,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
dateTime.toText12(
color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7),
),
if (isCurrentUser) 5.width,
if (isCurrentUser)
Icon(
isDelivered ? Icons.done_all : Icons.done_all,
color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor,
size: 14,
),
],
),
],
),
),
),
),
);
} }
Widget currentUser(context) { Widget currentUser(context) {
@ -166,9 +54,7 @@ class ChatBubble extends StatelessWidget {
children: [ children: [
if (isReplied) if (isReplied)
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(5.0),
5.0,
),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
@ -177,29 +63,71 @@ class ChatBubble extends StatelessWidget {
), ),
color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30), color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30),
), ),
child: Column( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: <Widget>[ Column(
(userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5), crossAxisAlignment: CrossAxisAlignment.start,
replyText.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4).paddingOnly(right: 5, top: 5, bottom: 8, left: 5), children: <Widget>[
(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),
],
).expanded,
if (cItem.userChatReplyResponse != null && cItem.userChatReplyResponse!.fileTypeId == 12 ||
cItem.userChatReplyResponse!.fileTypeId == 3 ||
cItem.userChatReplyResponse!.fileTypeId == 4)
// Container(
// padding: EdgeInsets.all(0), // Border width
// decoration: BoxDecoration(color: Colors.red, borderRadius: const BorderRadius.all(Radius.circular(8))),
// child: ClipRRect(
// borderRadius: const BorderRadius.all(
// Radius.circular(8),
// ),
// child: SizedBox.fromSize(
// size: Size.fromRadius(8), // Image radius
// child: showImage(
// isReplyPreview: true,
// fileName: cItem.userChatReplyResponse!.contant!,
// fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg"),
// ),
// ),
// ),
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: SizedBox(
height: 32,
width: 32,
child: showImage(
isReplyPreview: true,
fileName: cItem.userChatReplyResponse!.contant!,
fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg")
.paddingOnly(left: 10, right: 10, bottom: 16, top: 16),
),
),
], ],
).expanded, ),
), ),
).paddingOnly(right: 5, bottom: 7), ).paddingOnly(right: 5, bottom: 7),
if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3) showImage().paddingOnly(right: 5), if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3)
if (fileTypeID != 12 || fileTypeID != 4 || fileTypeID != 3) (text).toText12(), showImage(isReplyPreview: false, fileName: cItem.contant!, fileTypeDescription: cItem.fileTypeResponse!.fileTypeDescription).paddingOnly(right: 5).onPress(() {
showDialog(
context: context,
anchorPoint: screenOffset,
builder: (BuildContext context) => ChatImagePreviewScreen(imgTitle: cItem.contant!, img: cItem.image!),
);
}),
cItem.contant!.toText12(),
Align( Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
dateTime.toText10(color: MyColors.grey41Color.withOpacity(.5)), dateTime.toText10(
7.width, color: MyColors.grey41Color.withOpacity(.5),
Icon(
isDelivered ? Icons.done_all : Icons.done_all,
color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor,
size: 14,
), ),
7.width,
Icon(isDelivered ? Icons.done_all : Icons.done_all, color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor, size: 14),
], ],
), ),
), ),
@ -207,7 +135,7 @@ class ChatBubble extends StatelessWidget {
).paddingOnly(top: 11, left: 13, right: 7, bottom: 5).objectContainerView(disablePadding: true).paddingOnly(left: MediaQuery.of(context).size.width * 0.3); ).paddingOnly(top: 11, left: 13, right: 7, bottom: 5).objectContainerView(disablePadding: true).paddingOnly(left: MediaQuery.of(context).size.width * 0.3);
} }
Widget receiptUser(context) { Widget receiptUser(BuildContext context) {
return Container( return Container(
padding: const EdgeInsets.only(top: 11, left: 13, right: 7, bottom: 5), padding: const EdgeInsets.only(top: 11, left: 13, right: 7, bottom: 5),
decoration: BoxDecoration( decoration: BoxDecoration(
@ -227,57 +155,95 @@ class ChatBubble extends StatelessWidget {
children: [ children: [
if (isReplied) if (isReplied)
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(5.0),
5.0,
),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border( border: Border(left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white)),
left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white),
),
color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30), color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30),
), ),
child: Column( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: <Widget>[ Column(
(userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5), crossAxisAlignment: CrossAxisAlignment.start,
replyText.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4).paddingOnly(right: 5, top: 5, bottom: 8, left: 5), children: <Widget>[
(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),
],
).expanded,
if (cItem.userChatReplyResponse != null && cItem.userChatReplyResponse!.fileTypeId == 12 ||
cItem.userChatReplyResponse!.fileTypeId == 3 ||
cItem.userChatReplyResponse!.fileTypeId == 4)
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: SizedBox(
height: 32,
width: 32,
child: showImage(
isReplyPreview: true,
fileName: cItem.userChatReplyResponse!.contant!,
fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg"),
),
).paddingOnly(left: 10, right: 10, bottom: 16, top: 16)
], ],
).expanded, ),
), ),
).paddingOnly(right: 5, bottom: 7), ).paddingOnly(right: 5, bottom: 7),
if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3) showImage().paddingOnly(right: 5) else (text).toText12(color: Colors.white), if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3)
showImage(isReplyPreview: false, fileName: cItem.contant ?? "", fileTypeDescription: cItem.fileTypeResponse!.fileTypeDescription ?? "image/jpg").paddingOnly(right: 5).onPress(() {
showDialog(
context: context,
anchorPoint: screenOffset,
builder: (BuildContext context) => ChatImagePreviewScreen(imgTitle: cItem.contant ?? "", img: cItem.image!),
);
})
else
(cItem.contant ?? "").toText12(color: Colors.white),
Align( Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: dateTime.toText10( child: dateTime.toText10(color: Colors.white.withOpacity(.71)),
color: Colors.white.withOpacity(.71),
),
), ),
], ],
), ),
).paddingOnly(right: MediaQuery.of(context).size.width * 0.3); ).paddingOnly(right: MediaQuery.of(context).size.width * 0.3);
} }
Widget showImage() { Widget showImage({required bool isReplyPreview, required String fileName, required String fileTypeDescription}) {
return FutureBuilder<Uint8List>( if (cItem.isImageLoaded! && cItem.image != null) {
future: ChatApiClient().downloadURL(fileName: text, fileTypeDescription: fileTypeDescription!), return Image.memory(
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) { cItem.image!,
if (snapshot.connectionState != ConnectionState.waiting) { height: isReplyPreview ? 32 : 140,
if (snapshot.data == null) { width: isReplyPreview ? 32 : 227,
return (text).toText12(color: Colors.white); fit: BoxFit.cover,
);
} else {
return FutureBuilder<Uint8List>(
future: ChatApiClient().downloadURL(fileName: fileName, fileTypeDescription: fileTypeDescription),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState != ConnectionState.waiting) {
if (snapshot.data == null) {
return SizedBox();
} else {
cItem.image = snapshot.data;
cItem.isImageLoaded = true;
return Image.memory(
snapshot.data,
height: isReplyPreview ? 32 : 140,
width: isReplyPreview ? 32 : 227,
fit: BoxFit.cover,
);
}
} else { } else {
return Image.memory( return SizedBox(
snapshot.data, height: isReplyPreview ? 32 : 140,
height: 140, width: isReplyPreview ? 32 : 227,
width: 227, child: const Center(child: CircularProgressIndicator()),
fit: BoxFit.cover,
); );
} }
} else { },
return const SizedBox(height: 140, width: 227, child: Center(child: CircularProgressIndicator())); );
} }
},
);
} }
} }

@ -12,6 +12,7 @@ import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/call.dart'; import 'package:mohem_flutter_app/models/chat/call.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart'; import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart';
import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart'; import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart';
@ -74,7 +75,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
context, context,
title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach, title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach,
showHomeButton: false, showHomeButton: false,
image: userDetails["targetUser"].image, image: userDetails["targetUser"].image == null || userDetails["targetUser"].image.isEmpty ? null : userDetails["targetUser"].image,
actions: [ actions: [
SvgPicture.asset("assets/icons/chat/call.svg", width: 21, height: 23).onPress(() { SvgPicture.asset("assets/icons/chat/call.svg", width: 21, height: 23).onPress(() {
// makeCall(callType: "AUDIO", con: hubConnection); // makeCall(callType: "AUDIO", con: hubConnection);
@ -89,7 +90,9 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
body: Consumer<ChatProviderModel>( body: Consumer<ChatProviderModel>(
builder: (BuildContext context, ChatProviderModel m, Widget? child) { builder: (BuildContext context, ChatProviderModel m, Widget? child) {
return (m.isLoading return (m.isLoading
? ChatHomeShimmer() ? ChatHomeShimmer(
isDetailedScreen: true,
)
: Column( : Column(
children: <Widget>[ children: <Widget>[
SmartRefresher( SmartRefresher(
@ -115,16 +118,8 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
return SwipeTo( return SwipeTo(
iconColor: MyColors.lightGreenColor, iconColor: MyColors.lightGreenColor,
child: ChatBubble( child: ChatBubble(
text: m.userChatHistory[i].contant.toString(),
replyText: m.userChatHistory[i].userChatReplyResponse != null ? m.userChatHistory[i].userChatReplyResponse!.contant.toString() : "",
isSeen: m.userChatHistory[i].isSeen == true ? true : false,
isCurrentUser: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id ? true : false,
isDelivered: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id && m.userChatHistory[i].isDelivered == true ? true : false,
dateTime: m.dateFormte(m.userChatHistory[i].createdDate!), dateTime: m.dateFormte(m.userChatHistory[i].createdDate!),
isReplied: m.userChatHistory[i].userChatReplyResponse != null ? true : false, cItem: m.userChatHistory[i],
userName: AppState().chatDetails!.response!.userName == m.userChatHistory[i].currentUserName.toString() ? "You" : m.userChatHistory[i].currentUserName.toString(),
fileTypeID: m.userChatHistory[i].fileTypeId,
fileTypeDescription: m.userChatHistory[i].fileTypeResponse!.fileTypeDescription,
), ),
onRightSwipe: () { onRightSwipe: () {
m.chatReply( m.chatReply(
@ -159,6 +154,8 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
], ],
).expanded, ).expanded,
12.width, 12.width,
if (m.isMsgReply && m.repliedMsg.isNotEmpty) showReplyImage(m.repliedMsg),
12.width,
const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe), const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe),
], ],
), ),
@ -224,6 +221,19 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
); );
} }
Widget showReplyImage(List<SingleUserChatModel> data) {
if (data.first.isImageLoaded! && data.first.image != null) {
return Container(
width: 43,
height: 43,
decoration: BoxDecoration(
border: Border.all(color: MyColors.darkGrey3BColor, width: 1), borderRadius: BorderRadius.circular(10.0), image: DecorationImage(image: MemoryImage(data.first.image!), fit: BoxFit.cover)),
);
} else {
return const SizedBox();
}
}
void makeCall({required String callType, required HubConnection con}) async { void makeCall({required String callType, required HubConnection con}) async {
print("================== Make call Triggered ============================"); print("================== Make call Triggered ============================");
Map<String, dynamic> json = { Map<String, dynamic> json = {

@ -0,0 +1,50 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
class ChatImagePreviewScreen extends StatelessWidget {
const ChatImagePreviewScreen({Key? key, required this.imgTitle, required this.img}) : super(key: key);
final String imgTitle;
final Uint8List img;
@override
Widget build(BuildContext context) {
return Dialog(
backgroundColor: Colors.transparent,
insetPadding: const EdgeInsets.all(10),
child: Stack(
alignment: Alignment.center,
fit: StackFit.loose,
children: <Widget>[
Image.memory(
img,
fit: BoxFit.fill,
).paddingAll(15),
Positioned(
right: 0,
top: 0,
child: Container(
width: 30,
height: 30,
alignment: Alignment.center,
padding: EdgeInsets.zero,
margin: EdgeInsets.zero,
constraints: const BoxConstraints(),
color: MyColors.white,
child: const Icon(
Icons.cancel,
color: MyColors.redA3Color,
size: 30,
),
).onPress(() {
Navigator.of(context).pop();
}).circle(35),
)
],
),
);
}
}

@ -8,8 +8,10 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_home_screen.dart'; import 'package:mohem_flutter_app/ui/chat/chat_home_screen.dart';
import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart'; import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:signalr_netcore/signalr_client.dart';
class ChatHome extends StatefulWidget { class ChatHome extends StatefulWidget {
const ChatHome({Key? key}) : super(key: key); const ChatHome({Key? key}) : super(key: key);
@ -27,6 +29,17 @@ class _ChatHomeState extends State<ChatHome> {
void initState() { void initState() {
super.initState(); super.initState();
data = Provider.of<ChatProviderModel>(context, listen: false); data = Provider.of<ChatProviderModel>(context, listen: false);
data.registerEvents();
if (chatHubConnection.state != HubConnectionState.Connected) {
data.getUserAutoLoginToken().whenComplete(() async {
await data.buildHubConnection();
data.getUserRecentChats();
});
return;
}
if (data.searchedChats == null || data.searchedChats!.isEmpty) {
data.getUserRecentChats();
}
} }
@override @override

@ -1,9 +1,14 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_des/flutter_des.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/encryption.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/string_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/extensions/widget_extensions.dart';
@ -11,10 +16,13 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheet.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_sheet.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_sheet.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ChatHomeScreen extends StatefulWidget { class ChatHomeScreen extends StatefulWidget {
const ChatHomeScreen({Key? key}) : super(key: key);
@override @override
State<ChatHomeScreen> createState() => _ChatHomeScreenState(); State<ChatHomeScreen> createState() => _ChatHomeScreenState();
} }
@ -25,11 +33,8 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
@override @override
void initState() { void initState() {
// TODO: implement initState
super.initState(); super.initState();
data = Provider.of<ChatProviderModel>(context, listen: false); data = Provider.of<ChatProviderModel>(context, listen: false);
data.registerEvents();
data.getUserRecentChats();
} }
@override @override
@ -45,7 +50,7 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
body: Consumer<ChatProviderModel>( body: Consumer<ChatProviderModel>(
builder: (BuildContext context, ChatProviderModel m, Widget? child) { builder: (BuildContext context, ChatProviderModel m, Widget? child) {
return m.isLoading return m.isLoading
? ChatHomeShimmer() ? ChatHomeShimmer(isDetailedScreen: false,)
: Column( : Column(
children: <Widget>[ children: <Widget>[
TextField( TextField(
@ -62,7 +67,7 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
hintText: LocaleKeys.searchfromchat.tr(), hintText: LocaleKeys.searchfromchat.tr(),
hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic, fontWeight: FontWeight.w500, fontSize: 12), hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic, fontWeight: FontWeight.w500, fontSize: 12),
filled: true, filled: true,
fillColor: const Color(0xFFF7F7F7), fillColor: MyColors.greyF7Color,
suffixIconConstraints: const BoxConstraints(), suffixIconConstraints: const BoxConstraints(),
suffixIcon: m.search.text.isNotEmpty suffixIcon: m.search.text.isNotEmpty
? IconButton( ? IconButton(
@ -81,19 +86,33 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
itemCount: m.searchedChats!.length, itemCount: m.searchedChats!.length,
shrinkWrap: true, shrinkWrap: true,
physics: const ClampingScrollPhysics(), physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.only(bottom: 80.0),
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
// todo @aamir, remove list tile, make a custom ui instead
return SizedBox( return SizedBox(
height: 55, height: 55,
child: Row( child: Row(
children: [ children: [
Stack( Stack(
children: <Widget>[ children: <Widget>[
SvgPicture.asset( if (m.searchedChats![index].isImageLoading!)
"assets/images/user.svg", const SizedBox(
height: 48, height: 48,
width: 48, width: 48,
), ).toShimmer().circle(30),
if (m.searchedChats![index].isImageLoaded! && m.searchedChats![index].image != null && m.searchedChats![index].image.isNotEmpty)
CircularAvatar(
radius: 20,
height: 48,
width: 48,
url: m.searchedChats![index].image,
isImageBase64: true,
),
if (!m.searchedChats![index].isImageLoading! && m.searchedChats![index].isImageLoaded! && m.searchedChats![index].image.isEmpty)
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
Positioned( Positioned(
right: 5, right: 5,
bottom: 1, bottom: 1,
@ -102,11 +121,8 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
height: 10, height: 10,
decoration: BoxDecoration( decoration: BoxDecoration(
color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red,
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
), ),
), ).circle(10),
) )
], ],
), ),
@ -175,14 +191,13 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
AppRoutes.chatDetailed, AppRoutes.chatDetailed,
arguments: {"targetUser": m.searchedChats![index], "isNewChat": false}, arguments: {"targetUser": m.searchedChats![index], "isNewChat": false},
).then((Object? value) { ).then((Object? value) {
// m.GetUserChatHistoryNotDeliveredAsync(userId: int.parse(AppState().chatDetails!.response!.id.toString()));
m.clearSelections(); m.clearSelections();
m.notifyListeners(); m.notifyListeners();
}); });
}); });
}, },
separatorBuilder: (BuildContext context, int index) => const Divider(color: MyColors.lightGreyE5Color).paddingOnly(left: 59), separatorBuilder: (BuildContext context, int index) => const Divider(color: MyColors.lightGreyE5Color).paddingOnly(left: 59),
).paddingOnly(bottom: 70).expanded, ).expanded,
], ],
).paddingOnly(left: 21, right: 21); ).paddingOnly(left: 21, right: 21);
}, },
@ -227,13 +242,9 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
OutlineInputBorder fieldBorder({required double radius, required int color}) { OutlineInputBorder fieldBorder({required double radius, required int color}) {
return OutlineInputBorder( return OutlineInputBorder(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(radius),
radius,
),
borderSide: BorderSide( borderSide: BorderSide(
color: Color( color: Color(color),
color,
),
), ),
); );
} }

@ -9,6 +9,7 @@ import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/string_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/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -22,7 +23,7 @@ class ChatFavoriteUsersScreen extends StatelessWidget {
body: Consumer<ChatProviderModel>( body: Consumer<ChatProviderModel>(
builder: (BuildContext context, ChatProviderModel m, Widget? child) { builder: (BuildContext context, ChatProviderModel m, Widget? child) {
if (m.isLoading) { if (m.isLoading) {
return ChatHomeShimmer(); return ChatHomeShimmer(isDetailedScreen: false,);
} else { } else {
return m.favUsersList != null && m.favUsersList.isNotEmpty return m.favUsersList != null && m.favUsersList.isNotEmpty
? ListView.separated( ? ListView.separated(
@ -36,11 +37,25 @@ class ChatFavoriteUsersScreen extends StatelessWidget {
children: [ children: [
Stack( Stack(
children: <Widget>[ children: <Widget>[
SvgPicture.asset( if (m.favUsersList![index].isImageLoading!)
"assets/images/user.svg", const SizedBox(
height: 48, height: 48,
width: 48, width: 48,
), ).toShimmer().circle(30),
if (m.favUsersList![index].isImageLoaded! && m.favUsersList![index].image != null && m.favUsersList![index].image.isNotEmpty)
CircularAvatar(
radius: 20,
height: 48,
width: 48,
url: m.favUsersList![index].image,
isImageBase64: true,
),
if (!m.favUsersList![index].isImageLoading! && m.favUsersList![index].isImageLoaded! && m.favUsersList![index].image.isEmpty)
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
Positioned( Positioned(
right: 5, right: 5,
bottom: 1, bottom: 1,
@ -49,11 +64,8 @@ class ChatFavoriteUsersScreen extends StatelessWidget {
height: 10, height: 10,
decoration: BoxDecoration( decoration: BoxDecoration(
color: m.favUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, color: m.favUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red,
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
), ),
), ).circle(10),
) )
], ],
), ),

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:ui' as ui;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
@ -14,6 +15,7 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_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/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.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/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/ui/landing/widget/app_drawer.dart'; import 'package:mohem_flutter_app/ui/landing/widget/app_drawer.dart';
import 'package:mohem_flutter_app/ui/landing/widget/menus_widget.dart'; import 'package:mohem_flutter_app/ui/landing/widget/menus_widget.dart';
@ -28,7 +30,7 @@ import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:signalr_netcore/signalr_client.dart'; import 'package:signalr_netcore/signalr_client.dart';
late HubConnection hubConnection; late HubConnection chatHubConnection;
class DashboardScreen extends StatefulWidget { class DashboardScreen extends StatefulWidget {
DashboardScreen({Key? key}) : super(key: key); DashboardScreen({Key? key}) : super(key: key);
@ -42,6 +44,7 @@ class DashboardScreen extends StatefulWidget {
class _DashboardScreenState extends State<DashboardScreen> { class _DashboardScreenState extends State<DashboardScreen> {
late DashboardProviderModel data; late DashboardProviderModel data;
late MarathonProvider marathonProvider; late MarathonProvider marathonProvider;
late ChatProviderModel cProvider;
final GlobalKey<ScaffoldState> _scaffoldState = GlobalKey(); final GlobalKey<ScaffoldState> _scaffoldState = GlobalKey();
final RefreshController _refreshController = RefreshController(initialRefresh: false); final RefreshController _refreshController = RefreshController(initialRefresh: false);
@ -54,25 +57,21 @@ class _DashboardScreenState extends State<DashboardScreen> {
scheduleMicrotask(() { scheduleMicrotask(() {
data = Provider.of<DashboardProviderModel>(context, listen: false); data = Provider.of<DashboardProviderModel>(context, listen: false);
marathonProvider = Provider.of<MarathonProvider>(context, listen: false); marathonProvider = Provider.of<MarathonProvider>(context, listen: false);
cProvider = Provider.of<ChatProviderModel>(context, listen: false);
_bHubCon(); _bHubCon();
_onRefresh(); _onRefresh();
}); });
} }
void buildHubConnection() async {
hubConnection = await data.getHubConnection();
await hubConnection.start();
}
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
hubConnection.stop(); chatHubConnection.stop();
} }
void _bHubCon() { void _bHubCon() {
data.getUserAutoLoginToken().whenComplete(() { cProvider.getUserAutoLoginToken().whenComplete(() {
buildHubConnection(); cProvider.buildHubConnection();
}); });
} }
@ -105,9 +104,11 @@ class _DashboardScreenState extends State<DashboardScreen> {
// onPressed: () { // onPressed: () {
// data.getITGNotification().then((val) { // data.getITGNotification().then((val) {
// if (val!.result!.data != null) { // if (val!.result!.data != null) {
// print("-------------------- Survey ----------------------------");
// if (val.result!.data!.notificationType == "Survey") { // if (val.result!.data!.notificationType == "Survey") {
// Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data); // Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data);
// } else { // } else {
// print("------------------------------------------- Ads --------------------");
// DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then( // DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then(
// (value) { // (value) {
// if (value!.mohemmItgResponseItem!.statusCode == 200) { // if (value!.mohemmItgResponseItem!.statusCode == 200) {
@ -236,11 +237,14 @@ class _DashboardScreenState extends State<DashboardScreen> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
9.height, 9.height,
CountdownTimer( Directionality(
endTime: model.endTime, textDirection: ui.TextDirection.ltr,
onEnd: null, child: CountdownTimer(
endWidget: "00:00:00".toText14(color: Colors.white, isBold: true), endTime: model.endTime,
textStyle: const TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold), onEnd: null,
endWidget: "00:00:00".toText14(color: Colors.white, isBold: true),
textStyle: const TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold),
),
), ),
LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white),
9.height, 9.height,

@ -69,7 +69,7 @@ class _ITGAdsScreenState extends State<ITGAdsScreen> {
await controller.setLooping(false); await controller.setLooping(false);
return controller; return controller;
} catch (e) { } catch (e) {
return new VideoPlayerController.asset("dataSource"); return VideoPlayerController.asset("dataSource");
} }
} }
@ -94,29 +94,28 @@ class _ITGAdsScreenState extends State<ITGAdsScreen> {
if (advertisementData != null) { if (advertisementData != null) {
checkFileType(); checkFileType();
} }
double height = MediaQuery.of(context).size.height * .25; // double height = MediaQuery.of(context).size.height * .25;
return Scaffold( return Scaffold(
body: Column( body: Stack(
children: [ children: [
if (isVideo) if (isVideo)
SizedBox( FutureBuilder(
height: MediaQuery.of(context).size.height * .3, future: _futureController,
child: FutureBuilder( builder: (BuildContext context, AsyncSnapshot<Object?> snapshot) {
future: _futureController, if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) {
builder: (BuildContext context, AsyncSnapshot<Object?> snapshot) { _controller = snapshot.data as VideoPlayerController;
if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) { return Positioned.fill(
_controller = snapshot.data as VideoPlayerController; child: AspectRatio(
return AspectRatio(
aspectRatio: _controller.value.aspectRatio, aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller), child: VideoPlayer(_controller),
); ),
} else { );
return const Center( } else {
child: CircularProgressIndicator(), return const Center(
); child: CircularProgressIndicator(),
} );
}, }
), },
), ),
if (isImage) Image.file(imageFile), if (isImage) Image.file(imageFile),
if (skip) if (skip)

@ -99,10 +99,13 @@ class _TodayAttendanceScreenState extends State<TodayAttendanceScreen2> {
child: CountdownTimer( child: CountdownTimer(
endTime: model.endTime, endTime: model.endTime,
widgetBuilder: (context, v) { widgetBuilder: (context, v) {
return AutoSizeText( return Directionality(
getValue(v?.hours) + " : " + getValue(v?.min) + " : " + getValue(v?.sec), textDirection: TextDirection.ltr,
maxLines: 1, child: AutoSizeText(
style: const TextStyle(color: Colors.white, fontSize: 42, letterSpacing: -1.92, fontWeight: FontWeight.bold, height: 1), getValue(v?.hours) + " : " + getValue(v?.min) + " : " + getValue(v?.sec),
maxLines: 1,
style: const TextStyle(color: Colors.white, fontSize: 42, letterSpacing: -1.92, fontWeight: FontWeight.bold, height: 1),
),
); );
}, },
onEnd: null, onEnd: null,
@ -116,7 +119,7 @@ class _TodayAttendanceScreenState extends State<TodayAttendanceScreen2> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
LocaleKeys.shiftTime.tr().tr().toTextAuto(color: MyColors.greyACColor, fontSize: 18, maxLine: 1).paddingOnly(left: 21,right: 21), LocaleKeys.shiftTime.tr().tr().toTextAuto(color: MyColors.greyACColor, fontSize: 18, maxLine: 1).paddingOnly(left: 21, right: 21),
(model.attendanceTracking!.pShtName ?? "00:00:00").toString().toTextAuto(color: Colors.white, isBold: true, fontSize: 26, maxLine: 1), (model.attendanceTracking!.pShtName ?? "00:00:00").toString().toTextAuto(color: Colors.white, isBold: true, fontSize: 26, maxLine: 1),
], ],
), ),

@ -69,28 +69,28 @@ class _AppDrawerState extends State<AppDrawer> {
).expanded ).expanded
], ],
).paddingOnly(left: 14, right: 14, top: 21, bottom: 21), ).paddingOnly(left: 14, right: 14, top: 21, bottom: 21),
Row( // Row(
children: [ // children: [
Row( // Row(
children: [ // children: [
LocaleKeys.english.tr().toText14(color: AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() { // LocaleKeys.english.tr().toText14(color: AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() {
context.setLocale(const Locale("en", "US")); // context.setLocale(const Locale("en", "US"));
postLanguageChange(context); // postLanguageChange(context);
}), // }),
Container( // Container(
width: 1, // width: 1,
color: MyColors.darkWhiteColor, // color: MyColors.darkWhiteColor,
height: 16, // height: 16,
margin: const EdgeInsets.only(left: 10, right: 10), // margin: const EdgeInsets.only(left: 10, right: 10),
), // ),
LocaleKeys.arabic.tr().toText14(color: !AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() { // LocaleKeys.arabic.tr().toText14(color: !AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() {
context.setLocale(const Locale("ar", "SA")); // context.setLocale(const Locale("ar", "SA"));
postLanguageChange(context); // postLanguageChange(context);
}), // }),
], // ],
), // ),
], // ],
).paddingOnly(left: 14, right: 14, bottom: 14), // ).paddingOnly(left: 14, right: 14, bottom: 14),
const Divider( const Divider(
height: 1, height: 1,
thickness: 1, thickness: 1,

@ -109,17 +109,16 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
} }
} }
} }
await LeaveBalanceApiClient() await LeaveBalanceApiClient().validateAbsenceTransaction(
.validateAbsenceTransaction( selectedAbsenceType!.dESCFLEXCONTEXTCODE!,
selectedAbsenceType!.dESCFLEXCONTEXTCODE!, "HR_LOA_SS",
"HR_LOA_SS", selectedAbsenceType!.aBSENCEATTENDANCETYPEID!,
selectedAbsenceType!.aBSENCEATTENDANCETYPEID!, selectedReplacementEmployee != null ? selectedReplacementEmployee!.userName! : "",
selectedReplacementEmployee != null ? selectedReplacementEmployee!.userName! : "", DateUtil.getFormattedDate(startDateTime!, "MM/dd/yyyy"),
DateUtil.getFormattedDate(startDateTime!, "MM/dd/yyyy"), DateUtil.getFormattedDate(endDateTime!, "MM/dd/yyyy"),
DateUtil.getFormattedDate(endDateTime!, "MM/dd/yyyy"), -999,
-999, dffDataMap,
dffDataMap, comments: comment);
comments: comment);
SumbitAbsenceTransactionList submit = await LeaveBalanceApiClient().submitAbsenceTransaction( SumbitAbsenceTransactionList submit = await LeaveBalanceApiClient().submitAbsenceTransaction(
selectedAbsenceType!.dESCFLEXCONTEXTCODE!, selectedAbsenceType!.dESCFLEXCONTEXTCODE!,
@ -134,8 +133,10 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
Utils.hideLoading(context); Utils.hideLoading(context);
await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submit.pTRANSACTIONID!, "", "add_leave_balance")); var res = await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submit.pTRANSACTIONID!, "", "add_leave_balance"));
Utils.showLoading(context); if (res != null && res == true) {
Utils.showLoading(context);
}
await LeaveBalanceApiClient().cancelHrTransaction(submit.pTRANSACTIONID!); await LeaveBalanceApiClient().cancelHrTransaction(submit.pTRANSACTIONID!);
Utils.hideLoading(context); Utils.hideLoading(context);
} catch (ex) { } catch (ex) {

@ -143,8 +143,8 @@ class _LoginScreenState extends State<LoginScreen> {
isAppOpenBySystem = (ModalRoute.of(context)!.settings.arguments ?? true) as bool; isAppOpenBySystem = (ModalRoute.of(context)!.settings.arguments ?? true) as bool;
if (!kReleaseMode) { if (!kReleaseMode) {
// username.text = "15444"; // Maha User // username.text = "15444"; // Maha User
username.text = "15153"; // Tamer User // username.text = "15153"; // Tamer User
password.text = "Abcd@1234"; // password.text = "Abcd@1234";
// username.text = "206535"; // Hashim User // username.text = "206535"; // Hashim User
// password.text = "Namira786"; // password.text = "Namira786";

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:ui' as ui;
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -53,80 +54,83 @@ class BuildCountdownTimer extends StatelessWidget {
); );
Widget buildEmptyWidget() { Widget buildEmptyWidget() {
return Row( return Directionality(
mainAxisSize: MainAxisSize.min, textDirection: ui.TextDirection.ltr,
mainAxisAlignment: MainAxisAlignment.spaceEvenly, child: Row(
crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min,
children: <Widget>[ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
Column( crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
// todo @faiz: Make a separate method and pass string , so we can minimize code replication Column(
AutoSizeText( children: <Widget>[
"00", // todo @faiz: Make a separate method and pass string , so we can minimize code replication
maxFontSize: 24, AutoSizeText(
minFontSize: 20, "00",
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
), minFontSize: 20,
AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
LocaleKeys.days.tr(), ),
minFontSize: 7, AutoSizeText(
maxFontSize: 8, LocaleKeys.days.tr(),
style: screenFlag == 0 ? styleTextHome : styleTextMarathon, minFontSize: 7,
), maxFontSize: 8,
], style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
), ),
buildSeparator(), ],
Column( ),
children: <Widget>[ buildSeparator(),
AutoSizeText( Column(
"00", children: <Widget>[
maxFontSize: 24, AutoSizeText(
minFontSize: 20, "00",
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
), minFontSize: 20,
AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
LocaleKeys.hours.tr(), ),
minFontSize: 7, AutoSizeText(
maxFontSize: 8, LocaleKeys.hours.tr(),
style: screenFlag == 0 ? styleTextHome : styleTextMarathon, minFontSize: 7,
), maxFontSize: 8,
], style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
), ),
buildSeparator(), ],
Column( ),
children: <Widget>[ buildSeparator(),
AutoSizeText( Column(
"00", children: <Widget>[
maxFontSize: 24, AutoSizeText(
minFontSize: 20, "00",
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
), minFontSize: 20,
AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
LocaleKeys.minutes.tr(), ),
minFontSize: 7, AutoSizeText(
maxFontSize: 8, LocaleKeys.minutes.tr(),
style: screenFlag == 0 ? styleTextHome : styleTextMarathon, minFontSize: 7,
), maxFontSize: 8,
], style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
), ),
buildSeparator(), ],
Column( ),
children: <Widget>[ buildSeparator(),
AutoSizeText( Column(
"00", children: <Widget>[
maxFontSize: 24, AutoSizeText(
minFontSize: 20, "00",
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
), minFontSize: 20,
AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
LocaleKeys.seconds.tr(), ),
minFontSize: 7, AutoSizeText(
maxFontSize: 8, LocaleKeys.seconds.tr(),
style: screenFlag == 0 ? styleTextHome : styleTextMarathon, minFontSize: 7,
), maxFontSize: 8,
], style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
), ),
], ],
),
],
),
); );
} }
@ -149,108 +153,111 @@ class BuildCountdownTimer extends StatelessWidget {
return buildEmptyWidget(); return buildEmptyWidget();
} }
return Row( return Directionality(
mainAxisSize: MainAxisSize.min, textDirection: ui.TextDirection.ltr,
mainAxisAlignment: MainAxisAlignment.spaceEvenly, child: Row(
crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min,
children: <Widget>[ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
Column( crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
// todo @faiz: Make a separate method and pass value and string , so we can minimize code replication Column(
time.days == null children: <Widget>[
? AutoSizeText( // todo @faiz: Make a separate method and pass value and string , so we can minimize code replication
"00", time.days == null
maxFontSize: 24, ? AutoSizeText(
minFontSize: 20, "00",
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
) minFontSize: 20,
: AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
time.days! < 10 ? "0${time.days.toString()}" : time.days.toString(), )
maxFontSize: 24, : AutoSizeText(
minFontSize: 20, time.days! < 10 ? "0${time.days.toString()}" : time.days.toString(),
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
), minFontSize: 20,
AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
LocaleKeys.days.tr(), ),
minFontSize: 7, AutoSizeText(
maxFontSize: 8, LocaleKeys.days.tr(),
style: screenFlag == 0 ? styleTextHome : styleTextMarathon, minFontSize: 7,
), maxFontSize: 8,
], style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
), ),
buildSeparator(), ],
Column( ),
children: <Widget>[ buildSeparator(),
time.hours == null Column(
? AutoSizeText( children: <Widget>[
"00", time.hours == null
maxFontSize: 24, ? AutoSizeText(
minFontSize: 20, "00",
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
) minFontSize: 20,
: AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
time.hours! < 10 ? "0${time.hours.toString()}" : time.hours.toString(), )
maxFontSize: 24, : AutoSizeText(
minFontSize: 20, time.hours! < 10 ? "0${time.hours.toString()}" : time.hours.toString(),
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
), minFontSize: 20,
AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
LocaleKeys.hours.tr(), ),
minFontSize: 7, AutoSizeText(
maxFontSize: 8, LocaleKeys.hours.tr(),
style: screenFlag == 0 ? styleTextHome : styleTextMarathon, minFontSize: 7,
), maxFontSize: 8,
], style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
), ),
buildSeparator(), ],
Column( ),
children: <Widget>[ buildSeparator(),
time.min == null Column(
? AutoSizeText( children: <Widget>[
"00", time.min == null
maxFontSize: 24, ? AutoSizeText(
minFontSize: 20, "00",
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
) minFontSize: 20,
: AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
time.min! < 10 ? "0${time.min.toString()}" : time.min.toString(), )
maxFontSize: 24, : AutoSizeText(
minFontSize: 20, time.min! < 10 ? "0${time.min.toString()}" : time.min.toString(),
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
), minFontSize: 20,
AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
LocaleKeys.minutes.tr(), ),
minFontSize: 7, AutoSizeText(
maxFontSize: 8, LocaleKeys.minutes.tr(),
style: screenFlag == 0 ? styleTextHome : styleTextMarathon, minFontSize: 7,
), maxFontSize: 8,
], style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
), ),
buildSeparator(), ],
Column( ),
children: <Widget>[ buildSeparator(),
time.sec == null Column(
? AutoSizeText( children: <Widget>[
"00", time.sec == null
maxFontSize: 24, ? AutoSizeText(
minFontSize: 20, "00",
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
) minFontSize: 20,
: AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
time.sec! < 10 ? "0${time.sec.toString()}" : time.sec.toString(), )
maxFontSize: 24, : AutoSizeText(
minFontSize: 20, time.sec! < 10 ? "0${time.sec.toString()}" : time.sec.toString(),
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, maxFontSize: 24,
), minFontSize: 20,
AutoSizeText( style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
LocaleKeys.seconds.tr(), ),
minFontSize: 7, AutoSizeText(
maxFontSize: 8, LocaleKeys.seconds.tr(),
style: screenFlag == 0 ? styleTextHome : styleTextMarathon, minFontSize: 7,
), maxFontSize: 8,
], style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
), ),
], ],
),
],
),
); );
} }

@ -22,6 +22,7 @@ import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/button/simple_button.dart'; import 'package:mohem_flutter_app/widgets/button/simple_button.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:mohem_flutter_app/widgets/image_picker.dart';
import 'package:mohem_flutter_app/widgets/input_widget.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart';
class RequestSubmitScreenParams { class RequestSubmitScreenParams {
@ -48,6 +49,7 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
List<GetApprovesList> approverList = []; List<GetApprovesList> approverList = [];
List<File> attachmentFiles = []; List<File> attachmentFiles = [];
List<String> attachments = [];
@override @override
void initState() { void initState() {
@ -68,20 +70,20 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
} }
void submitRequest() async { void submitRequest() async {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
List<Map<String, dynamic>> list = []; List<Map<String, dynamic>> list = [];
if (attachmentFiles.isNotEmpty) { if (attachmentFiles.isNotEmpty) {
attachmentFiles.asMap().forEach((index, value) async { attachments.asMap().forEach((index, value) async {
String type = value.path.split('.').last; String type = attachmentFiles[index].path.split('.').last;
String name = value.path.split('/').last; String name = attachmentFiles[index].path.split('/').last;
List<int> fileContent = await value.readAsBytes(); // List<int> fileContent = await value.readAsBytes();
String encodedFile = base64Encode(fileContent); // String encodedFile = base64Encode(fileContent);
list.add(AttachmentModel( list.add(AttachmentModel(
attachmentID: index, attachmentID: index,
pFILECONTENTTYPE: type, pFILECONTENTTYPE: type,
pFILENAME: name, pFILENAME: name,
pFILEDATA: encodedFile, pFILEDATA: value,
pTRANSACTIONID: params!.transactionId, pTRANSACTIONID: params!.transactionId,
).toJson()); ).toJson());
}); });
@ -129,7 +131,7 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
params!.pItemId, params!.pItemId,
params!.transactionId, params!.transactionId,
); );
}else if (params!.approvalFlag == 'endEmployment') { } else if (params!.approvalFlag == 'endEmployment') {
await TerminationDffApiClient().startTermApprovalProcess( await TerminationDffApiClient().startTermApprovalProcess(
"SUBMIT", "SUBMIT",
comments.text, comments.text,
@ -261,12 +263,18 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
title.toText16().expanded, title.toText16().expanded,
6.width, 6.width,
SimpleButton(LocaleKeys.add.tr(), () async { SimpleButton(LocaleKeys.add.tr(), () async {
FilePickerResult? result = await FilePicker.platform.pickFiles(allowMultiple: true); ImageOptions.showImageOptionsNew(context, false, (String image, File file) {
if (result != null) { setState(() {
attachmentFiles = attachmentFiles + result.paths.map((path) => File(path!)).toList(); attachmentFiles.add(file);
attachmentFiles = attachmentFiles.toSet().toList(); attachments.add(image);
setState(() {}); Navigator.of(context).pop();
} });
});
// if (result != null) {
// attachmentFiles = attachmentFiles + result.paths.map((path) => File(path!)).toList();
// attachmentFiles = attachmentFiles.toSet().toList();
// setState(() {});
// }
}, fontSize: 14), }, fontSize: 14),
], ],
), ),

@ -50,6 +50,18 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
descFlexConTextTitle = genericResponseModel!.pDESCFLEXCONTEXTNAME ?? ""; descFlexConTextTitle = genericResponseModel!.pDESCFLEXCONTEXTNAME ?? "";
getEitDffStructureList = genericResponseModel?.getEITDFFStructureList ?? []; getEitDffStructureList = genericResponseModel?.getEITDFFStructureList ?? [];
//getEitDffStructureList = getEitDffStructureList!.where((element) => element.dISPLAYFLAG != "N").toList(); //getEitDffStructureList = getEitDffStructureList!.where((element) => element.dISPLAYFLAG != "N").toList();
if (dynamicParams!.collectionNotificationList != null && dynamicParams!.collectionNotificationList!.isNotEmpty) {
getEitDffStructureList!.forEach((element) {
dynamicParams!.collectionNotificationList!.forEach((element2) {
if (element.sEGMENTNAME == element2.segmentName) {
element.fieldAnswer = element2.varchar2Value;
element.eSERVICESDV ??= ESERVICESDV();
element.eSERVICESDV!.pIDCOLUMNNAME = element2.varchar2Value;
}
});
});
}
Utils.hideLoading(context); Utils.hideLoading(context);
setState(() {}); setState(() {});
} catch (ex) { } catch (ex) {
@ -96,9 +108,11 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
SubmitEITTransactionList submitEITTransactionList = SubmitEITTransactionList submitEITTransactionList =
await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp ?? ''); await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp ?? '');
Utils.hideLoading(context); Utils.hideLoading(context);
await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, var res = await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit')); arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit'));
Utils.showLoading(context); if (res != null && res == true) {
Utils.showLoading(context);
}
await LeaveBalanceApiClient().cancelHrTransaction(submitEITTransactionList.pTRANSACTIONID!); await LeaveBalanceApiClient().cancelHrTransaction(submitEITTransactionList.pTRANSACTIONID!);
Utils.hideLoading(context); Utils.hideLoading(context);
} catch (ex) { } catch (ex) {
@ -114,15 +128,22 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
for (int i = 0; i < (structureList.cHILDSEGMENTSVSSplited?.length ?? 0); i++) { for (int i = 0; i < (structureList.cHILDSEGMENTSVSSplited?.length ?? 0); i++) {
List<Map<String, dynamic>> values = [];
String segmentId = structureList.cHILDSEGMENTSVSSplited![i]; String segmentId = structureList.cHILDSEGMENTSVSSplited![i];
if (dESCFLEXCONTEXTCODE.isEmpty) dESCFLEXCONTEXTCODE = structureList.dESCFLEXCONTEXTCODE!; if (dESCFLEXCONTEXTCODE.isEmpty) dESCFLEXCONTEXTCODE = structureList.dESCFLEXCONTEXTCODE!;
List<GetEITDFFStructureList> filteredList = getEitDffStructureList?.where((element) => element.cHILDSEGMENTSVSSplited!.contains(segmentId)).toList() ?? []; List<GetEITDFFStructureList> filteredList = getEitDffStructureList?.where((element) => element.cHILDSEGMENTSVSSplited!.contains(segmentId)).toList() ?? [];
List<Map<String, dynamic>> values = filteredList
if (filteredList.isEmpty && structureList.cHILDSEGMENTSVSSplited!.isNotEmpty) {
segmentId = structureList.cHILDSEGMENTSVSSplited![0];
filteredList = getEitDffStructureList?.where((element) => element.cHILDSEGMENTSVSSplited!.contains(segmentId)).toList() ?? [];
}
values = filteredList
.map((e) => GetSetValuesRequestModel( .map((e) => GetSetValuesRequestModel(
sEGMENTNAME: e.sEGMENTNAME, vALUECOLUMNNAME: e.eSERVICESDV!.pVALUECOLUMNNAME, dESCRIPTION: "", iDCOLUMNNAME: e.eSERVICESDV!.pIDCOLUMNNAME, fLEXVALUESETNAME: e.fLEXVALUESETNAME) sEGMENTNAME: e.sEGMENTNAME, vALUECOLUMNNAME: e.eSERVICESDV!.pVALUECOLUMNNAME, dESCRIPTION: "", iDCOLUMNNAME: e.eSERVICESDV!.pIDCOLUMNNAME, fLEXVALUESETNAME: e.fLEXVALUESETNAME)
.toJson()) .toJson())
.toList(); .toList();
List<ESERVICESVS> eServicesResponseModel = await MyAttendanceApiClient().getValueSetValues(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, values, List<ESERVICESVS> eServicesResponseModel = await MyAttendanceApiClient().getValueSetValues(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, values,
empID: dynamicParams!.selectedEmp ?? '', parentValue: structureList.eSERVICESDV!.pVALUECOLUMNNAME); empID: dynamicParams!.selectedEmp ?? '', parentValue: structureList.eSERVICESDV!.pVALUECOLUMNNAME);
List<GetEITDFFStructureList> abc = genericResponseModel?.getEITDFFStructureList ?? []; List<GetEITDFFStructureList> abc = genericResponseModel?.getEITDFFStructureList ?? [];
@ -162,9 +183,28 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
List<Map<String, dynamic>> getSetList = getDefaultValuesIonicLogic(parent); List<Map<String, dynamic>> getSetList = getDefaultValuesIonicLogic(parent);
if (getSetList.isNotEmpty) { if (getSetList.isNotEmpty) {
ESERVICESDV defaultValue = await MyAttendanceApiClient().getDefaultValue(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, getSetList, dynamicParams!.selectedEmp); ESERVICESDV defaultValue =
await MyAttendanceApiClient().getDefaultValue(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, getSetList, empID: dynamicParams!.selectedEmp);
int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId); int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId);
getEitDffStructureList![index].eSERVICESDV = defaultValue; getEitDffStructureList![index].eSERVICESDV = defaultValue;
GetEITDFFStructureList defaultValueCheck = getEitDffStructureList!.where((GetEITDFFStructureList element) => element.sEGMENTNAME == segmentId).toList().first;
if (defaultValueCheck.cHILDSEGMENTSDVSplited!.isNotEmpty && defaultValueCheck.rEADONLY == 'Y') {
getDefaultValues(defaultValueCheck);
Utils.hideLoading(context);
// GetEITDFFStructureList? parent = getEitDffStructureList!.firstWhere((element) => element.sEGMENTNAME == segmentId);
// List<Map<String, dynamic>> getSetList = getDefaultValuesIonicLogic(parent);
// ESERVICESDV defaultValue = await MyAttendanceApiClient().getDefaultValue(segmentId, defaultValueCheck.dESCFLEXCONTEXTCODE!, defaultValueCheck.dESCFLEXNAME!, getSetList);
// int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId);
// getEitDffStructureList![index].eSERVICESDV = defaultValue;
} else if (defaultValueCheck.cHILDSEGMENTSVSSplited!.isNotEmpty && defaultValueCheck.rEADONLY == 'Y') {
calGetValueSetValues(defaultValueCheck);
Utils.hideLoading(context);
}
} else if (values.isNotEmpty) {
ESERVICESDV defaultValue = await MyAttendanceApiClient().getDefaultValue(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, values);
int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId);
} }
} }
await Future.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
@ -305,7 +345,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
idColName = val; idColName = val;
if (getEitDffStructureList![j].fORMATTYPE == "X") { if (getEitDffStructureList![j].fORMATTYPE == "X") {
idColName = Utils.formatDateNew(idColName!); idColName = Utils.formatDateDefault(idColName!);
// commenting to test // commenting to test
// DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!); // DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!);
// idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date); // idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date);
@ -324,7 +364,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
if (getEitDffStructureList![j].rEADONLY != "Y") { if (getEitDffStructureList![j].rEADONLY != "Y") {
var data = getEitDffStructureList![j].eSERVICESDV; var data = getEitDffStructureList![j].eSERVICESDV;
// let x = document.getElementById(getEitDffStructureList![j].aPPLICATIONCOLUMNNAME) as HTMLSelectElement; //let x = document.getElementById(getEitDffStructureList![j].aPPLICATIONCOLUMNNAME) as HTMLSelectElement;
String? text = data?.pIDCOLUMNNAME; //x.options[x.selectedIndex] ? x.options[x.selectedIndex].text : ""; String? text = data?.pIDCOLUMNNAME; //x.options[x.selectedIndex] ? x.options[x.selectedIndex].text : "";
String? val = data?.pVALUECOLUMNNAME; //x.options[x.selectedIndex] ? x.options[x.selectedIndex].value : null; String? val = data?.pVALUECOLUMNNAME; //x.options[x.selectedIndex] ? x.options[x.selectedIndex].value : null;
if ((val ?? "").isEmpty && parentsList[i].isRequired == "REQUIRED") { if ((val ?? "").isEmpty && parentsList[i].isRequired == "REQUIRED") {

@ -99,7 +99,7 @@ class _SubordinateLeaveState extends State<SubordinateLeave> {
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
var diffDays = DateUtil.convertStringToDate(getSubordinatesLeavesTotalList[index].dATEEND!) var diffDays = DateUtil.convertStringToDate(getSubordinatesLeavesTotalList[index].dATEEND!)
.difference(DateUtil.convertStringToDate(getSubordinatesLeavesTotalList[index].dATESTART!)) .difference(DateUtil.convertStringToDate(getSubordinatesLeavesTotalList[index].dATESTART!))
.inDays; .inDays + 1;
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [

@ -74,9 +74,9 @@ class _DynamicInputScreenState extends State<DynamicInputScreenProfile> {
getBasicDetColsStructureList?.forEach((GetBasicDetColsStructureList element) { getBasicDetColsStructureList?.forEach((GetBasicDetColsStructureList element) {
element.userBasicDetail = element.userBasicDetail =
dynamicParams!.getEmployeeBasicDetailsList!.singleWhere((GetEmployeeBasicDetailsList userDetail) => userDetail.aPPLICATIONCOLUMNNAME == element.aPPLICATIONCOLUMNNAME); dynamicParams!.getEmployeeBasicDetailsList!.singleWhere((GetEmployeeBasicDetailsList userDetail) => userDetail.aPPLICATIONCOLUMNNAME == element.aPPLICATIONCOLUMNNAME);
if (element.objectValuesList != null) { if (element.objectValuesList != null && element.userBasicDetail?.vARCHAR2VALUE != '') {
ObjectValuesList dropDownListValue = element.objectValuesList!.singleWhere((ObjectValuesList dropdown) => dropdown.cODE == element.userBasicDetail!.vARCHAR2VALUE); ObjectValuesList dropDownListValue = element.objectValuesList!.singleWhere((ObjectValuesList dropdown) => dropdown.cODE == element.userBasicDetail?.vARCHAR2VALUE);
element.userBasicDetail!.sEGMENTVALUEDSP = dropDownListValue.mEANING; element.userBasicDetail?.sEGMENTVALUEDSP = dropDownListValue.mEANING;
} }
}); });
} else { } else {
@ -93,9 +93,9 @@ class _DynamicInputScreenState extends State<DynamicInputScreenProfile> {
getBasicDetColsStructureList?.forEach((GetBasicDetColsStructureList element) { getBasicDetColsStructureList?.forEach((GetBasicDetColsStructureList element) {
element.userBasicDetail = element.userBasicDetail =
dynamicParams!.getEmployeeBasicDetailsList!.singleWhere((GetEmployeeBasicDetailsList userDetail) => userDetail.aPPLICATIONCOLUMNNAME == element.aPPLICATIONCOLUMNNAME); dynamicParams!.getEmployeeBasicDetailsList!.singleWhere((GetEmployeeBasicDetailsList userDetail) => userDetail.aPPLICATIONCOLUMNNAME == element.aPPLICATIONCOLUMNNAME);
if (element.objectValuesList != null) { if (element.objectValuesList != null && element.userBasicDetail!.vARCHAR2VALUE != '') {
ObjectValuesList dropDownListValue = element.objectValuesList!.singleWhere((ObjectValuesList dropdown) => dropdown.cODE == element.userBasicDetail!.vARCHAR2VALUE); ObjectValuesList dropDownListValue = element.objectValuesList!.singleWhere((ObjectValuesList dropdown) => dropdown.cODE == element.userBasicDetail!.vARCHAR2VALUE);
element.userBasicDetail!.sEGMENTVALUEDSP = dropDownListValue.mEANING; element.userBasicDetail?.sEGMENTVALUEDSP = dropDownListValue.mEANING;
} }
}); });
} }
@ -262,7 +262,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreenProfile> {
return PopupMenuButton( return PopupMenuButton(
child: DynamicTextFieldWidget( child: DynamicTextFieldWidget(
(model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""), (model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""),
getBasicDetColsStructureList![index].userBasicDetail!.sEGMENTVALUEDSP ?? "", getBasicDetColsStructureList![index].userBasicDetail?.sEGMENTVALUEDSP ?? "",
isEnable: false, isEnable: false,
isPopup: true, isPopup: true,
).paddingOnly(bottom: 12), ).paddingOnly(bottom: 12),
@ -363,7 +363,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreenProfile> {
Utils.showLoading(context); Utils.showLoading(context);
int numberValue = 0; int numberValue = 0;
List<Map<String, dynamic>> values = getBasicDetDffStructureList!.map((e) { List<Map<String, dynamic>> values = getBasicDetDffStructureList!.map((e) {
String tempVar = e.userBasicDetail!.vARCHAR2VALUE ?? ""; String tempVar = e.userBasicDetail?.vARCHAR2VALUE ?? "";
if (e.fORMATTYPE == "X") { if (e.fORMATTYPE == "X") {
// for date format type, date format is changed // for date format type, date format is changed

@ -43,7 +43,7 @@ class PersonalInfo extends StatelessWidget {
LocaleKeys.Payroll.tr().toText13(color: MyColors.lightGrayColor), LocaleKeys.Payroll.tr().toText13(color: MyColors.lightGrayColor),
(memberInformationList.pAYROLLNAME ?? "").toText16(), (memberInformationList.pAYROLLNAME ?? "").toText16(),
], ],
).objectContainerView(center: false).paddingAll(21), ).objectContainerView().paddingAll(21),
), ),
); );
} }

@ -95,7 +95,7 @@ class _AnnouncementsState extends State<Announcements> {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
(AppState().isArabic(context) ? _foundAnnouncements[index].titleAR! : getAnnouncementsObject[index].titleEN!).toText13(), (AppState().isArabic(context) ? _foundAnnouncements[index].titleAR! : _foundAnnouncements[index].titleEN!).toText13(),
8.height, 8.height,
_foundAnnouncements[index].created!.toText10(color: MyColors.grey98Color) _foundAnnouncements[index].created!.toText10(color: MyColors.grey98Color)
], ],

@ -35,6 +35,7 @@ class ItgDetailScreen extends StatefulWidget {
class _ItgDetailScreenState extends State<ItgDetailScreen> { class _ItgDetailScreenState extends State<ItgDetailScreen> {
int tabIndex = 0; int tabIndex = 0;
int animationIndex = 0;
PageController controller = PageController(); PageController controller = PageController();
bool showFabOptions = false; bool showFabOptions = false;
@ -82,6 +83,7 @@ class _ItgDetailScreenState extends State<ItgDetailScreen> {
void getDataFromState() { void getDataFromState() {
if (requestDetails == null) { if (requestDetails == null) {
animationIndex = animationIndex + 1;
requestDetails = AppState().requestAllList![AppState().itgWorkListIndex!]; // ModalRoute.of(context)!.settings.arguments as WorkListResponseModel; requestDetails = AppState().requestAllList![AppState().itgWorkListIndex!]; // ModalRoute.of(context)!.settings.arguments as WorkListResponseModel;
providerData.itgFormsModel!.totalCount = providerData.itgFormsModel!.totalCount! - 1; providerData.itgFormsModel!.totalCount = providerData.itgFormsModel!.totalCount! - 1;
getItgData(); getItgData();
@ -95,151 +97,170 @@ class _ItgDetailScreenState extends State<ItgDetailScreen> {
return Scaffold( return Scaffold(
appBar: AppBarWidget(context, title: LocaleKeys.details.tr()), appBar: AppBarWidget(context, title: LocaleKeys.details.tr()),
backgroundColor: Colors.white, backgroundColor: Colors.white,
body: Stack( body: AnimatedSwitcher(
children: [ duration: const Duration(milliseconds: 500),
Column( switchInCurve: Curves.easeInToLinear,
children: [ transitionBuilder: (Widget child, Animation<double> animation) {
Container( Animation<Offset> custom = Tween<Offset>(
padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16), begin: const Offset(1.0, 0.0),
decoration: const BoxDecoration( end: Offset.zero,
borderRadius: BorderRadius.only( ).animate(animation);
bottomLeft: Radius.circular(25), return ClipRect(
bottomRight: Radius.circular(25), child: SlideTransition(
position: custom,
child: child,
// textDirection: TextDirection.ltr,
),
);
},
child: Stack(
key: ValueKey(animationIndex),
children: [
Column(
children: [
Container(
padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16),
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(25),
bottomRight: Radius.circular(25),
),
gradient: LinearGradient(
transform: GradientRotation(.83),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
),
), ),
gradient: LinearGradient( child: Row(
transform: GradientRotation(.83), children: [
begin: Alignment.topRight, myTab(LocaleKeys.requestDetails.tr(), 0),
end: Alignment.bottomLeft, myTab(LocaleKeys.approvalLevel.tr(), 1),
colors: [ myTab(LocaleKeys.requesterDetails.tr(), 2),
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
], ],
), ),
), ),
child: Row( PageView(
controller: controller,
onPageChanged: (pageIndex) {
setState(() {
tabIndex = pageIndex;
});
},
children: [ children: [
myTab(LocaleKeys.requestDetails.tr(), 0), RequestDetailFragment(fields: itgRequest?.fieldGoups?[1].fields ?? []),
myTab(LocaleKeys.approvalLevel.tr(), 1), ApprovalLevelfragment(
myTab(LocaleKeys.requesterDetails.tr(), 2), wFHistory: itgRequest?.wFHistory ?? [],
voidCallback: reloadITG,
),
RequestDetailFragment(fields: itgRequest?.fieldGoups?[0].fields ?? []),
], ],
), ).expanded,
), if (isApproveAvailable || isRejectAvailable || isCloseAvailable)
PageView( Container(
controller: controller, padding: const EdgeInsets.only(top: 14, bottom: 14, left: 21, right: 21),
onPageChanged: (pageIndex) { decoration: const BoxDecoration(
setState(() { color: Colors.white,
tabIndex = pageIndex; border: Border(
}); top: BorderSide(
}, color: MyColors.lightGreyEFColor,
children: [ width: 1.0,
RequestDetailFragment(fields: itgRequest?.fieldGoups?[1].fields ?? []), ),
ApprovalLevelfragment(
wFHistory: itgRequest?.wFHistory ?? [],
voidCallback: reloadITG,
),
RequestDetailFragment(fields: itgRequest?.fieldGoups?[0].fields ?? []),
],
).expanded,
if (isApproveAvailable || isRejectAvailable || isCloseAvailable)
Container(
padding: const EdgeInsets.only(top: 14, bottom: 14, left: 21, right: 21),
decoration: const BoxDecoration(
color: Colors.white,
border: Border(
top: BorderSide(
color: MyColors.lightGreyEFColor,
width: 1.0,
), ),
), ),
), child: Row(
child: Row( children: [
if (isRejectAvailable)
DefaultButton(
LocaleKeys.reject.tr(),
() => performAction("REJECTED"),
colors: const [
Color(0xffE47A7E),
Color(0xffDE6D71),
],
).expanded,
if (isApproveAvailable && isRejectAvailable) 8.width,
if (isApproveAvailable)
DefaultButton(
LocaleKeys.approve.tr(),
() => performAction("APPROVED"),
colors: const [
Color(0xff28C884),
Color(0xff1BB271),
],
).expanded,
if (isCloseAvailable)
DefaultButton(
LocaleKeys.ok.tr(),
() => performAction("CLOSE"),
colors: const [
Color(0xff32D892),
Color(0xff1AB170),
],
).expanded,
8.width,
Container(
height: 43,
width: 43,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: MyColors.lightGreyE6Color,
),
child: Icon(showFabOptions ? Icons.more_vert_rounded : Icons.more_horiz_rounded, color: MyColors.darkIconColor),
).onPress(() {
setState(() {
showFabOptions = true;
});
})
],
),
)
],
),
IgnorePointer(
ignoring: !showFabOptions,
child: AnimatedOpacity(
opacity: showFabOptions ? 1 : 0,
duration: const Duration(milliseconds: 250),
child: Container(
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 75 - 12),
width: double.infinity,
height: double.infinity,
color: Colors.white.withOpacity(.67),
alignment: Alignment.bottomRight,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
if (isRejectAvailable) myFab(LocaleKeys.skip.tr(), "assets/images/skip.svg").onPress(() {
DefaultButton( if (AppState().requestAllList!.length - 1 > AppState().itgWorkListIndex!) {
LocaleKeys.reject.tr(), animationIndex = animationIndex + 1;
() => performAction("REJECTED"), AppState().itgWorkListIndex = AppState().itgWorkListIndex! + 1;
colors: const [ requestDetails = null;
Color(0xffE47A7E), itgRequest = null;
Color(0xffDE6D71), tabIndex = 0;
], showFabOptions = false;
).expanded, getDataFromState();
if (isApproveAvailable && isRejectAvailable) 8.width, } else if (AppState().requestAllList!.length - 1 == AppState().itgWorkListIndex!) {
if (isApproveAvailable) Navigator.pop(context);
DefaultButton( }
LocaleKeys.approve.tr(), }),
() => performAction("APPROVED"), 12.height,
colors: const [ ...viewApiButtonsList(allowedActionList),
Color(0xff28C884),
Color(0xff1BB271),
],
).expanded,
if (isCloseAvailable)
DefaultButton(
LocaleKeys.ok.tr(),
() => performAction("CLOSE"),
colors: const [
Color(0xff32D892),
Color(0xff1AB170),
],
).expanded,
8.width,
Container(
height: 43,
width: 43,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: MyColors.lightGreyE6Color,
),
child: Icon(showFabOptions ? Icons.more_vert_rounded : Icons.more_horiz_rounded, color: MyColors.darkIconColor),
).onPress(() {
setState(() {
showFabOptions = true;
});
})
], ],
), ),
)
],
),
IgnorePointer(
ignoring: !showFabOptions,
child: AnimatedOpacity(
opacity: showFabOptions ? 1 : 0,
duration: const Duration(milliseconds: 250),
child: Container(
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 75 - 12),
width: double.infinity,
height: double.infinity,
color: Colors.white.withOpacity(.67),
alignment: Alignment.bottomRight,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
myFab(LocaleKeys.skip.tr(), "assets/images/skip.svg").onPress(() {
if (AppState().requestAllList!.length - 1 > AppState().itgWorkListIndex!) {
AppState().itgWorkListIndex = AppState().itgWorkListIndex! + 1;
requestDetails = null;
itgRequest = null;
tabIndex = 0;
showFabOptions = false;
getDataFromState();
} else if (AppState().requestAllList!.length - 1 == AppState().itgWorkListIndex!) {
Navigator.pop(context);
}
}),
12.height,
...viewApiButtonsList(allowedActionList),
],
), ),
), ).onPress(() {
).onPress(() { setState(() {
setState(() { showFabOptions = false;
showFabOptions = false; });
}); }),
}), ),
), ],
], ),
), ),
floatingActionButton: (!isApproveAvailable && !isRejectAvailable && !isCloseAvailable) floatingActionButton: (!isApproveAvailable && !isRejectAvailable && !isCloseAvailable)
? Container( ? Container(
@ -514,6 +535,7 @@ class _ItgDetailScreenState extends State<ItgDetailScreen> {
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.showToast(LocaleKeys.yourChangeHasBeenSavedSuccessfully.tr()); Utils.showToast(LocaleKeys.yourChangeHasBeenSavedSuccessfully.tr());
// Navigator.pop(context, "delegate_reload"); // Navigator.pop(context, "delegate_reload");
animationIndex=animationIndex+1;
AppState().requestAllList!.removeAt(AppState().itgWorkListIndex!); AppState().requestAllList!.removeAt(AppState().itgWorkListIndex!);
if (AppState().requestAllList!.isEmpty) { if (AppState().requestAllList!.isEmpty) {
Navigator.pop(context, "delegate_reload"); Navigator.pop(context, "delegate_reload");
@ -534,9 +556,11 @@ class _ItgDetailScreenState extends State<ItgDetailScreen> {
void performDataCorrectionORReportGeneratedAction(String requestType, int taskId, int itemId, String employeeNumber) async { void performDataCorrectionORReportGeneratedAction(String requestType, int taskId, int itemId, String employeeNumber) async {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
animationIndex = animationIndex + 1;
ITGRequest? itgRequest = await WorkListApiClient().grantITGRequest(requestType, taskId, itemId, employeeNumber, "", ""); ITGRequest? itgRequest = await WorkListApiClient().grantITGRequest(requestType, taskId, itemId, employeeNumber, "", "");
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.showToast(LocaleKeys.yourChangeHasBeenSavedSuccessfully.tr()); Utils.showToast(LocaleKeys.yourChangeHasBeenSavedSuccessfully.tr());
AppState().requestAllList!.removeAt(AppState().itgWorkListIndex!); AppState().requestAllList!.removeAt(AppState().itgWorkListIndex!);
if (AppState().requestAllList!.isEmpty) { if (AppState().requestAllList!.isEmpty) {
Navigator.pop(context, "delegate_reload"); Navigator.pop(context, "delegate_reload");
@ -555,6 +579,7 @@ class _ItgDetailScreenState extends State<ItgDetailScreen> {
} }
void reloadITG() { void reloadITG() {
animationIndex = animationIndex + 1;
AppState().requestAllList!.removeAt(AppState().itgWorkListIndex!); AppState().requestAllList!.removeAt(AppState().itgWorkListIndex!);
if (AppState().requestAllList!.isEmpty) { if (AppState().requestAllList!.isEmpty) {
Navigator.pop(context, "delegate_reload"); Navigator.pop(context, "delegate_reload");

@ -528,7 +528,7 @@ class _WorkListScreenState extends State<WorkListScreen> {
10.height, 10.height,
Row( Row(
children: [ children: [
DateUtil.formatDateToDate(DateUtil.convertSimpleStringDateToDate(workData.bEGINDATE!), false).toText10(color: MyColors.lightTextColor).expanded, DateUtil.formatDateToDate(DateUtil.convertSimpleStringDateToDateddMMyyyy(workData.bEGINDATE!), false).toText10(color: MyColors.lightTextColor).expanded,
RotatedBox(quarterTurns: AppState().isArabic(context) ? 2 : 4, child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.darkIconColor)), RotatedBox(quarterTurns: AppState().isArabic(context) ? 2 : 4, child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.darkIconColor)),
], ],
), ),

@ -55,6 +55,7 @@ class WorkListDetailScreen extends StatefulWidget {
class _WorkListDetailScreenState extends State<WorkListDetailScreen> { class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
int tabIndex = 0; int tabIndex = 0;
int animationIndex = 0;
PageController controller = PageController(); PageController controller = PageController();
bool showFabOptions = false; bool showFabOptions = false;
@ -146,7 +147,9 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
getPRNotification(); getPRNotification();
} }
controller.jumpToPage(0); if (controller.hasClients) {
controller.jumpToPage(0);
}
// List dataToFetch = await Future.wait([ // List dataToFetch = await Future.wait([
// //
@ -187,173 +190,191 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
getDataFromState(); getDataFromState();
return Scaffold( return Scaffold(
appBar: AppBarWidget(context, title: LocaleKeys.details.tr()), appBar: AppBarWidget(context, title: LocaleKeys.details.tr()),
backgroundColor: Colors.white, backgroundColor: Colors.white,
body: Stack( body: AnimatedSwitcher(
children: [ duration: const Duration(milliseconds: 500),
Column( switchInCurve: Curves.easeInToLinear,
children: [ transitionBuilder: (Widget child, Animation<double> animation) {
Container( Animation<Offset> custom = Tween<Offset>(
padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16), begin: const Offset(1.0, 0.0),
decoration: const BoxDecoration( end: Offset.zero,
borderRadius: BorderRadius.only( ).animate(animation);
bottomLeft: Radius.circular(25), return ClipRect(
bottomRight: Radius.circular(25), child: SlideTransition(
), position: custom,
gradient: LinearGradient( child: child,
transform: GradientRotation(.83), // textDirection: TextDirection.ltr,
begin: Alignment.topRight, ),
end: Alignment.bottomLeft, );
colors: [ },
MyColors.gradiantEndColor, child: Stack(
MyColors.gradiantStartColor, key: ValueKey(animationIndex),
], children: [
), Column(
), children: [
child: Row(
children: [
myTab(LocaleKeys.info.tr(), 0),
(workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") ? myTab(LocaleKeys.details.tr(), 1) : myTab(LocaleKeys.request.tr(), 1),
myTab(LocaleKeys.actions.tr(), 2),
myTab(LocaleKeys.attachments.tr(), 3),
],
),
),
if ((workListData?.sUBJECT ?? "").isNotEmpty) workListData!.sUBJECT!.toText14().paddingOnly(top: 20, right: 21, left: 21),
PageView(
controller: controller,
onPageChanged: (pageIndex) {
setState(() {
tabIndex = pageIndex;
});
},
children: [
InfoFragment(
poHeaderList: getPoNotificationBody?.pOHeader ?? [],
workListData: workListData,
itemCreationHeader: getItemCreationNtfBody?.itemCreationHeader ?? [],
getStampMsNotifications: getStampMsNotifications,
getStampNsNotifications: getStampNsNotifications,
getEitCollectionNotificationBodyList: getEitCollectionNotificationBodyList,
getPhonesNotificationBodyList: getPhonesNotificationBodyList,
getBasicDetNtfBodyList: getBasicDetNtfBodyList,
getAbsenceCollectionNotificationBodyList: getAbsenceCollectionNotificationBodyList,
getContactNotificationBodyList: getContactNotificationBodyList,
getPrNotificationBodyList: getPrNotificationBody,
),
(workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP")
? DetailFragment(workListData, memberInformationListModel)
: RequestFragment(
moNotificationBodyList: getMoNotificationBodyList,
poLinesList: getPoNotificationBody?.pOLines ?? [],
itemCreationLines: getItemCreationNtfBody?.itemCreationLines ?? [],
prLinesList: getPrNotificationBody?.pRLines ?? [],
),
isActionHistoryLoaded
? actionHistoryList.isEmpty
? Utils.getNoDataWidget(context)
: ActionsFragment(
workListData!.nOTIFICATIONID,
actionHistoryList,
voidCallback: reloadWorkList,
)
: showLoadingAnimation(),
isAttachmentLoaded
? getAttachmentList.isEmpty
? Utils.getNoDataWidget(context)
: AttachmentsFragment(getAttachmentList)
: showLoadingAnimation(),
],
).expanded,
if (isApproveAvailable || isRejectAvailable || isCloseAvailable)
Container( Container(
padding: const EdgeInsets.only(top: 14, bottom: 14, left: 21, right: 21), padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16),
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.only(
border: Border( bottomLeft: Radius.circular(25),
top: BorderSide(color: MyColors.lightGreyEFColor, width: 1.0), bottomRight: Radius.circular(25),
),
gradient: LinearGradient(
transform: GradientRotation(.83),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
), ),
), ),
child: Row( child: Row(
children: [ children: [
if (isRejectAvailable) (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") ? myTab(LocaleKeys.details.tr(), 0) : myTab(LocaleKeys.request.tr(), 0),
DefaultButton( myTab(LocaleKeys.actions.tr(), 1),
LocaleKeys.reject.tr(), myTab(LocaleKeys.info.tr(), 2),
() => performAction("REJECTED"), myTab(LocaleKeys.attachments.tr(), 3),
colors: const [Color(0xffE47A7E), Color(0xffDE6D71)],
).expanded,
if (isApproveAvailable && isRejectAvailable) 8.width,
if (isApproveAvailable)
DefaultButton(
LocaleKeys.approve.tr(),
() => performAction("APPROVED"),
colors: const [Color(0xff28C884), Color(0xff1BB271)],
).expanded,
if (isCloseAvailable)
DefaultButton(
LocaleKeys.ok.tr(),
() => performAction("CLOSE"),
colors: const [Color(0xff32D892), Color(0xff1AB170)],
).expanded,
8.width,
Container(
height: 43,
width: 43,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: MyColors.lightGreyE6Color,
),
child: Icon(showFabOptions ? Icons.more_vert_rounded : Icons.more_horiz_rounded, color: MyColors.darkIconColor),
).onPress(() {
setState(() {
showFabOptions = true;
});
})
], ],
), ),
) ),
], if ((workListData?.sUBJECT ?? "").isNotEmpty) workListData!.sUBJECT!.toText14().paddingOnly(top: 20, right: 21, left: 21),
), PageView(
IgnorePointer( controller: controller,
ignoring: !showFabOptions, onPageChanged: (pageIndex) {
child: AnimatedOpacity( setState(() {
opacity: showFabOptions ? 1 : 0, tabIndex = pageIndex;
duration: const Duration(milliseconds: 250), });
child: Container( },
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 75 - 12),
width: double.infinity,
height: double.infinity,
color: Colors.white.withOpacity(.67),
alignment: Alignment.bottomRight,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
myFab(LocaleKeys.skip.tr(), "assets/images/skip.svg").onPress(() { (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP")
if (AppState().workList!.length - 1 > AppState().workListIndex!) { ? DetailFragment(workListData, memberInformationListModel)
AppState().setWorkListIndex = AppState().workListIndex! + 1; : RequestFragment(
workListData = null; moNotificationBodyList: getMoNotificationBodyList,
showFabOptions = false; poLinesList: getPoNotificationBody?.pOLines ?? [],
tabIndex = 0; itemCreationLines: getItemCreationNtfBody?.itemCreationLines ?? [],
getDataFromState(); prLinesList: getPrNotificationBody?.pRLines ?? [],
} else if (AppState().workList!.length - 1 == AppState().workListIndex!) { ),
Navigator.pop(context); isActionHistoryLoaded
} ? actionHistoryList.isEmpty
}), ? Utils.getNoDataWidget(context)
12.height, : ActionsFragment(
...viewApiButtonsList(notificationButtonsList), workListData!.nOTIFICATIONID,
actionHistoryList,
voidCallback: reloadWorkList,
)
: showLoadingAnimation(),
InfoFragment(
poHeaderList: getPoNotificationBody?.pOHeader ?? [],
workListData: workListData,
itemCreationHeader: getItemCreationNtfBody?.itemCreationHeader ?? [],
getStampMsNotifications: getStampMsNotifications,
getStampNsNotifications: getStampNsNotifications,
getEitCollectionNotificationBodyList: getEitCollectionNotificationBodyList,
getPhonesNotificationBodyList: getPhonesNotificationBodyList,
getBasicDetNtfBodyList: getBasicDetNtfBodyList,
getAbsenceCollectionNotificationBodyList: getAbsenceCollectionNotificationBodyList,
getContactNotificationBodyList: getContactNotificationBodyList,
getPrNotificationBodyList: getPrNotificationBody,
),
isAttachmentLoaded
? getAttachmentList.isEmpty
? Utils.getNoDataWidget(context)
: AttachmentsFragment(getAttachmentList)
: showLoadingAnimation(),
], ],
).expanded,
if (isApproveAvailable || isRejectAvailable || isCloseAvailable)
Container(
padding: const EdgeInsets.only(top: 14, bottom: 14, left: 21, right: 21),
decoration: const BoxDecoration(
color: Colors.white,
border: Border(
top: BorderSide(color: MyColors.lightGreyEFColor, width: 1.0),
),
),
child: Row(
children: [
if (isRejectAvailable)
DefaultButton(
LocaleKeys.reject.tr(),
() => performAction("REJECTED"),
colors: const [Color(0xffE47A7E), Color(0xffDE6D71)],
).expanded,
if (isApproveAvailable && isRejectAvailable) 8.width,
if (isApproveAvailable)
DefaultButton(
LocaleKeys.approve.tr(),
() => performAction("APPROVED"),
colors: const [Color(0xff28C884), Color(0xff1BB271)],
).expanded,
if (isCloseAvailable)
DefaultButton(
LocaleKeys.ok.tr(),
() => performAction("CLOSE"),
colors: const [Color(0xff32D892), Color(0xff1AB170)],
).expanded,
8.width,
Container(
height: 43,
width: 43,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: MyColors.lightGreyE6Color,
),
child: Icon(showFabOptions ? Icons.more_vert_rounded : Icons.more_horiz_rounded, color: MyColors.darkIconColor),
).onPress(() {
setState(() {
showFabOptions = true;
});
})
],
),
)
],
),
IgnorePointer(
ignoring: !showFabOptions,
child: AnimatedOpacity(
opacity: showFabOptions ? 1 : 0,
duration: const Duration(milliseconds: 250),
child: Container(
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 75 - 12),
width: double.infinity,
height: double.infinity,
color: Colors.white.withOpacity(.67),
alignment: Alignment.bottomRight,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
myFab(LocaleKeys.skip.tr(), "assets/images/skip.svg").onPress(() {
if (AppState().workList!.length - 1 > AppState().workListIndex!) {
animationIndex = animationIndex + 1;
AppState().setWorkListIndex = AppState().workListIndex! + 1;
workListData = null;
showFabOptions = false;
tabIndex = 0;
getDataFromState();
} else if (AppState().workList!.length - 1 == AppState().workListIndex!) {
Navigator.pop(context);
}
}),
12.height,
...viewApiButtonsList(notificationButtonsList),
],
),
), ),
), ).onPress(() {
).onPress(() { setState(() {
setState(() { showFabOptions = false;
showFabOptions = false; });
}); }),
}), ),
), ],
], ),
), ),
floatingActionButton: (!isApproveAvailable && !isRejectAvailable && !isCloseAvailable) floatingActionButton: (!isApproveAvailable && !isRejectAvailable && !isCloseAvailable)
? Container( ? Container(
@ -667,6 +688,7 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
GenericResponseModel model = await WorkListApiClient().postNotificationActions(payload); GenericResponseModel model = await WorkListApiClient().postNotificationActions(payload);
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.showToast(LocaleKeys.yourChangeHasBeenSavedSuccessfully.tr()); Utils.showToast(LocaleKeys.yourChangeHasBeenSavedSuccessfully.tr());
animationIndex=animationIndex+1;
AppState().workList!.removeAt(AppState().workListIndex!); AppState().workList!.removeAt(AppState().workListIndex!);
if (AppState().workList!.isEmpty) { if (AppState().workList!.isEmpty) {
Navigator.pop(context, "delegate_reload"); Navigator.pop(context, "delegate_reload");
@ -685,6 +707,7 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
} }
void reloadWorkList() { void reloadWorkList() {
animationIndex = animationIndex + 1;
AppState().workList!.removeAt(AppState().workListIndex!); AppState().workList!.removeAt(AppState().workListIndex!);
if (AppState().workList!.isEmpty) { if (AppState().workList!.isEmpty) {
Navigator.pop(context, "delegate_reload"); Navigator.pop(context, "delegate_reload");

@ -46,6 +46,7 @@ class _DetailFragmentState extends State<DetailFragment> {
], ],
).objectContainerView(), ).objectContainerView(),
12.height, 12.height,
widget.memberInformationListModel != null ?
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -69,7 +70,7 @@ class _DetailFragmentState extends State<DetailFragment> {
isItLast: true, isItLast: true,
), ),
], ],
).objectContainerView(), ).objectContainerView() : Container(),
], ],
).paddingAll(21), ).paddingAll(21),
); );

@ -5,6 +5,7 @@ import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.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/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
AppBar AppBarWidget(BuildContext context, AppBar AppBarWidget(BuildContext context,
{required String title, {required String title,
@ -34,10 +35,11 @@ AppBar AppBarWidget(BuildContext context,
), ),
4.width, 4.width,
if (image != null) if (image != null)
SvgPicture.asset( CircularAvatar(
image, url: image,
height: 40, height: 40,
width: 40, width: 40,
isImageBase64: true,
), ),
if (image != null) 14.width, if (image != null) 14.width,
title.toText24(color: MyColors.darkTextColor, isBold: true).expanded, title.toText24(color: MyColors.darkTextColor, isBold: true).expanded,

@ -188,7 +188,6 @@ class ServicesMenuShimmer extends StatelessWidget {
} }
} }
class MarathonBannerShimmer extends StatelessWidget { class MarathonBannerShimmer extends StatelessWidget {
const MarathonBannerShimmer({Key? key}) : super(key: key); const MarathonBannerShimmer({Key? key}) : super(key: key);
@ -236,6 +235,11 @@ class MarathonBannerShimmer extends StatelessWidget {
} }
class ChatHomeShimmer extends StatelessWidget { class ChatHomeShimmer extends StatelessWidget {
bool isDetailedScreen;
ChatHomeShimmer({Key? key, required this.isDetailedScreen}) : super(key: key);
@override
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
@ -254,42 +258,42 @@ class ChatHomeShimmer extends StatelessWidget {
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Container( if (!isDetailedScreen)
width: 48.0, Container(
height: 48.0, width: 48.0,
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(40))), height: 48.0,
), decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(40))),
const Padding( ),
padding: EdgeInsets.symmetric(horizontal: 8.0), if (!isDetailedScreen)
), const Padding(
Expanded( padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: double.infinity,
height: 8.0,
color: Colors.white,
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 2.0),
),
Container(
width: double.infinity,
height: 8.0,
color: Colors.white,
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 2.0),
),
Container(
width: 40.0,
height: 8.0,
color: Colors.white,
),
],
), ),
) Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: double.infinity,
height: 8.0,
color: Colors.white,
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 2.0),
),
Container(
width: double.infinity,
height: 8.0,
color: Colors.white,
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 2.0),
),
Container(
width: 40.0,
height: 8.0,
color: Colors.white,
),
],
).expanded
], ],
), ),
), ),

@ -93,8 +93,8 @@ dependencies:
flutter_webrtc: ^0.9.16 flutter_webrtc: ^0.9.16
camera: ^0.10.0+4 camera: ^0.10.0+4
#Encryption
flutter_des: ^2.1.0
video_player: ^2.4.7 video_player: ^2.4.7
just_audio: ^0.9.30 just_audio: ^0.9.30

Loading…
Cancel
Save