Chat video fixes

development_sikander
haroon amjad 2 years ago
parent d3358d578c
commit 55c096aa7e

@ -4,7 +4,6 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.CAMERA" />
@ -18,7 +17,7 @@
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<!-- <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />-->
<!-- Chat Web RTC Calling -->
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

@ -376,7 +376,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 3.7.8;
MARKETING_VERSION = 3.7.9;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -514,7 +514,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 3.7.8;
MARKETING_VERSION = 3.7.9;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -544,7 +544,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 3.7.8;
MARKETING_VERSION = 3.7.9;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

@ -39,7 +39,7 @@ class ChatApiClient {
"platform": Platform.isIOS ? "ios" : "android",
"deviceToken": AppState().getIsHuawei ? AppState().getHuaweiPushToken : AppState().getDeviceToken,
"isHuaweiDevice": AppState().getIsHuawei,
"voipToken": "80a3b01fc1ef2453eb4f1daa4fc31d8142d9cb67baf848e91350b607971fe2ba",
"voipToken": Platform.isIOS ? "80a3b01fc1ef2453eb4f1daa4fc31d8142d9cb67baf848e91350b607971fe2ba" : "",
},
);
@ -145,14 +145,14 @@ class ChatApiClient {
}
// Upload Chat Media
Future<Object?> uploadMedia(String userId, File file) async {
Future<Object?> uploadMedia(String userId, File file, String fileSource) async {
if (kDebugMode) {
print("${ApiConsts.chatMediaImageUploadUrl}upload");
print(AppState().chatDetails!.response!.token);
}
dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatMediaImageUploadUrl}upload'));
request.fields.addAll({'userId': userId, 'fileSource': '1'});
request.fields.addAll({'userId': userId, 'fileSource': fileSource});
request.files.add(await MultipartFile.fromPath('files', file.path));
request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'});
StreamedResponse response = await request.send();
@ -164,10 +164,10 @@ class ChatApiClient {
}
// Download File For Chat
Future<Uint8List> downloadURL({required String fileName, required String fileTypeDescription}) async {
Future<Uint8List> downloadURL({required String fileName, required String fileTypeDescription, required int fileSource}) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatMediaImageUploadUrl}download",
{"fileType": fileTypeDescription, "fileName": fileName, "fileSource": 1},
{"fileType": fileTypeDescription, "fileName": fileName, "fileSource": fileSource},
token: AppState().chatDetails!.response!.token,
);
Uint8List data = Uint8List.fromList(response.bodyBytes);

