Merge branch 'master' into development_sikander

sultan-dev
Sikander Saleem 2 years ago
commit f5684ab27e

@ -147,7 +147,7 @@ class ChatApiClient {
} }
Future<StreamedResponse> uploadMedia(String userId, File file) async { Future<StreamedResponse> uploadMedia(String userId, File file) async {
dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatServerBaseApiUrl}upload')); dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatMediaImageUploadUrl}upload'));
request.fields.addAll({'userId': userId, 'fileSource': '1'}); request.fields.addAll({'userId': userId, 'fileSource': '1'});
request.files.add(await MultipartFile.fromPath('files', file.path)); request.files.add(await MultipartFile.fromPath('files', file.path));
request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'}); request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'});

@ -1,32 +1,35 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/foundation.dart';
List<SingleUserChatModel> singleUserChatModelFromJson(String str) => List<SingleUserChatModel>.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); List<SingleUserChatModel> singleUserChatModelFromJson(String str) => List<SingleUserChatModel>.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x)));
String singleUserChatModelToJson(List<SingleUserChatModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson()))); String singleUserChatModelToJson(List<SingleUserChatModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class SingleUserChatModel { class SingleUserChatModel {
SingleUserChatModel({ SingleUserChatModel(
this.userChatHistoryId, {this.userChatHistoryId,
this.userChatHistoryLineId, this.userChatHistoryLineId,
this.contant, this.contant,
this.contantNo, this.contantNo,
this.currentUserId, this.currentUserId,
this.currentUserName, this.currentUserName,
this.targetUserId, this.targetUserId,
this.targetUserName, this.targetUserName,
this.encryptedTargetUserId, this.encryptedTargetUserId,
this.encryptedTargetUserName, this.encryptedTargetUserName,
this.chatEventId, this.chatEventId,
this.fileTypeId, this.fileTypeId,
this.isSeen, this.isSeen,
this.isDelivered, this.isDelivered,
this.createdDate, this.createdDate,
this.chatSource, this.chatSource,
this.conversationId, this.conversationId,
this.fileTypeResponse, this.fileTypeResponse,
this.userChatReplyResponse, this.userChatReplyResponse,
this.isReplied, this.isReplied,
}); this.isImageLoaded,
this.image});
int? userChatHistoryId; int? userChatHistoryId;
int? userChatHistoryLineId; int? userChatHistoryLineId;
@ -48,29 +51,32 @@ class SingleUserChatModel {
FileTypeResponse? fileTypeResponse; FileTypeResponse? fileTypeResponse;
UserChatReplyResponse? userChatReplyResponse; UserChatReplyResponse? userChatReplyResponse;
bool? isReplied; bool? isReplied;
bool? isImageLoaded;
Uint8List? image;
factory SingleUserChatModel.fromJson(Map<String, dynamic> json) => SingleUserChatModel( factory SingleUserChatModel.fromJson(Map<String, dynamic> json) => SingleUserChatModel(
userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"], userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"],
userChatHistoryLineId: json["userChatHistoryLineId"] == null ? null : json["userChatHistoryLineId"], userChatHistoryLineId: json["userChatHistoryLineId"] == null ? null : json["userChatHistoryLineId"],
contant: json["contant"] == null ? null : json["contant"], contant: json["contant"] == null ? null : json["contant"],
contantNo: json["contantNo"] == null ? null : json["contantNo"], contantNo: json["contantNo"] == null ? null : json["contantNo"],
currentUserId: json["currentUserId"] == null ? null : json["currentUserId"], currentUserId: json["currentUserId"] == null ? null : json["currentUserId"],
currentUserName: json["currentUserName"] == null ? null : json["currentUserName"], currentUserName: json["currentUserName"] == null ? null : json["currentUserName"],
targetUserId: json["targetUserId"] == null ? null : json["targetUserId"], targetUserId: json["targetUserId"] == null ? null : json["targetUserId"],
targetUserName: json["targetUserName"] == null ? null : json["targetUserName"], targetUserName: json["targetUserName"] == null ? null : json["targetUserName"],
encryptedTargetUserId: json["encryptedTargetUserId"] == null ? null : json["encryptedTargetUserId"], encryptedTargetUserId: json["encryptedTargetUserId"] == null ? null : json["encryptedTargetUserId"],
encryptedTargetUserName: json["encryptedTargetUserName"] == null ? null : json["encryptedTargetUserName"], encryptedTargetUserName: json["encryptedTargetUserName"] == null ? null : json["encryptedTargetUserName"],
chatEventId: json["chatEventId"] == null ? null : json["chatEventId"], chatEventId: json["chatEventId"] == null ? null : json["chatEventId"],
fileTypeId: json["fileTypeId"], fileTypeId: json["fileTypeId"],
isSeen: json["isSeen"] == null ? null : json["isSeen"], isSeen: json["isSeen"] == null ? null : json["isSeen"],
isDelivered: json["isDelivered"] == null ? null : json["isDelivered"], isDelivered: json["isDelivered"] == null ? null : json["isDelivered"],
createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]), createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]),
chatSource: json["chatSource"] == null ? null : json["chatSource"], chatSource: json["chatSource"] == null ? null : json["chatSource"],
conversationId: json["conversationId"] == null ? null : json["conversationId"], conversationId: json["conversationId"] == null ? null : json["conversationId"],
fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]), fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]),
userChatReplyResponse: json["userChatReplyResponse"] == null ? null : UserChatReplyResponse.fromJson(json["userChatReplyResponse"]), userChatReplyResponse: json["userChatReplyResponse"] == null ? null : UserChatReplyResponse.fromJson(json["userChatReplyResponse"]),
isReplied: false, isReplied: false,
); isImageLoaded: false,
image: null);
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId, "userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId,
@ -138,6 +144,8 @@ class UserChatReplyResponse {
this.targetUserId, this.targetUserId,
this.targetUserName, this.targetUserName,
this.fileTypeResponse, this.fileTypeResponse,
this.isImageLoaded,
this.image,
}); });
int? userChatHistoryId; int? userChatHistoryId;
@ -149,18 +157,21 @@ class UserChatReplyResponse {
int? targetUserId; int? targetUserId;
String? targetUserName; String? targetUserName;
FileTypeResponse? fileTypeResponse; FileTypeResponse? fileTypeResponse;
bool? isImageLoaded;
Uint8List? image;
factory UserChatReplyResponse.fromJson(Map<String, dynamic> json) => UserChatReplyResponse( factory UserChatReplyResponse.fromJson(Map<String, dynamic> json) => UserChatReplyResponse(
userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"], userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"],
chatEventId: json["chatEventId"] == null ? null : json["chatEventId"], chatEventId: json["chatEventId"] == null ? null : json["chatEventId"],
contant: json["contant"] == null ? null : json["contant"], contant: json["contant"] == null ? null : json["contant"],
contantNo: json["contantNo"] == null ? null : json["contantNo"], contantNo: json["contantNo"] == null ? null : json["contantNo"],
fileTypeId: json["fileTypeId"], fileTypeId: json["fileTypeId"],
createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]), createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]),
targetUserId: json["targetUserId"] == null ? null : json["targetUserId"], targetUserId: json["targetUserId"] == null ? null : json["targetUserId"],
targetUserName: json["targetUserName"] == null ? null : json["targetUserName"], targetUserName: json["targetUserName"] == null ? null : json["targetUserName"],
fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]), fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]),
); isImageLoaded: false,
image: null);
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId, "userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId,

