Chat Fixes & Counter Updated on Signal R

merge-requests/99/head
Aamir Muhammad 3 years ago
parent 75603d7530
commit 7d1086522d

@ -2,11 +2,11 @@ import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.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/models/chat/chat_user_image_model.dart';
@ -29,6 +29,9 @@ class ChatApiClient {
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
},
);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
user.UserAutoLoginModel userLoginResponse = user.userAutoLoginModelFromJson(response.body);
return userLoginResponse;
}
@ -38,33 +41,36 @@ class ChatApiClient {
"${ApiConsts.chatLoginTokenUrl}getUserWithStatusAndFavAsync/$sName/$cUserId",
token: AppState().chatDetails!.response!.token,
);
return searchUserJsonModel(response.body);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
return List<ChatUser>.from(json.decode(response.body).map((x) => ChatUser.fromJson(x)));
}
List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from(json.decode(str).map((x) => ChatUser.fromJson(x)));
Future<ChatUserModel> getRecentChats() async {
try {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatRecentUrl}getchathistorybyuserid",
token: AppState().chatDetails!.response!.token,
);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
return ChatUserModel.fromJson(
json.decode(response.body),
);
} catch (e) {
e as APIException;
if (e.message == "api_common_unauthorized") {
user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
getRecentChats();
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
}
}
// if (e.message == "api_common_unauthorized") {
// user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
// if (userLoginResponse.response != null) {
// AppState().setchatUserDetails = userLoginResponse;
// getRecentChats();
// } else {
// Utils.showToast(
// userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
// );
// }
// }
throw e;
}
}
@ -74,9 +80,10 @@ class ChatApiClient {
"${ApiConsts.chatFavUser}getFavUserById/${AppState().chatDetails!.response!.id}",
token: AppState().chatDetails!.response!.token,
);
return ChatUserModel.fromJson(
json.decode(favRes.body),
);
if (!kReleaseMode) {
logger.i("res: " + favRes.body);
}
return ChatUserModel.fromJson(json.decode(favRes.body));
}
Future<Response> getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false, required int paginationVal}) async {
@ -85,24 +92,30 @@ class ChatApiClient {
"${ApiConsts.chatSingleUserHistoryUrl}GetUserChatHistory/$senderUID/$receiverUID/$paginationVal",
token: AppState().chatDetails!.response!.token,
);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
return response;
} catch (e) {
e as APIException;
if (e.message == "api_common_unauthorized") {
user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore, paginationVal: paginationVal);
} else {
Utils.showToast(userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr");
}
}
// e as APIException;
// if (e.message == "api_common_unauthorized") {
// user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
// if (userLoginResponse.response != null) {
// AppState().setchatUserDetails = userLoginResponse;
// getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore, paginationVal: paginationVal);
// } else {
// Utils.showToast(userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr");
// }
// }
throw e;
}
}
Future<fav.FavoriteChatUser> favUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient().postJsonForResponse("${ApiConsts.chatFavUser}addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser;
}
@ -114,20 +127,23 @@ class ChatApiClient {
{"targetUserId": targetUserID, "userId": userID},
token: AppState().chatDetails!.response!.token,
);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser;
} catch (e) {
e as APIException;
if (e.message == "api_common_unauthorized") {
logger.d("Token Generated On APIIIIII");
user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
unFavUser(userID: userID, targetUserID: targetUserID);
} else {
Utils.showToast(userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr");
}
}
// if (e.message == "api_common_unauthorized") {
// user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
// if (userLoginResponse.response != null) {
// AppState().setchatUserDetails = userLoginResponse;
// unFavUser(userID: userID, targetUserID: targetUserID);
// } else {
// Utils.showToast(userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr");
// }
// }
throw e;
}
}
@ -138,6 +154,7 @@ class ChatApiClient {
request.files.add(await MultipartFile.fromPath('files', file.path));
request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'});
StreamedResponse response = await request.send();
if (!kReleaseMode) {}
return response;
}
@ -159,6 +176,9 @@ class ChatApiClient {
{"encryptedEmails": encryptedEmails, "fromClient": false},
token: AppState().chatDetails!.response!.token,
);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
return chatUserImageModelFromJson(response.body);
}
}