@ -19,19 +19,14 @@ 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/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' 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/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';
@ -64,10 +59,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
List<ChatUser> favUsersList = [];
int paginationVal = 0;
int? cTypingUserId = 0;
bool isTextMsg = false,
isReplyMsg = false,
isAttachmentMsg = false,
isVoiceMsg = false;
bool isTextMsg = false, isReplyMsg = false, isAttachmentMsg = false, isVoiceMsg = false;
// Audio Recoding Work
Timer? _timer;
@ -100,8 +92,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
List<groups.GroupResponse>? uGroups = [], searchGroups = [];
Future<void> getUserAutoLoginToken() async {
userLoginToken.UserAutoLoginModel userLoginResponse =
await ChatApiClient().getUserLoginToken();
userLoginToken.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
} else {
@ -130,15 +121,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
Future<HubConnection> getHubConnection() async {
HubConnection hub;
HttpConnectionOptions httpOp =
HttpConnectionOptions(skipNegotiation: false, logMessageContent: true);
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();
.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;
}
@ -150,12 +136,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
chatHubConnection.on("OnUserTypingAsync", onUserTyping);
chatHubConnection.on("OnUserCountAsync", userCountAsync);
// chatHubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
chatHubConnection.on(
"OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
chatHubConnection.on(
"OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
chatHubConnection.on(
"OnGetGroupUserStatusAsync", getGroupUserStatus);
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}]]}
@ -171,8 +154,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
// 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()));
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) {
@ -183,12 +165,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
pChatHistory = recentChat.response ?? [];
uGroups = userGroups.groupresponse ?? [];
pChatHistory!.sort((ChatUser a, ChatUser b) =>
a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase()));
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()));
await invokeUserChatHistoryNotDeliveredAsync(userId: int.parse(AppState().chatDetails!.response!.id.toString()));
sort();
notifyListeners();
if (searchedChats!.isNotEmpty || favUsersList.isNotEmpty) {
@ -197,38 +177,27 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
Future invokeUserChatHistoryNotDeliveredAsync({required int userId}) async {
await chatHubConnection
.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]);
await chatHubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]);
return "";
}
void getSingleUserChatHistory(
{required int senderUID,
required int receiverUID,
required bool loadMore,
bool isNewChat = false}) async {
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);
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();
List<SingleUserChatModel> temp = getSingleUserChatModel(response.body).reversed.toList();
userChatHistory.addAll(temp);
} else {
userChatHistory =
getSingleUserChatModel(response.body).reversed.toList();
userChatHistory = getSingleUserChatModel(response.body).reversed.toList();
}
}
isLoading = false;
@ -255,9 +224,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
dynamic data = [
{
"userChatHistoryId": element.userChatHistoryId,
"TargetUserId": element.currentUserId == receiverID
? element.currentUserId
: element.targetUserId,
"TargetUserId": element.currentUserId == receiverID ? element.currentUserId : element.targetUserId,
"isDelivered": true,
"isSeen": true,
}
@ -279,8 +246,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void updateUserChatHistoryStatusAsync(List data) {
try {
chatHubConnection
.invoke("UpdateUserChatHistoryStatusAsync", args: [data]);
chatHubConnection.invoke("UpdateUserChatHistoryStatusAsync", args: [data]);
} catch (e) {
throw e;
}
@ -288,26 +254,21 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void updateUserChatHistoryOnMsg(List data) {
try {
chatHubConnection
.invoke("UpdateUserChatHistoryStatusAsync", args: [data]);
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<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)));
List<groupchathistory.GetGroupChatHistoryAsync>.from(json.decode(str).map((x) => groupchathistory.GetGroupChatHistoryAsync.fromJson(x)));
Future<dynamic> uploadAttachments(String userId, File file) async {
Future<dynamic> uploadAttachments(String userId, File file, String fileSource) async {
dynamic result;
try {
Object? response = await ChatApiClient().uploadMedia(userId, file);
Object? response = await ChatApiClient().uploadMedia(userId, file, fileSource);
if (response != null) {
result = response;
} else {
@ -363,8 +324,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void updateChatHistoryWindow(List<Object?>? args) {
dynamic items = args!.toList();
if (kDebugMode) {
logger.i(
"---------------------------------Update Chat History Windows Async -------------------------------------");
logger.i("---------------------------------Update Chat History Windows Async -------------------------------------");
}
logger.d(items);
// for (var user in searchedChats!) {
@ -433,26 +393,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
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.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", fileSource: 1);
}
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");
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", fileSource: 1);
data.first.userChatReplyResponse!.isImageLoaded = true;
}
}
@ -460,14 +408,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
if (searchedChats != null) {
dynamic contain = searchedChats!
.where((ChatUser element) => element.id == data.first.currentUserId);
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);
emails.add(await EmailImageEncryption().encrypt(val: data.first.currentUserEmail!));
List<ChatUserImageModel> chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails);
searchedChats!.add(
ChatUser(
id: data.first.currentUserId,
@ -479,9 +424,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isImageLoaded: true,
userStatus: 1,
isTyping: false,
userLocalDownlaodedImage: await downloadImageLocal(
chatImages.first.profilePicture,
data.first.currentUserId.toString()),
userLocalDownlaodedImage: await downloadImageLocal(chatImages.first.profilePicture, data.first.currentUserId.toString()),
),
);
}
@ -506,9 +449,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
"userChatHistoryId": data.first.userChatHistoryId,
"TargetUserId": temp.first.targetUserId,
"isDelivered": true,
"isSeen": isChatScreenActive && data.first.currentUserId == receiverID
? true
: false
"isSeen": isChatScreenActive && data.first.currentUserId == receiverID ? true : false
}
];
updateUserChatHistoryOnMsg(list);
@ -519,7 +460,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
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));
@ -530,27 +470,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
// 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.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", fileSource: 2);
}
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");
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", fileSource: 2);
data.first.groupChatReplyResponse!.isImageLoaded = true;
}
}
@ -615,8 +542,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners();
}
void OnSubmitChatAsync(List<Object?>? parameters) {
print(isChatScreenActive);
print(receiverID);
@ -634,8 +559,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
data.first.currentUserEmail = temp.first.targetUserEmail;
}
if (isChatScreenActive && data.first.currentUserId == receiverID) {
int index = userChatHistory.indexWhere(
(SingleUserChatModel element) => element.userChatHistoryId == 0);
int index = userChatHistory.indexWhere((SingleUserChatModel element) => element.userChatHistoryId == 0);
logger.d(index);
userChatHistory[index] = data.first;
}
@ -645,8 +569,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void sort() {
searchedChats!.sort(
(ChatUser a, ChatUser b) =>
b.unreadMessageCount!.compareTo(a.unreadMessageCount!),
(ChatUser a, ChatUser b) => b.unreadMessageCount!.compareTo(a.unreadMessageCount!),
);
}
@ -698,6 +621,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
return 13;
case ".mp3":
return 14;
case ".mp4":
return 16;
case ".mov":
return 16;
case ".avi":
return 16;
case ".flv":
return 16;
default:
return 0;
}
@ -735,6 +667,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
return "audio/aac";
case ".mp3":
return "audio/mp3";
case ".mp4":
return "video/mp4";
case ".avi":
return "video/avi";
case ".flv":
return "video/flv";
case ".mov":
return "video/mov";
default:
return "";
}
@ -777,22 +718,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
targetUserName: targetUserName,
isReplied: false,
fileTypeId: fileTypeId,
userChatReplyResponse: isReply
? UserChatReplyResponse.fromJson(repliedMsg.first.toJson())
: null,
userChatReplyResponse: isReply ? UserChatReplyResponse.fromJson(repliedMsg.first.toJson()) : null,
fileTypeResponse: isAttachment
? FileTypeResponse(
fileTypeId: fileTypeId,
fileTypeName: isVoiceMsg
? getFileExtension(voiceFile!.path).toString()
: getFileExtension(selectedFile.path).toString(),
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()),
fileTypeDescription: isVoiceMsg ? getFileTypeDescription(getFileExtension(voiceFile!.path).toString()) : getFileTypeDescription(getFileExtension(selectedFile.path).toString()),
)
: null,
image: image,
@ -814,8 +747,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
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)]);
await chatHubConnection.invoke("AddChatUserAsync", args: <Object>[json.decode(chatData)]);
}
//groupChatMessage
@ -834,8 +766,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
int? userStatus,
File? voiceFile,
required bool isVoiceAttached,
required List<GroupUserList> userList
}) async {
required List<GroupUserList> userList}) async {
Uuid uuid = const Uuid();
String contentNo = uuid.v4();
String msg;
@ -845,8 +776,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
msg = message.text;
logger.w(msg);
}
groupchathistory.GetGroupChatHistoryAsync data =
groupchathistory.GetGroupChatHistoryAsync(
groupchathistory.GetGroupChatHistoryAsync data = groupchathistory.GetGroupChatHistoryAsync(
//userChatHistoryId: 0,
chatEventId: chatEventId,
chatSource: 1,
@ -866,7 +796,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
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,
fileTypeDescription: isVoiceMsg ? getFileTypeDescription(getFileExtension(voiceFile!.path).toString()) : getFileTypeDescription(getFileExtension(selectedFile.path).toString()))
: null,
image: image,
isImageLoaded: isImageLoaded,
voice: isVoiceMsg ? voiceFile! : null,
@ -887,18 +818,17 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
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)]);
await chatHubConnection.invoke("AddGroupChatHistoryAsync", args: <Object>[json.decode(chatData)]);
}
void sendGroupChatMessage(BuildContext context,
{required int targetUserId,
void sendGroupChatMessage(
BuildContext context, {
required int targetUserId,
required int userStatus,
required String userEmail,
required String targetUserName,
@ -922,8 +852,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isVoiceAttached: false,
userEmail: userEmail,
userStatus: userStatus,
userList:userList
);
userList: userList);
} else if (isTextMsg && !isAttachmentMsg && !isVoiceMsg && isReplyMsg) {
logger.d("// Text Message as Reply");
if (message.text.isEmpty) {
@ -943,15 +872,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
voiceFile: null,
userEmail: userEmail,
userStatus: userStatus,
userList:userList
);
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);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile, "2");
String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context);
sendGroupChatToServer(
@ -967,19 +894,16 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isVoiceAttached: false,
userEmail: userEmail,
userStatus: userStatus,
userList:userList
);
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);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile, "2");
String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context);
sendGroupChatToServer(
chatEventId: 2,
fileTypeId: getFileType(ext.toString()),
targetGroupId: targetUserId,
targetUserName: targetUserName,
isAttachment: true,
@ -990,8 +914,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isVoiceAttached: false,
userEmail: userEmail,
userStatus: userStatus,
userList:userList
);
userList: userList);
}
//Voice
@ -1011,8 +934,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isPlaying = false;
isRecoding = false;
Utils.showLoading(context);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), voiceFile);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), voiceFile, "2");
String? ext = getFileExtension(voiceFile.path);
Utils.hideLoading(context);
sendGroupChatToServer(
@ -1029,8 +951,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isVoiceAttached: true,
userEmail: userEmail,
userStatus: userStatus,
userList:userList
);
userList: userList);
notifyListeners();
} else if (!isTextMsg && !isAttachmentMsg && isVoiceMsg && isReplyMsg) {
logger.d("// Voice as Reply Msg");
@ -1049,8 +970,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isRecoding = false;
Utils.showLoading(context);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), voiceFile);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), voiceFile, "2");
String? ext = getFileExtension(voiceFile.path);
Utils.hideLoading(context);
sendGroupChatToServer(
@ -1066,18 +986,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isVoiceAttached: true,
userEmail: userEmail,
userStatus: userStatus,
userList:userList
);
userList: userList);
notifyListeners();
}
if (searchedChats != null) {
dynamic contain = searchedChats!
.where((ChatUser element) => element.id == targetUserId);
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);
List<ChatUserImageModel> chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails);
searchedChats!.add(
ChatUser(
id: targetUserId,
@ -1098,12 +1015,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
}
void sendChatMessage(BuildContext context,
{required int targetUserId,
void sendChatMessage(
BuildContext context, {
required int targetUserId,
required int userStatus,
required String userEmail,
required String targetUserName,
}) async {
if (kDebugMode) {
print("====================== Values ============================");
@ -1155,8 +1072,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && !isReplyMsg) {
logger.d("// Normal Image Message");
Utils.showLoading(context);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), selectedFile);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile, "1");
String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context);
sendChatToServer(
@ -1175,8 +1091,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} 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);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile, "1");
String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context);
sendChatToServer(
@ -1211,8 +1126,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isPlaying = false;
isRecoding = false;
Utils.showLoading(context);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), voiceFile);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), voiceFile, "1");
String? ext = getFileExtension(voiceFile.path);
Utils.hideLoading(context);
sendChatToServer(
@ -1246,8 +1160,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isRecoding = false;
Utils.showLoading(context);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), voiceFile);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), voiceFile, "1");
String? ext = getFileExtension(voiceFile.path);
Utils.hideLoading(context);
sendChatToServer(
@ -1266,13 +1179,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners();
}
if (searchedChats != null) {
dynamic contain = searchedChats!
.where((ChatUser element) => element.id == targetUserId);
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);
List<ChatUserImageModel> chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails);
searchedChats!.add(
ChatUser(
id: targetUserId,
@ -1285,8 +1196,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isTyping: false,
isFav: false,
userStatus: userStatus,
userLocalDownlaodedImage: await downloadImageLocal(
chatImages.first.profilePicture, targetUserId.toString()),
userLocalDownlaodedImage: await downloadImageLocal(chatImages.first.profilePicture, targetUserId.toString()),
),
);
notifyListeners();
@ -1316,8 +1226,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
void selectImageToUpload(BuildContext context) {
ImageOptions.showImageOptionsNew(context, true,
(String image, File file) async {
ImageOptions.showImageOptionsNew(context, true, (String image, File file) async {
if (checkFileSize(file.path)) {
selectedFile = file;
isAttachmentMsg = true;
@ -1353,8 +1262,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
bool checkFileSize(String path) {
int fileSizeLimit = 1024;
File f = File(path);
double fileSizeInKB = f.lengthSync() / 1024;
double fileSizeInMB = fileSizeInKB / 1024;
double fileSizeInKB = f.lengthSync() / 5000;
double fileSizeInMB = fileSizeInKB / 5000;
if (fileSizeInKB > fileSizeLimit) {
return false;
} else {
@ -1406,6 +1315,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
repliedMsg.add(data);
notifyListeners();
}
void groupChatReply(groupchathistory.GetGroupChatHistoryAsync data) {
groupChatReplyData = [];
data.isReplied = true;
@ -1413,6 +1323,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
groupChatReplyData.add(data);
notifyListeners();
}
void closeMe() {
repliedMsg = [];
isReplyMsg = false;
@ -1425,18 +1336,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
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);
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!);
dynamic contain = favUsersList!.where((ChatUser element) => element.id == favoriteChatUser.response!.targetUserId!);
if (contain.isEmpty) {
favUsersList.add(user);
}
@ -1446,8 +1352,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
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!);
dynamic contain = favUsersList!.where((ChatUser element) => element.id == favoriteChatUser.response!.targetUserId!);
if (contain.isEmpty) {
favUsersList.add(user);
}
@ -1466,10 +1371,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners();
}
Future<void> unFavoriteUser(
{required int userID, required int targetUserID}) async {
fav.FavoriteChatUser favoriteChatUser = await ChatApiClient()
.unFavUser(userID: userID, targetUserID: targetUserID);
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!) {
@ -1574,14 +1477,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
emails.add(await EmailImageEncryption().encrypt(val: element.email!));
}
List<ChatUserImageModel> chatImages =
await ChatApiClient().getUsersImages(encryptedEmails: emails);
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.userLocalDownlaodedImage = await downloadImageLocal(uImage.profilePicture, user.id.toString());
user.isImageLoading = false;
user.isImageLoaded = true;
}
@ -1591,8 +1492,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.userLocalDownlaodedImage = await downloadImageLocal(uImage.profilePicture, favUser.id.toString());
favUser.isImageLoading = false;
favUser.isImageLoaded = true;
}
@ -1609,8 +1509,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} else {
await deleteFile(userID);
Uint8List decodedBytes = base64Decode(encodedBytes);
Directory appDocumentsDirectory =
await getApplicationDocumentsDirectory();
Directory appDocumentsDirectory = await getApplicationDocumentsDirectory();
String dirPath = '${appDocumentsDirectory.path}/chat_images';
if (!await Directory(dirPath).exists()) {
await Directory(dirPath).create();
@ -1633,8 +1532,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
Future<String> downChatMedia(Uint8List bytes, String ext) async {
String dir = (await getApplicationDocumentsDirectory()).path;
File file = File(
"$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext);
File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext);
await file.writeAsBytes(bytes);
return file.path;
}
@ -1657,20 +1555,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
}
Future<void> getChatMedia(BuildContext context,
{required String fileName,
required String fileTypeName,
required int fileTypeID}) async {
Future<void> getChatMedia(BuildContext context, {required String fileName, required String fileTypeName, required int fileTypeID, required int fileSource}) 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));
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 || fileTypeID == 2 || fileTypeID == 16) {
Uint8List encodedString = await ChatApiClient().downloadURL(fileName: fileName, fileTypeDescription: getFileTypeDescription(fileTypeName), fileSource: fileSource);
try {
String path = await downChatMedia(encodedString, fileTypeName ?? "");
Utils.hideLoading(context);
@ -1692,19 +1580,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
return "";
}
void userTypingInvoke(
{required int currentUser, required int reciptUser}) async {
await chatHubConnection
.invoke("UserTypingAsync", args: [reciptUser, currentUser]);
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 {
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 ]);
await chatHubConnection.invoke("GroupTypingAsync", args: ["${groupDetails.adminUser!.userName}", data, groupId]);
}
//////// Audio Recoding Work ////////////////////
Future<void> initAudio({required int receiverId}) async {
@ -1718,8 +1602,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
await Directory(dirPath).create();
await File('$dirPath/.nomedia').create();
}
path =
"$dirPath/${AppState().chatDetails!.response!.id}-$receiverID-${DateTime.now().microsecondsSinceEpoch}.aac";
path = "$dirPath/${AppState().chatDetails!.response!.id}-$receiverID-${DateTime.now().microsecondsSinceEpoch}.aac";
recorderController = RecorderController()
..androidEncoder = AndroidEncoder.aac
..androidOutputFormat = AndroidOutputFormat.mpeg4
@ -1849,19 +1732,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
return numberStr;
}
Future<File> downChatVoice(
Uint8List bytes, String ext, SingleUserChatModel data) async {
Future<File> downChatVoice(Uint8List bytes, String ext, SingleUserChatModel data) async {
File file;
try {
String dirPath =
'${(await getApplicationDocumentsDirectory()).path}/chat_audios';
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);
file = File("$dirPath/${data.currentUserId}-${data.targetUserId}-${DateTime.now().microsecondsSinceEpoch}" + ext);
await file.writeAsBytes(bytes);
} catch (e) {
if (kDebugMode) {
@ -1873,14 +1752,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
void scrollToMsg(SingleUserChatModel data) {
if (data.userChatReplyResponse != null &&
data.userChatReplyResponse!.userChatHistoryId != null) {
int index = userChatHistory.indexWhere((SingleUserChatModel element) =>
element.userChatHistoryId ==
data.userChatReplyResponse!.userChatHistoryId);
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 contentSize = scrollController.position.viewportDimension + scrollController.position.maxScrollExtent;
double target = contentSize * index / userChatHistory.length;
scrollController.position.animateTo(
target,
@ -1912,18 +1787,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isImageLoading: false,
image: element.eMPLOYEEIMAGE ?? "",
isImageLoaded: element.eMPLOYEEIMAGE == null ? false : true,
userLocalDownlaodedImage: element.eMPLOYEEIMAGE == null
? null
: await downloadImageLocal(
element.eMPLOYEEIMAGE ?? "", element.eMPLOYEENUMBER!),
userLocalDownlaodedImage: element.eMPLOYEEIMAGE == null ? null : await downloadImageLocal(element.eMPLOYEEIMAGE ?? "", element.eMPLOYEENUMBER!),
),
);
}
}
}
} else {
getEmployeeSubordinatesList =
await MyTeamApiClient().getEmployeeSubordinates("", "", "");
getEmployeeSubordinatesList = await MyTeamApiClient().getEmployeeSubordinates("", "", "");
AppState().setemployeeSubordinatesList = getEmployeeSubordinatesList;
for (GetEmployeeSubordinatesList element in getEmployeeSubordinatesList) {
if (element.eMPLOYEEEMAILADDRESS != null) {
@ -1941,10 +1812,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isImageLoading: false,
image: element.eMPLOYEEIMAGE ?? "",
isImageLoaded: element.eMPLOYEEIMAGE == null ? false : true,
userLocalDownlaodedImage: element.eMPLOYEEIMAGE == null
? null
: await downloadImageLocal(
element.eMPLOYEEIMAGE ?? "", element.eMPLOYEENUMBER!),
userLocalDownlaodedImage: element.eMPLOYEEIMAGE == null ? null : await downloadImageLocal(element.eMPLOYEEIMAGE ?? "", element.eMPLOYEENUMBER!),
),
);
}
@ -2013,14 +1881,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
SingleUserChatModel nUser = SingleUserChatModel();
Utils.saveStringFromPrefs("isAppOpendByChat", "false");
if (await Utils.getStringFromPrefs("notificationData") != "null") {
nUser = SingleUserChatModel.fromJson(
jsonDecode(await Utils.getStringFromPrefs("notificationData")));
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));
Navigator.pushNamed(context, AppRoutes.chatDetailed, arguments: ChatDetailedScreenParams(user, false));
return;
}
}
@ -2057,9 +1923,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
Future getGroupChatHistory(groups.GroupResponse groupDetails) async {
isLoading = true;
groupChatHistory = await ChatApiClient().getGroupChatHistory(
groupDetails.groupId,
groupDetails.groupUserList as List<GroupUserList>);
groupChatHistory = await ChatApiClient().getGroupChatHistory(groupDetails.groupId, groupDetails.groupUserList as List<GroupUserList>);
isLoading = false;
@ -2076,12 +1940,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
Future addGroupAndUsers(createGroup.CreateGroupRequest request) async {
isLoading = true;
var groups = await ChatApiClient().addGroupAndUsers(request);
userGroups.groupresponse!
.add(GroupResponse.fromJson(json.decode(groups)['response']));
userGroups.groupresponse!.add(GroupResponse.fromJson(json.decode(groups)['response']));
isLoading = false;
notifyListeners();
}
Future updateGroupAndUsers(createGroup.CreateGroupRequest request) async {
isLoading = true;
await ChatApiClient().updateGroupAndUsers(request);

@ -1,5 +1,4 @@
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -18,9 +17,9 @@ import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.da
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_full_image_preview.dart';
import 'package:mohem_flutter_app/ui/chat/common.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
import 'package:video_player/video_player.dart';
class ChatBubble extends StatelessWidget {
ChatBubble({Key? key, required this.dateTime, required this.cItem}) : super(key: key);
@ -82,7 +81,8 @@ class ChatBubble extends StatelessWidget {
}
} else {
Utils.showLoading(context);
Uint8List encodedString = await ChatApiClient().downloadURL(fileName: data.contant!, fileTypeDescription: provider.getFileTypeDescription(data.fileTypeResponse!.fileTypeName ?? ""));
Uint8List encodedString =
await ChatApiClient().downloadURL(fileName: data.contant!, fileTypeDescription: provider.getFileTypeDescription(data.fileTypeResponse!.fileTypeName ?? ""), fileSource: 1);
// try {
File sFile = await provider.downChatVoice(encodedString, data.fileTypeResponse!.fileTypeName ?? "", data);
if (sFile.path.isEmpty) {
@ -195,20 +195,26 @@ class ChatBubble extends StatelessWidget {
}),
),
).paddingOnly(bottom: 4),
if (fileTypeID == 13 && cItem.voiceController != null)
currentWaveBubble(context, cItem)
else
if (fileTypeID == 13 && cItem.voiceController != null) currentWaveBubble(context, cItem),
if (fileTypeID == 16)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
showVideoThumb(context, cItem),
Row(
children: [
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8
// || fileTypeID == 2
Directionality(textDirection: provider.getTextDirection(cItem.contant ?? ""), child: (cItem.contant ?? "").toText12().expanded),
],
),
],
)
else
Row(
children: [
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8)
SvgPicture.asset(provider.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 0, right: 10),
Directionality(textDirection: provider.getTextDirection(cItem.contant ?? ""), child: (cItem.contant ?? "").toText12().expanded),
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8
//|| fileTypeID == 2
)
const Icon(Icons.remove_red_eye, size: 16)
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8) const Icon(Icons.remove_red_eye, size: 16)
],
),
Align(
@ -276,7 +282,12 @@ class ChatBubble extends StatelessWidget {
child: showImage(
isReplyPreview: true,
fileName: cItem.userChatReplyResponse!.contant!,
fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg"),
fileTypeDescription: cItem.fileTypeResponse != null && cItem.fileTypeResponse!.fileTypeDescription != null
? cItem.fileTypeResponse!.fileTypeDescription
: cItem.fileTypeResponse!.fileTypeName
// fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg"
),
),
).paddingOnly(left: 10, right: 10, bottom: 16, top: 16)
],
@ -300,20 +311,26 @@ class ChatBubble extends StatelessWidget {
}),
),
).paddingOnly(bottom: 4),
if (fileTypeID == 13 && cItem.voiceController != null)
recipetWaveBubble(context, cItem)
else
if (fileTypeID == 13 && cItem.voiceController != null) recipetWaveBubble(context, cItem),
if (fileTypeID == 16)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
showVideoThumb(context, cItem),
Row(
children: [
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8
// || fileTypeID == 2
Directionality(textDirection: provider.getTextDirection(cItem.contant ?? ""), child: (cItem.contant ?? "").toText12(color: Colors.white).expanded),
],
),
],
)
else
Row(
children: [
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8)
SvgPicture.asset(provider.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 0, right: 10),
Directionality(textDirection: provider.getTextDirection(cItem.contant ?? ""), child: (cItem.contant ?? "").toText12(color: Colors.white).expanded),
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8
//|| fileTypeID == 2
)
const Icon(Icons.remove_red_eye, color: Colors.white, size: 16)
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8) const Icon(Icons.remove_red_eye, color: Colors.white, size: 16)
],
),
Align(
@ -324,11 +341,7 @@ class ChatBubble extends StatelessWidget {
),
],
),
).paddingOnly(right: MediaQuery.of(context).size.width * 0.3);
}
Widget voiceMsg(BuildContext context) {
return Container();
).paddingOnly(right: MediaQuery.of(context).size.width * 0.33);
}
Widget showImage({required bool isReplyPreview, required String fileName, required String fileTypeDescription}) {
@ -342,7 +355,7 @@ class ChatBubble extends StatelessWidget {
);
} else {
return FutureBuilder<Uint8List>(
future: ChatApiClient().downloadURL(fileName: fileName, fileTypeDescription: fileTypeDescription),
future: ChatApiClient().downloadURL(fileName: fileName, fileTypeDescription: fileTypeDescription, fileSource: 1),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState != ConnectionState.waiting) {
if (snapshot.data == null) {
@ -470,4 +483,50 @@ class ChatBubble extends StatelessWidget {
},
);
}
Widget showVideoThumb(BuildContext context, SingleUserChatModel data) {
return LoadVideo(data: data);
}
}
class LoadVideo extends StatefulWidget {
final SingleUserChatModel data;
const LoadVideo({Key? key, required this.data}) : super(key: key);
@override
State<LoadVideo> createState() => _LoadVideoState();
}
class _LoadVideoState extends State<LoadVideo> {
late VideoPlayerController videoController;
@override
void initState() {
videoController = VideoPlayerController.networkUrl(Uri.parse('https://apiderichat.hmg.com/attachments/${widget.data.fileTypeResponse?.fileName}'))..initialize().then((_) {});
super.initState();
}
@override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: AspectRatio(
aspectRatio: videoController.value.aspectRatio,
child: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
VideoPlayer(videoController),
Align(
alignment: Alignment.center,
child: Icon(
Icons.play_arrow,
color: Colors.white.withOpacity(.7),
size: 56,
),
)
],
),
));
}
}

