Chat Updates & Stability

merge-requests/69/head
Aamir Muhammad 3 years ago
parent dc9d1715d9
commit eb7e5a4837

@ -0,0 +1,103 @@
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as user;
import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav;
class ChatApiClient {
static final ChatApiClient _instance = ChatApiClient._internal();
ChatApiClient._internal();
factory ChatApiClient() => _instance;
Future<user.UserAutoLoginModel> getUserLoginToken() async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin",
{
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
},
);
user.UserAutoLoginModel userLoginResponse = user.userAutoLoginModelFromJson(
response.body,
);
return userLoginResponse;
}
Future<List<ChatUser>?> getChatMemberFromSearch(String sName, int cUserId) async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSearchMember}$sName/$cUserId",
token: AppState().chatDetails!.response!.token,
);
return searchUserJsonModel(response.body);
}
List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from(
json.decode(str).map((x) => ChatUser.fromJson(x)),
);
Future<ChatUserModel> getRecentChats() async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatRecentUrl}",
token: AppState().chatDetails!.response!.token,
);
return ChatUserModel.fromJson(
json.decode(response.body),
);
}
Future<ChatUserModel> getFavUsers() async {
Response favRes = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatFavoriteUsers}${AppState().chatDetails!.response!.id}",
token: AppState().chatDetails!.response!.token,
);
return ChatUserModel.fromJson(
json.decode(favRes.body),
);
}
Future<Response> getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false, required int paginationVal}) async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal",
token: AppState().chatDetails!.response!.token,
);
return response;
}
Future<fav.FavoriteChatUser> favUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}FavUser/addFavUser",
{
"targetUserId": targetUserID,
"userId": userID,
},
token: AppState().chatDetails!.response!.token);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser;
}
Future<fav.FavoriteChatUser> unFavUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}FavUser/deleteFavUser",
{"targetUserId": targetUserID, "userId": userID},
token: AppState().chatDetails!.response!.token,
);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser;
}
Future<StreamedResponse> uploadMedia(String userId, File file) async {
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}'});
StreamedResponse response = await request.send();
return response;
}
}

@ -3,7 +3,7 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/codegen_loader.g.dart'; import 'package:mohem_flutter_app/generated/codegen_loader.g.dart';