@ -125,6 +125,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
userChatHistory, userChatHistory,
receiverUID, receiverUID,
); );
generateConvId(); generateConvId();
} }
@ -177,16 +178,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
try { try {
StreamedResponse response = await ChatApiClient().uploadMedia(userId, file); 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(),
);
} else { } else {
result = []; result = [];
} }
} catch (e) { } catch (e) {
print(e); throw e;
} }
;
return result; return result;
} }
@ -292,8 +291,22 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
data.first.targetUserName = temp.first.currentUserName; data.first.targetUserName = temp.first.currentUserName;
data.first.currentUserId = temp.first.targetUserId; data.first.currentUserId = temp.first.targetUserId;
data.first.currentUserName = temp.first.targetUserName; data.first.currentUserName = temp.first.targetUserName;
if (data.first.fileTypeId == 12 || data.first.fileTypeId == 4 || data.first.fileTypeId == 3) {
data.first.image = await ChatApiClient().downloadURL(fileName: data.first.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg");
}
if (data.first.userChatReplyResponse != null) {
if (data.first.fileTypeResponse != null) {
if (data.first.userChatReplyResponse!.fileTypeId == 12 || data.first.userChatReplyResponse!.fileTypeId == 4 || data.first.userChatReplyResponse!.fileTypeId == 3) {
data.first.userChatReplyResponse!.image =
await ChatApiClient().downloadURL(fileName: data.first.userChatReplyResponse!.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg");
data.first.userChatReplyResponse!.isImageLoaded = true;
}
}
}
} }
userChatHistory.insert(0, data.first); userChatHistory.insert(0, data.first);
var list = [ var list = [
{ {
"userChatHistoryId": data.first.userChatHistoryId, "userChatHistoryId": data.first.userChatHistoryId,
@ -389,7 +402,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
Future<void> sendChatToServer( Future<void> sendChatToServer(
{required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { {required int chatEventId,
required fileTypeId,
required int targetUserId,
required String targetUserName,
required chatReplyId,
required bool isAttachment,
required bool isReply,
Uint8List? image,
required bool isImageLoaded}) async {
Uuid uuid = const Uuid(); Uuid uuid = const Uuid();
var msg = message.text; var msg = message.text;
@ -416,6 +437,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
fileTypeDescription: getFileTypeDescription(getFileExtension(selectedFile.path).toString()), fileTypeDescription: getFileTypeDescription(getFileExtension(selectedFile.path).toString()),
) )
: null, : null,
image: image,
isImageLoaded: isImageLoaded,
); );
userChatHistory.insert(0, data); userChatHistory.insert(0, data);
isFileSelected = false; isFileSelected = false;
@ -442,39 +465,63 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners(); notifyListeners();
} }
if (!isFileSelected && !isMsgReply) { if (!isFileSelected && !isMsgReply) {
print("Normal Text Msg");
if (message.text == null || message.text.isEmpty) { if (message.text == null || message.text.isEmpty) {
return; return;
} }
sendChatToServer(chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: false, chatReplyId: null, isReply: false); sendChatToServer(
} chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: false, chatReplyId: null, isReply: false, isImageLoaded: false, image: null);
} // normal Text msg
if (isFileSelected && !isMsgReply) { if (isFileSelected && !isMsgReply) {
print("Normal Attachment Msg");
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);
logger.d(value);
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,
isImageLoaded: true,
image: selectedFile.readAsBytesSync());
} // normal attachemnt msg
if (!isFileSelected && isMsgReply) { if (!isFileSelected && isMsgReply) {
print("Normal Text To Text Reply");
if (message.text == null || message.text.isEmpty) { if (message.text == null || message.text.isEmpty) {
return; return;
} }
sendChatToServer( sendChatToServer(
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,
isImageLoaded: repliedMsg.first.isImageLoaded!,
image: repliedMsg.first.image);
} // reply msg over image && normal
if (isFileSelected && isMsgReply) { if (isFileSelected && isMsgReply) {
print("Reply With File");
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);
Utils.hideLoading(context); Utils.hideLoading(context);
sendChatToServer( sendChatToServer(
chatEventId: 2, chatEventId: 2,
fileTypeId: getFileType(ext.toString()), fileTypeId: getFileType(ext.toString()),
targetUserId: targetUserId, targetUserId: targetUserId,
targetUserName: targetUserName, targetUserName: targetUserName,
isAttachment: true, isAttachment: true,
chatReplyId: repliedMsg.first.userChatHistoryId, chatReplyId: repliedMsg.first.userChatHistoryId,
isReply: true, isReply: true,
); isImageLoaded: true,
image: selectedFile.readAsBytesSync());
} }
} }

