diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 6bb88970..3cab3aa3 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -5,11 +5,12 @@ class URLs { // static const host1 = "https://atomsm.hmg.com"; // production url // static const host1 = "https://atomsmdev.hmg.com"; // local DEV url - // static const host1 = "https://atomsmuat.hmg.com"; // local UAT url - static const host1 = "http://10.201.111.125:9495"; // temporary Server UAT url + static const host1 = "https://atomsmuat.hmg.com"; // local UAT url + // static const host1 = "http://10.201.111.125:9495"; // temporary Server UAT url - // static String _baseUrl = "$_host/mobile"; - static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis + static String _baseUrl = "$_host/mobile"; + + // static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis // static final String _baseUrl = "$_host/v4/mobile"; // for asset inventory on UAT // static final String _baseUrl = "$_host/mobile"; // host local UAT // static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index eabd9fce..a8fd4f51 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -6,6 +6,21 @@ extension StringExtensions on String { void get showToast => Fluttertoast.showToast(msg: this); + String get chatMsgTime { + DateTime dateTime = DateTime.parse(this); + return DateFormat('hh:mm a').format(dateTime); + } + + String get chatMsgDate { + DateTime dateTime = DateTime.parse(this); + return DateFormat('EEE dd MMM').format(dateTime); + } + + String get chatMsgDateWithYear { + DateTime dateTime = DateTime.parse(this); + return DateFormat('EEE dd MMM yyyy').format(dateTime); + } + String get toServiceRequestCardFormat { DateTime dateTime = DateTime.parse(this); return "${DateFormat('dd MMM, yyyy').format(dateTime)}\n${DateFormat('hh:mm a').format(dateTime)}"; diff --git a/lib/modules/cx_module/chat/chat_page.dart b/lib/modules/cx_module/chat/chat_page.dart index 75cb2fba..800ebc46 100644 --- a/lib/modules/cx_module/chat/chat_page.dart +++ b/lib/modules/cx_module/chat/chat_page.dart @@ -13,6 +13,8 @@ import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; +import 'model/user_chat_history_model.dart'; + enum ChatState { idle, voiceRecordingStarted, voiceRecordingCompleted } class ChatPage extends StatefulWidget { @@ -105,7 +107,7 @@ class _ChatPageState extends State { child: Row( children: [ Text( - "Engineer: Mahmoud Shrouf", + chatProvider.recipient?.userName ?? "", overflow: TextOverflow.ellipsis, maxLines: 2, style: AppTextStyles.bodyText2.copyWith(color: AppColor.white10), @@ -123,18 +125,16 @@ class _ChatPageState extends State { ), ), Container( - // width: double.infinity, color: AppColor.neutral100, - child: !chatProvider.userChatHistoryLoading + child: chatProvider.userChatHistoryLoading ? ListView( padding: const EdgeInsets.all(16), children: [ - recipientMsgCard(true, "Please let me know what is the issue? Please let me know what is the issue?", loading: true), - recipientMsgCard(false, "testing", loading: true), - recipientMsgCard(false, "testing testing testing", loading: true), - // dateCard("Mon 27 Oct",), - senderMsgCard(true, "Please let me know what is the issue? Please let me know what is the issue?", loading: true), - senderMsgCard(false, "Please let me know what is the issue?", loading: true), + recipientMsgCard(true, null, msg: "Please let me know what is the issue? Please let me know what is the issue?", loading: true), + recipientMsgCard(false, null, msg: "testing", loading: true), + recipientMsgCard(false, null, msg: "testing testing testing", loading: true), + senderMsgCard(true, null, msg: "Please let me know what is the issue? Please let me know what is the issue?", loading: true), + senderMsgCard(false, null, msg: "Please let me know what is the issue?", loading: true), ], ) : chatProvider.chatResponseList.isEmpty @@ -145,7 +145,29 @@ class _ChatPageState extends State { style: AppTextStyles.heading6.copyWith(color: AppColor.neutral50.withOpacity(.5), fontWeight: FontWeight.w500), ).center : ListView.builder( - itemBuilder: (cxt, index) => recipientMsgCard(true, chatProvider.chatResponseList[index].content ?? ""), itemCount: chatProvider.chatResponseList.length)) + padding: const EdgeInsets.all(16), + reverse: true, + itemBuilder: (cxt, index) { + final currentMessage = chatProvider.chatResponseList[index]; + final bool showSenderName = (index == chatProvider.chatResponseList.length - 1) || (currentMessage.userId != chatProvider.chatResponseList[index + 1].userId); + bool isSender = chatProvider.chatResponseList[index].userId == chatProvider.sender?.userId!; + bool showDateHeader = false; + if (index == chatProvider.chatResponseList.length - 1) { + showDateHeader = true; + } else { + final nextMessage = chatProvider.chatResponseList[index + 1]; + final currentDate = DateUtils.dateOnly(DateTime.parse(currentMessage.createdAt!)); + final nextDate = DateUtils.dateOnly(DateTime.parse(nextMessage.createdAt!)); + if (!currentDate.isAtSameMomentAs(nextDate)) { + showDateHeader = true; + } + } + return Column(mainAxisSize: MainAxisSize.min, children: [ + if (showDateHeader) dateCard(currentMessage.createdAt?.chatMsgDate ?? ""), + isSender ? senderMsgCard(showSenderName, chatProvider.chatResponseList[index]) : recipientMsgCard(showSenderName, chatProvider.chatResponseList[index]) + ]); + }, + itemCount: chatProvider.chatResponseList.length)) .expanded, if (!widget.readOnly) ...[ Divider(height: 1, thickness: 1, color: const Color(0xff767676).withOpacity(.11)), @@ -428,6 +450,9 @@ class _ChatPageState extends State { // ), IconButton( + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + hoverColor: Colors.transparent, onPressed: () { chatProvider.sendTextMessage(textEditingController.text).then((success) { if (success) { @@ -470,12 +495,12 @@ class _ChatPageState extends State { .center; } - Widget senderMsgCard(bool showHeader, String msg, {bool loading = false}) { + Widget senderMsgCard(bool showHeader, ChatResponse? chatResponse, {bool loading = false, String msg = ""}) { Widget senderHeader = Row( mainAxisSize: MainAxisSize.min, children: [ Text( - "Jeniffer Jeniffer Jeniffer(Me)", + "${chatResponse?.userName ?? "User"}(Me)", overflow: TextOverflow.ellipsis, maxLines: 1, style: AppTextStyles.bodyText.copyWith(color: AppColor.neutral50, fontWeight: FontWeight.w600), @@ -484,7 +509,7 @@ class _ChatPageState extends State { Container( height: 26, width: 26, - decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.grey), + decoration: const BoxDecoration(shape: BoxShape.circle, color: Colors.grey), ).toShimmer(context: context, isShow: loading), ], ); @@ -500,7 +525,7 @@ class _ChatPageState extends State { padding: const EdgeInsets.all(8), margin: const EdgeInsets.only(right: 26 + 8, left: 26 + 8), decoration: BoxDecoration( - color: AppColor.white10, + color: loading ? Colors.transparent : AppColor.white10, borderRadius: BorderRadius.circular(6), ), child: Column( @@ -508,11 +533,12 @@ class _ChatPageState extends State { crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( - msg, + chatResponse?.content ?? msg, style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120), ).toShimmer(context: context, isShow: loading), + if (loading) 4.height, Text( - "2:00 PM", + chatResponse?.createdAt?.chatMsgTime ?? "2:00 PM", style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.neutral50.withOpacity(0.5)), ).toShimmer(context: context, isShow: loading), ], @@ -522,18 +548,28 @@ class _ChatPageState extends State { ); } - Widget recipientMsgCard(bool showHeader, String msg, {bool loading = false}) { + Widget recipientMsgCard(bool showHeader, ChatResponse? chatResponse, {bool loading = false, String msg = ""}) { + String extraSpaces = ""; + int length = 0; + if ((chatResponse?.content ?? "").isNotEmpty) { + if (chatResponse!.content!.length < 8) { + length = 8 - chatResponse.content!.length; + } + } + + String contentMsg = chatResponse?.content == null ? msg : chatResponse!.content! + extraSpaces; + print("'$contentMsg'"); Widget recipientHeader = Row( mainAxisSize: MainAxisSize.min, children: [ Container( height: 26, width: 26, - decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.grey), + decoration: const BoxDecoration(shape: BoxShape.circle, color: Colors.grey), ).toShimmer(context: context, isShow: loading), 8.width, Text( - "Mahmoud Shrouf", + chatResponse?.userName ?? "User", overflow: TextOverflow.ellipsis, maxLines: 1, style: AppTextStyles.bodyText.copyWith(color: AppColor.neutral50, fontWeight: FontWeight.w600), @@ -552,7 +588,7 @@ class _ChatPageState extends State { padding: const EdgeInsets.all(8), margin: const EdgeInsets.only(left: 26 + 8, right: 26 + 8), decoration: BoxDecoration( - color: AppColor.primary10, + color: loading ? Colors.transparent : AppColor.primary10, borderRadius: BorderRadius.circular(6), ), child: Column( @@ -560,19 +596,20 @@ class _ChatPageState extends State { crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( - msg, + contentMsg, style: AppTextStyles.bodyText2.copyWith(color: AppColor.white10), - ).toShimmer(context: context, isShow: loading), + ).paddingOnly(end: 6 * length).toShimmer(context: context, isShow: loading), + if (loading) 4.height, Align( alignment: Alignment.centerRight, widthFactor: 1, child: Text( - "2:00 PM", + chatResponse?.createdAt?.chatMsgTime ?? "2:00 PM", style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.white10), ), - ), + ).toShimmer(context: context, isShow: loading), ], - ).toShimmer(context: context, isShow: loading)), + )), ], ), ); diff --git a/lib/modules/cx_module/chat/chat_provider.dart b/lib/modules/cx_module/chat/chat_provider.dart index 48438375..94dcad71 100644 --- a/lib/modules/cx_module/chat/chat_provider.dart +++ b/lib/modules/cx_module/chat/chat_provider.dart @@ -119,6 +119,9 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { List chatResponseList = []; + Participants? sender; + Participants? recipient; + void reset() { chatLoginTokenLoading = false; chatParticipantLoading = false; @@ -126,6 +129,8 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { chatLoginResponse = null; chatParticipantModel = null; userChatHistory = null; + sender = null; + recipient = null; ChatApiClient().chatLoginResponse = null; } @@ -152,7 +157,18 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { Future loadChatHistory(int moduleId, int requestId, String myId, String? assigneeEmployeeNumber) async { userChatHistoryLoading = true; notifyListeners(); - chatParticipantModel = await ChatApiClient().loadParticipants(moduleId, requestId, assigneeEmployeeNumber); + try { + chatParticipantModel = await ChatApiClient().loadParticipants(moduleId, requestId, assigneeEmployeeNumber); + } catch (ex) { + userChatHistoryLoading = false; + notifyListeners(); + return; + } + + try { + sender = chatParticipantModel?.participants?.singleWhere((participant) => participant.employeeNumber == myId); + recipient = chatParticipantModel?.participants?.singleWhere((participant) => participant.employeeNumber == assigneeEmployeeNumber); + } catch (e) {} userChatHistory = await ChatApiClient().loadChatHistory(moduleId, requestId, myId, "12"); chatResponseList = userChatHistory?.response ?? []; @@ -168,6 +184,9 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { if (chatResponse != null) { returnStatus = true; chatResponseList.add(chatResponse); + try { + chatResponseList.sort((a, b) => b.createdAt!.compareTo(a.createdAt!)); + } catch (ex) {} } messageIsSending = false; notifyListeners();