You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			2094 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			2094 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			Dart
		
	
| import 'dart:async';
 | |
| import 'dart:convert';
 | |
| import 'dart:io';
 | |
| import 'dart:typed_data';
 | |
| import 'package:audio_waveforms/audio_waveforms.dart';
 | |
| import 'package:easy_localization/easy_localization.dart';
 | |
| import 'package:flutter/cupertino.dart';
 | |
| import 'package:flutter/foundation.dart';
 | |
| import 'package:flutter/services.dart';
 | |
| import 'package:http/http.dart';
 | |
| import 'package:just_audio/just_audio.dart' as JustAudio;
 | |
| import 'package:just_audio/just_audio.dart';
 | |
| import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
 | |
| import 'package:mohem_flutter_app/api/my_team/my_team_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/encryption.dart';
 | |
| import 'package:mohem_flutter_app/classes/utils.dart';
 | |
| import 'package:mohem_flutter_app/config/routes.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/create_group_request.dart'
 | |
|     as createGroup;
 | |
| import 'package:mohem_flutter_app/models/chat/get_group_chat_history.dart'
 | |
|     as groupchathistory;
 | |
| 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_user_groups_by_id.dart'
 | |
|     as groups;
 | |
| import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart';
 | |
| 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/target_users.dart';
 | |
| import 'package:mohem_flutter_app/models/my_team/get_employee_subordinates_list.dart';
 | |
| import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart';
 | |
| 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:permission_handler/permission_handler.dart';
 | |
| import 'package:signalr_netcore/hub_connection.dart';
 | |
| import 'package:signalr_netcore/signalr_client.dart';
 | |
| import 'package:uuid/uuid.dart';
 | |
| import 'package:flutter/material.dart' as Material;
 | |
| 
 | |
| class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
 | |
|   ScrollController scrollController = ScrollController();
 | |
| 
 | |
|   TextEditingController message = TextEditingController();
 | |
|   TextEditingController search = TextEditingController();
 | |
|   TextEditingController searchGroup = TextEditingController();
 | |
| 
 | |
|   List<SingleUserChatModel> userChatHistory = [], repliedMsg = [];
 | |
|   List<ChatUser>? pChatHistory, searchedChats;
 | |
|   String chatCID = '';
 | |
|   bool isLoading = true;
 | |
|   bool isChatScreenActive = false;
 | |
|   int receiverID = 0;
 | |
|   late File selectedFile;
 | |
|   String sFileType = "";
 | |
| 
 | |
|   List<ChatUser> favUsersList = [];
 | |
|   int paginationVal = 0;
 | |
|   int? cTypingUserId = 0;
 | |
|   bool isTextMsg = false,
 | |
|       isReplyMsg = false,
 | |
|       isAttachmentMsg = false,
 | |
|       isVoiceMsg = false;
 | |
| 
 | |
|   // Audio Recoding Work
 | |
|   Timer? _timer;
 | |
|   int _recodeDuration = 0;
 | |
|   bool isRecoding = false;
 | |
|   bool isPause = false;
 | |
|   bool isPlaying = false;
 | |
|   String? path;
 | |
|   String? musicFile;
 | |
|   late Directory appDirectory;
 | |
|   late RecorderController recorderController;
 | |
|   late PlayerController playerController;
 | |
|   List<GetEmployeeSubordinatesList> getEmployeeSubordinatesList = [];
 | |
|   List<ChatUser> teamMembersList = [];
 | |
|   groups.GetUserGroups userGroups = groups.GetUserGroups();
 | |
|   Material.TextDirection textDirection = Material.TextDirection.ltr;
 | |
|   bool isRTL = false;
 | |
|   String msgText = "";
 | |
| 
 | |
|   //Chat Home Page Counter
 | |
|   int chatUConvCounter = 0;
 | |
| 
 | |
|   late List<groupchathistory.GetGroupChatHistoryAsync> groupChatHistory, groupChatReplyData;
 | |
| 
 | |
|   /// Search Provider
 | |
|   List<ChatUser>? chatUsersList = [];
 | |
|   int pageNo = 1;
 | |
| 
 | |
|   bool disbaleChatForThisUser = false;
 | |
|   List<groups.GroupResponse>? uGroups = [], searchGroups = [];
 | |
| 
 | |