@ -155,11 +155,10 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
m.userChatHistory[i].fileTypeId! == 5 ||
m.userChatHistory[i].fileTypeId! == 7 ||
m.userChatHistory[i].fileTypeId! == 6 ||
m.userChatHistory[i].fileTypeId! == 8
// || m.userChatHistory[i].fileTypeId! == 2
) {
m.userChatHistory[i].fileTypeId! == 8 ||
m.userChatHistory[i].fileTypeId! == 16) {
m.getChatMedia(context,
fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.userChatHistory[i].fileTypeId!, fileName: m.userChatHistory[i].contant!);
fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.userChatHistory[i].fileTypeId!, fileName: m.userChatHistory[i].contant!, fileSource: 1);
}
}
});

@ -22,6 +22,7 @@ import 'package:mohem_flutter_app/ui/chat/common.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
import 'package:video_player/video_player.dart';
class GroupChatBubble extends StatelessWidget {
GroupChatBubble({Key? key, required this.dateTime, required this.cItem})
@ -100,7 +101,7 @@ class GroupChatBubble extends StatelessWidget {
Uint8List encodedString = await ChatApiClient().downloadURL(
fileName: data.contant!,
fileTypeDescription: provider.getFileTypeDescription(
data.fileTypeResponse!.fileTypeName ?? ""));
data.fileTypeResponse!.fileTypeName ?? ""), fileSource: 2);
// try {
File sFile = await provider.downChatVoice(
encodedString, data.fileTypeResponse!.fileTypeName ?? "", data);
@ -245,8 +246,11 @@ class GroupChatBubble extends StatelessWidget {
child: showImage(
isReplyPreview: false,
fileName: cItem.contant!,
fileTypeDescription:
cItem.fileTypeResponse!.fileTypeDescription)
fileTypeDescription: cItem.fileTypeResponse != null &&
cItem.fileTypeResponse!.fileTypeDescription !=
null
? cItem.fileTypeResponse!.fileTypeDescription
: cItem.fileTypeResponse!.fileTypeName)
.onPress(() {
showDialog(
context: context,
@ -258,7 +262,9 @@ class GroupChatBubble extends StatelessWidget {
),
).paddingOnly(bottom: 4),
if (fileTypeID == 13 && cItem.voiceController != null)
currentWaveBubble(context, cItem)
currentWaveBubble(context, cItem),
if (fileTypeID == 16)
showVideoThumb(context, cItem)
else
Row(
children: [
@ -422,14 +428,18 @@ class GroupChatBubble extends StatelessWidget {
),
).paddingOnly(bottom: 4),
if (fileTypeID == 13 && cItem.voiceController != null)
recipetWaveBubble(context, cItem)
recipetWaveBubble(context, cItem),
if (fileTypeID == 16)
showVideoThumb(context, cItem)
else
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
cItem.currentUserName!.toText10(
cItem.currentUserName!
.toText10(
color: Colors.black,
).paddingOnly(bottom: 5),
)
.paddingOnly(bottom: 5),
Row(
children: [
if (fileTypeID == 1 ||
@ -464,9 +474,11 @@ class GroupChatBubble extends StatelessWidget {
),
Align(
alignment: Alignment.topRight,
child: dateTime.toText10(
child: dateTime
.toText10(
color: Colors.white.withOpacity(.71),
).paddingOnly(top:5),
)
.paddingOnly(top: 5),
),
],
),
@ -492,7 +504,7 @@ class GroupChatBubble extends StatelessWidget {
} else {
return FutureBuilder<Uint8List>(
future: ChatApiClient().downloadURL(
fileName: fileName, fileTypeDescription: fileTypeDescription),
fileName: fileName, fileTypeDescription: fileTypeDescription, fileSource:2),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState != ConnectionState.waiting) {
if (snapshot.data == null) {
@ -557,6 +569,11 @@ class GroupChatBubble extends StatelessWidget {
).circle(5);
}
Widget showVideoThumb(BuildContext context, GetGroupChatHistoryAsync data) {
return LoadVideo(data: data);
}
Widget recipetWaveBubble(
BuildContext context, GetGroupChatHistoryAsync data) {
return Container(
@ -641,3 +658,51 @@ class GroupChatBubble extends StatelessWidget {
);
}
}
class LoadVideo extends StatefulWidget {
final GetGroupChatHistoryAsync data;
const LoadVideo({Key? key, required this.data}) : super(key: key);
@override
State<LoadVideo> createState() => _LoadVideoState();
}
class _LoadVideoState extends State<LoadVideo> {
late VideoPlayerController videoController;
@override
void initState() {
videoController = VideoPlayerController.networkUrl(Uri.parse(
'https://apiderichat.hmg.com/groupattachments/${widget.data.fileTypeResponse?.fileName}'))
..initialize().then((_) {
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: AspectRatio(
aspectRatio: videoController.value.aspectRatio,
child: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
VideoPlayer(videoController),
Align(
alignment: Alignment.center,
child: Icon(
Icons.play_arrow,
color: Colors.white.withOpacity(.7),
size: 56,
),
)
],
),
));
}
}

@ -83,8 +83,7 @@ class _GroupChatDetailScreenState extends State<GroupChatDetailScreen> {
data = Provider.of<ChatProviderModel>(context, listen: false);
// callPro = Provider.of<ChatCallProvider>(context, listen: false);
if (params != null) {
data.getGroupChatHistory(
params!.groupChatDetails!
data.getGroupChatHistory(params!.groupChatDetails!
// senderUID: AppState().chatDetails!.response!.id!.toInt(),
// receiverUID: params!.groupChatHistory!.groupId!,
// loadMore: false,
@ -159,11 +158,10 @@ class _GroupChatDetailScreenState extends State<GroupChatDetailScreen> {
m.userChatHistory[i].fileTypeId! == 5 ||
m.userChatHistory[i].fileTypeId! == 7 ||
m.userChatHistory[i].fileTypeId! == 6 ||
m.userChatHistory[i].fileTypeId! == 8
// || m.userChatHistory[i].fileTypeId! == 2
) {
m.userChatHistory[i].fileTypeId! == 8 ||
m.userChatHistory[i].fileTypeId! == 16) {
m.getChatMedia(context,
fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.userChatHistory[i].fileTypeId!, fileName: m.userChatHistory[i].contant!);
fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.userChatHistory[i].fileTypeId!, fileName: m.userChatHistory[i].contant!, fileSource: 2);
}
}
});
@ -254,8 +252,7 @@ class _GroupChatDetailScreenState extends State<GroupChatDetailScreen> {
userStatus: 0,
userEmail: "",
targetUserName: params!.groupChatDetails!.groupName!,
userList: params!.groupChatDetails!.groupUserList!
),
userList: params!.groupChatDetails!.groupUserList!),
)
.paddingOnly(right: 21),
],
@ -309,9 +306,7 @@ class _GroupChatDetailScreenState extends State<GroupChatDetailScreen> {
RotationTransition(
turns: const AlwaysStoppedAnimation(45 / 360),
child: const Icon(Icons.attach_file_rounded, size: 26, color: MyColors.grey3AColor).onPress(
() => {
m.selectImageToUpload(context)
},
() => {m.selectImageToUpload(context)},
),
).paddingOnly(right: 15),
const Icon(
@ -327,8 +322,7 @@ class _GroupChatDetailScreenState extends State<GroupChatDetailScreen> {
userStatus: 0,
userEmail: "",
targetUserName: params!.groupChatDetails!.groupName!,
userList: params!.groupChatDetails!.groupUserList!
),
userList: params!.groupChatDetails!.groupUserList!),
)
.paddingOnly(right: 21),
],
@ -387,8 +381,8 @@ class _GroupChatDetailScreenState extends State<GroupChatDetailScreen> {
// callPro.stopListeners();
// });
}
GroupUserList getCurrentUser(int id, GroupResponse groupChatDetails) {
return groupChatDetails.groupUserList!.firstWhere((GroupUserList item) => item.id == id);
}
}

