From 55ff08c3f3f3e813f7258e30ea796d099e58d9fe Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Sun, 13 Nov 2022 13:50:35 +0300 Subject: [PATCH] Chat Favorite Screen & Fixes --- assets/langs/ar-SA.json | 5 +- assets/langs/en-US.json | 5 +- lib/api/chat/chat_provider_model.dart | 45 ++-- lib/classes/consts.dart | 4 +- lib/config/routes.dart | 5 +- lib/generated/locale_keys.g.dart | 2 + lib/ui/chat/chat_bubble.dart | 4 +- lib/ui/chat/chat_detailed_screen.dart | 3 +- lib/ui/chat/chat_home.dart | 275 +++++++------------------ lib/ui/chat/chat_home_screen.dart | 226 ++++++++++++++++++++ lib/ui/chat/favorite_users_screen.dart | 102 +++++++++ lib/widgets/image_picker.dart | 2 +- 12 files changed, 445 insertions(+), 233 deletions(-) create mode 100644 lib/ui/chat/chat_home_screen.dart create mode 100644 lib/ui/chat/favorite_users_screen.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index f72ea36..bdec4f0 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -498,5 +498,8 @@ "verification": "تَحَقّق", "resend": "إعادة إرسال", "codeExpire": "انتهت صلاحية رمز التحقق", - "typeheretoreply": "اكتب هنا للرد" + "typeheretoreply": "اكتب هنا للرد", + "favorite" : "مفضل", + "searchfromchat": "البحث من الدردشة" + } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index e0b9019..1cd1a33 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -498,5 +498,8 @@ "resend": "Resend", "codeExpire": "The verification code has been expired", "allQuestionsCorrect": "You have answered all questions correct", - "typeheretoreply": "Type here to reply" + "typeheretoreply": "Type here to reply", + "favorite" : "Favorite", + "searchfromchat": "Search from chat" + } \ No newline at end of file diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index b85aa85..4e79374 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -33,6 +33,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { String sFileType = ""; bool isMsgReply = false; List repliedMsg = []; + List favUsersList = []; int paginationVal = 0; Future getUserAutoLoginToken() async { @@ -60,25 +61,26 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { token: AppState().chatDetails!.response!.token, ); - logger.d(AppState().chatDetails!.response!.token); + //logger.d(AppState().chatDetails!.response!.token); ChatUserModel recentChat = userToList(response.body); Response favRes = await ApiClient().getJsonForResponse( "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatFavoriteUsers}${AppState().chatDetails!.response!.id}", token: AppState().chatDetails!.response!.token, ); - print("============================== Fav Response ====================================="); - ChatUserModel favUsersList = userToList(favRes.body); - for (var user in recentChat.response!) { - for (var favUser in favUsersList.response!) { - logger.d(favUser.isFav); - if (user.id == favUser.id) { - user.isFav = favUser.isFav; + ChatUserModel favUList = userToList(favRes.body); + if (favUList.response != null) { + favUsersList = favUList.response!; + for (dynamic user in recentChat.response!) { + for (dynamic favUser in favUList.response!) { + if (user.id == favUser.id) { + user.isFav = favUser.isFav; + } } } } - pChatHistory = recentChat.response; + pChatHistory!.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase()!.compareTo(b.userName!.toLowerCase()!)); searchedChats = pChatHistory; isLoading = false; notifyListeners(); @@ -87,7 +89,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void getSingleUserChatHistory({required String senderUID, required int receiverUID, required bool loadMore}) async { isLoading = true; if (!loadMore) paginationVal = 0; - logger.d(paginationVal); isChatScreenActive = true; Response response = await ApiClient().getJsonForResponse( "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal", @@ -150,24 +151,16 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ({String? connectionId}) {}, ); if (hubConnection.state != HubConnectionState.Connected) { + print("================= Connection Established =========================="); await hubConnection.start(); hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); - hubConnection.on("OnUserTypingAsync", onUserTyping); + //hubConnection.on("OnUserTypingAsync", onUserTyping); // hubConnection.on("OnUserCountAsync", userCountAsync); - // hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); + hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); - } else { - hubConnection.on("OnUpdateUserStatusAsync", changeStatus); - hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); - - hubConnection.on("OnUserTypingAsync", onUserTyping); - // hubConnection.on("OnUserCountAsync", userCountAsync); - // hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); - // hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); - hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); } isLoading = false; notifyListeners(); @@ -189,8 +182,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void userCountAsync(List? args) { List items = args!.toList(); - print("---------------------------------User Count Async -------------------------------------"); - logger.d(items); + //print("---------------------------------User Count Async -------------------------------------"); + //logger.d(items); // for (var user in searchedChats!) { // if (user.id == items.first["id"]) { // user.userStatus = items.first["userStatus"]; @@ -537,7 +530,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } String dateFormte(DateTime data) { - DateFormat f = new DateFormat('hh:mm a dd MMM yyyy'); + DateFormat f = DateFormat('hh:mm a dd MMM yyyy'); f.format(data); return f.format(data); } @@ -547,9 +540,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { await ApiClient().postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token); fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); if (favoriteChatUser.response != null) { - for (var user in searchedChats!) { + for (ChatUser user in searchedChats!) { if (user.id == favoriteChatUser.response!.targetUserId!) { user.isFav = favoriteChatUser.response!.isFav; + favUsersList.add(user); } } } @@ -566,6 +560,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { user.isFav = favoriteChatUser.response!.isFav; } } + favUsersList.removeWhere((ChatUser element) => element.id == targetUserID); } notifyListeners(); } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index c5788f9..ede22e3 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server - //static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - static String baseUrl = "https://hmgwebservices.com"; // Live server + static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + //static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 1fcbf2e..ab3fb9a 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -5,6 +5,7 @@ import 'package:mohem_flutter_app/ui/attendance/vacation_rule_screen.dart'; import 'package:mohem_flutter_app/ui/bottom_sheets/attendence_details_bottom_sheet.dart'; import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart'; import 'package:mohem_flutter_app/ui/chat/chat_home.dart'; +import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart'; import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; import 'package:mohem_flutter_app/ui/landing/itg/survey_screen.dart'; import 'package:mohem_flutter_app/ui/landing/today_attendance_screen.dart'; @@ -177,6 +178,7 @@ class AppRoutes { //Chat static const String chat = "/chat"; static const String chatDetailed = "/chatDetailed"; + static const String chatFavoriteUsers = "/chatFavoriteUsers"; //Marathon static const String marathonIntroScreen = "/marathonIntroScreen"; @@ -287,8 +289,9 @@ class AppRoutes { changePassword: (BuildContext context) => ChangePasswordScreen(), //Chat - chat: (BuildContext context) => ChatHomeScreen(), + chat: (BuildContext context) => ChatHome(), chatDetailed: (BuildContext context) => ChatDetailScreen(), + chatFavoriteUsers: (BuildContext context) => ChatFavoriteUsersScreen(), // Marathon marathonIntroScreen: (BuildContext context) => MarathonIntroScreen(), diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index f52bb89..f5d4960 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -485,5 +485,7 @@ abstract class LocaleKeys { static const resend = 'resend'; static const codeExpire = 'codeExpire'; static const typeheretoreply = 'typeheretoreply'; + static const favorite = 'favorite'; + static const searchfromchat = 'searchfromchat'; } diff --git a/lib/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index 5a878ca..d9bd599 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -36,7 +36,7 @@ class ChatBubble extends StatelessWidget { alignment: isCurrentUser ? Alignment.centerRight : Alignment.centerLeft, child: DecoratedBox( decoration: BoxDecoration( - color: Colors.white, + color: MyColors.white, gradient: isCurrentUser ? null : const LinearGradient( @@ -89,7 +89,7 @@ class ChatBubble extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, children: [ - dateTime.toText12(color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : Colors.white.withOpacity(0.7)), + dateTime.toText12(color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7)), if (isCurrentUser) 5.width, if (isCurrentUser) Icon( diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index fe7a968..c13e6d3 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -26,7 +26,6 @@ class ChatDetailScreen extends StatelessWidget { RefreshController _refreshController = RefreshController(initialRefresh: false); void getMoreChat() async { - if (userDetails != null) { data.paginationVal = data.paginationVal + 10; data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: true); @@ -63,7 +62,7 @@ class ChatDetailScreen extends StatelessWidget { controller: scrollController, shrinkWrap: true, itemCount: m.userChatHistory.length, - padding: EdgeInsets.zero, + padding: const EdgeInsets.only(top: 20), itemBuilder: (BuildContext context, int i) { return SwipeTo( iconColor: MyColors.lightGreenColor, diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 38388ca..5176273 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -1,224 +1,103 @@ -import 'dart:convert'; - import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; -import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/config/routes.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/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/ui/chat/chat_home_screen.dart'; +import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart'; +import 'package:mohem_flutter_app/ui/screens/items_for_sale/fragments/items_for_sale.dart'; +import 'package:mohem_flutter_app/ui/screens/items_for_sale/fragments/my_posted_ads_fragment.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; -import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; -import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_sheet.dart'; -import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; -import 'package:provider/provider.dart'; -import 'package:sizer/sizer.dart'; -class ChatHomeScreen extends StatefulWidget { - const ChatHomeScreen({Key? key}) : super(key: key); +class ChatHome extends StatefulWidget { + const ChatHome({Key? key}) : super(key: key); @override - State createState() => _ChatHomeScreenState(); + State createState() => _ChatHomeState(); } -class _ChatHomeScreenState extends State { - TextEditingController search = TextEditingController(); - late ChatProviderModel data; - - @override - void initState() { - super.initState(); - data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().whenComplete(() { - data.getUserRecentChats(); - }); - } - - @override - void dispose() { - super.dispose(); - } +class _ChatHomeState extends State { + int tabIndex = 0; + PageController controller = PageController(); @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Colors.white, - appBar: AppBarWidget(context, title: LocaleKeys.mychats.tr(), showHomeButton: false), - body: Consumer(builder: (BuildContext context, ChatProviderModel m, Widget? child) { - return m.isLoading - ? ChatHomeShimmer() - : ListView( - shrinkWrap: true, - physics: const AlwaysScrollableScrollPhysics(), - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 20), - child: TextField( - onChanged: (String val) { - m.filter(val); - }, - decoration: InputDecoration( - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(5), - borderSide: const BorderSide( - color: Color(0xFFE5E5E5), - ), - ), - errorBorder: InputBorder.none, - disabledBorder: InputBorder.none, - contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), - hintText: "Search from chat", - hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic), - filled: true, - fillColor: const Color(0xFFF7F7F7), - ), - ), - ), - if (m.searchedChats != null) - ListView.separated( - itemCount: m.searchedChats!.length, - padding: const EdgeInsets.only(top: 20), - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (BuildContext context, int index) { - return SizedBox( - height: 55, - child: ListTile( - leading: Stack( - children: [ - SvgPicture.asset( - "assets/images/user.svg", - height: 48, - width: 48, - ), - Positioned( - right: 5, - bottom: 1, - child: Container( - width: 10, - height: 10, - decoration: BoxDecoration( - color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, - borderRadius: const BorderRadius.all( - Radius.circular(10), - ), - ), - ), - ) - ], - ), - title: (m.searchedChats![index].userName ?? "").toText14(color: MyColors.darkTextColor), - // subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), - trailing: SizedBox( - width: 60, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.max, - children: [ - if (m.searchedChats![index].unreadMessageCount! > 0) - Flexible( - child: Container( - padding: EdgeInsets.zero, - alignment: Alignment.centerRight, - width: 18, - height: 18, - decoration: const BoxDecoration( - color: MyColors.redColor, - borderRadius: BorderRadius.all( - Radius.circular(20), - ), - ), - child: (m.searchedChats![index].unreadMessageCount!.toString()) - .toText10( - color: MyColors.white, - ) - .center, - ), - ), - Flexible( - child: IconButton( - alignment: Alignment.centerRight, - padding: EdgeInsets.zero, - icon: Icon(m.searchedChats![index].isFav! ? Icons.star : Icons.star_border), - color: m.searchedChats![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, - onPressed: () { - if (m.searchedChats![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); - if (!m.searchedChats![index].isFav!) m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); - }, - ), - ) - ], - ), - ), - minVerticalPadding: 0, - onTap: () { - Navigator.pushNamed( - context, - AppRoutes.chatDetailed, - arguments: {"targetUser": m.searchedChats![index]}, - ).then((value) { - m.clearSelections(); - }); - }, - onLongPress: () {}, - ), - ); - }, - separatorBuilder: (BuildContext context, int index) => const Padding( - padding: EdgeInsets.only(right: 10, left: 70), - child: Divider( - color: Color(0xFFE5E5E5), - ), - ), - ), + backgroundColor: MyColors.white, + appBar: AppBarWidget( + context, + title: LocaleKeys.chat.tr(), + showHomeButton: true, + ), + body: Column( + children: [ + Container( + padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16), + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(25), + bottomRight: Radius.circular(25), + ), + gradient: LinearGradient( + transform: GradientRotation(.83), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, ], - ); - }), - floatingActionButton: FloatingActionButton( - child: Container( - width: 60, - height: 60, - decoration: const BoxDecoration( - shape: BoxShape.circle, - gradient: LinearGradient( - transform: GradientRotation(.46), - begin: Alignment.topRight, - end: Alignment.bottomLeft, - colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, + ), + ), + child: Row( + children: [ + myTab(LocaleKeys.mychats.tr(), 0), + myTab( + LocaleKeys.favorite.tr(), + 1) ], ), ), - child: const Icon( - Icons.add, - size: 30, - color: MyColors.white, - ), - ), - onPressed: () async { - showMyBottomSheet( - context, - callBackFunc: () {}, - child: SearchEmployeeBottomSheet( - title: LocaleKeys.searchForEmployee.tr(), - apiMode: LocaleKeys.delegate.tr(), - fromChat: true, - onSelectEmployee: (_selectedEmployee) { - setState(() {}); - }, - ), - ); - }, + PageView( + controller: controller, + physics: const NeverScrollableScrollPhysics(), + onPageChanged: (int pageIndex) { + setState(() { + tabIndex = pageIndex; + }); + }, + children: [ChatHomeScreen(), ChatFavoriteUsersScreen()], + ).expanded, + ], ), ); } + + Widget myTab(String title, int index) { + bool isSelected = (index == tabIndex); + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + title.toText12(color: isSelected ? MyColors.white : MyColors.white.withOpacity(.74), isCenter: true), + 4.height, + Container( + height: 8, + width: 8, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: isSelected ? MyColors.white : Colors.transparent, + ), + ).onPress(() { + setState(() { + // showFabOptions = true; + }); + }) + ], + ).onPress(() { + controller.jumpToPage(index); + }).expanded; + } } diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart new file mode 100644 index 0000000..328354b --- /dev/null +++ b/lib/ui/chat/chat_home_screen.dart @@ -0,0 +1,226 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; +import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_sheet.dart'; +import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; +import 'package:provider/provider.dart'; + +class ChatHomeScreen extends StatefulWidget { + const ChatHomeScreen({Key? key}) : super(key: key); + + @override + State createState() => _ChatHomeScreenState(); +} + +class _ChatHomeScreenState extends State { + TextEditingController search = TextEditingController(); + late ChatProviderModel data; + + @override + void initState() { + super.initState(); + data = Provider.of(context, listen: false); + data.getUserAutoLoginToken().whenComplete(() { + data.getUserRecentChats(); + }); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: MyColors.white, + body: Consumer(builder: (BuildContext context, ChatProviderModel m, Widget? child) { + return m.isLoading + ? ChatHomeShimmer() + : ListView( + shrinkWrap: true, + physics: const AlwaysScrollableScrollPhysics(), + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20), + child: TextField( + onChanged: (String val) { + m.filter(val); + }, + decoration: InputDecoration( + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide( + color: Color(0xFFE5E5E5), + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide( + color: Color(0xFFE5E5E5), + ), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide( + color: Color(0xFFE5E5E5), + ), + ), + contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), + hintText: LocaleKeys.searchfromchat.tr(), + hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic), + filled: true, + fillColor: const Color(0xFFF7F7F7), + ), + ), + ), + if (m.searchedChats != null) + ListView.separated( + itemCount: m.searchedChats!.length, + padding: const EdgeInsets.only(bottom: 80), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return SizedBox( + height: 55, + child: ListTile( + leading: Stack( + children: [ + SvgPicture.asset( + "assets/images/user.svg", + height: 48, + width: 48, + ), + Positioned( + right: 5, + bottom: 1, + child: Container( + width: 10, + height: 10, + decoration: BoxDecoration( + color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, + borderRadius: const BorderRadius.all( + Radius.circular(10), + ), + ), + ), + ) + ], + ), + title: (m.searchedChats![index].userName ?? "").toText14(color: MyColors.darkTextColor), + // subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), + trailing: SizedBox( + width: 60, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + if (m.searchedChats![index].unreadMessageCount! > 0) + Flexible( + child: Container( + padding: EdgeInsets.zero, + alignment: Alignment.centerRight, + width: 18, + height: 18, + decoration: const BoxDecoration( + color: MyColors.redColor, + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + ), + child: (m.searchedChats![index].unreadMessageCount!.toString()) + .toText10( + color: MyColors.white, + ) + .center, + ), + ), + Flexible( + child: IconButton( + alignment: Alignment.centerRight, + padding: EdgeInsets.zero, + icon: Icon(m.searchedChats![index].isFav! ? Icons.star : Icons.star_border), + color: m.searchedChats![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, + onPressed: () { + if (m.searchedChats![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + if (!m.searchedChats![index].isFav!) m.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.searchedChats![index].id!); + }, + ), + ) + ], + ), + ), + minVerticalPadding: 0, + onTap: () { + Navigator.pushNamed( + context, + AppRoutes.chatDetailed, + arguments: {"targetUser": m.searchedChats![index]}, + ).then((value) { + m.clearSelections(); + }); + }, + onLongPress: () {}, + ), + ); + }, + separatorBuilder: (BuildContext context, int index) => const Padding( + padding: EdgeInsets.only(right: 10, left: 70), + child: Divider( + color: Color(0xFFE5E5E5), + ), + ), + ), + ], + ); + }), + floatingActionButton: FloatingActionButton( + child: Container( + width: 60, + height: 60, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + transform: GradientRotation(.46), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ], + ), + ), + child: const Icon( + Icons.add, + size: 30, + color: MyColors.white, + ), + ), + onPressed: () async { + showMyBottomSheet( + context, + callBackFunc: () {}, + child: SearchEmployeeBottomSheet( + title: LocaleKeys.searchForEmployee.tr(), + apiMode: LocaleKeys.delegate.tr(), + fromChat: true, + onSelectEmployee: (_selectedEmployee) { + setState(() {}); + }, + ), + ); + }, + ), + ); + } +} diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart new file mode 100644 index 0000000..b84b827 --- /dev/null +++ b/lib/ui/chat/favorite_users_screen.dart @@ -0,0 +1,102 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/api/chat/chat_provider_model.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/utils.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; +import 'package:provider/provider.dart'; + +class ChatFavoriteUsersScreen extends StatelessWidget { + const ChatFavoriteUsersScreen({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // TODO: implement build + return Scaffold( + backgroundColor: MyColors.white, + body: Consumer(builder: (BuildContext context, ChatProviderModel m, Widget? child) { + return m.isLoading + ? ChatHomeShimmer() + : ListView( + shrinkWrap: true, + physics: const AlwaysScrollableScrollPhysics(), + padding: const EdgeInsets.only(top: 20), + children: [ + if (m.favUsersList != null && m.favUsersList.isNotEmpty) + ListView.separated( + itemCount: m.favUsersList!.length, + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return SizedBox( + height: 55, + child: ListTile( + leading: Stack( + children: [ + SvgPicture.asset( + "assets/images/user.svg", + height: 48, + width: 48, + ), + Positioned( + right: 5, + bottom: 1, + child: Container( + width: 10, + height: 10, + decoration: BoxDecoration( + color: m.favUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, + borderRadius: const BorderRadius.all( + Radius.circular(10), + ), + ), + ), + ) + ], + ), + title: (m.favUsersList![index].userName ?? "").toText14(color: MyColors.darkTextColor), + // subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor), + trailing: IconButton( + alignment: Alignment.centerRight, + padding: EdgeInsets.zero, + icon: Icon(m.favUsersList![index].isFav! ? Icons.star : Icons.star_border), + color: m.favUsersList![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, + onPressed: () { + if (m.favUsersList![index].isFav!) m.unFavoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: m.favUsersList![index].id!); + }, + ), + minVerticalPadding: 0, + onTap: () { + Navigator.pushNamed( + context, + AppRoutes.chatDetailed, + arguments: {"targetUser": m.favUsersList![index]}, + ).then((value) { + m.clearSelections(); + }); + }, + onLongPress: () {}, + ), + ); + }, + separatorBuilder: (BuildContext context, int index) => const Padding( + padding: EdgeInsets.only(right: 10, left: 70), + child: Divider( + color: Color(0xFFE5E5E5), + ), + ), + ) + else + Utils.getNoDataWidget(context).expanded + ], + ); + }), + ); + } +} diff --git a/lib/widgets/image_picker.dart b/lib/widgets/image_picker.dart index 9fa0336..f92f9f4 100644 --- a/lib/widgets/image_picker.dart +++ b/lib/widgets/image_picker.dart @@ -48,7 +48,7 @@ class ImageOptions { allowedExtensions: ['jpg', 'jpeg ', 'pdf', 'txt', 'docx', 'doc', 'pptx', 'xlsx', 'png', 'rar', 'zip', 'xls'], ); List files = result!.paths.map((path) => File(path!)).toList(); - image(result!.files.first.path.toString(), files.first); + image(result.files.first.path.toString(), files.first); }, ), );