|   Future<void> getUserAutoLoginToken() async {
 | |
|     userLoginToken.UserAutoLoginModel userLoginResponse =
 | |
|         await ChatApiClient().getUserLoginToken();
 | |
|     if (userLoginResponse.response != null) {
 | |
|       AppState().setchatUserDetails = userLoginResponse;
 | |
|     } else {
 | |
|       AppState().setchatUserDetails = userLoginResponse;
 | |
|       Utils.showToast(
 | |
|         userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
 | |
|       );
 | |
|       disbaleChatForThisUser = true;
 | |
|       notifyListeners();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Future<void> buildHubConnection() async {
 | |
|     chatHubConnection = await getHubConnection();
 | |
|     await chatHubConnection.start();
 | |
|     if (kDebugMode) {
 | |
|       logger.i("Hub Conn: Startedddddddd");
 | |
|     }
 | |
|     chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
 | |
|     chatHubConnection.on("OnGetChatConversationCount", onNewChatConversion);
 | |
| 
 | |
|     //group On message
 | |
| 
 | |
|     chatHubConnection.on("OnDeliveredGroupChatHistoryAsync", onGroupMsgReceived);
 | |
|   }
 | |
| 
 | |
|   Future<HubConnection> getHubConnection() async {
 | |
|     HubConnection hub;
 | |
|     HttpConnectionOptions httpOp =
 | |
|         HttpConnectionOptions(skipNegotiation: false, logMessageContent: true);
 | |
|     hub = HubConnectionBuilder()
 | |
|         .withUrl(
 | |
|             ApiConsts.chatHubConnectionUrl +
 | |
|                 "?UserId=${AppState().chatDetails!.response!.id}&source=Desktop&access_token=${AppState().chatDetails!.response!.token}",
 | |
|             options: httpOp)
 | |
|         .withAutomaticReconnect(
 | |
|             retryDelays: <int>[2000, 5000, 10000, 20000]).build();
 | |
|     return hub;
 | |
|   }
 | |
| 
 | |
|   void registerEvents() {
 | |
|     chatHubConnection.on("OnUpdateUserStatusAsync", changeStatus);
 | |
|     //   chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
 | |
| 
 | |
|     chatHubConnection.on("OnSubmitChatAsync", OnSubmitChatAsync);
 | |
|     chatHubConnection.on("OnUserTypingAsync", onUserTyping);
 | |
|     chatHubConnection.on("OnUserCountAsync", userCountAsync);
 | |
|     //  chatHubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
 | |
|     chatHubConnection.on(
 | |
|         "OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
 | |
|     chatHubConnection.on(
 | |
|         "OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
 | |
|     chatHubConnection.on(
 | |
|         "OnGetGroupUserStatusAsync", getGroupUserStatus);
 | |
| 
 | |
|     //
 | |
|     // {"type":1,"target":"","arguments":[[{"id":217869,"userName":"Sultan.Khan","email":"Sultan.Khan@cloudsolutions.com.sa","phone":null,"title":"Sultan.Khan","userStatus":1,"image":null,"unreadMessageCount":0,"userAction":3,"isPin":false,"isFav":false,"isAdmin":false,"rKey":null,"totalCount":0,"isHuaweiDevice":false,"deviceToken":null},{"id":15153,"userName":"Tamer.Fanasheh","email":"Tamer.F@cloudsolutions.com.sa","phone":null,"title":"Tamer Fanasheh","userStatus":2,"image":null,"unreadMessageCount":0,"userAction":3,"isPin":false,"isFav":false,"isAdmin":true,"rKey":null,"totalCount":0,"isHuaweiDevice":false,"deviceToken":null}]]}
 | |
| 
 | |
|     if (kDebugMode) {
 | |
|       logger.i("All listeners registered");
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Future<void> getUserRecentChats() async {
 | |
|     ChatUserModel recentChat = await ChatApiClient().getRecentChats();
 | |
|     ChatUserModel favUList = await ChatApiClient().getFavUsers();
 | |
|     // userGroups = await ChatApiClient().getGroupsByUserId();
 | |
|     if (favUList.response != null && recentChat.response != null) {
 | |
|       favUsersList = favUList.response!;
 | |
|       favUsersList.sort((ChatUser a, ChatUser b) =>
 | |
|           a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase()));
 | |
|       for (dynamic user in recentChat.response!) {
 | |
|         for (dynamic favUser in favUList.response!) {
 | |
|           if (user.id == favUser.id) {
 | |
|             user.isFav = favUser.isFav;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     pChatHistory = recentChat.response ?? [];
 | |
|     uGroups = userGroups.groupresponse ?? [];
 | |
|     pChatHistory!.sort((ChatUser a, ChatUser b) =>
 | |
|         a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase()));
 | |
|     searchedChats = pChatHistory;
 | |
|     isLoading = false;
 | |
|     await invokeUserChatHistoryNotDeliveredAsync(
 | |
|         userId: int.parse(AppState().chatDetails!.response!.id.toString()));
 | |
|     sort();
 | |
|     notifyListeners();
 | |
|     if (searchedChats!.isNotEmpty || favUsersList.isNotEmpty) {
 | |
|       getUserImages();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Future invokeUserChatHistoryNotDeliveredAsync({required int userId}) async {
 | |
|     await chatHubConnection
 | |
|         .invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]);
 | |
|     return "";
 | |
|   }
 | |
| 
 | |
|   void getSingleUserChatHistory(
 | |
|       {required int senderUID,
 | |
|       required int receiverUID,
 | |
|       required bool loadMore,
 | |
|       bool isNewChat = false}) async {
 | |
|     isLoading = true;
 | |
|     if (isNewChat) userChatHistory = [];
 | |
|     if (!loadMore) paginationVal = 0;
 | |
|     isChatScreenActive = true;
 | |
|     receiverID = receiverUID;
 | |
|     Response response = await ChatApiClient().getSingleUserChatHistory(
 | |
|         senderUID: senderUID,
 | |
|         receiverUID: receiverUID,
 | |
|         loadMore: loadMore,
 | |
|         paginationVal: paginationVal);
 | |
|     if (response.statusCode == 204) {
 | |
|       if (isNewChat) {
 | |
|         userChatHistory = [];
 | |
|       } else if (loadMore) {}
 | |
|     } else {
 | |
|       if (loadMore) {
 | |
|         List<SingleUserChatModel> temp =
 | |
|             getSingleUserChatModel(response.body).reversed.toList();
 | |
|         userChatHistory.addAll(temp);
 | |
|       } else {
 | |
|         userChatHistory =
 | |
|             getSingleUserChatModel(response.body).reversed.toList();
 | |
|       }
 | |
|     }
 | |
|     isLoading = false;
 | |
|     notifyListeners();
 | |
| 
 | |
|     if (isChatScreenActive && receiverUID == receiverID) {
 | |
|       markRead(userChatHistory, receiverUID);
 | |
|     }
 | |
| 
 | |
|     generateConvId();
 | |
|   }
 | |
| 
 | |
|   void generateConvId() async {
 | |
|     Uuid uuid = const Uuid();
 | |
|     chatCID = uuid.v4();
 | |
|   }
 | |
| 
 | |
|   void markRead(List<SingleUserChatModel> data, int receiverID) {
 | |
|     for (SingleUserChatModel element in data!) {
 | |
|       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;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void updateUserChatHistoryStatusAsync(List data) {
 | |
|     try {
 | |
|       chatHubConnection
 | |
|           .invoke("UpdateUserChatHistoryStatusAsync", args: [data]);
 | |
|     } catch (e) {
 | |
|       throw e;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void updateUserChatHistoryOnMsg(List data) {
 | |
|     try {
 | |
|       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)));
 | |
| 
 | |
|   List<groupchathistory.GetGroupChatHistoryAsync> getGroupChatHistoryAsync(String str) =>
 | |
|       List<groupchathistory.GetGroupChatHistoryAsync>.from(
 | |
|           json.decode(str).map((x) => groupchathistory.GetGroupChatHistoryAsync.fromJson(x)));
 | |
| 
 | |
| 
 | |
|   Future<dynamic> uploadAttachments(String userId, File file) async {
 | |
|     dynamic result;
 | |
|     try {
 | |
|       Object? response = await ChatApiClient().uploadMedia(userId, file);
 | |
|       if (response != null) {
 | |
|         result = response;
 | |
|       } else {
 | |
|         result = [];
 | |
|       }
 | |
|     } catch (e) {
 | |
|       throw e;
 | |
|     }
 | |
|     return result;
 | |
|   }
 | |
| 
 | |
|   void updateUserChatStatus(List<Object?>? args) {
 | |
|     dynamic items = args!.toList();
 | |
|     for (var cItem in items[0]) {
 | |
|       for (SingleUserChatModel chat in userChatHistory) {
 | |
|         if (cItem["contantNo"].toString() == chat.contantNo.toString()) {
 | |
|           chat.isSeen = cItem["isSeen"];
 | |
|           chat.isDelivered = cItem["isDelivered"];
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void getGroupUserStatus(List<Object?>? args){
 | |
|   //note: need to implement this function...
 | |
|   print(args);
 | |
|   }
 | |
| 
 | |
|   void onChatSeen(List<Object?>? args) {
 | |
|     dynamic items = args!.toList();
 | |
|     // for (var user in searchedChats!) {
 | |
|     //   if (user.id == items.first["id"]) {
 | |
|     //     user.userStatus = items.first["userStatus"];
 | |
|     //   }
 | |
|     // }
 | |
|     // notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void userCountAsync(List<Object?>? args) {
 | |
|     dynamic items = args!.toList();
 | |
|     // logger.d(items);
 | |
|     //logger.d("---------------------------------User Count Async -------------------------------------");
 | |
|     //logger.d(items);
 | |
|     // for (var user in searchedChats!) {
 | |
|     //   if (user.id == items.first["id"]) {
 | |
|     //     user.userStatus = items.first["userStatus"];
 | |
|     //   }
 | |
|     // }
 | |
|     // notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void updateChatHistoryWindow(List<Object?>? args) {
 | |
|     dynamic items = args!.toList();
 | |
|     if (kDebugMode) {
 | |
|       logger.i(
 | |
|           "---------------------------------Update Chat History Windows  Async -------------------------------------");
 | |
|     }
 | |
|     logger.d(items);
 | |
|     // for (var user in searchedChats!) {
 | |
|     //   if (user.id == items.first["id"]) {
 | |
|     //     user.userStatus = items.first["userStatus"];
 | |
|     //   }
 | |
|     // }
 | |
|     // notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void chatNotDelivered(List<Object?>? args) {
 | |
|     dynamic items = args!.toList();
 | |
|     for (dynamic item in items[0]) {
 | |
|       for (ChatUser element in searchedChats!) {
 | |
|         if (element.id == item["currentUserId"]) {
 | |
|           int? val = element.unreadMessageCount ?? 0;
 | |
|           element.unreadMessageCount = val! + 1;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void changeStatus(List<Object?>? args) {
 | |
|     dynamic items = args!.toList();
 | |
|     for (ChatUser user in searchedChats!) {
 | |
|       if (user.id == items.first["id"]) {
 | |
|         user.userStatus = items.first["userStatus"];
 | |
|       }
 | |
|     }
 | |
|     if (teamMembersList.isNotEmpty) {
 | |
|       for (ChatUser user in teamMembersList!) {
 | |
|         if (user.id == items.first["id"]) {
 | |
|           user.userStatus = items.first["userStatus"];
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void filter(String value) async {
 | |
|     List<ChatUser>? tmp = [];
 | |
|     if (value.isEmpty || value == "") {
 | |
|       tmp = pChatHistory;
 | |
|     } else {
 | |
|       for (ChatUser element in pChatHistory!) {
 | |
|         if (element.userName!.toLowerCase().contains(value.toLowerCase())) {
 | |
|           tmp.add(element);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     searchedChats = tmp;
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   Future<void> onMsgReceived(List<Object?>? parameters) async {
 | |
|     List<SingleUserChatModel> data = [], temp = [];
 | |
|     for (dynamic msg in parameters!) {
 | |
|       data = getSingleUserChatModel(jsonEncode(msg));
 | |
|       temp = getSingleUserChatModel(jsonEncode(msg));
 | |
|       data.first.targetUserId = temp.first.currentUserId;
 | |
|       data.first.targetUserName = temp.first.currentUserName;
 | |
|       data.first.targetUserEmail = temp.first.currentUserEmail;
 | |
|       data.first.currentUserId = temp.first.targetUserId;
 | |
|       data.first.currentUserName = temp.first.targetUserName;
 | |
|       data.first.currentUserEmail = temp.first.targetUserEmail;
 | |
| 
 | |
|       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;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (searchedChats != null) {
 | |
|       dynamic contain = searchedChats!
 | |
|           .where((ChatUser element) => element.id == data.first.currentUserId);
 | |
|       if (contain.isEmpty) {
 | |
|         List<String> emails = [];
 | |
|         emails.add(await EmailImageEncryption()
 | |
|             .encrypt(val: data.first.currentUserEmail!));
 | |
|         List<ChatUserImageModel> chatImages =
 | |
|             await ChatApiClient().getUsersImages(encryptedEmails: emails);
 | |
|         searchedChats!.add(
 | |
|           ChatUser(
 | |
|             id: data.first.currentUserId,
 | |
|             userName: data.first.currentUserName,
 | |
|             email: data.first.currentUserEmail,
 | |
|             unreadMessageCount: 0,
 | |
|             isImageLoading: false,
 | |
|             image: chatImages!.first.profilePicture ?? "",
 | |
|             isImageLoaded: true,
 | |
|             userStatus: 1,
 | |
|             isTyping: false,
 | |
|             userLocalDownlaodedImage: await downloadImageLocal(
 | |
|                 chatImages.first.profilePicture,
 | |
|                 data.first.currentUserId.toString()),
 | |
|           ),
 | |
|         );
 | |
|       }
 | |
|     }
 | |
|     setMsgTune();
 | |
|     if (isChatScreenActive && data.first.currentUserId == receiverID) {
 | |
|       userChatHistory.insert(0, data.first);
 | |
|     } else {
 | |
|       if (searchedChats != null) {
 | |
|         for (ChatUser user in searchedChats!) {
 | |
|           if (user.id == data.first.currentUserId) {
 | |
|             int tempCount = user.unreadMessageCount ?? 0;
 | |
|             user.unreadMessageCount = tempCount + 1;
 | |
|           }
 | |
|         }
 | |
|         sort();
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     List<Object> list = [
 | |
|       {
 | |
|         "userChatHistoryId": data.first.userChatHistoryId,
 | |
|         "TargetUserId": temp.first.targetUserId,
 | |
|         "isDelivered": true,
 | |
|         "isSeen": isChatScreenActive && data.first.currentUserId == receiverID
 | |
|             ? true
 | |
|             : false
 | |
|       }
 | |
|     ];
 | |
|     updateUserChatHistoryOnMsg(list);
 | |
|     invokeChatCounter(userId: AppState().chatDetails!.response!.id!);
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   Future<void> onGroupMsgReceived(List<Object?>? parameters) async {
 | |
|     List<groupchathistory.GetGroupChatHistoryAsync> data = [], temp = [];
 | |
| 
 | |
| 
 | |
|     for (dynamic msg in parameters!) {
 | |
|      // groupChatHistory.add(groupchathistory.GetGroupChatHistoryAsync.fromJson(msg));
 | |
|       data.add(groupchathistory.GetGroupChatHistoryAsync.fromJson(msg));
 | |
|       temp =data;
 | |
|       // data.first.currentUserId = temp.first.currentUserId;
 | |
|       // data.first.currentUserName = temp.first.currentUserName;
 | |
|       //
 | |
|       // data.first.currentUserId = temp.first.currentUserId;
 | |
|       // data.first.currentUserName = temp.first.currentUserName;
 | |
| 
 | |
| 
 | |
|       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.groupChatReplyResponse != null) {
 | |
|         if (data.first.fileTypeResponse != null) {
 | |
|           if (data.first.groupChatReplyResponse!.fileTypeId == 12 ||
 | |
|               data.first.groupChatReplyResponse!.fileTypeId == 4 ||
 | |
|               data.first.groupChatReplyResponse!.fileTypeId == 3) {
 | |
|             data.first.groupChatReplyResponse!.image = await ChatApiClient()
 | |
|                 .downloadURL(
 | |
|                 fileName: data.first.groupChatReplyResponse!.contant!,
 | |
|                 fileTypeDescription:
 | |
|                 data.first.fileTypeResponse!.fileTypeDescription ??
 | |
|                     "image/jpg");
 | |
|             data.first.groupChatReplyResponse!.isImageLoaded = true;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // if (searchedChats != null) {
 | |
|     //   dynamic contain = searchedChats!
 | |
|     //       .where((ChatUser element) => element.id == data.first.currentUserId);
 | |
|     //   if (contain.isEmpty) {
 | |
|     //     List<String> emails = [];
 | |
|     //     emails.add(await EmailImageEncryption()
 | |
|     //         .encrypt(val: data.first.currentUserEmail!));
 | |
|     //     List<ChatUserImageModel> chatImages =
 | |
|     //     await ChatApiClient().getUsersImages(encryptedEmails: emails);
 | |
|     //     searchedChats!.add(
 | |
|     //       ChatUser(
 | |
|     //         id: data.first.currentUserId,
 | |
|     //         userName: data.first.currentUserName,
 | |
|     //         email: data.first.currentUserEmail,
 | |
|     //         unreadMessageCount: 0,
 | |
|     //         isImageLoading: false,
 | |
|     //         image: chatImages!.first.profilePicture ?? "",
 | |
|     //         isImageLoaded: true,
 | |
|     //         userStatus: 1,
 | |
|     //         isTyping: false,
 | |
|     //         userLocalDownlaodedImage: await downloadImageLocal(
 | |
|     //             chatImages.first.profilePicture,
 | |
|     //             data.first.currentUserId.toString()),
 | |
|     //       ),
 | |
|     //     );
 | |
|     //   }
 | |
|    // }
 | |
|     groupChatHistory.insert(0, data.first);
 | |
|     setMsgTune();
 | |
|    // if (isChatScreenActive && data.first.currentUserId == receiverID) {
 | |
| 
 | |
|     // } else {
 | |
|     //   if (searchedChats != null) {
 | |
|     //     for (ChatUser user in searchedChats!) {
 | |
|     //       if (user.id == data.first.currentUserId) {
 | |
|     //         int tempCount = user.unreadMessageCount ?? 0;
 | |
|     //         user.unreadMessageCount = tempCount + 1;
 | |
|     //       }
 | |
|     //     }
 | |
|         sort();
 | |
|       //}
 | |
|     //}
 | |
|     //
 | |
|     // List<Object> list = [
 | |
|     //   {
 | |
|     //     "userChatHistoryId": data.first.groupId,
 | |
|     //     "TargetUserId": temp.first.currentUserId,
 | |
|     //     "isDelivered": true,
 | |
|     //     "isSeen": isChatScreenActive && data.first.currentUserId == receiverID
 | |
|     //         ? true
 | |
|     //         : false
 | |
|     //   }
 | |
|     // ];
 | |
|    // updateUserChatHistoryOnMsg(list);
 | |
|    // invokeChatCounter(userId: AppState().chatDetails!.response!.id!);
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
| 
 | |
| 
 | |
|   void OnSubmitChatAsync(List<Object?>? parameters) {
 | |
|     print(isChatScreenActive);
 | |
|     print(receiverID);
 | |
|     print(isChatScreenActive);
 | |
|     logger.i(parameters);
 | |
|     List<SingleUserChatModel> data = [], temp = [];
 | |
|     for (dynamic msg in parameters!) {
 | |
|       data = getSingleUserChatModel(jsonEncode(msg));
 | |
|       temp = getSingleUserChatModel(jsonEncode(msg));
 | |
|       data.first.targetUserId = temp.first.currentUserId;
 | |
|       data.first.targetUserName = temp.first.currentUserName;
 | |
|       data.first.targetUserEmail = temp.first.currentUserEmail;
 | |
|       data.first.currentUserId = temp.first.targetUserId;
 | |
|       data.first.currentUserName = temp.first.targetUserName;
 | |
|       data.first.currentUserEmail = temp.first.targetUserEmail;
 | |
|     }
 | |
|     if (isChatScreenActive && data.first.currentUserId == receiverID) {
 | |
|       int index = userChatHistory.indexWhere(
 | |
|           (SingleUserChatModel element) => element.userChatHistoryId == 0);
 | |
|       logger.d(index);
 | |
|       userChatHistory[index] = data.first;
 | |
|     }
 | |
| 
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void sort() {
 | |
|     searchedChats!.sort(
 | |
|       (ChatUser a, ChatUser b) =>
 | |
|           b.unreadMessageCount!.compareTo(a.unreadMessageCount!),
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   void onUserTyping(List<Object?>? parameters) {
 | |
|     for (ChatUser user in searchedChats!) {
 | |
|       if (user.id == parameters![1] && parameters[0] == true) {
 | |
|         user.isTyping = parameters[0] as bool?;
 | |
|         Future.delayed(
 | |
|           const Duration(seconds: 2),
 | |
|           () {
 | |
|             user.isTyping = false;
 | |
|             notifyListeners();
 | |
|           },
 | |
|         );
 | |
|       }
 | |
|     }
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   int getFileType(String value) {
 | |
|     switch (value) {
 | |
|       case ".pdf":
 | |
|         return 1;
 | |
|       case ".png":
 | |
|         return 3;
 | |
|       case ".txt":
 | |
|         return 5;
 | |
|       case ".jpg":
 | |
|         return 12;
 | |
|       case ".jpeg":
 | |
|         return 4;
 | |
|       case ".xls":
 | |
|         return 7;
 | |
|       case ".xlsx":
 | |
|         return 7;
 | |
|       case ".doc":
 | |
|         return 6;
 | |
|       case ".docx":
 | |
|         return 6;
 | |
|       case ".ppt":
 | |
|         return 8;
 | |
|       case ".pptx":
 | |
|         return 8;
 | |
|       case ".zip":
 | |
|         return 2;
 | |
|       case ".rar":
 | |
|         return 2;
 | |
|       case ".aac":
 | |
|         return 13;
 | |
|       case ".mp3":
 | |
|         return 14;
 | |
|       default:
 | |
|         return 0;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   String getFileTypeDescription(String value) {
 | |
|     switch (value) {
 | |
|       case ".pdf":
 | |
|         return "application/pdf";
 | |
|       case ".png":
 | |
|         return "image/png";
 | |
|       case ".txt":
 | |
|         return "text/plain";
 | |
|       case ".jpg":
 | |
|         return "image/jpg";
 | |
|       case ".jpeg":
 | |
|         return "image/jpeg";
 | |
|       case ".ppt":
 | |
|         return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
 | |
|       case ".pptx":
 | |
|         return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
 | |
|       case ".doc":
 | |
|         return "application/vnd.openxmlformats-officedocument.wordprocessingm";
 | |
|       case ".docx":
 | |
|         return "application/vnd.openxmlformats-officedocument.wordprocessingm";
 | |
|       case ".xls":
 | |
|         return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
 | |
|       case ".xlsx":
 | |
|         return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
 | |
|       case ".zip":
 | |
|         return "application/octet-stream";
 | |
|       case ".rar":
 | |
|         return "application/octet-stream";
 | |
|       case ".aac":
 | |
|         return "audio/aac";
 | |
|       case ".mp3":
 | |
|         return "audio/mp3";
 | |
|       default:
 | |
|         return "";
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Future<void> sendChatToServer(
 | |
|       {required int chatEventId,
 | |
|       required fileTypeId,
 | |
|       required int targetUserId,
 | |
|       required String targetUserName,
 | |
|       required chatReplyId,
 | |
|       required bool isAttachment,
 | |
|       required bool isReply,
 | |
|       Uint8List? image,
 | |
|       required bool isImageLoaded,
 | |
|       String? userEmail,
 | |
|       int? userStatus,
 | |
|       File? voiceFile,
 | |
|       required bool isVoiceAttached}) async {
 | |
|     Uuid uuid = const Uuid();
 | |
|     String contentNo = uuid.v4();
 | |
|     String msg;
 | |
|     if (isVoiceAttached) {
 | |
|       msg = voiceFile!.path.split("/").last;
 | |
|     } else {
 | |
|       msg = message.text;
 | |
|       logger.w(msg);
 | |
|     }
 | |
|     SingleUserChatModel data = SingleUserChatModel(
 | |
|         userChatHistoryId: 0,
 | |
|         chatEventId: chatEventId,
 | |
|         chatSource: 1,
 | |
|         contant: msg,
 | |
|         contantNo: contentNo,
 | |
|         conversationId: chatCID,
 | |
|         createdDate: DateTime.now(),
 | |
|         currentUserId: AppState().chatDetails!.response!.id,
 | |
|         currentUserName: AppState().chatDetails!.response!.userName,
 | |
|         targetUserId: targetUserId,
 | |
|         targetUserName: targetUserName,
 | |
|         isReplied: false,
 | |
|         fileTypeId: fileTypeId,
 | |
|         userChatReplyResponse: isReply
 | |
|             ? UserChatReplyResponse.fromJson(repliedMsg.first.toJson())
 | |
|             : null,
 | |
|         fileTypeResponse: isAttachment
 | |
|             ? FileTypeResponse(
 | |
|                 fileTypeId: fileTypeId,
 | |
|                 fileTypeName: isVoiceMsg
 | |
|                     ? getFileExtension(voiceFile!.path).toString()
 | |
|                     : getFileExtension(selectedFile.path).toString(),
 | |
|                 fileKind: "file",
 | |
|                 fileName: isVoiceMsg ? msg : selectedFile.path.split("/").last,
 | |
|                 fileTypeDescription: isVoiceMsg
 | |
|                     ? getFileTypeDescription(
 | |
|                         getFileExtension(voiceFile!.path).toString())
 | |
|                     : getFileTypeDescription(
 | |
|                         getFileExtension(selectedFile.path).toString()),
 | |
|               )
 | |
|             : null,
 | |
|         image: image,
 | |
|         isImageLoaded: isImageLoaded,
 | |
|         voice: isVoiceMsg ? voiceFile! : null,
 | |
|         voiceController: isVoiceMsg ? AudioPlayer() : null);
 | |
|     if (kDebugMode) {
 | |
|       logger.i("model data: " + jsonEncode(data));
 | |
|     }
 | |
|     userChatHistory.insert(0, data);
 | |
|     isTextMsg = false;
 | |
|     isReplyMsg = false;
 | |
|     isAttachmentMsg = false;
 | |
|     isVoiceMsg = false;
 | |
|     sFileType = "";
 | |
|     message.clear();
 | |
|     notifyListeners();
 | |
| 
 | |
|     String chatData =
 | |
|         '{"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 chatHubConnection
 | |
|         .invoke("AddChatUserAsync", args: <Object>[json.decode(chatData)]);
 | |
|   }
 | |
| 
 | |
|   //groupChatMessage
 | |
| 
 | |
|   Future<void> sendGroupChatToServer(
 | |
|       {required int chatEventId,
 | |
|       required fileTypeId,
 | |
|       required int targetGroupId,
 | |
|       required String targetUserName,
 | |
|       required chatReplyId,
 | |
|       required bool isAttachment,
 | |
|       required bool isReply,
 | |
|       Uint8List? image,
 | |
|       required bool isImageLoaded,
 | |
|       String? userEmail,
 | |
|       int? userStatus,
 | |
|       File? voiceFile,
 | |
|       required bool isVoiceAttached,
 | |
|       required List<GroupUserList>  userList
 | |
|       }) async {
 | |
|     Uuid uuid = const Uuid();
 | |
|     String contentNo = uuid.v4();
 | |
|     String msg;
 | |
|     if (isVoiceAttached) {
 | |
|       msg = voiceFile!.path.split("/").last;
 | |
|     } else {
 | |
|       msg = message.text;
 | |
|       logger.w(msg);
 | |
|     }
 | |
|     groupchathistory.GetGroupChatHistoryAsync data =
 | |
|         groupchathistory.GetGroupChatHistoryAsync(
 | |
|             //userChatHistoryId: 0,
 | |
|             chatEventId: chatEventId,
 | |
|             chatSource: 1,
 | |
|             contant: msg,
 | |
|             contantNo: contentNo,
 | |
|             conversationId: chatCID,
 | |
|             createdDate: DateTime.now().toString(),
 | |
|             currentUserId: AppState().chatDetails!.response!.id,
 | |
|             currentUserName: AppState().chatDetails!.response!.userName,
 | |
|             groupId: targetGroupId,
 | |
|             groupName: targetUserName,
 | |
|             isReplied: false,
 | |
|             fileTypeId: fileTypeId,
 | |
|             fileTypeResponse: isAttachment
 | |
|              ? groupchathistory.FileTypeResponse(
 | |
|             fileTypeId: fileTypeId,
 | |
|             fileTypeName: isVoiceMsg ? getFileExtension(voiceFile!.path).toString() : getFileExtension(selectedFile.path).toString(),
 | |
|              fileKind: "file",
 | |
|             fileName: isVoiceMsg ? msg : selectedFile.path.split("/").last,
 | |
|             fileTypeDescription: isVoiceMsg ? getFileTypeDescription(getFileExtension(voiceFile!.path).toString()) : getFileTypeDescription(getFileExtension(selectedFile.path).toString())) : null,
 | |
|             image: image,
 | |
|             isImageLoaded: isImageLoaded,
 | |
|             voice: isVoiceMsg ? voiceFile! : null,
 | |
|             voiceController: isVoiceMsg ? AudioPlayer() : null);
 | |
|     if (kDebugMode) {
 | |
|       logger.i("model data: " + jsonEncode(data));
 | |
|     }
 | |
|      groupChatHistory.insert(0, data);
 | |
|     isTextMsg = false;
 | |
|     isReplyMsg = false;
 | |
|     isAttachmentMsg = false;
 | |
|     isVoiceMsg = false;
 | |
|     sFileType = "";
 | |
|     message.clear();
 | |
|     notifyListeners();
 | |
| 
 | |
|     List<TargetUsers> targetUsers =[];
 | |
| 
 | |
|     for (GroupUserList element in userList) {
 | |
|       targetUsers.add(TargetUsers(isDelivered: false,isSeen: false, targetUserId: element.id, userAction: element.userAction, userStatus: element.userStatus));
 | |
| 
 | |
|     }
 | |
| 
 | |
|     String chatData =
 | |
|         '{"contant":"$msg","contantNo":"$contentNo","chatEventId":$chatEventId,"fileTypeId":$fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"groupId":$targetGroupId,"groupChatHistoryLineRequestList":${json.encode(targetUsers)},"chatReplyId": $chatReplyId,"conversationId":"${uuid.v4()}"}';
 | |
| 
 | |
|     await chatHubConnection.invoke("AddGroupChatHistoryAsync",
 | |
|         args: <Object>[json.decode(chatData)]);
 | |
|   }
 | |
| 
 | |
|   void sendGroupChatMessage(BuildContext context,
 | |
|       {required int targetUserId,
 | |
|       required int userStatus,
 | |
|       required String userEmail,
 | |
|       required String targetUserName,
 | |
|         required List<GroupUserList> userList,
 | |
|       }) async {
 | |
|     if (isTextMsg && !isAttachmentMsg && !isVoiceMsg && !isReplyMsg) {
 | |
|       logger.d("// Normal Text Message");
 | |
|       if (message.text.isEmpty) {
 | |
|         return;
 | |
|       }
 | |
|       sendGroupChatToServer(
 | |
|           chatEventId: 1,
 | |
|           fileTypeId: null,
 | |
|           targetGroupId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           isAttachment: false,
 | |
|           chatReplyId: null,
 | |
|           isReply: false,
 | |
|           isImageLoaded: false,
 | |
|           image: null,
 | |
|           isVoiceAttached: false,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus,
 | |
|           userList:userList
 | |
|       );
 | |
|     } else if (isTextMsg && !isAttachmentMsg && !isVoiceMsg && isReplyMsg) {
 | |
|       logger.d("// Text Message as Reply");
 | |
|       if (message.text.isEmpty) {
 | |
|         return;
 | |
|       }
 | |
|       sendGroupChatToServer(
 | |
|           chatEventId: 1,
 | |
|           fileTypeId: null,
 | |
|           targetGroupId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           chatReplyId: groupChatReplyData.first.groupChatHistoryId,
 | |
|           isAttachment: false,
 | |
|           isReply: true,
 | |
|           isImageLoaded: groupChatReplyData.first.isImageLoaded!,
 | |
|           image: groupChatReplyData.first.image,
 | |
|           isVoiceAttached: false,
 | |
|           voiceFile: null,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus,
 | |
|           userList:userList
 | |
|       );
 | |
|     }
 | |
|     //  Attachment
 | |
|     else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && !isReplyMsg) {
 | |
|       logger.d("// Normal Image Message");
 | |
|       Utils.showLoading(context);
 | |
|       dynamic value = await uploadAttachments(
 | |
|           AppState().chatDetails!.response!.id.toString(), selectedFile);
 | |
|       String? ext = getFileExtension(selectedFile.path);
 | |
|       Utils.hideLoading(context);
 | |
|       sendGroupChatToServer(
 | |
|           chatEventId: 2,
 | |
|           fileTypeId: getFileType(ext.toString()),
 | |
|           targetGroupId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           isAttachment: true,
 | |
|           chatReplyId: null,
 | |
|           isReply: false,
 | |
|           isImageLoaded: true,
 | |
|           image: selectedFile.readAsBytesSync(),
 | |
|           isVoiceAttached: false,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus,
 | |
|           userList:userList
 | |
|       );
 | |
|     } else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && isReplyMsg) {
 | |
|       logger.d("// Image as Reply Msg");
 | |
|       Utils.showLoading(context);
 | |
|       dynamic value = await uploadAttachments(
 | |
|           AppState().chatDetails!.response!.id.toString(), selectedFile);
 | |
|       String? ext = getFileExtension(selectedFile.path);
 | |
|       Utils.hideLoading(context);
 | |
|       sendGroupChatToServer(
 | |
|           chatEventId: 2,
 | |
|           fileTypeId: getFileType(ext.toString()),
 | |
| 
 | |
|           targetGroupId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           isAttachment: true,
 | |
|           chatReplyId: repliedMsg.first.userChatHistoryId,
 | |
|           isReply: true,
 | |
|           isImageLoaded: true,
 | |
|           image: selectedFile.readAsBytesSync(),
 | |
|           isVoiceAttached: false,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus,
 | |
|           userList:userList
 | |
|       );
 | |
|     }
 | |
|     //Voice
 | |
| 
 | |
|     else if (!isTextMsg && !isAttachmentMsg && isVoiceMsg && !isReplyMsg) {
 | |
|       logger.d("// Normal Voice Message");
 | |
| 
 | |
|       if (!isPause) {
 | |
|         path = await recorderController.stop(false);
 | |
|       }
 | |
|       if (kDebugMode) {
 | |
|         logger.i("path:" + path!);
 | |
|       }
 | |
|       File voiceFile = File(path!);
 | |
|       voiceFile.readAsBytesSync();
 | |
|       _timer?.cancel();
 | |
|       isPause = false;
 | |
|       isPlaying = false;
 | |
|       isRecoding = false;
 | |
|       Utils.showLoading(context);
 | |
|       dynamic value = await uploadAttachments(
 | |
|           AppState().chatDetails!.response!.id.toString(), voiceFile);
 | |
|        String? ext = getFileExtension(voiceFile.path);
 | |
|       Utils.hideLoading(context);
 | |
|       sendGroupChatToServer(
 | |
|           chatEventId: 2,
 | |
|           fileTypeId: getFileType(ext.toString()),
 | |
|           //,
 | |
|           targetGroupId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           chatReplyId: null,
 | |
|           isAttachment: true,
 | |
|           isReply: isReplyMsg,
 | |
|           isImageLoaded: false,
 | |
|           voiceFile: voiceFile,
 | |
|           isVoiceAttached: true,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus,
 | |
|           userList:userList
 | |
|       );
 | |
|       notifyListeners();
 | |
|     } else if (!isTextMsg && !isAttachmentMsg && isVoiceMsg && isReplyMsg) {
 | |
|       logger.d("// Voice as Reply Msg");
 | |
| 
 | |
|       if (!isPause) {
 | |
|         path = await recorderController.stop(false);
 | |
|       }
 | |
|       if (kDebugMode) {
 | |
|         logger.i("path:" + path!);
 | |
|       }
 | |
|       File voiceFile = File(path!);
 | |
|       voiceFile.readAsBytesSync();
 | |
|       _timer?.cancel();
 | |
|       isPause = false;
 | |
|       isPlaying = false;
 | |
|       isRecoding = false;
 | |
| 
 | |
|       Utils.showLoading(context);
 | |
|       dynamic value = await uploadAttachments(
 | |
|           AppState().chatDetails!.response!.id.toString(), voiceFile);
 | |
|        String? ext = getFileExtension(voiceFile.path);
 | |
|       Utils.hideLoading(context);
 | |
|       sendGroupChatToServer(
 | |
|           chatEventId: 2,
 | |
|           fileTypeId: getFileType(ext.toString()),
 | |
|           targetGroupId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           chatReplyId: null,
 | |
|           isAttachment: true,
 | |
|           isReply: isReplyMsg,
 | |
|           isImageLoaded: false,
 | |
|           voiceFile: voiceFile,
 | |
|           isVoiceAttached: true,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus,
 | |
|           userList:userList
 | |
|       );
 | |
|       notifyListeners();
 | |
|     }
 | |
|     if (searchedChats != null) {
 | |
|       dynamic contain = searchedChats!
 | |
|           .where((ChatUser element) => element.id == targetUserId);
 | |
|       if (contain.isEmpty) {
 | |
|         List<String> emails = [];
 | |
|         emails.add(await EmailImageEncryption().encrypt(val: userEmail));
 | |
|         List<ChatUserImageModel> chatImages =
 | |
|             await ChatApiClient().getUsersImages(encryptedEmails: emails);
 | |
|         searchedChats!.add(
 | |
|           ChatUser(
 | |
|             id: targetUserId,
 | |
|             userName: targetUserName,
 | |
|             unreadMessageCount: 0,
 | |
|             email: userEmail,
 | |
|             isImageLoading: false,
 | |
|             image: chatImages.first.profilePicture ?? "",
 | |
|             isImageLoaded: true,
 | |
|             isTyping: false,
 | |
|             isFav: false,
 | |
|             userStatus: userStatus,
 | |
|             // userLocalDownlaodedImage: await downloadImageLocal(chatImages.first.profilePicture, targetUserId.toString()),
 | |
|           ),
 | |
|         );
 | |
|         notifyListeners();
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void sendChatMessage(BuildContext context,
 | |
|       {required int targetUserId,
 | |
|       required int userStatus,
 | |
|       required String userEmail,
 | |
|       required String targetUserName,
 | |
| 
 | |
|       }) async {
 | |
|     if (kDebugMode) {
 | |
|       print("====================== Values ============================");
 | |
|       print("Is Text " + isTextMsg.toString());
 | |
|       print("isReply " + isReplyMsg.toString());
 | |
|       print("isAttachment " + isAttachmentMsg.toString());
 | |
|       print("isVoice " + isVoiceMsg.toString());
 | |
|     }
 | |
|     //Text
 | |
|     if (isTextMsg && !isAttachmentMsg && !isVoiceMsg && !isReplyMsg) {
 | |
|       logger.d("// Normal Text Message");
 | |
|       if (message.text.isEmpty) {
 | |
|         return;
 | |
|       }
 | |
|       sendChatToServer(
 | |
|           chatEventId: 1,
 | |
|           fileTypeId: null,
 | |
|           targetUserId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           isAttachment: false,
 | |
|           chatReplyId: null,
 | |
|           isReply: false,
 | |
|           isImageLoaded: false,
 | |
|           image: null,
 | |
|           isVoiceAttached: false,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus);
 | |
|     } else if (isTextMsg && !isAttachmentMsg && !isVoiceMsg && isReplyMsg) {
 | |
|       logger.d("// Text Message as Reply");
 | |
|       if (message.text.isEmpty) {
 | |
|         return;
 | |
|       }
 | |
|       sendChatToServer(
 | |
|           chatEventId: 1,
 | |
|           fileTypeId: null,
 | |
|           targetUserId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           chatReplyId: repliedMsg.first.userChatHistoryId,
 | |
|           isAttachment: false,
 | |
|           isReply: true,
 | |
|           isImageLoaded: repliedMsg.first.isImageLoaded!,
 | |
|           image: repliedMsg.first.image,
 | |
|           isVoiceAttached: false,
 | |
|           voiceFile: null,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus);
 | |
|     }
 | |
|     //  Attachment
 | |
|     else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && !isReplyMsg) {
 | |
|       logger.d("// Normal Image Message");
 | |
|       Utils.showLoading(context);
 | |
|       dynamic value = await uploadAttachments(
 | |
|           AppState().chatDetails!.response!.id.toString(), selectedFile);
 | |
|       String? ext = getFileExtension(selectedFile.path);
 | |
|       Utils.hideLoading(context);
 | |
|       sendChatToServer(
 | |
|           chatEventId: 2,
 | |
|           fileTypeId: getFileType(ext.toString()),
 | |
|           targetUserId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           isAttachment: true,
 | |
|           chatReplyId: null,
 | |
|           isReply: false,
 | |
|           isImageLoaded: true,
 | |
|           image: selectedFile.readAsBytesSync(),
 | |
|           isVoiceAttached: false,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus);
 | |
|     } else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && isReplyMsg) {
 | |
|       logger.d("// Image as Reply Msg");
 | |
|       Utils.showLoading(context);
 | |
|       dynamic value = await uploadAttachments(
 | |
|           AppState().chatDetails!.response!.id.toString(), selectedFile);
 | |
|       String? ext = getFileExtension(selectedFile.path);
 | |
|       Utils.hideLoading(context);
 | |
|       sendChatToServer(
 | |
|           chatEventId: 2,
 | |
|           fileTypeId: getFileType(ext.toString()),
 | |
|           targetUserId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           isAttachment: true,
 | |
|           chatReplyId: repliedMsg.first.userChatHistoryId,
 | |
|           isReply: true,
 | |
|           isImageLoaded: true,
 | |
|           image: selectedFile.readAsBytesSync(),
 | |
|           isVoiceAttached: false,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus);
 | |
|     }
 | |
|     //Voice
 | |
| 
 | |
|     else if (!isTextMsg && !isAttachmentMsg && isVoiceMsg && !isReplyMsg) {
 | |
|       logger.d("// Normal Voice Message");
 | |
| 
 | |
|       if (!isPause) {
 | |
|         path = await recorderController.stop(false);
 | |
|       }
 | |
|       if (kDebugMode) {
 | |
|         logger.i("path:" + path!);
 | |
|       }
 | |
|       File voiceFile = File(path!);
 | |
|       voiceFile.readAsBytesSync();
 | |
|       _timer?.cancel();
 | |
|       isPause = false;
 | |
|       isPlaying = false;
 | |
|       isRecoding = false;
 | |
|       Utils.showLoading(context);
 | |
|       dynamic value = await uploadAttachments(
 | |
|           AppState().chatDetails!.response!.id.toString(), voiceFile);
 | |
|       String? ext = getFileExtension(voiceFile.path);
 | |
|       Utils.hideLoading(context);
 | |
|       sendChatToServer(
 | |
|           chatEventId: 2,
 | |
|           fileTypeId: getFileType(ext.toString()),
 | |
|           targetUserId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           chatReplyId: null,
 | |
|           isAttachment: true,
 | |
|           isReply: isReplyMsg,
 | |
|           isImageLoaded: false,
 | |
|           voiceFile: voiceFile,
 | |
|           isVoiceAttached: true,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus);
 | |
|       notifyListeners();
 | |
|     } else if (!isTextMsg && !isAttachmentMsg && isVoiceMsg && isReplyMsg) {
 | |
|       logger.d("// Voice as Reply Msg");
 | |
| 
 | |
|       if (!isPause) {
 | |
|         path = await recorderController.stop(false);
 | |
|       }
 | |
|       if (kDebugMode) {
 | |
|         logger.i("path:" + path!);
 | |
|       }
 | |
|       File voiceFile = File(path!);
 | |
|       voiceFile.readAsBytesSync();
 | |
|       _timer?.cancel();
 | |
|       isPause = false;
 | |
|       isPlaying = false;
 | |
|       isRecoding = false;
 | |
| 
 | |
|       Utils.showLoading(context);
 | |
|       dynamic value = await uploadAttachments(
 | |
|           AppState().chatDetails!.response!.id.toString(), voiceFile);
 | |
|       String? ext = getFileExtension(voiceFile.path);
 | |
|       Utils.hideLoading(context);
 | |
|       sendChatToServer(
 | |
|           chatEventId: 2,
 | |
|           fileTypeId: getFileType(ext.toString()),
 | |
|           targetUserId: targetUserId,
 | |
|           targetUserName: targetUserName,
 | |
|           chatReplyId: null,
 | |
|           isAttachment: true,
 | |
|           isReply: isReplyMsg,
 | |
|           isImageLoaded: false,
 | |
|           voiceFile: voiceFile,
 | |
|           isVoiceAttached: true,
 | |
|           userEmail: userEmail,
 | |
|           userStatus: userStatus);
 | |
|       notifyListeners();
 | |
|     }
 | |
|     if (searchedChats != null) {
 | |
|       dynamic contain = searchedChats!
 | |
|           .where((ChatUser element) => element.id == targetUserId);
 | |
|       if (contain.isEmpty) {
 | |
|         List<String> emails = [];
 | |
|         emails.add(await EmailImageEncryption().encrypt(val: userEmail));
 | |
|         List<ChatUserImageModel> chatImages =
 | |
|             await ChatApiClient().getUsersImages(encryptedEmails: emails);
 | |
|         searchedChats!.add(
 | |
|           ChatUser(
 | |
|             id: targetUserId,
 | |
|             userName: targetUserName,
 | |
|             unreadMessageCount: 0,
 | |
|             email: userEmail,
 | |
|             isImageLoading: false,
 | |
|             image: chatImages.first.profilePicture ?? "",
 | |
|             isImageLoaded: true,
 | |
|             isTyping: false,
 | |
|             isFav: false,
 | |
|             userStatus: userStatus,
 | |
|             userLocalDownlaodedImage: await downloadImageLocal(
 | |
|                 chatImages.first.profilePicture, targetUserId.toString()),
 | |
|           ),
 | |
|         );
 | |
|         notifyListeners();
 | |
|       }
 | |
|     }
 | |
|     // else {
 | |
|     //   List<String> emails = [];
 | |
|     //   emails.add(await EmailImageEncryption().encrypt(val: userEmail));
 | |
|     //   List<ChatUserImageModel> chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails);
 | |
|     //   searchedChats!.add(
 | |
|     //     ChatUser(
 | |
|     //       id: targetUserId,
 | |
|     //       userName: targetUserName,
 | |
|     //       unreadMessageCount: 0,
 | |
|     //       email: userEmail,
 | |
|     //       isImageLoading: false,
 | |
|     //       image: chatImages.first.profilePicture ?? "",
 | |
|     //       isImageLoaded: true,
 | |
|     //       isTyping: false,
 | |
|     //       isFav: false,
 | |
|     //       userStatus: userStatus,
 | |
|     //       userLocalDownlaodedImage: await downloadImageLocal(chatImages.first.profilePicture, targetUserId.toString()),
 | |
|     //     ),
 | |
|     //   );
 | |
|     //   notifyListeners();
 | |
|     // }
 | |
|   }
 | |
| 
 | |
|   void selectImageToUpload(BuildContext context) {
 | |
|     ImageOptions.showImageOptionsNew(context, true,
 | |
|         (String image, File file) async {
 | |
|       if (checkFileSize(file.path)) {
 | |
|         selectedFile = file;
 | |
|         isAttachmentMsg = true;
 | |
|         isTextMsg = false;
 | |
|         sFileType = getFileExtension(file.path)!;
 | |
|         message.text = file.path.split("/").last;
 | |
|         Navigator.of(context).pop();
 | |
|       } else {
 | |
|         Utils.showToast("Max 1 mb size is allowed to upload");
 | |
|       }
 | |
|       notifyListeners();
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   void removeAttachment() {
 | |
|     isAttachmentMsg = false;
 | |
|     sFileType = "";
 | |
|     message.text = '';
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   String? getFileExtension(String fileName) {
 | |
|     try {
 | |
|       if (kDebugMode) {
 | |
|         logger.i("ext: " + "." + fileName.split('.').last);
 | |
|       }
 | |
|       return "." + fileName.split('.').last;
 | |
|     } catch (e) {
 | |
|       return null;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   bool checkFileSize(String path) {
 | |
|     int fileSizeLimit = 1024;
 | |
|     File f = File(path);
 | |
|     double fileSizeInKB = f.lengthSync() / 1024;
 | |
|     double fileSizeInMB = fileSizeInKB / 1024;
 | |
|     if (fileSizeInKB > fileSizeLimit) {
 | |
|       return false;
 | |
|     } else {
 | |
|       return true;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   String getType(String type) {
 | |
|     switch (type) {
 | |
|       case ".pdf":
 | |
|         return "assets/images/pdf.svg";
 | |
|       case ".png":
 | |
|         return "assets/images/png.svg";
 | |
|       case ".txt":
 | |
|         return "assets/icons/chat/txt.svg";
 | |
|       case ".jpg":
 | |
|         return "assets/images/jpg.svg";
 | |
|       case ".jpeg":
 | |
|         return "assets/images/jpg.svg";
 | |
|       case ".xls":
 | |
|         return "assets/icons/chat/xls.svg";
 | |
|       case ".xlsx":
 | |
|         return "assets/icons/chat/xls.svg";
 | |
|       case ".doc":
 | |
|         return "assets/icons/chat/doc.svg";
 | |
|       case ".docx":
 | |
|         return "assets/icons/chat/doc.svg";
 | |
|       case ".ppt":
 | |
|         return "assets/icons/chat/ppt.svg";
 | |
|       case ".pptx":
 | |
|         return "assets/icons/chat/ppt.svg";
 | |
|       case ".zip":
 | |
|         return "assets/icons/chat/zip.svg";
 | |
|       case ".rar":
 | |
|         return "assets/icons/chat/zip.svg";
 | |
|       case ".aac":
 | |
|         return "assets/icons/chat/aac.svg";
 | |
|       case ".mp3":
 | |
|         return "assets/icons/chat/zip.mp3";
 | |
|       default:
 | |
|         return "assets/images/thumb.svg";
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void chatReply(SingleUserChatModel data) {
 | |
|     repliedMsg = [];
 | |
|     data.isReplied = true;
 | |
|     isReplyMsg = true;
 | |
|     repliedMsg.add(data);
 | |
|     notifyListeners();
 | |
|   }
 | |
|   void groupChatReply(groupchathistory.GetGroupChatHistoryAsync data) {
 | |
|     groupChatReplyData = [];
 | |
|     data.isReplied = true;
 | |
|     isReplyMsg = true;
 | |
|     groupChatReplyData.add(data);
 | |
|     notifyListeners();
 | |
|   }
 | |
|   void closeMe() {
 | |
|     repliedMsg = [];
 | |
|     isReplyMsg = false;
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   String dateFormte(DateTime data) {
 | |
|     DateFormat f = DateFormat('hh:mm a dd MMM yyyy', "en_US");
 | |
|     f.format(data);
 | |
|     return f.format(data);
 | |
|   }
 | |
| 
 | |
|   Future<void> favoriteUser(
 | |
|       {required int userID,
 | |
|       required int targetUserID,
 | |
|       required bool fromSearch}) async {
 | |
|     fav.FavoriteChatUser favoriteChatUser = await ChatApiClient()
 | |
|         .favUser(userID: userID, targetUserID: targetUserID);
 | |
|     if (favoriteChatUser.response != null) {
 | |
|       for (ChatUser user in searchedChats!) {
 | |
|         if (user.id == favoriteChatUser.response!.targetUserId!) {
 | |
|           user.isFav = favoriteChatUser.response!.isFav;
 | |
|           dynamic contain = favUsersList!.where((ChatUser element) =>
 | |
|               element.id == favoriteChatUser.response!.targetUserId!);
 | |
|           if (contain.isEmpty) {
 | |
|             favUsersList.add(user);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       for (ChatUser user in chatUsersList!) {
 | |
|         if (user.id == favoriteChatUser.response!.targetUserId!) {
 | |
|           user.isFav = favoriteChatUser.response!.isFav;
 | |
|           dynamic contain = favUsersList!.where((ChatUser element) =>
 | |
|               element.id == favoriteChatUser.response!.targetUserId!);
 | |
|           if (contain.isEmpty) {
 | |
|             favUsersList.add(user);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     if (fromSearch) {
 | |
|       for (ChatUser user in favUsersList) {
 | |
|         if (user.id == targetUserID) {
 | |
|           user.userLocalDownlaodedImage = null;
 | |
|           user.isImageLoading = false;
 | |
|           user.isImageLoaded = false;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   Future<void> unFavoriteUser(
 | |
|       {required int userID, required int targetUserID}) async {
 | |
|     fav.FavoriteChatUser favoriteChatUser = await ChatApiClient()
 | |
|         .unFavUser(userID: userID, targetUserID: targetUserID);
 | |
| 
 | |
|     if (favoriteChatUser.response != null) {
 | |
|       for (ChatUser user in searchedChats!) {
 | |
|         if (user.id == favoriteChatUser.response!.targetUserId!) {
 | |
|           user.isFav = favoriteChatUser.response!.isFav;
 | |
|         }
 | |
|       }
 | |
|       favUsersList.removeWhere(
 | |
|         (ChatUser element) => element.id == targetUserID,
 | |
|       );
 | |
|     }
 | |
| 
 | |
|     for (ChatUser user in chatUsersList!) {
 | |
|       if (user.id == favoriteChatUser.response!.targetUserId!) {
 | |
|         user.isFav = favoriteChatUser.response!.isFav;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void clearSelections() {
 | |
|     searchedChats = pChatHistory;
 | |
|     search.clear();
 | |
|     isChatScreenActive = false;
 | |
|     receiverID = 0;
 | |
|     paginationVal = 0;
 | |
|     message.text = '';
 | |
|     isAttachmentMsg = false;
 | |
|     repliedMsg = [];
 | |
|     sFileType = "";
 | |
|     isReplyMsg = false;
 | |
|     isTextMsg = false;
 | |
|     isVoiceMsg = false;
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void clearAll() {
 | |
|     searchedChats = pChatHistory;
 | |
|     search.clear();
 | |
|     isChatScreenActive = false;
 | |
|     receiverID = 0;
 | |
|     paginationVal = 0;
 | |
|     message.text = '';
 | |
|     isTextMsg = false;
 | |
|     isAttachmentMsg = false;
 | |
|     isVoiceMsg = false;
 | |
|     isReplyMsg = false;
 | |
|     repliedMsg = [];
 | |
|     sFileType = "";
 | |
|   }
 | |
| 
 | |
|   void disposeData() {
 | |
|     if (!disbaleChatForThisUser) {
 | |
|       search.clear();
 | |
|       isChatScreenActive = false;
 | |
|       receiverID = 0;
 | |
|       paginationVal = 0;
 | |
|       message.text = '';
 | |
|       isTextMsg = false;
 | |
|       isAttachmentMsg = false;
 | |
|       isVoiceMsg = false;
 | |
|       isReplyMsg = false;
 | |
|       repliedMsg = [];
 | |
|       sFileType = "";
 | |
|       deleteData();
 | |
|       favUsersList.clear();
 | |
|       searchedChats?.clear();
 | |
|       pChatHistory?.clear();
 | |
|       uGroups?.clear();
 | |
|       searchGroup?.clear();
 | |
|       chatHubConnection.stop();
 | |
|       AppState().chatDetails = null;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void deleteData() {
 | |
|     List<ChatUser> exists = [], unique = [];
 | |
|     if (searchedChats != null) exists.addAll(searchedChats!);
 | |
|     exists.addAll(favUsersList!);
 | |
|     Map<String, ChatUser> profileMap = {};
 | |
|     for (ChatUser item in exists) {
 | |
|       profileMap[item.email!] = item;
 | |
|     }
 | |
|     unique = profileMap.values.toList();
 | |
|     for (ChatUser element in unique!) {
 | |
|       deleteFile(element.id.toString());
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void getUserImages() async {
 | |
|     List<String> emails = [];
 | |
|     List<ChatUser> exists = [], unique = [];
 | |
|     exists.addAll(searchedChats!);
 | |
|     exists.addAll(favUsersList!);
 | |
|     Map<String, ChatUser> profileMap = {};
 | |
|     for (ChatUser item in exists) {
 | |
|       profileMap[item.email!] = item;
 | |
|     }
 | |
|     unique = profileMap.values.toList();
 | |
|     for (ChatUser element in unique!) {
 | |
|       emails.add(await EmailImageEncryption().encrypt(val: element.email!));
 | |
|     }
 | |
| 
 | |
|     List<ChatUserImageModel> chatImages =
 | |
|         await ChatApiClient().getUsersImages(encryptedEmails: emails);
 | |
|     for (ChatUser user in searchedChats!) {
 | |
|       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;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     for (ChatUser favUser in favUsersList) {
 | |
|       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;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     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();
 | |
|       String dirPath = '${appDocumentsDirectory.path}/chat_images';
 | |
|       if (!await Directory(dirPath).exists()) {
 | |
|         await Directory(dirPath).create();
 | |
|         await File('$dirPath/.nomedia').create();
 | |
|       }
 | |
|       late File imageFile = File("$dirPath/$userID.jpg");
 | |
|       imageFile.writeAsBytesSync(decodedBytes);
 | |
|       return imageFile;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Future deleteFile(String userID) async {
 | |
|     Directory appDocumentsDirectory = await getApplicationDocumentsDirectory();
 | |
|     String dirPath = '${appDocumentsDirectory.path}/chat_images';
 | |
|     late File imageFile = File('$dirPath/$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 {
 | |
|     JustAudio.AudioPlayer player = JustAudio.AudioPlayer();
 | |
|     await player.setVolume(1.0);
 | |
|     String audioAsset = "";
 | |
|     if (Platform.isAndroid) {
 | |
|       audioAsset = "assets/audio/pulse_tone_android.mp3";
 | |
|     } else {
 | |
|       audioAsset = "assets/audio/pulse_tune_ios.caf";
 | |
|     }
 | |
|     try {
 | |
|       await player.setAsset(audioAsset);
 | |
|       await player.load();
 | |
|       player.play();
 | |
|     } catch (e) {
 | |
|       print("Error: $e");
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Future<void> getChatMedia(BuildContext context,
 | |
|       {required String fileName,
 | |
|       required String fileTypeName,
 | |
|       required int fileTypeID}) async {
 | |
|     Utils.showLoading(context);
 | |
|     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 ?? "");
 | |
|         Utils.hideLoading(context);
 | |
|         OpenFile.open(path);
 | |
|       } catch (e) {
 | |
|         Utils.showToast("Cannot open file.");
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void onNewChatConversion(List<Object?>? params) {
 | |
|     dynamic items = params!.toList();
 | |
|     chatUConvCounter = items[0]["singleChatCount"] ?? 0;
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   Future invokeChatCounter({required int userId}) async {
 | |
|     await chatHubConnection.invoke("GetChatCounversationCount", args: [userId]);
 | |
|     return "";
 | |
|   }
 | |
| 
 | |
|   void userTypingInvoke(
 | |
|       {required int currentUser, required int reciptUser}) async {
 | |
|     await chatHubConnection
 | |
|         .invoke("UserTypingAsync", args: [reciptUser, currentUser]);
 | |
|   }
 | |
|   void groupTypingInvoke(
 | |
|       {required GroupResponse groupDetails, required int groupId}) async {
 | |
|     var data = json.decode(json.encode(groupDetails.groupUserList));
 | |
|     await chatHubConnection
 | |
|         .invoke("GroupTypingAsync", args: ["${groupDetails.adminUser!.userName}",data, groupId ]);
 | |
|   }
 | |
| 
 | |
| 
 | |
| //////// Audio Recoding Work ////////////////////
 | |
| 
 | |
|   Future<void> initAudio({required int receiverId}) async {
 | |
|     // final dir = Directory((Platform.isAndroid
 | |
|     //     ? await getExternalStorageDirectory() //FOR ANDROID
 | |
|     //     : await getApplicationSupportDirectory() //FOR IOS
 | |
|     // )!
 | |
|     appDirectory = await getApplicationDocumentsDirectory();
 | |
|     String dirPath = '${appDirectory.path}/chat_audios';
 | |
|     if (!await Directory(dirPath).exists()) {
 | |
|       await Directory(dirPath).create();
 | |
|       await File('$dirPath/.nomedia').create();
 | |
|     }
 | |
|     path =
 | |
|         "$dirPath/${AppState().chatDetails!.response!.id}-$receiverID-${DateTime.now().microsecondsSinceEpoch}.aac";
 | |
|     recorderController = RecorderController()
 | |
|       ..androidEncoder = AndroidEncoder.aac
 | |
|       ..androidOutputFormat = AndroidOutputFormat.mpeg4
 | |
|       ..iosEncoder = IosEncoder.kAudioFormatMPEG4AAC
 | |
|       ..sampleRate = 6000
 | |
|       ..updateFrequency = const Duration(milliseconds: 100)
 | |
|       ..bitRate = 18000;
 | |
|     playerController = PlayerController();
 | |
|   }
 | |
| 
 | |
|   void disposeAudio() {
 | |
|     isRecoding = false;
 | |
|     isPlaying = false;
 | |
|     isPause = false;
 | |
|     isVoiceMsg = false;
 | |
|     recorderController.dispose();
 | |
|     playerController.dispose();
 | |
|   }
 | |
| 
 | |
|   void startRecoding(BuildContext context) async {
 | |
|     await Permission.microphone.request().then((PermissionStatus status) {
 | |
|       if (status.isPermanentlyDenied) {
 | |
|         Utils.confirmDialog(
 | |
|           context,
 | |
|           "The app needs microphone access to be able to record audio.",
 | |
|           onTap: () {
 | |
|             Navigator.of(context).pop();
 | |
|             openAppSettings();
 | |
|           },
 | |
|         );
 | |
|       } else if (status.isDenied) {
 | |
|         Utils.confirmDialog(
 | |
|           context,
 | |
|           "The app needs microphone access to be able to record audio.",
 | |
|           onTap: () {
 | |
|             Navigator.of(context).pop();
 | |
|             openAppSettings();
 | |
|           },
 | |
|         );
 | |
|       } else if (status.isGranted) {
 | |
|         sRecoding();
 | |
|       } else {
 | |
|         startRecoding(context);
 | |
|       }
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   void sRecoding() async {
 | |
|     isVoiceMsg = true;
 | |
|     recorderController.reset();
 | |
|     await recorderController.record(path);
 | |
|     _recodeDuration = 0;
 | |
|     _startTimer();
 | |
|     isRecoding = !isRecoding;
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   Future<void> _startTimer() async {
 | |
|     _timer?.cancel();
 | |
|     _timer = Timer.periodic(const Duration(seconds: 1), (Timer t) async {
 | |
|       _recodeDuration++;
 | |
|       if (_recodeDuration <= 59) {
 | |
|         applyCounter();
 | |
|       } else {
 | |
|         pauseRecoding();
 | |
|       }
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   void applyCounter() {
 | |
|     buildTimer();
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   Future<void> pauseRecoding() async {
 | |
|     isPause = true;
 | |
|     isPlaying = true;
 | |
|     recorderController.pause();
 | |
|     path = await recorderController.stop(false);
 | |
|     File file = File(path!);
 | |
|     file.readAsBytesSync();
 | |
|     path = file.path;
 | |
|     await playerController.preparePlayer(file.path, 1.0);
 | |
|     _timer?.cancel();
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   Future<void> deleteRecoding() async {
 | |
|     _recodeDuration = 0;
 | |
|     _timer?.cancel();
 | |
|     if (path == null) {
 | |
|       path = await recorderController.stop(true);
 | |
|     } else {
 | |
|       await recorderController.stop(true);
 | |
|     }
 | |
|     if (path != null && path!.isNotEmpty) {
 | |
|       File delFile = File(path!);
 | |
|       double fileSizeInKB = delFile.lengthSync() / 1024;
 | |
|       double fileSizeInMB = fileSizeInKB / 1024;
 | |
|       if (kDebugMode) {
 | |
|         debugPrint("Deleted file size: ${delFile.lengthSync()}");
 | |
|         debugPrint("Deleted file size in KB: " + fileSizeInKB.toString());
 | |
|         debugPrint("Deleted file size in MB: " + fileSizeInMB.toString());
 | |
|       }
 | |
|       if (await delFile.exists()) {
 | |
|         delFile.delete();
 | |
|       }
 | |
|       isPause = false;
 | |
|       isRecoding = false;
 | |
|       isPlaying = false;
 | |
|       isVoiceMsg = false;
 | |
|       notifyListeners();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   String buildTimer() {
 | |
|     String minutes = _formatNum(_recodeDuration ~/ 60);
 | |
|     String seconds = _formatNum(_recodeDuration % 60);
 | |
|     return '$minutes : $seconds';
 | |
|   }
 | |
| 
 | |
|   String _formatNum(int number) {
 | |
|     String numberStr = number.toString();
 | |
|     if (number < 10) {
 | |
|       numberStr = '0' + numberStr;
 | |
|     }
 | |
|     return numberStr;
 | |
|   }
 | |
| 
 | |
|   Future<File> downChatVoice(
 | |
|       Uint8List bytes, String ext, SingleUserChatModel data) async {
 | |
|     File file;
 | |
|     try {
 | |
|       String dirPath =
 | |
|           '${(await getApplicationDocumentsDirectory()).path}/chat_audios';
 | |
|       if (!await Directory(dirPath).exists()) {
 | |
|         await Directory(dirPath).create();
 | |
|         await File('$dirPath/.nomedia').create();
 | |
|       }
 | |
|       file = File(
 | |
|           "$dirPath/${data.currentUserId}-${data.targetUserId}-${DateTime.now().microsecondsSinceEpoch}" +
 | |
|               ext);
 | |
|       await file.writeAsBytes(bytes);
 | |
|     } catch (e) {
 | |
|       if (kDebugMode) {
 | |
|         print(e);
 | |
|       }
 | |
|       file = File("");
 | |
|     }
 | |
|     return file;
 | |
|   }
 | |
| 
 | |
|   void scrollToMsg(SingleUserChatModel data) {
 | |
|     if (data.userChatReplyResponse != null &&
 | |
|         data.userChatReplyResponse!.userChatHistoryId != null) {
 | |
|       int index = userChatHistory.indexWhere((SingleUserChatModel element) =>
 | |
|           element.userChatHistoryId ==
 | |
|           data.userChatReplyResponse!.userChatHistoryId);
 | |
|       if (index >= 1) {
 | |
|         double contentSize = scrollController.position.viewportDimension +
 | |
|             scrollController.position.maxScrollExtent;
 | |
|         double target = contentSize * index / userChatHistory.length;
 | |
|         scrollController.position.animateTo(
 | |
|           target,
 | |
|           duration: const Duration(seconds: 1),
 | |
|           curve: Curves.easeInOut,
 | |
|         );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Future<void> getTeamMembers() async {
 | |
|     teamMembersList = [];
 | |
|     isLoading = true;
 | |
|     if (AppState().getemployeeSubordinatesList.isNotEmpty) {
 | |
|       getEmployeeSubordinatesList = AppState().getemployeeSubordinatesList;
 | |
|       for (GetEmployeeSubordinatesList element in getEmployeeSubordinatesList) {
 | |
|         if (element.eMPLOYEEEMAILADDRESS != null) {
 | |
|           if (element.eMPLOYEEEMAILADDRESS!.isNotEmpty) {
 | |
|             teamMembersList.add(
 | |
|               ChatUser(
 | |
|                 id: int.parse(element.eMPLOYEENUMBER!),
 | |
|                 email: element.eMPLOYEEEMAILADDRESS,
 | |
|                 userName: element.eMPLOYEENAME,
 | |
|                 phone: element.eMPLOYEEMOBILENUMBER,
 | |
|                 userStatus: 0,
 | |
|                 unreadMessageCount: 0,
 | |
|                 isFav: false,
 | |
|                 isTyping: false,
 | |
|                 isImageLoading: false,
 | |
|                 image: element.eMPLOYEEIMAGE ?? "",
 | |
|                 isImageLoaded: element.eMPLOYEEIMAGE == null ? false : true,
 | |
|                 userLocalDownlaodedImage: element.eMPLOYEEIMAGE == null
 | |
|                     ? null
 | |
|                     : await downloadImageLocal(
 | |
|                         element.eMPLOYEEIMAGE ?? "", element.eMPLOYEENUMBER!),
 | |
|               ),
 | |
|             );
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     } else {
 | |
|       getEmployeeSubordinatesList =
 | |
|           await MyTeamApiClient().getEmployeeSubordinates("", "", "");
 | |
|       AppState().setemployeeSubordinatesList = getEmployeeSubordinatesList;
 | |
|       for (GetEmployeeSubordinatesList element in getEmployeeSubordinatesList) {
 | |
|         if (element.eMPLOYEEEMAILADDRESS != null) {
 | |
|           if (element.eMPLOYEEEMAILADDRESS!.isNotEmpty) {
 | |
|             teamMembersList.add(
 | |
|               ChatUser(
 | |
|                 id: int.parse(element.eMPLOYEENUMBER!),
 | |
|                 email: element.eMPLOYEEEMAILADDRESS,
 | |
|                 userName: element.eMPLOYEENAME,
 | |
|                 phone: element.eMPLOYEEMOBILENUMBER,
 | |
|                 userStatus: 0,
 | |
|                 unreadMessageCount: 0,
 | |
|                 isFav: false,
 | |
|                 isTyping: false,
 | |
|                 isImageLoading: false,
 | |
|                 image: element.eMPLOYEEIMAGE ?? "",
 | |
|                 isImageLoaded: element.eMPLOYEEIMAGE == null ? false : true,
 | |
|                 userLocalDownlaodedImage: element.eMPLOYEEIMAGE == null
 | |
|                     ? null
 | |
|                     : await downloadImageLocal(
 | |
|                         element.eMPLOYEEIMAGE ?? "", element.eMPLOYEENUMBER!),
 | |
|               ),
 | |
|             );
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     for (ChatUser user in searchedChats!) {
 | |
|       for (ChatUser teamUser in teamMembersList!) {
 | |
|         if (user.id == teamUser.id) {
 | |
|           teamUser.userStatus = user.userStatus;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     isLoading = false;
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void inputBoxDirection(String val) {
 | |
|     if (val.isNotEmpty) {
 | |
|       isTextMsg = true;
 | |
|     } else {
 | |
|       isTextMsg = false;
 | |
|     }
 | |
|     msgText = val;
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void onDirectionChange(bool val) {
 | |
|     isRTL = val;
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   Material.TextDirection getTextDirection(String v) {
 | |
|     String str = v.trim();
 | |
|     if (str.isEmpty) return Material.TextDirection.ltr;
 | |
|     int firstUnit = str.codeUnitAt(0);
 | |
|     if (firstUnit > 0x0600 && firstUnit < 0x06FF ||
 | |
|         firstUnit > 0x0750 && firstUnit < 0x077F ||
 | |
|         firstUnit > 0x07C0 && firstUnit < 0x07EA ||
 | |
|         firstUnit > 0x0840 && firstUnit < 0x085B ||
 | |
|         firstUnit > 0x08A0 && firstUnit < 0x08B4 ||
 | |
|         firstUnit > 0x08E3 && firstUnit < 0x08FF ||
 | |
|         firstUnit > 0xFB50 && firstUnit < 0xFBB1 ||
 | |
|         firstUnit > 0xFBD3 && firstUnit < 0xFD3D ||
 | |
|         firstUnit > 0xFD50 && firstUnit < 0xFD8F ||
 | |
|         firstUnit > 0xFD92 && firstUnit < 0xFDC7 ||
 | |
|         firstUnit > 0xFDF0 && firstUnit < 0xFDFC ||
 | |
|         firstUnit > 0xFE70 && firstUnit < 0xFE74 ||
 | |
|         firstUnit > 0xFE76 && firstUnit < 0xFEFC ||
 | |
|         firstUnit > 0x10800 && firstUnit < 0x10805 ||
 | |
|         firstUnit > 0x1B000 && firstUnit < 0x1B0FF ||
 | |
|         firstUnit > 0x1D165 && firstUnit < 0x1D169 ||
 | |
|         firstUnit > 0x1D16D && firstUnit < 0x1D172 ||
 | |
|         firstUnit > 0x1D17B && firstUnit < 0x1D182 ||
 | |
|         firstUnit > 0x1D185 && firstUnit < 0x1D18B ||
 | |
|         firstUnit > 0x1D1AA && firstUnit < 0x1D1AD ||
 | |
|         firstUnit > 0x1D242 && firstUnit < 0x1D244) {
 | |
|       return Material.TextDirection.rtl;
 | |
|     }
 | |
|     return Material.TextDirection.ltr;
 | |
|   }
 | |
| 
 | |
|   void openChatByNoti(BuildContext context) async {
 | |
|     SingleUserChatModel nUser = SingleUserChatModel();
 | |
|     Utils.saveStringFromPrefs("isAppOpendByChat", "false");
 | |
|     if (await Utils.getStringFromPrefs("notificationData") != "null") {
 | |
|       nUser = SingleUserChatModel.fromJson(
 | |
|           jsonDecode(await Utils.getStringFromPrefs("notificationData")));
 | |
|       Utils.saveStringFromPrefs("notificationData", "null");
 | |
|       Future.delayed(const Duration(seconds: 2));
 | |
|       for (ChatUser user in searchedChats!) {
 | |
|         if (user.id == nUser.targetUserId) {
 | |
|           Navigator.pushNamed(context, AppRoutes.chatDetailed,
 | |
|               arguments: ChatDetailedScreenParams(user, false));
 | |
|           return;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     Utils.saveStringFromPrefs("notificationData", "null");
 | |
|   }
 | |
| 
 | |
|   //group chat functions added here
 | |
| 
 | |
|   void filterGroups(String value) async {
 | |
|     // filter function added here.
 | |
|     List<groups.GroupResponse> tmp = [];
 | |
|     if (value.isEmpty || value == "") {
 | |
|       tmp = userGroups.groupresponse!;
 | |
|     } else {
 | |
|       for (groups.GroupResponse element in uGroups!) {
 | |
|         if (element.groupName!.toLowerCase().contains(value.toLowerCase())) {
 | |
|           tmp.add(element);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     uGroups = tmp;
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   Future deleteGroup(GroupResponse groupDetails) async {
 | |
|     isLoading = true;
 | |
|     await ChatApiClient().deleteGroup(groupDetails.groupId);
 | |
|     userGroups = await ChatApiClient().getGroupsByUserId();
 | |
|     uGroups = userGroups.groupresponse;
 | |
|     isLoading = false;
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   Future getGroupChatHistory(groups.GroupResponse groupDetails) async {
 | |
|     isLoading = true;
 | |
|     groupChatHistory = await ChatApiClient().getGroupChatHistory(
 | |
|         groupDetails.groupId,
 | |
|         groupDetails.groupUserList as List<GroupUserList>);
 | |
| 
 | |
|     isLoading = false;
 | |
| 
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   void updateGroupAdmin(int? groupId, List<GroupUserList> groupUserList) async {
 | |
|     isLoading = true;
 | |
|     await ChatApiClient().updateGroupAdmin(groupId, groupUserList);
 | |
|     isLoading = false;
 | |
|     notifyListeners();
 | |
|   }
 | |
| 
 | |
|   Future addGroupAndUsers(createGroup.CreateGroupRequest request) async {
 | |
|     isLoading = true;
 | |
|     var groups = await ChatApiClient().addGroupAndUsers(request);
 | |
|     userGroups.groupresponse!
 | |
|         .add(GroupResponse.fromJson(json.decode(groups)['response']));
 | |
| 
 | |
|     isLoading = false;
 | |
|     notifyListeners();
 | |
|   }
 | |
|   Future updateGroupAndUsers(createGroup.CreateGroupRequest request) async {
 | |
|     isLoading = true;
 | |
|     await ChatApiClient().updateGroupAndUsers(request);
 | |
|     userGroups = await ChatApiClient().getGroupsByUserId();
 | |
|     uGroups = userGroups.groupresponse;
 | |
|     isLoading = false;
 | |
|     notifyListeners();
 | |
|   }
 | |
| }
 |