@ -3,161 +3,46 @@ import 'dart:typed_data';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/api_client.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/api/chat/chat_api_client.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';
import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_full_image_preview.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheet.dart';
// todo: @aamir use extension methods, and use correct widgets. // todo: @aamir use extension methods, and use correct widgets.
class ChatBubble extends StatelessWidget { class ChatBubble extends StatelessWidget {
const ChatBubble( ChatBubble({Key? key, required this.dateTime, required this.cItem}) : super(key: key);
{Key? key,
required this.text,
required this.replyText,
required this.isCurrentUser,
required this.isSeen,
required this.isDelivered,
required this.dateTime,
required this.isReplied,
required this.userName,
this.fileTypeID,
this.fileTypeDescription})
: super(key: key);
final String text;
final String replyText;
final bool isCurrentUser;
final bool isSeen;
final bool isDelivered;
final String dateTime; final String dateTime;
final bool isReplied; final SingleUserChatModel cItem;
final String userName;
final int? fileTypeID; bool isCurrentUser = false;
final String? fileTypeDescription; bool isSeen = false;
bool isReplied = false;
int? fileTypeID;
String? fileTypeDescription;
bool isDelivered = false;
String userName = '';
void makeAssign() {
isCurrentUser = cItem.currentUserId == AppState().chatDetails!.response!.id ? true : false;
isSeen = cItem.isSeen == true ? true : false;
isReplied = cItem.userChatReplyResponse != null ? true : false;
fileTypeID = cItem.fileTypeId;
fileTypeDescription = cItem.fileTypeResponse != null ? cItem.fileTypeResponse!.fileTypeDescription : "";
isDelivered = cItem.currentUserId == AppState().chatDetails!.response!.id && cItem.isDelivered == true ? true : false;
userName = AppState().chatDetails!.response!.userName == cItem.currentUserName.toString() ? "You" : cItem.currentUserName.toString();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
makeAssign();
return isCurrentUser ? currentUser(context) : receiptUser(context); return isCurrentUser ? currentUser(context) : receiptUser(context);
return Padding(
// padding: EdgeInsets.zero,
padding: EdgeInsets.only(
left: isCurrentUser ? 110 : 20,
right: isCurrentUser ? 20 : 110,
bottom: 9,
),
child: Align(
alignment: isCurrentUser ? Alignment.centerRight : Alignment.centerLeft,
child: DecoratedBox(
decoration: BoxDecoration(
color: MyColors.white,
gradient: isCurrentUser
? null
: const LinearGradient(
transform: GradientRotation(
.46,
),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: <Color>[
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
),
borderRadius: BorderRadius.circular(
10,
),
),
child: Padding(
padding: EdgeInsets.only(
top: isReplied ? 8 : 5,
right: 8,
left: 8,
bottom: 5,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (isReplied)
ClipRRect(
borderRadius: BorderRadius.circular(
5.0,
),
child: Container(
decoration: BoxDecoration(
border: Border(
left: BorderSide(
width: 6,
color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white,
),
),
color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30),
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
(userName)
.toText12(
color: MyColors.gradiantStartColor,
isBold: false,
)
.paddingOnly(
right: 5,
top: 5,
bottom: 0,
left: 5,
),
replyText
.toText10(
color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5),
isBold: false,
maxlines: 4,
)
.paddingOnly(
right: 5,
top: 5,
bottom: 8,
left: 5,
),
],
),
),
],
),
),
),
if (isReplied) 8.height,
text.toText12(
color: isCurrentUser ? MyColors.grey57Color : MyColors.white,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
dateTime.toText12(
color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7),
),
if (isCurrentUser) 5.width,
if (isCurrentUser)
Icon(
isDelivered ? Icons.done_all : Icons.done_all,
color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor,
size: 14,
),
],
),
],
),
),
),
),
);
} }
Widget currentUser(context) { Widget currentUser(context) {
@ -166,9 +51,7 @@ class ChatBubble extends StatelessWidget {
children: [ children: [
if (isReplied) if (isReplied)
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(5.0),
5.0,
),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
@ -177,29 +60,49 @@ class ChatBubble extends StatelessWidget {
), ),
color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30), color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30),
), ),
child: Column( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: <Widget>[ Column(
(userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5), crossAxisAlignment: CrossAxisAlignment.start,
replyText.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4).paddingOnly(right: 5, top: 5, bottom: 8, left: 5), children: <Widget>[
(userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5),
(cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : "")
.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4)
.paddingOnly(right: 5, top: 5, bottom: 8, left: 5),
],
).expanded,
if (cItem.userChatReplyResponse != null && cItem.userChatReplyResponse!.fileTypeId == 12 ||
cItem.userChatReplyResponse!.fileTypeId == 3 ||
cItem.userChatReplyResponse!.fileTypeId == 4)
ClipRRect(
borderRadius: BorderRadius.circular(
8,
),
child: showImage(
isReplyPreview: true,
fileName: cItem.userChatReplyResponse!.contant!,
fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg")
.paddingOnly(left: 10, right: 10, bottom: 16, top: 16),
)
], ],
).expanded, ),
), ),
).paddingOnly(right: 5, bottom: 7), ).paddingOnly(right: 5, bottom: 7),
if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3) showImage().paddingOnly(right: 5), if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3)
if (fileTypeID != 12 || fileTypeID != 4 || fileTypeID != 3) (text).toText12(), showImage(isReplyPreview: false, fileName: cItem.contant!, fileTypeDescription: cItem.fileTypeResponse!.fileTypeDescription).paddingOnly(right: 5).onPress(() {
showDialog(context: context, builder: (index) => ChatImagePreviewScreen(imgTitle: cItem.contant!, img: cItem.image!));
}),
cItem.contant!.toText12(),
Align( Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
dateTime.toText10(color: MyColors.grey41Color.withOpacity(.5)), dateTime.toText10(
7.width, color: MyColors.grey41Color.withOpacity(.5),
Icon(
isDelivered ? Icons.done_all : Icons.done_all,
color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor,
size: 14,
), ),
7.width,
Icon(isDelivered ? Icons.done_all : Icons.done_all, color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor, size: 14),
], ],
), ),
), ),
@ -227,27 +130,45 @@ class ChatBubble extends StatelessWidget {
children: [ children: [
if (isReplied) if (isReplied)
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(5.0),
5.0,
),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border( border: Border(left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white)),
left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white),
),
color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30), color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30),
), ),
child: Column( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: <Widget>[ Column(
(userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5), crossAxisAlignment: CrossAxisAlignment.start,
replyText.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4).paddingOnly(right: 5, top: 5, bottom: 8, left: 5), children: <Widget>[
(userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5),
(cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : "")
.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4)
.paddingOnly(right: 5, top: 5, bottom: 8, left: 5),
],
).expanded,
if (cItem.userChatReplyResponse != null && cItem.userChatReplyResponse!.fileTypeId == 12 ||
cItem.userChatReplyResponse!.fileTypeId == 3 ||
cItem.userChatReplyResponse!.fileTypeId == 4)
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: showImage(
isReplyPreview: true,
fileName: cItem.userChatReplyResponse!.contant!,
fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg")
.paddingOnly(left: 10, right: 10, bottom: 16, top: 16),
)
], ],
).expanded, ),
), ),
).paddingOnly(right: 5, bottom: 7), ).paddingOnly(right: 5, bottom: 7),
if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3) showImage().paddingOnly(right: 5) else (text).toText12(color: Colors.white), if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3)
showImage(isReplyPreview: false, fileName: cItem.contant!, fileTypeDescription: cItem.fileTypeResponse!.fileTypeDescription ?? "image/jpg").paddingOnly(right: 5).onPress(() {
showDialog(context: context, builder: (index) => ChatImagePreviewScreen(imgTitle: cItem.contant!, img: cItem.image!));
})
else
(cItem.contant! ?? "").toText12(color: Colors.white),
Align( Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: dateTime.toText10( child: dateTime.toText10(
@ -259,25 +180,41 @@ class ChatBubble extends StatelessWidget {
).paddingOnly(right: MediaQuery.of(context).size.width * 0.3); ).paddingOnly(right: MediaQuery.of(context).size.width * 0.3);
} }
Widget showImage() { Widget showImage({required bool isReplyPreview, required String fileName, required String fileTypeDescription}) {
return FutureBuilder<Uint8List>( if (cItem.isImageLoaded! && cItem.image != null) {
future: ChatApiClient().downloadURL(fileName: text, fileTypeDescription: fileTypeDescription!), return Image.memory(
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) { cItem.image!,
if (snapshot.connectionState != ConnectionState.waiting) { height: isReplyPreview ? 32 : 140,
if (snapshot.data == null) { width: isReplyPreview ? 32 : 227,
return (text).toText12(color: Colors.white); fit: BoxFit.cover,
);
} else {
return FutureBuilder<Uint8List>(
future: ChatApiClient().downloadURL(fileName: fileName, fileTypeDescription: fileTypeDescription),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState != ConnectionState.waiting) {
if (snapshot.data == null) {
return SizedBox();
} else {
//data = image;
cItem.image = snapshot.data;
cItem.isImageLoaded = true;
return Image.memory(
snapshot.data,
height: isReplyPreview ? 32 : 140,
width: isReplyPreview ? 32 : 227,
fit: BoxFit.cover,
);
}
} else { } else {
return Image.memory( return SizedBox(
snapshot.data, height: isReplyPreview ? 32 : 140,
height: 140, width: isReplyPreview ? 32 : 227,
width: 227, child: const Center(child: CircularProgressIndicator()),
fit: BoxFit.cover,
); );
} }
} else { },
return const SizedBox(height: 140, width: 227, child: Center(child: CircularProgressIndicator())); );
} }
},
);
} }
} }