@ -1,21 +1,21 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:logger/logger.dart' as L;
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart'; import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as login; import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as login;
import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav;
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/image_picker.dart'; import 'package:mohem_flutter_app/widgets/image_picker.dart';
import 'package:signalr_netcore/signalr_client.dart'; import 'package:signalr_netcore/signalr_client.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@ -26,9 +26,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
TextEditingController search = TextEditingController(); TextEditingController search = TextEditingController();
List<SingleUserChatModel> userChatHistory = []; List<SingleUserChatModel> userChatHistory = [];
List<ChatUser>? pChatHistory, searchedChats; List<ChatUser>? pChatHistory, searchedChats;
late HubConnection hubConnection;
L.Logger logger = L.Logger();
bool hubConInitialized = false;
String chatCID = ''; String chatCID = '';
bool isLoading = true; bool isLoading = true;
bool isChatScreenActive = false; bool isChatScreenActive = false;
@ -40,56 +37,20 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
List<ChatUser> favUsersList = []; List<ChatUser> favUsersList = [];
int paginationVal = 0; int paginationVal = 0;
Future<void> getUserAutoLoginToken(BuildContext cxt) async { void registerEvents() {
Response response = await ApiClient().postJsonForResponse( hubConnection.on("OnUpdateUserStatusAsync", changeStatus);
"${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
{ // hubConnection.on("OnSeenChatUserAsync", onChatSeen);
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), //hubConnection.on("OnUserTypingAsync", onUserTyping);
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", hubConnection.on("OnUserCountAsync", userCountAsync);
}, hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
); hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
login.UserAutoLoginModel userLoginResponse = login.userAutoLoginModelFromJson( hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
response.body,
);
if (userLoginResponse.response != null) {
hubConInitialized = true;
AppState().setchatUserDetails = userLoginResponse;
await buildHubConnection();
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
return;
}
}
Future<List<ChatUser>?> getChatMemberFromSearch(String sName, int cUserId) async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSearchMember}$sName/$cUserId",
token: AppState().chatDetails!.response!.token,
);
return searchUserJsonModel(response.body);
} }
List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from(
json.decode(str).map(
(x) => ChatUser.fromJson(x),
),
);
void getUserRecentChats() async { void getUserRecentChats() async {
Response response = await ApiClient().getJsonForResponse( ChatUserModel recentChat = await ChatApiClient().getRecentChats();
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatRecentUrl}", ChatUserModel favUList = await ChatApiClient().getFavUsers();
token: AppState().chatDetails!.response!.token,
);
ChatUserModel recentChat = userToList(response.body);
Response favRes = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatFavoriteUsers}${AppState().chatDetails!.response!.id}",
token: AppState().chatDetails!.response!.token,
);
ChatUserModel favUList = userToList(favRes.body);
if (favUList.response != null && recentChat.response != null) { if (favUList.response != null && recentChat.response != null) {
favUsersList = favUList.response!; favUsersList = favUList.response!;
@ -108,14 +69,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
pChatHistory = recentChat.response ?? []; pChatHistory = recentChat.response ?? [];
pChatHistory!.sort( pChatHistory!.sort(
(ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo( (ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase()),
b.userName!.toLowerCase(),
),
); );
searchedChats = pChatHistory; searchedChats = pChatHistory;
isLoading = false; isLoading = false;
getUserChatHistoryNotDeliveredAsync( await getUserChatHistoryNotDeliveredAsync(
userId: int.parse( userId: int.parse(
AppState().chatDetails!.response!.id.toString(), AppState().chatDetails!.response!.id.toString(),
), ),
@ -124,14 +82,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
Future getUserChatHistoryNotDeliveredAsync({required int userId}) async { Future getUserChatHistoryNotDeliveredAsync({required int userId}) async {
await hubConnection.invoke( // try {
"GetUserChatHistoryNotDeliveredAsync", await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]);
args: [userId], // } finally {
).onError( // hubConnection.off("OnGetUserChatHistoryNotDeliveredAsync", method: chatNotDelivered);
(Error error, StackTrace stackTrace) => { // }
logger.d(error),
},
);
return ""; return "";
} }
@ -140,9 +96,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
if (isNewChat) userChatHistory = []; if (isNewChat) userChatHistory = [];
if (!loadMore) paginationVal = 0; if (!loadMore) paginationVal = 0;
isChatScreenActive = true; isChatScreenActive = true;
Response response = await ApiClient().getJsonForResponse( Response response = await ChatApiClient().getSingleUserChatHistory(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal", senderUID: senderUID,
token: AppState().chatDetails!.response!.token, receiverUID: receiverUID,
loadMore: loadMore,
paginationVal: paginationVal,
); );
if (response.statusCode == 204) { if (response.statusCode == 204) {
if (isNewChat) { if (isNewChat) {
@ -165,9 +123,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
).reversed.toList(); ).reversed.toList();
} }
} }
await getUserChatHistoryNotDeliveredAsync(
userId: senderUID,
);
isLoading = false; isLoading = false;
notifyListeners(); notifyListeners();
markRead( markRead(
@ -184,16 +139,18 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void markRead(List<SingleUserChatModel> data, reciverID) { void markRead(List<SingleUserChatModel> data, reciverID) {
for (SingleUserChatModel element in data!) { for (SingleUserChatModel element in data!) {
if (!element.isSeen!) { if (element.isSeen != null) {
dynamic data = [ if (!element.isSeen!) {
{ dynamic data = [
"userChatHistoryId": element.userChatHistoryId, {
"TargetUserId": element.targetUserId, "userChatHistoryId": element.userChatHistoryId,
"isDelivered": true, "TargetUserId": element.targetUserId,
"isSeen": true, "isDelivered": true,
} "isSeen": true,
]; }
updateUserChatHistoryStatusAsync(data); ];
updateUserChatHistoryStatusAsync(data);
}
} }
} }
for (ChatUser element in searchedChats!) { for (ChatUser element in searchedChats!) {
@ -217,34 +174,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
), ),
); );
ChatUserModel userToList(String str) => ChatUserModel.fromJson(
json.decode(str),
);
Future<dynamic> uploadAttachments(String userId, File file) async { Future<dynamic> uploadAttachments(String userId, File file) async {
dynamic result; dynamic result;
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}',
},
);
try { try {
StreamedResponse response = await request.send(); StreamedResponse response = await ChatApiClient().uploadMedia(userId, file);
if (response.statusCode == 200) { if (response.statusCode == 200) {
result = jsonDecode( result = jsonDecode(
await response.stream.bytesToString(), await response.stream.bytesToString(),
@ -253,60 +186,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
result = []; result = [];
} }
} catch (e) { } catch (e) {
if (kDebugMode) { print(e);
print(e);
}
} }
; ;
return result; return result;
} }
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,
)
.withAutomaticReconnect(
retryDelays: <int>[
2000,
5000,
10000,
20000,
],
)
.configureLogging(
Logger("Loggin"),
)
.build();
hubConnection.onclose(
({Exception? error}) {},
);
hubConnection.onreconnecting(
({Exception? error}) {},
);
hubConnection.onreconnected(
({String? connectionId}) {},
);
if (hubConnection.state != HubConnectionState.Connected) {
await hubConnection.start();
print("Connnnnn Stablished");
hubConnection.on("OnUpdateUserStatusAsync", changeStatus);
hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
// hubConnection.on("OnSeenChatUserAsync", onChatSeen);
//hubConnection.on("OnUserTypingAsync", onUserTyping);
hubConnection.on("OnUserCountAsync", userCountAsync);
hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
}
}
void updateUserChatStatus(List<Object?>? args) { void updateUserChatStatus(List<Object?>? args) {
dynamic items = args!.toList(); dynamic items = args!.toList();
for (dynamic cItem in items[0]) { for (dynamic cItem in items[0]) {
@ -359,6 +244,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void chatNotDelivered(List<Object?>? args) { void chatNotDelivered(List<Object?>? args) {
dynamic items = args!.toList(); dynamic items = args!.toList();
logger.d(items);
for (dynamic item in items[0]) { for (dynamic item in items[0]) {
searchedChats!.forEach( searchedChats!.forEach(
(ChatUser element) { (ChatUser element) {
@ -374,11 +260,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
void changeStatus(List<Object?>? args) { void changeStatus(List<Object?>? args) {
if (kDebugMode) {
// print("================= Status Online // Offline ====================");
}
dynamic items = args!.toList(); dynamic items = args!.toList();
// logger.d(items);
for (ChatUser user in searchedChats!) { for (ChatUser user in searchedChats!) {
if (user.id == items.first["id"]) { if (user.id == items.first["id"]) {
user.userStatus = items.first["userStatus"]; user.userStatus = items.first["userStatus"];
@ -413,14 +295,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
data.first.currentUserId = temp.first.targetUserId; data.first.currentUserId = temp.first.targetUserId;
data.first.currentUserName = temp.first.targetUserName; data.first.currentUserName = temp.first.targetUserName;
} }
logger.d(jsonEncode(data));
userChatHistory.insert(0, data.first); userChatHistory.insert(0, data.first);
// searchedChats!.forEach((element) {
// if (element.id == data.first.currentUserId) {
// var val = element.unreadMessageCount == null ? 0 : element.unreadMessageCount;
// element.unreadMessageCount = val! + 1;
// }
// });
var list = [ var list = [
{ {
"userChatHistoryId": data.first.userChatHistoryId, "userChatHistoryId": data.first.userChatHistoryId,
@ -430,14 +306,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
]; ];
updateUserChatHistoryStatusAsync(list); updateUserChatHistoryStatusAsync(list);
notifyListeners(); notifyListeners();
// if (isChatScreenActive) scrollToBottom();
} }
void onUserTyping(List<Object?>? parameters) { void onUserTyping(List<Object?>? parameters) {
// print("==================== Typing Active ==================");
// logger.d(parameters);
for (ChatUser user in searchedChats!) { for (ChatUser user in searchedChats!) {
if (user.id == parameters![1] && parameters[0] == true) { if (user.id == parameters![1] && parameters[0] == true) {
user.isTyping = parameters[0] as bool?; user.isTyping = parameters[0] as bool?;
@ -572,7 +444,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners(); notifyListeners();
} }
if (!isFileSelected && !isMsgReply) { if (!isFileSelected && !isMsgReply) {
logger.d("Normal Text Message");
if (message.text == null || message.text.isEmpty) { if (message.text == null || message.text.isEmpty) {
return; return;
} }
@ -580,14 +451,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
if (isFileSelected && !isMsgReply) { if (isFileSelected && !isMsgReply) {
Utils.showLoading(context); Utils.showLoading(context);
//logger.d("Normal Attachment Message");
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
String? ext = getFileExtension(selectedFile.path); String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context); Utils.hideLoading(context);
sendChatToServer(chatEventId: 2, fileTypeId: getFileType(ext.toString()), targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: true, chatReplyId: null, isReply: false); sendChatToServer(chatEventId: 2, fileTypeId: getFileType(ext.toString()), targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: true, chatReplyId: null, isReply: false);
} }
if (!isFileSelected && isMsgReply) { if (!isFileSelected && isMsgReply) {
// logger.d("Normal Text Message With Reply");
if (message.text == null || message.text.isEmpty) { if (message.text == null || message.text.isEmpty) {
return; return;
} }
@ -595,7 +464,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, chatReplyId: repliedMsg.first.userChatHistoryId, isAttachment: false, isReply: true); chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, chatReplyId: repliedMsg.first.userChatHistoryId, isAttachment: false, isReply: true);
} }
if (isFileSelected && isMsgReply) { if (isFileSelected && isMsgReply) {
// logger.d("Attachment Message With Reply");
Utils.showLoading(context); Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
String? ext = getFileExtension(selectedFile.path); String? ext = getFileExtension(selectedFile.path);
@ -708,9 +576,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
Future<void> favoriteUser({required int userID, required int targetUserID}) async { Future<void> favoriteUser({required int userID, required int targetUserID}) async {
Response response = fav.FavoriteChatUser favoriteChatUser = await ChatApiClient().favUser(userID: userID, targetUserID: targetUserID);
await ApiClient().postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
if (favoriteChatUser.response != null) { if (favoriteChatUser.response != null) {
for (ChatUser user in searchedChats!) { for (ChatUser user in searchedChats!) {
if (user.id == favoriteChatUser.response!.targetUserId!) { if (user.id == favoriteChatUser.response!.targetUserId!) {
@ -723,16 +589,16 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
Future<void> unFavoriteUser({required int userID, required int targetUserID}) async { Future<void> unFavoriteUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient() fav.FavoriteChatUser favoriteChatUser = await ChatApiClient().unFavUser(userID: userID, targetUserID: targetUserID);
.postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/deleteFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
if (favoriteChatUser.response != null) { if (favoriteChatUser.response != null) {
for (var user in searchedChats!) { for (ChatUser user in searchedChats!) {
if (user.id == favoriteChatUser.response!.targetUserId!) { if (user.id == favoriteChatUser.response!.targetUserId!) {
user.isFav = favoriteChatUser.response!.isFav; user.isFav = favoriteChatUser.response!.isFav;
} }
} }
favUsersList.removeWhere((ChatUser element) => element.id == targetUserID); favUsersList.removeWhere(
(ChatUser element) => element.id == targetUserID,
);
} }
notifyListeners(); notifyListeners();
} }
@ -784,4 +650,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
curve: Curves.easeIn, curve: Curves.easeIn,
); );
} }
// void getUserChatHistoryNotDeliveredAsync({required int userId}) async {
// try {
// await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]);
// } finally {
// hubConnection.off("GetUserChatHistoryNotDeliveredAsync", method: chatNotDelivered);
// }
// }
} }

@ -1,13 +1,16 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/api/offers_and_discounts_api_client.dart'; import 'package:mohem_flutter_app/api/offers_and_discounts_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/chat_count_conversation_model.dart'; import 'package:mohem_flutter_app/models/chat/chat_count_conversation_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart';
import 'package:mohem_flutter_app/models/dashboard/drawer_menu_item_model.dart'; import 'package:mohem_flutter_app/models/dashboard/drawer_menu_item_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_accrual_balances_list_model.dart'; import 'package:mohem_flutter_app/models/dashboard/get_accrual_balances_list_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart'; import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart';
@ -287,6 +290,18 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
} }
Future<void> getUserAutoLoginToken() async {
logger.d("Token Generated On Home");
UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
}
}
void notify() { void notify() {
notifyListeners(); notifyListeners();
} }

@ -4,7 +4,7 @@ import 'dart:convert';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -15,6 +15,7 @@ import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/call.dart'; import 'package:mohem_flutter_app/models/chat/call.dart';
import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart'; import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart';
import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart'; import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -79,7 +80,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
onPressed: () { onPressed: () {
makeCall( makeCall(
callType: "AUDIO", callType: "AUDIO",
con: data.hubConnection, con: hubConnection,
); );
}, },
icon: SvgPicture.asset( icon: SvgPicture.asset(
@ -92,7 +93,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
onPressed: () { onPressed: () {
makeCall( makeCall(
callType: "VIDEO", callType: "VIDEO",
con: data.hubConnection, con: hubConnection,
); );
}, },
icon: SvgPicture.asset( icon: SvgPicture.asset(

@ -2,7 +2,7 @@ import 'dart:convert';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
@ -31,21 +31,14 @@ class _ChatHomeState extends State<ChatHome> {
@override @override
void initState() { void initState() {
// TODO: implement initState
super.initState(); super.initState();
data = Provider.of<ChatProviderModel>(context, listen: false); data = Provider.of<ChatProviderModel>(context, listen: false);
data.getUserAutoLoginToken(context).whenComplete(() {
data.getUserRecentChats();
});
} }
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
data.clearAll(); data.clearAll();
if (data.hubConInitialized) {
data.hubConnection.stop();
}
} }
@override @override

@ -2,7 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
@ -21,6 +21,16 @@ class ChatHomeScreen extends StatefulWidget {
class _ChatHomeScreenState extends State<ChatHomeScreen> { class _ChatHomeScreenState extends State<ChatHomeScreen> {
TextEditingController search = TextEditingController(); TextEditingController search = TextEditingController();
late ChatProviderModel data;
@override
void initState() {
// TODO: implement initState
super.initState();
data = Provider.of<ChatProviderModel>(context, listen: false);
data.registerEvents();
data.getUserRecentChats();
}
@override @override
void dispose() { void dispose() {
@ -135,22 +145,22 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: <Widget>[ children: <Widget>[
if (m.searchedChats![index].isLoadingCounter!) // if (m.searchedChats![index].isLoadingCounter!)
Flexible( // Flexible(
child: Container( // child: Container(
padding: EdgeInsets.zero, // padding: EdgeInsets.zero,
alignment: Alignment.centerRight, // alignment: Alignment.centerRight,
width: 18, // width: 18,
height: 18, // height: 18,
decoration: const BoxDecoration( // decoration: const BoxDecoration(
// color: MyColors.redColor, // // color: MyColors.redColor,
borderRadius: BorderRadius.all( // borderRadius: BorderRadius.all(
Radius.circular(20), // Radius.circular(20),
), // ),
), // ),
child: CircularProgressIndicator(), // child: CircularProgressIndicator(),
), // ),
), // ),
if (m.searchedChats![index].unreadMessageCount! > 0) if (m.searchedChats![index].unreadMessageCount! > 0)
Flexible( Flexible(
child: Container( child: Container(

@ -1,7 +1,7 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';

@ -7,6 +7,7 @@ import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -26,6 +27,9 @@ import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'
import 'package:mohem_flutter_app/widgets/shimmer/offers_shimmer_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/offers_shimmer_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:signalr_netcore/signalr_client.dart';
late HubConnection hubConnection;
class DashboardScreen extends StatefulWidget { class DashboardScreen extends StatefulWidget {
DashboardScreen({Key? key}) : super(key: key); DashboardScreen({Key? key}) : super(key: key);
@ -49,13 +53,40 @@ class _DashboardScreenState extends State<DashboardScreen> {
super.initState(); super.initState();
scheduleMicrotask(() { scheduleMicrotask(() {
data = Provider.of<DashboardProviderModel>(context, listen: false); data = Provider.of<DashboardProviderModel>(context, listen: false);
data.getUserAutoLoginToken().whenComplete(() {
buildHubConnection();
});
_onRefresh(); _onRefresh();
}); });
} }
Future<void> buildHubConnection() async {
logger.d("Connnnnn Statred");
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)
.withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
hubConnection.onclose(({Exception? error}) {
logger.d("Con Closedddddd");
});
hubConnection.onreconnecting(({Exception? error}) {});
hubConnection.onreconnected(({String? connectionId}) {});
if (hubConnection.state != HubConnectionState.Connected) {
await hubConnection.start();
}
}
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
hubConnection.stop();
} }
void _onRefresh() async { void _onRefresh() async {

@ -5,7 +5,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
@ -88,7 +88,12 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
void fetchChatUser({bool isNeedLoading = true}) async { void fetchChatUser({bool isNeedLoading = true}) async {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
chatUsersList = await ChatProviderModel().getChatMemberFromSearch(searchText, int.parse(AppState().chatDetails!.response!.id.toString())); chatUsersList = await ChatApiClient().getChatMemberFromSearch(
searchText,
int.parse(
AppState().chatDetails!.response!.id.toString(),
),
);
Utils.hideLoading(context); Utils.hideLoading(context);
setState(() {}); setState(() {});
} catch (e) { } catch (e) {
@ -236,7 +241,6 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
arguments: {"targetUser": chatUsersList![index], "isNewChat": true}, arguments: {"targetUser": chatUsersList![index], "isNewChat": true},
); );
}, },
), ),
); );
}, },

Loading…
Cancel
Save