1 to 1 chat ui completed for text message, with 2 users.

design_3.0_cx_module
Sikander Saleem 2 months ago
parent a902204ff1
commit db1e7ea0bd

@ -18,7 +18,7 @@ extension StringExtensions on String {
String get chatMsgDateWithYear { String get chatMsgDateWithYear {
DateTime dateTime = DateTime.parse(this); DateTime dateTime = DateTime.parse(this);
return DateFormat('EEE dd MMM yyyy').format(dateTime); return DateFormat('EEE dd MMM, yyyy').format(dateTime);
} }
String get toServiceRequestCardFormat { String get toServiceRequestCardFormat {

@ -78,18 +78,18 @@ class ChatApiClient {
Response response = await ApiClient().postJsonForResponse( Response response = await ApiClient().postJsonForResponse(
"${URLs.chatHubUrlApi}/UserChatHistory/GetUserChatHistory/$myId/$otherId/0", {"moduleCode": moduleId.toString(), "referenceId": referenceId.toString()}, "${URLs.chatHubUrlApi}/UserChatHistory/GetUserChatHistory/$myId/$otherId/0", {"moduleCode": moduleId.toString(), "referenceId": referenceId.toString()},
token: chatLoginResponse!.token); token: chatLoginResponse!.token);
try { // try {
if (response.statusCode == 200) { if (response.statusCode == 200) {
List data = jsonDecode(response.body); List data = jsonDecode(response.body);
return data.map((elemet) => ChatHistoryResponse.fromJson(elemet)).toList(); return data.map((elemet) => ChatHistoryResponse.fromJson(elemet)).toList();
// return UserChatHistoryModel.fromJson(jsonDecode(response.body)); // return UserChatHistoryModel.fromJson(jsonDecode(response.body));
} else { } else {
return [];
}
} catch (ex) {
return []; return [];
} }
// } catch (ex) {
// return [];
// }
} }
Future<ChatResponse?> sendTextMessage(String message, int conversationId) async { Future<ChatResponse?> sendTextMessage(String message, int conversationId) async {

@ -59,8 +59,17 @@ class _ChatPageState extends State<ChatPage> {
void getChatToken() { void getChatToken() {
String assigneeEmployeeNumber = Provider.of<ServiceRequestDetailProvider>(context, listen: false).currentWorkOrder?.data?.assignedEmployee?.employeeId ?? ""; String assigneeEmployeeNumber = Provider.of<ServiceRequestDetailProvider>(context, listen: false).currentWorkOrder?.data?.assignedEmployee?.employeeId ?? "";
Provider.of<ChatProvider>(context, listen: false).getUserAutoLoginToken(widget.moduleId, widget.requestId, widget.title, String myEmployeeId = context.userProvider.user!.username!;
Provider.of<ServiceRequestDetailProvider>(context, listen: false).currentWorkOrder!.data!.workOrderContactPerson.first.employeeId!, assigneeEmployeeNumber);
// String sender = context.settingProvider.username;
String receiver = context.userProvider.isNurse
? assigneeEmployeeNumber
: (context.userProvider.isEngineer ? Provider.of<ServiceRequestDetailProvider>(context, listen: false).currentWorkOrder!.data!.workOrderContactPerson.first.employeeId! : "");
// assigneeEmployeeNumber
// Provider.of<ChatProvider>(context, listen: false).getUserAutoLoginToken(widget.moduleId, widget.requestId, widget.title, myEmployeeId, assigneeEmployeeNumber);
Provider.of<ChatProvider>(context, listen: false).getUserAutoLoginToken(widget.moduleId, widget.requestId, widget.title, myEmployeeId, receiver);
} }
@override @override
@ -152,21 +161,22 @@ class _ChatPageState extends State<ChatPage> {
reverse: true, reverse: true,
itemBuilder: (cxt, index) { itemBuilder: (cxt, index) {
final currentMessage = chatProvider.chatResponseList[index]; final currentMessage = chatProvider.chatResponseList[index];
final bool showSenderName = (index == chatProvider.chatResponseList.length - 1) || (currentMessage.userId != chatProvider.chatResponseList[index + 1].userId); final bool showSenderName =
bool isSender = chatProvider.chatResponseList[index].userId == chatProvider.sender?.userId!; (index == chatProvider.chatResponseList.length - 1) || (currentMessage.currentUserId != chatProvider.chatResponseList[index + 1].currentUserId);
bool isSender = chatProvider.chatResponseList[index].currentUserId == chatProvider.sender?.userId!;
bool showDateHeader = false; bool showDateHeader = false;
if (index == chatProvider.chatResponseList.length - 1) { if (index == chatProvider.chatResponseList.length - 1) {
showDateHeader = true; showDateHeader = true;
} else { } else {
final nextMessage = chatProvider.chatResponseList[index + 1]; final nextMessage = chatProvider.chatResponseList[index + 1];
final currentDate = DateUtils.dateOnly(DateTime.parse(currentMessage.createdAt!)); final currentDate = DateUtils.dateOnly(DateTime.parse(currentMessage.createdDate!));
final nextDate = DateUtils.dateOnly(DateTime.parse(nextMessage.createdAt!)); final nextDate = DateUtils.dateOnly(DateTime.parse(nextMessage.createdDate!));
if (!currentDate.isAtSameMomentAs(nextDate)) { if (!currentDate.isAtSameMomentAs(nextDate)) {
showDateHeader = true; showDateHeader = true;
} }
} }
return Column(mainAxisSize: MainAxisSize.min, children: [ return Column(mainAxisSize: MainAxisSize.min, children: [
if (showDateHeader) dateCard(currentMessage.createdAt?.chatMsgDate ?? ""), if (showDateHeader) dateCard(currentMessage.createdDate?.chatMsgDateWithYear ?? ""),
isSender ? senderMsgCard(showSenderName, chatProvider.chatResponseList[index]) : recipientMsgCard(showSenderName, chatProvider.chatResponseList[index]) isSender ? senderMsgCard(showSenderName, chatProvider.chatResponseList[index]) : recipientMsgCard(showSenderName, chatProvider.chatResponseList[index])
]); ]);
}, },
@ -200,15 +210,6 @@ class _ChatPageState extends State<ChatPage> {
suffixIconConstraints: const BoxConstraints(), suffixIconConstraints: const BoxConstraints(),
hintText: "Type your message here...", hintText: "Type your message here...",
hintStyle: AppTextStyles.bodyText.copyWith(color: const Color(0xffCCCCCC)), hintStyle: AppTextStyles.bodyText.copyWith(color: const Color(0xffCCCCCC)),
// suffixIcon: Row(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.end,
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
//
// 8.width,
// ],
// )
), ),
).expanded, ).expanded,
IconButton( IconButton(
@ -498,12 +499,12 @@ class _ChatPageState extends State<ChatPage> {
.center; .center;
} }
Widget senderMsgCard(bool showHeader, ChatResponse? chatResponse, {bool loading = false, String msg = ""}) { Widget senderMsgCard(bool showHeader, ChatHistoryResponse? chatResponse, {bool loading = false, String msg = ""}) {
Widget senderHeader = Row( Widget senderHeader = Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
"${chatResponse?.userName ?? "User"}(Me)", "${chatResponse?.currentUserName ?? "User"}(Me)",
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 1, maxLines: 1,
style: AppTextStyles.bodyText.copyWith(color: AppColor.neutral50, fontWeight: FontWeight.w600), style: AppTextStyles.bodyText.copyWith(color: AppColor.neutral50, fontWeight: FontWeight.w600),
@ -524,44 +525,60 @@ class _ChatPageState extends State<ChatPage> {
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
if (showHeader) ...[senderHeader, 4.height] else 8.height, if (showHeader) ...[senderHeader, 4.height] else 8.height,
Container( Row(
padding: const EdgeInsets.all(8), mainAxisSize: MainAxisSize.min,
margin: const EdgeInsets.only(right: 26 + 8, left: 26 + 8), crossAxisAlignment: CrossAxisAlignment.end,
decoration: BoxDecoration( children: [
color: loading ? Colors.transparent : AppColor.white10, Flexible(
borderRadius: BorderRadius.circular(6), fit: FlexFit.loose,
child: Container(
padding: const EdgeInsets.all(8),
margin: const EdgeInsets.only(right: 8, left: 26 + 8),
decoration: BoxDecoration(
color: loading ? Colors.transparent : AppColor.white10,
borderRadius: BorderRadius.circular(6),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
chatResponse?.contant ?? msg,
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
).toShimmer(context: context, isShow: loading),
if (loading) 4.height,
Text(
chatResponse?.createdDate?.chatMsgTime ?? "2:00 PM",
style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.neutral50.withOpacity(0.5)),
).toShimmer(context: context, isShow: loading),
],
)),
), ),
child: Column( if (chatResponse != null)
mainAxisSize: MainAxisSize.min, if (chatResponse.isSeen!)
crossAxisAlignment: CrossAxisAlignment.end, "chat_seen".toSvgAsset(width: 16, height: 16)
children: [ else if (chatResponse.isDelivered!)
Text( "chat_delivered".toSvgAsset(width: 16, height: 16)
chatResponse?.content ?? msg, else
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120), "chat_sent".toSvgAsset(width: 16, height: 16),
).toShimmer(context: context, isShow: loading), (26 + 8).width,
if (loading) 4.height, ],
Text( ),
chatResponse?.createdAt?.chatMsgTime ?? "2:00 PM",
style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.neutral50.withOpacity(0.5)),
).toShimmer(context: context, isShow: loading),
],
)),
], ],
), ),
); );
} }
Widget recipientMsgCard(bool showHeader, ChatResponse? chatResponse, {bool loading = false, String msg = ""}) { Widget recipientMsgCard(bool showHeader, ChatHistoryResponse? chatResponse, {bool loading = false, String msg = ""}) {
String extraSpaces = ""; String extraSpaces = "";
int length = 0; int length = 0;
if ((chatResponse?.content ?? "").isNotEmpty) { if ((chatResponse?.contant ?? "").isNotEmpty) {
if (chatResponse!.content!.length < 8) { if (chatResponse!.contant!.length < 8) {
length = 8 - chatResponse.content!.length; length = 8 - chatResponse.contant!.length;
} }
} }
String contentMsg = chatResponse?.content == null ? msg : chatResponse!.content! + extraSpaces; String contentMsg = chatResponse?.contant == null ? msg : chatResponse!.contant! + extraSpaces;
print("'$contentMsg'");
Widget recipientHeader = Row( Widget recipientHeader = Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -572,7 +589,7 @@ class _ChatPageState extends State<ChatPage> {
).toShimmer(context: context, isShow: loading), ).toShimmer(context: context, isShow: loading),
8.width, 8.width,
Text( Text(
chatResponse?.userName ?? "User", chatResponse?.currentUserName ?? "User",
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 1, maxLines: 1,
style: AppTextStyles.bodyText.copyWith(color: AppColor.neutral50, fontWeight: FontWeight.w600), style: AppTextStyles.bodyText.copyWith(color: AppColor.neutral50, fontWeight: FontWeight.w600),
@ -607,7 +624,7 @@ class _ChatPageState extends State<ChatPage> {
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
widthFactor: 1, widthFactor: 1,
child: Text( child: Text(
chatResponse?.createdAt?.chatMsgTime ?? "2:00 PM", chatResponse?.createdDate?.chatMsgTime ?? "2:00 PM",
style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.white10), style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.white10),
), ),
).toShimmer(context: context, isShow: loading), ).toShimmer(context: context, isShow: loading),

@ -120,7 +120,7 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin {
bool messageIsSending = false; bool messageIsSending = false;
List<ChatResponse> chatResponseList = []; List<ChatHistoryResponse> chatResponseList = [];
Participants? sender; Participants? sender;
Participants? recipient; Participants? recipient;
@ -137,16 +137,16 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin {
ChatApiClient().chatLoginResponse = null; ChatApiClient().chatLoginResponse = null;
} }
Future<void> getUserAutoLoginToken(int moduleId, int requestId, String title, String employeeNumber, String assigneeEmployeeNumber) async { Future<void> getUserAutoLoginToken(int moduleId, int requestId, String title, String myId, String assigneeEmployeeNumber) async {
reset(); reset();
chatLoginTokenLoading = true; chatLoginTokenLoading = true;
notifyListeners(); notifyListeners();
chatLoginResponse = await ChatApiClient().getChatLoginToken(moduleId, requestId, title, employeeNumber); chatLoginResponse = await ChatApiClient().getChatLoginToken(moduleId, requestId, title, myId);
chatLoginTokenLoading = false; chatLoginTokenLoading = false;
chatParticipantLoading = true; chatParticipantLoading = true;
notifyListeners(); notifyListeners();
// loadParticipants(moduleId, requestId); // loadParticipants(moduleId, requestId);
loadChatHistory(moduleId, requestId, employeeNumber, assigneeEmployeeNumber); loadChatHistory(moduleId, requestId, myId, assigneeEmployeeNumber);
} }
// Future<void> loadParticipants(int moduleId, int requestId) async { // Future<void> loadParticipants(int moduleId, int requestId) async {
@ -173,8 +173,8 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin {
recipient = chatParticipantModel?.participants?.singleWhere((participant) => participant.employeeNumber == assigneeEmployeeNumber); recipient = chatParticipantModel?.participants?.singleWhere((participant) => participant.employeeNumber == assigneeEmployeeNumber);
} catch (e) {} } catch (e) {}
userChatHistory = await ChatApiClient().loadChatHistory(moduleId, requestId, myId, assigneeEmployeeNumber); userChatHistory = await ChatApiClient().loadChatHistory(moduleId, requestId, myId, assigneeEmployeeNumber);
// chatResponseList = userChatHistory?.response ?? []; chatResponseList = userChatHistory ?? [];
chatResponseList.sort((a, b) => b.createdDate!.compareTo(a.createdDate!));
userChatHistoryLoading = false; userChatHistoryLoading = false;
notifyListeners(); notifyListeners();
} }
@ -186,9 +186,9 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin {
ChatResponse? chatResponse = await ChatApiClient().sendTextMessage(message, chatParticipantModel!.id!); ChatResponse? chatResponse = await ChatApiClient().sendTextMessage(message, chatParticipantModel!.id!);
if (chatResponse != null) { if (chatResponse != null) {
returnStatus = true; returnStatus = true;
chatResponseList.add(chatResponse); // chatResponseList.add(chatResponse);
try { try {
chatResponseList.sort((a, b) => b.createdAt!.compareTo(a.createdAt!)); chatResponseList.sort((a, b) => b.createdDate!.compareTo(a.createdDate!));
} catch (ex) {} } catch (ex) {}
} }
messageIsSending = false; messageIsSending = false;

Loading…
Cancel
Save