@ -12,6 +12,7 @@ import 'package:mohem_flutter_app/extensions/widget_extensions.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/call.dart'; import 'package:mohem_flutter_app/models/chat/call.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.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';
@ -115,16 +116,8 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
return SwipeTo( return SwipeTo(
iconColor: MyColors.lightGreenColor, iconColor: MyColors.lightGreenColor,
child: ChatBubble( child: ChatBubble(
text: m.userChatHistory[i].contant.toString(),
replyText: m.userChatHistory[i].userChatReplyResponse != null ? m.userChatHistory[i].userChatReplyResponse!.contant.toString() : "",
isSeen: m.userChatHistory[i].isSeen == true ? true : false,
isCurrentUser: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id ? true : false,
isDelivered: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id && m.userChatHistory[i].isDelivered == true ? true : false,
dateTime: m.dateFormte(m.userChatHistory[i].createdDate!), dateTime: m.dateFormte(m.userChatHistory[i].createdDate!),
isReplied: m.userChatHistory[i].userChatReplyResponse != null ? true : false, cItem: m.userChatHistory[i],
userName: AppState().chatDetails!.response!.userName == m.userChatHistory[i].currentUserName.toString() ? "You" : m.userChatHistory[i].currentUserName.toString(),
fileTypeID: m.userChatHistory[i].fileTypeId,
fileTypeDescription: m.userChatHistory[i].fileTypeResponse!.fileTypeDescription,
), ),
onRightSwipe: () { onRightSwipe: () {
m.chatReply( m.chatReply(
@ -159,6 +152,8 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
], ],
).expanded, ).expanded,
12.width, 12.width,
if (m.isMsgReply && m.repliedMsg.isNotEmpty) showReplyImage(m.repliedMsg),
12.width,
const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe), const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe),
], ],
), ),
@ -224,6 +219,22 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
); );
} }
Widget showReplyImage(List<SingleUserChatModel> data) {
if (data.first.isImageLoaded! && data.first.image != null) {
return ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Image.memory(
data.first.image!,
height: 43,
width: 43,
fit: BoxFit.cover,
),
);
} else {
return const SizedBox();
}
}
void makeCall({required String callType, required HubConnection con}) async { void makeCall({required String callType, required HubConnection con}) async {
print("================== Make call Triggered ============================"); print("================== Make call Triggered ============================");
Map<String, dynamic> json = { Map<String, dynamic> json = {

@ -0,0 +1,40 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
class ChatImagePreviewScreen extends StatelessWidget {
const ChatImagePreviewScreen({Key? key, required this.imgTitle, required this.img}) : super(key: key);
final String imgTitle;
final Uint8List img;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.of(context).pop();
},
child: Dialog(
backgroundColor: Colors.transparent,
insetPadding: const EdgeInsets.all(10),
child: Stack(
alignment: Alignment.center,
children: [
Image.memory(
img,
fit: BoxFit.cover,
).paddingAll(10),
const Positioned(
right: 0,
top: 0,
child: Icon(Icons.cancel, color: MyColors.redA3Color, size: 35),
)
],
),
),
);
}
}
Loading…
Cancel
Save