|  |  |  | @ -44,7 +44,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { | 
		
	
		
			
				|  |  |  |  |   bool _firstAutoscrollExecuted = false; | 
		
	
		
			
				|  |  |  |  |   bool _shouldAutoscroll = false; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   Future<void> getUserAutoLoginToken() async { | 
		
	
		
			
				|  |  |  |  |   Future<void> getUserAutoLoginToken(BuildContext cxt) async { | 
		
	
		
			
				|  |  |  |  |     Response response = await ApiClient().postJsonForResponse( | 
		
	
		
			
				|  |  |  |  |       "${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", | 
		
	
		
			
				|  |  |  |  |       { | 
		
	
	
		
			
				
					|  |  |  | @ -76,7 +76,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { | 
		
	
		
			
				|  |  |  |  |     return searchUserJsonModel(response.body); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from(json.decode(str).map((x) => ChatUser.fromJson(x))); | 
		
	
		
			
				|  |  |  |  |   List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from( | 
		
	
		
			
				|  |  |  |  |         json.decode(str).map( | 
		
	
		
			
				|  |  |  |  |               (x) => ChatUser.fromJson(x), | 
		
	
		
			
				|  |  |  |  |             ), | 
		
	
		
			
				|  |  |  |  |       ); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   void getUserRecentChats() async { | 
		
	
		
			
				|  |  |  |  |     Response response = await ApiClient().getJsonForResponse( | 
		
	
	
		
			
				
					|  |  |  | @ -90,9 +94,18 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { | 
		
	
		
			
				|  |  |  |  |       token: AppState().chatDetails!.response!.token, | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |     ChatUserModel favUList = userToList(favRes.body); | 
		
	
		
			
				|  |  |  |  |     GetUserChatHistoryNotDeliveredAsync( | 
		
	
		
			
				|  |  |  |  |       userId: int.parse( | 
		
	
		
			
				|  |  |  |  |         AppState().chatDetails!.response!.id.toString(), | 
		
	
		
			
				|  |  |  |  |       ), | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |     if (favUList.response != null) { | 
		
	
		
			
				|  |  |  |  |       favUsersList = favUList.response!; | 
		
	
		
			
				|  |  |  |  |       favUsersList.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase())); | 
		
	
		
			
				|  |  |  |  |       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) { | 
		
	
	
		
			
				
					|  |  |  | @ -101,16 +114,23 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     pChatHistory = recentChat.response == null ? [] : recentChat.response; | 
		
	
		
			
				|  |  |  |  |     if (pChatHistory != null) pChatHistory!.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase())); | 
		
	
		
			
				|  |  |  |  |     pChatHistory = recentChat.response ?? []; | 
		
	
		
			
				|  |  |  |  |     pChatHistory!.sort( | 
		
	
		
			
				|  |  |  |  |       (ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo( | 
		
	
		
			
				|  |  |  |  |             b.userName!.toLowerCase(), | 
		
	
		
			
				|  |  |  |  |           ), | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     searchedChats = pChatHistory; | 
		
	
		
			
				|  |  |  |  |     isLoading = false; | 
		
	
		
			
				|  |  |  |  |     notifyListeners(); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   Future GetUserChatHistoryNotDeliveredAsync(int userId) async { | 
		
	
		
			
				|  |  |  |  |     await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]); | 
		
	
		
			
				|  |  |  |  |   Future GetUserChatHistoryNotDeliveredAsync({required int userId}) async { | 
		
	
		
			
				|  |  |  |  |     await hubConnection.invoke( | 
		
	
		
			
				|  |  |  |  |       "GetUserChatHistoryNotDeliveredAsync", | 
		
	
		
			
				|  |  |  |  |       args: [userId], | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |     return ""; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -132,35 +152,89 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       if (loadMore) { | 
		
	
		
			
				|  |  |  |  |         List<SingleUserChatModel> temp = getSingleUserChatModel(response.body).reversed.toList(); | 
		
	
		
			
				|  |  |  |  |         userChatHistory.addAll(temp); | 
		
	
		
			
				|  |  |  |  |         List<SingleUserChatModel> temp = getSingleUserChatModel( | 
		
	
		
			
				|  |  |  |  |           response.body, | 
		
	
		
			
				|  |  |  |  |         ).reversed.toList(); | 
		
	
		
			
				|  |  |  |  |         userChatHistory.addAll( | 
		
	
		
			
				|  |  |  |  |           temp, | 
		
	
		
			
				|  |  |  |  |         ); | 
		
	
		
			
				|  |  |  |  |       } else { | 
		
	
		
			
				|  |  |  |  |         userChatHistory = getSingleUserChatModel(response.body).reversed.toList(); | 
		
	
		
			
				|  |  |  |  |         userChatHistory = getSingleUserChatModel( | 
		
	
		
			
				|  |  |  |  |           response.body, | 
		
	
		
			
				|  |  |  |  |         ).reversed.toList(); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     await GetUserChatHistoryNotDeliveredAsync( | 
		
	
		
			
				|  |  |  |  |       userId: senderUID, | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |     isLoading = false; | 
		
	
		
			
				|  |  |  |  |     await GetUserChatHistoryNotDeliveredAsync(senderUID); | 
		
	
		
			
				|  |  |  |  |     notifyListeners(); | 
		
	
		
			
				|  |  |  |  |     markRead( | 
		
	
		
			
				|  |  |  |  |       userChatHistory, | 
		
	
		
			
				|  |  |  |  |       receiverUID, | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   void markRead(List<SingleUserChatModel> data, reciverID) { | 
		
	
		
			
				|  |  |  |  |     for (SingleUserChatModel element in data!) { | 
		
	
		
			
				|  |  |  |  |       if (!element.isSeen!) { | 
		
	
		
			
				|  |  |  |  |         dynamic data = [ | 
		
	
		
			
				|  |  |  |  |           { | 
		
	
		
			
				|  |  |  |  |             "userChatHistoryId": element.userChatHistoryId, | 
		
	
		
			
				|  |  |  |  |             "TargetUserId": element.targetUserId, | 
		
	
		
			
				|  |  |  |  |             "isDelivered": true, | 
		
	
		
			
				|  |  |  |  |             "isSeen": true, | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |         ]; | 
		
	
		
			
				|  |  |  |  |         updateUserChatHistoryStatusAsync(data); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     for (ChatUser element in searchedChats!) { | 
		
	
		
			
				|  |  |  |  |       if (element.id == reciverID) { | 
		
	
		
			
				|  |  |  |  |         element.unreadMessageCount = 0; | 
		
	
		
			
				|  |  |  |  |         notifyListeners(); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   void updateUserChatHistoryStatusAsync(List data) { | 
		
	
		
			
				|  |  |  |  |     hubConnection.invoke("UpdateUserChatHistoryStatusAsync", args: [data]); | 
		
	
		
			
				|  |  |  |  |     hubConnection.invoke( | 
		
	
		
			
				|  |  |  |  |       "UpdateUserChatHistoryStatusAsync", | 
		
	
		
			
				|  |  |  |  |       args: [data], | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   List<SingleUserChatModel> getSingleUserChatModel(String str) => List<SingleUserChatModel>.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); | 
		
	
		
			
				|  |  |  |  |   List<SingleUserChatModel> getSingleUserChatModel(String str) => List<SingleUserChatModel>.from( | 
		
	
		
			
				|  |  |  |  |         json.decode(str).map( | 
		
	
		
			
				|  |  |  |  |               (x) => SingleUserChatModel.fromJson(x), | 
		
	
		
			
				|  |  |  |  |             ), | 
		
	
		
			
				|  |  |  |  |       ); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   ChatUserModel userToList(String str) => ChatUserModel.fromJson(json.decode(str)); | 
		
	
		
			
				|  |  |  |  |   ChatUserModel userToList(String str) => ChatUserModel.fromJson( | 
		
	
		
			
				|  |  |  |  |         json.decode(str), | 
		
	
		
			
				|  |  |  |  |       ); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   Future<dynamic> uploadAttachments(String userId, File file) async { | 
		
	
		
			
				|  |  |  |  |     dynamic result; | 
		
	
		
			
				|  |  |  |  |     dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatMediaImageUploadUrl}')); | 
		
	
		
			
				|  |  |  |  |     dynamic request = MultipartRequest( | 
		
	
		
			
				|  |  |  |  |       'POST', | 
		
	
		
			
				|  |  |  |  |       Uri.parse( | 
		
	
		
			
				|  |  |  |  |         '${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatMediaImageUploadUrl}', | 
		
	
		
			
				|  |  |  |  |       ), | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |     request.fields.addAll({'userId': userId, 'fileSource': '1'}); | 
		
	
		
			
				|  |  |  |  |     request.files.add(await MultipartFile.fromPath('files', file.path)); | 
		
	
		
			
				|  |  |  |  |     request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'}); | 
		
	
		
			
				|  |  |  |  |     request.headers.addAll( | 
		
	
		
			
				|  |  |  |  |       { | 
		
	
		
			
				|  |  |  |  |         'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}', | 
		
	
		
			
				|  |  |  |  |       }, | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |     try { | 
		
	
		
			
				|  |  |  |  |       StreamedResponse response = await request.send(); | 
		
	
		
			
				|  |  |  |  |       if (response.statusCode == 200) { | 
		
	
		
			
				|  |  |  |  |         result = jsonDecode(await response.stream.bytesToString()); | 
		
	
		
			
				|  |  |  |  |         result = jsonDecode( | 
		
	
		
			
				|  |  |  |  |           await response.stream.bytesToString(), | 
		
	
		
			
				|  |  |  |  |         ); | 
		
	
		
			
				|  |  |  |  |       } else { | 
		
	
		
			
				|  |  |  |  |         result = []; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
	
		
			
				
					|  |  |  | @ -176,7 +250,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { | 
		
	
		
			
				|  |  |  |  |   Future<void> buildHubConnection() async { | 
		
	
		
			
				|  |  |  |  |     HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); | 
		
	
		
			
				|  |  |  |  |     hubConnection = HubConnectionBuilder() | 
		
	
		
			
				|  |  |  |  |         .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp) | 
		
	
		
			
				|  |  |  |  |         .withUrl( | 
		
	
		
			
				|  |  |  |  |           ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", | 
		
	
		
			
				|  |  |  |  |           options: httpOp, | 
		
	
		
			
				|  |  |  |  |         ) | 
		
	
		
			
				|  |  |  |  |         .withAutomaticReconnect( | 
		
	
		
			
				|  |  |  |  |           retryDelays: <int>[2000, 5000, 10000, 20000], | 
		
	
		
			
				|  |  |  |  |         ) | 
		
	
	
		
			
				
					|  |  |  | @ -194,6 +271,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { | 
		
	
		
			
				|  |  |  |  |       ({String? connectionId}) {}, | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |     if (hubConnection.state != HubConnectionState.Connected) { | 
		
	
		
			
				|  |  |  |  |       print("Started"); | 
		
	
		
			
				|  |  |  |  |       await hubConnection.start(); | 
		
	
		
			
				|  |  |  |  |       hubConnection.on("OnUpdateUserStatusAsync", changeStatus); | 
		
	
		
			
				|  |  |  |  |       hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); | 
		
	
	
		
			
				
					|  |  |  | @ -260,23 +338,23 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { | 
		
	
		
			
				|  |  |  |  |   void chatNotDelivered(List<Object?>? args) { | 
		
	
		
			
				|  |  |  |  |     dynamic items = args!.toList(); | 
		
	
		
			
				|  |  |  |  |     for (dynamic item in items[0]) { | 
		
	
		
			
				|  |  |  |  |       dynamic data = [ | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |           "userChatHistoryId": item["userChatHistoryId"], | 
		
	
		
			
				|  |  |  |  |           "TargetUserId": item["targetUserId"], | 
		
	
		
			
				|  |  |  |  |           "isDelivered": true, | 
		
	
		
			
				|  |  |  |  |           "isSeen": true, | 
		
	
		
			
				|  |  |  |  |       searchedChats!.forEach((element) { | 
		
	
		
			
				|  |  |  |  |         if (element.id == item["currentUserId"]) { | 
		
	
		
			
				|  |  |  |  |           var val = element.unreadMessageCount == null ? 0 : element.unreadMessageCount; | 
		
	
		
			
				|  |  |  |  |           element.unreadMessageCount = val! + 1; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       ]; | 
		
	
		
			
				|  |  |  |  |       updateUserChatHistoryStatusAsync(data); | 
		
	
		
			
				|  |  |  |  |       }); | 
		
	
		
			
				|  |  |  |  |       // dynamic data = [ | 
		
	
		
			
				|  |  |  |  |       //   { | 
		
	
		
			
				|  |  |  |  |       //     "userChatHistoryId": item["userChatHistoryId"], | 
		
	
		
			
				|  |  |  |  |       //     "TargetUserId": item["targetUserId"], | 
		
	
		
			
				|  |  |  |  |       //     "isDelivered": true, | 
		
	
		
			
				|  |  |  |  |       //     "isSeen": true, | 
		
	
		
			
				|  |  |  |  |       //   } | 
		
	
		
			
				|  |  |  |  |       // ]; | 
		
	
		
			
				|  |  |  |  |       // updateUserChatHistoryStatusAsync(data); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     logger.d(items); | 
		
	
		
			
				|  |  |  |  |     // for (var user in searchedChats!) { | 
		
	
		
			
				|  |  |  |  |     //   if (user.id == items.first["id"]) { | 
		
	
		
			
				|  |  |  |  |     //     user.userStatus = items.first["userStatus"]; | 
		
	
		
			
				|  |  |  |  |     //   } | 
		
	
		
			
				|  |  |  |  |     // } | 
		
	
		
			
				|  |  |  |  |     // notifyListeners();2 | 
		
	
		
			
				|  |  |  |  |     notifyListeners(); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   void changeStatus(List<Object?>? args) { | 
		
	
	
		
			
				
					|  |  |  | 
 |