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