@ -184,7 +184,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
handleErmChannel(list);
} catch (ex) {
Utils.hideLoading(context);
Utils.handleException(ex, context, null);
// Utils.handleException(ex, context, null);
return;
}
}

@ -8,23 +8,25 @@ import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheet.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheets/attachment_options.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:permission_handler/permission_handler.dart';
final ImagePicker picker = ImagePicker();
class ImageOptions {
static void showImageOptionsNew(BuildContext context, bool showFilesOption, Function(String, File) image) {
showMyBottomSheet(
context,
callBackFunc: () {},
child: AttachmentOptions(
showFilesOption: showFilesOption,
onCameraTap: () async {
if (Platform.isAndroid) {
cameraImageAndroid(image);
} else {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 20))?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
// XFile? media = await picker.pickMedia();
String? fileName = _image?.path;
var bytes = File(fileName!).readAsBytesSync();
String base64Encode = base64.encode(bytes);
if (base64Encode != null) {
image(base64Encode, _image);
@ -35,7 +37,7 @@ class ImageOptions {
if (Platform.isAndroid) {
galleryImageAndroid(image);
} else {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20))?.path ?? "");
File _image = File((await picker.pickMedia())?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes);
@ -45,41 +47,6 @@ class ImageOptions {
}
},
onFilesTap: () async {
Permission.storage.isGranted.then((isGranted) async {
if (!isGranted) {
Permission.storage.request().then((granted) async {
if (granted == PermissionStatus.granted) {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: [
'jpg',
'jpeg ',
'pdf',
'txt',
'docx',
'doc',
'pptx',
'xlsx',
'png',
'rar',
'zip',
],
);
List<File> files = result!.paths.map((path) => File(path!)).toList();
image(result.files.first.path.toString(), files.first);
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give storage permission to upload files.",
onTap: () {
Navigator.pop(context);
},
),
);
}
});
} else {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: [
@ -98,8 +65,6 @@ class ImageOptions {
);
List<File> files = result!.paths.map((path) => File(path!)).toList();
image(result.files.first.path.toString(), files.first);
}
});
},
),
);
@ -165,7 +130,7 @@ class ImageOptions {
}
void galleryImageAndroid(Function(String, File) image) async {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20))?.path ?? "");
File _image = File((await picker.pickMedia())?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
@ -176,7 +141,7 @@ void galleryImageAndroid(Function(String, File) image) async {
}
void cameraImageAndroid(Function(String, File) image) async {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 20))?.path ?? "");
File _image = File(( await picker.pickMedia())?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes);

Loading…
Cancel
Save