@ -180,12 +180,7 @@ class DashboardApiClient {
}, url, postParams);
}
Future<ChatUnreadCovnCountModel> getChatCount() async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatLoginTokenUrl}unreadconversationcount/${AppState().getUserName}",
);
return chatUnreadCovnCountModelFromJson(response.body);
}
// Future setAdvertisementViewed(String masterID, int advertisementId) async {
// String url = "${ApiConsts.cocRest}Mohemm_ITG_UpdateAdvertisementAsViewed";

@ -1,8 +1,8 @@
import 'dart:convert';
ChatUnreadCovnCountModel chatUnreadCovnCountModelFromJson(String str) => ChatUnreadCovnCountModel.fromJson(json.decode(str));
// To parse this JSON data, do
//
// final chatUnreadCovnCountModel = chatUnreadCovnCountModelFromMap(jsonString);
String chatUnreadCovnCountModelToJson(ChatUnreadCovnCountModel data) => json.encode(data.toJson());
import 'dart:convert';
class ChatUnreadCovnCountModel {
ChatUnreadCovnCountModel({
@ -13,13 +13,17 @@ class ChatUnreadCovnCountModel {
int? singleChatCount;
int? groupChatCount;
factory ChatUnreadCovnCountModel.fromJson(Map<String, dynamic> json) => ChatUnreadCovnCountModel(
singleChatCount: json["singleChatCount"] == null ? null : json["singleChatCount"],
groupChatCount: json["groupChatCount"] == null ? null : json["groupChatCount"],
);
factory ChatUnreadCovnCountModel.fromJson(String str) => ChatUnreadCovnCountModel.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory ChatUnreadCovnCountModel.fromMap(Map<String, dynamic> json) => ChatUnreadCovnCountModel(
singleChatCount: json["singleChatCount"] == null ? null : json["singleChatCount"],
groupChatCount: json["groupChatCount"] == null ? null : json["groupChatCount"],
);
Map<String, dynamic> toJson() => {
"singleChatCount": singleChatCount == null ? null : singleChatCount,
"groupChatCount": groupChatCount == null ? null : groupChatCount,
};
Map<String, dynamic> toMap() => {
"singleChatCount": singleChatCount == null ? null : singleChatCount,
"groupChatCount": groupChatCount == null ? null : groupChatCount,
};
}

@ -1,3 +1,5 @@
import 'dart:io';
class ChatUserModel {
ChatUserModel({
this.response,
@ -35,6 +37,7 @@ class ChatUser {
this.isTyping,
this.isImageLoaded,
this.isImageLoading,
this.userLocalDownlaodedImage,
});
int? id;
@ -52,24 +55,25 @@ class ChatUser {
bool? isTyping;
bool? isImageLoaded;
bool? isImageLoading;
File? userLocalDownlaodedImage;
factory ChatUser.fromJson(Map<String, dynamic> json) => ChatUser(
id: json["id"] == null ? null : json["id"],
userName: json["userName"] == null ? null : json["userName"],
email: json["email"] == null ? null : json["email"],
phone: json["phone"],
title: json["title"],
userStatus: json["userStatus"] == null ? null : json["userStatus"],
image: json["image"],
unreadMessageCount: json["unreadMessageCount"] == null ? null : json["unreadMessageCount"],
userAction: json["userAction"],
isPin: json["isPin"] == null ? null : json["isPin"],
isFav: json["isFav"] == null ? null : json["isFav"],
isAdmin: json["isAdmin"] == null ? null : json["isAdmin"],
isTyping: false,
isImageLoaded: false,
isImageLoading: true,
);
id: json["id"] == null ? null : json["id"],
userName: json["userName"] == null ? null : json["userName"],
email: json["email"] == null ? null : json["email"],
phone: json["phone"],
title: json["title"],
userStatus: json["userStatus"] == null ? null : json["userStatus"],
image: json["image"],
unreadMessageCount: json["unreadMessageCount"] == null ? null : json["unreadMessageCount"],
userAction: json["userAction"],
isPin: json["isPin"] == null ? null : json["isPin"],
isFav: json["isFav"] == null ? null : json["isFav"],
isAdmin: json["isAdmin"] == null ? null : json["isAdmin"],
isTyping: false,
isImageLoaded: false,
isImageLoading: true,
userLocalDownlaodedImage: null);
Map<String, dynamic> toJson() => {
"id": id == null ? null : id,

@ -12,6 +12,7 @@ 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/main.dart';
import 'package:mohem_flutter_app/models/chat/chat_count_conversation_model.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_single_user_chat_list_model.dart';
@ -19,6 +20,8 @@ import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' a
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/widgets/image_picker.dart';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';
import 'package:signalr_netcore/hub_connection.dart';
import 'package:signalr_netcore/signalr_client.dart';
import 'package:uuid/uuid.dart';
@ -39,6 +42,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
List<SingleUserChatModel> repliedMsg = [];
List<ChatUser> favUsersList = [];
int paginationVal = 0;
bool currentUserTyping = false;
//Chat
int chatUConvCounter = 0;
Future<void> getUserAutoLoginToken() async {
userLoginToken.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
@ -56,30 +63,23 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
await chatHubConnection.start();
print("Startedddddddd");
chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
chatHubConnection.on("OnGetChatConversationCount", onNewChatConversion);
}
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() {
chatHubConnection.on("OnUpdateUserStatusAsync", changeStatus);
// chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
// hubConnection.on("OnSeenChatUserAsync", onChatSeen);
//hubConnection.on("OnUserTypingAsync", onUserTyping);
chatHubConnection.on("OnUserTypingAsync", onUserTyping);
chatHubConnection.on("OnUserCountAsync", userCountAsync);
// hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
chatHubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
@ -164,7 +164,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
isLoading = false;
notifyListeners();
markRead(userChatHistory, receiverUID);
generateConvId();
}
@ -176,26 +178,28 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void markRead(List<SingleUserChatModel> data, int receiverID) {
if (data != null) {
for (SingleUserChatModel element in data!) {
if (element.isSeen != null) {
if (!element.isSeen!) {
element.isSeen = true;
dynamic data = [
{
"userChatHistoryId": element.userChatHistoryId,
"TargetUserId": element.currentUserId == receiverID ? element.currentUserId : element.targetUserId,
"isDelivered": true,
"isSeen": true,
}
];
updateUserChatHistoryStatusAsync(data);
notifyListeners();
if (AppState().chatDetails!.response!.id! == element.targetUserId) {
if (element.isSeen != null) {
if (!element.isSeen!) {
element.isSeen = true;
dynamic data = [
{
"userChatHistoryId": element.userChatHistoryId,
"TargetUserId": element.currentUserId == receiverID ? element.currentUserId : element.targetUserId,
"isDelivered": true,
"isSeen": true,
}
];
updateUserChatHistoryStatusAsync(data);
notifyListeners();
}
}
for (ChatUser element in searchedChats!) {
if (element.id == receiverID) {
element.unreadMessageCount = 0;
chatUConvCounter = 0;
}
}
}
}
for (ChatUser element in searchedChats!) {
if (element.id == receiverID) {
element.unreadMessageCount = 0;
// notifyListeners();
}
}
notifyListeners();
@ -346,9 +350,23 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
}
}
dynamic contain = searchedChats!.where((ChatUser element) => element.id == data.first.currentUserId);
if (contain.isEmpty) {
searchedChats!.add(ChatUser(id: data.first.currentUserId, userName: data.first.currentUserName, unreadMessageCount: 0, isImageLoading: false, image: "", isImageLoaded: true, userStatus: 1));
if (searchedChats != null) {
dynamic contain = searchedChats!.where((ChatUser element) => element.id == data.first.currentUserId);
if (contain.isEmpty) {
searchedChats!.add(
ChatUser(
id: data.first.currentUserId,
userName: data.first.currentUserName,
unreadMessageCount: 0,
isImageLoading: false,
image: "",
isImageLoaded: true,
userStatus: 1,
isTyping: false,
userLocalDownlaodedImage: null),
);
}
}
setMsgTune();
@ -368,6 +386,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
{"userChatHistoryId": data.first.userChatHistoryId, "TargetUserId": temp.first.targetUserId, "isDelivered": true, "isSeen": isChatScreenActive ? true : false}
];
updateUserChatHistoryOnMsg(list);
invokeChatCounter(userId: AppState().chatDetails!.response!.id!);
notifyListeners();
}
@ -384,7 +403,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
if (user.id == parameters![1] && parameters[0] == true) {
user.isTyping = parameters[0] as bool?;
Future.delayed(
const Duration(seconds: 2),
const Duration(seconds: 1),
() {
user.isTyping = false;
notifyListeners();
@ -392,6 +411,17 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
);
}
}
if (isChatScreenActive) {
currentUserTyping = true;
notifyListeners();
Future.delayed(
const Duration(seconds: 2),
() {
currentUserTyping = false;
notifyListeners();
},
);
}
notifyListeners();
}
@ -473,7 +503,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
required bool isImageLoaded}) async {
Uuid uuid = const Uuid();
String contentNo = uuid.v4();
String msg = message.text;
SingleUserChatModel data = SingleUserChatModel(
chatEventId: chatEventId,
@ -492,8 +521,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
fileTypeResponse: isAttachment
? FileTypeResponse(
fileTypeId: fileTypeId,
fileTypeName: getFileType(getFileExtension(selectedFile.path).toString()),
fileKind: getFileExtension(selectedFile.path),
fileTypeName: getFileExtension(selectedFile.path).toString(),
fileKind: "file",
fileName: selectedFile.path.split("/").last,
fileTypeDescription: getFileTypeDescription(getFileExtension(selectedFile.path).toString()),
)
@ -517,7 +546,17 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
dynamic contain = searchedChats!.where((ChatUser element) => element.id == targetUserId);
if (contain.isEmpty) {
searchedChats!.add(
ChatUser(id: targetUserId, userName: targetUserName, unreadMessageCount: 0, isImageLoading: false, image: "", isImageLoaded: true),
ChatUser(
id: targetUserId,
userName: targetUserName,
unreadMessageCount: 0,
isImageLoading: false,
image: "",
isImageLoaded: true,
isTyping: false,
isFav: false,
userLocalDownlaodedImage: null,
),
);
notifyListeners();
}
@ -530,6 +569,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: false, chatReplyId: null, isReply: false, isImageLoaded: false, image: null);
} // normal Text msg
if (isFileSelected && !isMsgReply) {
bool isImage = false;
print("Normal Attachment Msg");
Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
@ -605,6 +645,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
String? getFileExtension(String fileName) {
try {
print("Ext: " + "." + fileName.split('.').last);
return "." + fileName.split('.').last;
} catch (e) {
return null;
@ -740,6 +781,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
for (ChatUserImageModel uImage in chatImages) {
if (user.email == uImage.email) {
user.image = uImage.profilePicture ?? "";
user.userLocalDownlaodedImage = await downloadImageLocal(uImage.profilePicture, user.id.toString());
user.isImageLoading = false;
user.isImageLoaded = true;
}
@ -749,6 +791,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
for (ChatUserImageModel uImage in chatImages) {
if (favUser.email == uImage.email) {
favUser.image = uImage.profilePicture ?? "";
favUser.userLocalDownlaodedImage = await downloadImageLocal(uImage.profilePicture, favUser.id.toString());
favUser.isImageLoading = false;
favUser.isImageLoaded = true;
}
@ -758,6 +801,35 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners();
}
Future<File?> downloadImageLocal(String? encodedBytes, String userID) async {
File? myfile;
if (encodedBytes == null) {
return myfile;
} else {
await deleteFile(userID);
Uint8List decodedBytes = base64Decode(encodedBytes);
Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1
late File imageFile = File("${appDocumentsDirectory.path}/$userID.jpg");
imageFile.writeAsBytesSync(decodedBytes);
return imageFile;
}
}
Future deleteFile(String userID) async {
Directory appDocumentsDirectory = await getApplicationDocumentsDirectory();
late File imageFile = File('${appDocumentsDirectory.path}/$userID.jpg');
if (await imageFile.exists()) {
await imageFile.delete();
}
}
Future<String> downChatMedia(Uint8List bytes, String ext) async {
String dir = (await getApplicationDocumentsDirectory()).path;
File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext);
await file.writeAsBytes(bytes);
return file.path;
}
void setMsgTune() async {
AudioPlayer player = AudioPlayer();
await player.setVolume(1.0);
@ -775,4 +847,29 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
print("Error: $e");
}
}
Future<void> getChatMedia({required String fileName, required String fileTypeName, required int fileTypeID}) async {
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 || fileTypeID == 2) {
Uint8List encodedString = await ChatApiClient().downloadURL(fileName: fileName, fileTypeDescription: getFileTypeDescription(fileTypeName));
try {
String path = await downChatMedia(encodedString, fileTypeName ?? "");
OpenFile.open(path);
} catch (e) {
Utils.showToast("Cannot open file.");
}
}
}
void onNewChatConversion(List<Object?>? params) {
dynamic items = params!.toList();
logger.d(items);
chatUConvCounter = items[0]["singleChatCount"] ?? 0;
notifyListeners();
}
Future invokeChatCounter({required int userId}) async {
print("invokedd");
await chatHubConnection.invoke("GetChatCounversationCount", args: [userId]);
return "";
}
}

@ -7,7 +7,6 @@ import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.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/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_attendance_tracking_list_model.dart';
@ -20,6 +19,7 @@ import 'package:mohem_flutter_app/models/dashboard/mohemm_itg_pending_task_respo
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/offers_and_discounts/get_offers_list.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
/// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool
@ -35,9 +35,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
bool isWorkListLoading = true;
int workListCounter = 0;
//Chat
bool isChatCounterLoding = true;
int chatUConvCounter = 0;
//Misssing Swipe
bool isMissingSwipeLoading = true;
@ -96,8 +94,6 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
accrualList = null;
leaveBalanceAccrual = null;
isChatCounterLoding = true;
chatUConvCounter = 0;
ticketBalance = 0;
isServicesMenusLoading = true;
@ -273,21 +269,6 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
MohemmItgResponseItem? res = await DashboardApiClient().getITGPageNotification();
return res;
}
void fetchChatCounts() async {
try {
ChatUnreadCovnCountModel response = await DashboardApiClient().getChatCount();
chatUConvCounter = response.singleChatCount!;
isChatCounterLoding = false;
notifyListeners();
} catch (ex) {
logger.wtf(ex);
notifyListeners();
Utils.handleException(ex, null, null);
}
}
void notify() {
notifyListeners();
}

@ -1,17 +1,23 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.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/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.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/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_full_image_preview.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheet.dart';
import 'package:open_file/open_file.dart';
import 'package:provider/provider.dart';
// todo: @aamir use extension methods, and use correct widgets.
@ -19,11 +25,12 @@ class ChatBubble extends StatelessWidget {
ChatBubble({Key? key, required this.dateTime, required this.cItem}) : super(key: key);
final String dateTime;
final SingleUserChatModel cItem;
bool isCurrentUser = false;
bool isSeen = false;
bool isReplied = false;
int? fileTypeID;
String? fileTypeName;
late ChatProviderModel data;
String? fileTypeDescription;
bool isDelivered = false;
@ -35,6 +42,7 @@ class ChatBubble extends StatelessWidget {
isSeen = cItem.isSeen == true ? true : false;
isReplied = cItem.userChatReplyResponse != null ? true : false;
fileTypeID = cItem.fileTypeId;
fileTypeName = cItem.fileTypeResponse != null ? cItem.fileTypeResponse!.fileTypeName : "";
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();
@ -45,6 +53,8 @@ class ChatBubble extends StatelessWidget {
Size windowSize = MediaQuery.of(context).size;
screenOffset = Offset(windowSize.width / 2, windowSize.height / 2);
makeAssign();
data = Provider.of<ChatProviderModel>(context, listen: false);
return isCurrentUser ? currentUser(context) : receiptUser(context);
}
@ -77,22 +87,6 @@ class ChatBubble extends StatelessWidget {
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(
@ -116,8 +110,15 @@ class ChatBubble extends StatelessWidget {
anchorPoint: screenOffset,
builder: (BuildContext context) => ChatImagePreviewScreen(imgTitle: cItem.contant!, img: cItem.image!),
);
}),
cItem.contant!.toText12(),
})
else
Row(
children: [
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 || fileTypeID == 2)
SvgPicture.asset(data.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 0, right: 10),
(cItem.contant ?? "").toText12(),
],
),
Align(
alignment: Alignment.centerRight,
child: Row(
@ -200,7 +201,16 @@ class ChatBubble extends StatelessWidget {
);
})
else
(cItem.contant ?? "").toText12(color: Colors.white),
Row(
children: [
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 || fileTypeID == 2)
SvgPicture.asset(data.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(
left: 0,
right: 10,
),
(cItem.contant ?? "").toText12(color: Colors.white),
],
),
Align(
alignment: Alignment.centerRight,
child: dateTime.toText10(color: Colors.white.withOpacity(.71)),

@ -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/main.dart';
import 'package:mohem_flutter_app/models/chat/call.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/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart';
@ -23,9 +24,15 @@ import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:signalr_netcore/signalr_client.dart';
import 'package:swipe_to/swipe_to.dart';
class ChatDetailedScreenParams {
ChatUser? chatUser;
bool? isNewChat;
ChatDetailedScreenParams(this.chatUser, this.isNewChat);
}
class ChatDetailScreen extends StatefulWidget {
// ignore: prefer_const_constructors_in_immutables
ChatDetailScreen({Key? key}) : super(key: key);
const ChatDetailScreen({Key? key}) : super(key: key);
@override
State<ChatDetailScreen> createState() => _ChatDetailScreenState();
@ -33,16 +40,16 @@ class ChatDetailScreen extends StatefulWidget {
class _ChatDetailScreenState extends State<ChatDetailScreen> {
final RefreshController _rc = RefreshController(initialRefresh: false);
dynamic userDetails;
late ChatProviderModel data;
ChatDetailedScreenParams? params;
void getMoreChat() async {
if (userDetails != null) {
if (params != null) {
data.paginationVal = data.paginationVal + 10;
if (userDetails != null) {
if (params != null) {
data.getSingleUserChatHistory(
senderUID: AppState().chatDetails!.response!.id!.toInt(),
receiverUID: userDetails["targetUser"].id,
receiverUID: params!.chatUser!.id!,
loadMore: true,
isNewChat: false,
);
@ -56,14 +63,14 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
@override
Widget build(BuildContext context) {
userDetails = ModalRoute.of(context)!.settings.arguments;
params = ModalRoute.of(context)!.settings.arguments as ChatDetailedScreenParams;
data = Provider.of<ChatProviderModel>(context, listen: false);
if (userDetails != null) {
if (params != null) {
data.getSingleUserChatHistory(
senderUID: AppState().chatDetails!.response!.id!.toInt(),
receiverUID: userDetails["targetUser"].id,
receiverUID: params!.chatUser!.id!,
loadMore: false,
isNewChat: userDetails["isNewChat"],
isNewChat: params!.isNewChat!,
);
}
@ -71,9 +78,10 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
backgroundColor: MyColors.backgroundColor,
appBar: AppBarWidget(
context,
title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach,
title: params!.chatUser!.userName.toString().replaceAll(".", " ").capitalizeFirstofEach,
showHomeButton: false,
image: userDetails["targetUser"].image == null || userDetails["targetUser"].image.isEmpty ? null : userDetails["targetUser"].image,
image: params!.chatUser!.image == null || params!.chatUser!.image.isEmpty ? null : params!.chatUser!.image,
showTyping: true,
actions: [
SvgPicture.asset("assets/icons/chat/call.svg", width: 21, height: 23).onPress(() {
// makeCall(callType: "AUDIO", con: hubConnection);
@ -124,8 +132,13 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
m.userChatHistory[i],
);
},
).onPress(() {
logger.d(jsonEncode(m.userChatHistory[i]));
).onPress(() async {
if (m.userChatHistory[i].fileTypeResponse != null) {
m.getChatMedia(
fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "",
fileTypeID: m.userChatHistory[i].fileTypeResponse!.fileTypeId!,
fileName: m.userChatHistory[i].contant!);
}
});
},
),
@ -152,7 +165,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
],
).expanded,
12.width,
if (m.isMsgReply && m.repliedMsg.isNotEmpty) showReplyImage(m.repliedMsg),
if (m.isMsgReply && m.repliedMsg.isNotEmpty) showReplyImage(m.repliedMsg, m),
12.width,
const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe),
],
@ -209,7 +222,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
),
).paddingOnly(right: 25),
SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26).onPress(
() => m.sendChatMessage(userDetails["targetUser"].id, userDetails["targetUser"].userName, context),
() => m.sendChatMessage(params!.chatUser!.id!, params!.chatUser!.userName!, context),
),
],
),
@ -223,7 +236,8 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
);
}
Widget showReplyImage(List<SingleUserChatModel> data) {
Widget showReplyImage(List<SingleUserChatModel> data, ChatProviderModel m) {
logger.d(jsonEncode(data));
if (data.first.isImageLoaded! && data.first.image != null) {
return Container(
width: 43,
@ -232,7 +246,14 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
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();
return data.first.fileTypeResponse != null
? Container(
width: 43,
height: 43,
constraints: BoxConstraints(),
decoration: BoxDecoration(border: Border.all(color: MyColors.darkGrey3BColor, width: 1), borderRadius: BorderRadius.circular(10.0), color: Colors.white),
child: SvgPicture.asset(m.getType(data.first.fileTypeResponse!.fileTypeName), alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 5, right: 5, top: 5, bottom: 5))
: SizedBox();
}
}
@ -240,7 +261,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
print("================== Make call Triggered ============================");
Map<String, dynamic> json = {
"callerID": AppState().chatDetails!.response!.id!.toString(),
"callReceiverID": userDetails["targetUser"].id.toString(),
"callReceiverID": params!.chatUser!.id.toString(),
"notification_foreground": "true",
"message": "Aamir is calling",
"title": "Video Call",
@ -259,7 +280,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
{
"isSeen": false,
"isDelivered": false,
"targetUserId": userDetails["targetUser"].id,
"targetUserId": params!.chatUser!.id!,
"targetUserStatus": 4,
}
],

@ -30,6 +30,16 @@ class _ChatHomeState extends State<ChatHome> {
super.initState();
data = Provider.of<ChatProviderModel>(context, listen: false);
data.registerEvents();
}
@override
void dispose() {
super.dispose();
data.clearAll();
}
void fetchAgain() {
print("Fetch Triggered");
if (chatHubConnection.state != HubConnectionState.Connected) {
data.getUserAutoLoginToken().whenComplete(() async {
await data.buildHubConnection();
@ -42,14 +52,9 @@ class _ChatHomeState extends State<ChatHome> {
}
}
@override
void dispose() {
super.dispose();
data.clearAll();
}
@override
Widget build(BuildContext context) {
fetchAgain();
return Scaffold(
backgroundColor: MyColors.white,
appBar: AppBarWidget(context, title: LocaleKeys.chat.tr(), showHomeButton: true),
@ -85,7 +90,6 @@ class _ChatHomeState extends State<ChatHome> {
onPageChanged: (int pageIndex) {
setState(() {
tabIndex = pageIndex;
});
},
children: <Widget>[

@ -1,22 +1,19 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.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:mohem_flutter_app/app_state/app_state.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/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.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/circular_avatar.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
@ -53,7 +50,9 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
body: Consumer<ChatProviderModel>(
builder: (BuildContext context, ChatProviderModel m, Widget? child) {
return m.isLoading
? ChatHomeShimmer(isDetailedScreen: false,)
? ChatHomeShimmer(
isDetailedScreen: false,
)
: Column(
children: <Widget>[
TextField(
@ -102,20 +101,24 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
height: 48,
width: 48,
).toShimmer().circle(30),
if (m.searchedChats![index].isImageLoaded! && 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)
if (!m.searchedChats![index].isImageLoading! && m.searchedChats![index].userLocalDownlaodedImage == null)
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
if (!m.searchedChats![index].isImageLoading! && m.searchedChats![index].userLocalDownlaodedImage != null)
Container(
width: 48.0,
height: 48.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: FileImage(m.searchedChats![index].userLocalDownlaodedImage!),
),
),
),
Positioned(
right: 5,
bottom: 1,
@ -128,14 +131,13 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
).circle(10),
)
],
).onPress(() {
print(jsonEncode(m.searchedChats![index]));
}),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(m.searchedChats![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor).paddingOnly(left: 11, top: 13),
(m.searchedChats![index].isTyping! ? "Typing ..." : "").toText10(color: MyColors.lightGreyColor).paddingOnly(left: 11, top: 0),
],
).expanded,
SizedBox(
@ -194,7 +196,7 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
Navigator.pushNamed(
context,
AppRoutes.chatDetailed,
arguments: {"targetUser": m.searchedChats![index], "isNewChat": false},
arguments: ChatDetailedScreenParams(m.searchedChats![index], false),
).then((Object? value) {
m.clearSelections();
m.notifyListeners();

@ -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/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
@ -45,20 +46,24 @@ class ChatFavoriteUsersScreen extends StatelessWidget {
height: 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)
if (!m.favUsersList![index].isImageLoading! && m.favUsersList![index].userLocalDownlaodedImage == null)
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
if (!m.favUsersList![index].isImageLoading! && m.favUsersList![index].userLocalDownlaodedImage != null)
Container(
width: 48.0,
height: 48.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: FileImage(m.favUsersList![index].userLocalDownlaodedImage!),
),
),
),
Positioned(
right: 5,
bottom: 1,
@ -106,7 +111,7 @@ class ChatFavoriteUsersScreen extends StatelessWidget {
Navigator.pushNamed(
context,
AppRoutes.chatDetailed,
arguments: {"targetUser": m.favUsersList![index], "isNewChat": false},
arguments: ChatDetailedScreenParams(m.favUsersList![index], false),
).then(
(Object? value) {
m.clearSelections();

@ -90,7 +90,6 @@ class _DashboardScreenState extends State<DashboardScreen> {
data.fetchMenuEntries();
data.getCategoryOffersListAPI(context);
marathonProvider.getMarathonDetailsFromApi();
data.fetchChatCounts();
_refreshController.refreshCompleted();
}
@ -503,8 +502,8 @@ class _DashboardScreenState extends State<DashboardScreen> {
"assets/icons/chat/chat.svg",
color: currentIndex == 4 ? MyColors.grey3AColor : MyColors.grey98Color,
).paddingAll(4),
Consumer<DashboardProviderModel>(
builder: (BuildContext cxt, DashboardProviderModel data, Widget? child) {
Consumer<ChatProviderModel>(
builder: (BuildContext cxt, ChatProviderModel data, Widget? child) {
return Positioned(
right: 0,
top: 0,
@ -538,9 +537,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
} else if (index == 3) {
Navigator.pushNamed(context, AppRoutes.itemsForSale);
} else if (index == 4) {
Navigator.pushNamed(context, AppRoutes.chat).then((Object? value) {
data.fetchChatCounts();
});
Navigator.pushNamed(context, AppRoutes.chat);
}
},
),

@ -5,7 +5,9 @@ import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:provider/provider.dart';
AppBar AppBarWidget(BuildContext context,
{required String title,
@ -13,6 +15,7 @@ AppBar AppBarWidget(BuildContext context,
bool showNotificationButton = false,
bool showMemberButton = false,
String? image,
bool showTyping = false,
List<Widget>? actions,
void Function()? onHomeTapped,
void Function()? onBackTapped}) {
@ -43,6 +46,16 @@ AppBar AppBarWidget(BuildContext context,
),
if (image != null) 14.width,
title.toText24(color: MyColors.darkTextColor, isBold: true).expanded,
if(showTyping)
Consumer<ChatProviderModel>(
builder: (BuildContext cxt, ChatProviderModel data, Widget? child) {
if (data.currentUserTyping) {
return ("Typing ...").toText10(color: MyColors.lightGreyColor).paddingOnly(left: 5, top: 0);
} else {
return const SizedBox();
}
},
),
],
),
centerTitle: false,

@ -20,6 +20,7 @@ import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/get_action_history_list_model.dart';
import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart';
import 'package:mohem_flutter_app/models/worklist/replacement_list_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart';
@ -238,7 +239,7 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
Navigator.pushNamed(
context,
AppRoutes.chatDetailed,
arguments: {"targetUser": chatUsersList![index], "isNewChat": true},
arguments: ChatDetailedScreenParams(chatUsersList![index], true),
);
},
),

@ -45,7 +45,7 @@ class ImageOptions {
onFilesTap: () async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'jpeg ', 'pdf', 'txt', 'docx', 'doc', 'pptx', 'xlsx', 'png', 'rar', 'zip', 'xls'],
allowedExtensions: ['jpg', 'jpeg ', 'pdf', 'txt', 'docx', 'doc', 'pptx', 'xlsx', 'png', 'rar', 'zip',],
);
List<File> files = result!.paths.map((path) => File(path!)).toList();
image(result.files.first.path.toString(), files.first);

Loading…
Cancel
Save