From 967257ec2ec96234ec48124c5d4d1587871bfcf1 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 28 Nov 2022 10:26:15 +0300 Subject: [PATCH] Chat Fixes --- lib/api/api_client.dart | 115 +++----------- lib/api/chat/chat_api_client.dart | 34 +++- lib/provider/chat_provider_model.dart | 3 + lib/ui/chat/chat_home_screen.dart | 210 ++++++++++--------------- lib/ui/chat/favorite_users_screen.dart | 118 +++++++------- 5 files changed, 189 insertions(+), 291 deletions(-) diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart index 7a6f668..1e66d45 100644 --- a/lib/api/api_client.dart +++ b/lib/api/api_client.dart @@ -18,8 +18,7 @@ class APIError { APIError(this.errorCode, this.errorMessage); - Map toJson() => - {'errorCode': errorCode, 'errorMessage': errorMessage}; + Map toJson() => {'errorCode': errorCode, 'errorMessage': errorMessage}; @override String toString() { @@ -54,8 +53,7 @@ APIException _throwAPIException(Response response) { return APIException(APIException.INTERNAL_SERVER_ERROR); case 444: var downloadUrl = response.headers["location"]; - return APIException(APIException.UPGRADE_REQUIRED, - arguments: downloadUrl); + return APIException(APIException.UPGRADE_REQUIRED, arguments: downloadUrl); default: return APIException(APIException.OTHER); } @@ -68,13 +66,8 @@ class ApiClient { factory ApiClient() => _instance; - Future postJsonForObject( - FactoryConstructor factoryConstructor, String url, T jsonObject, - {String? token, - Map? queryParameters, - Map? headers, - int retryTimes = 0, - bool isFormData = false}) async { + Future postJsonForObject(FactoryConstructor factoryConstructor, String url, T jsonObject, + {String? token, Map? queryParameters, Map? headers, int retryTimes = 0, bool isFormData = false}) async { var _headers = {'Accept': 'application/json'}; if (headers != null && headers.isNotEmpty) { _headers.addAll(headers); @@ -84,12 +77,7 @@ class ApiClient { var bodyJson = json.encode(jsonObject); print("body:$bodyJson"); } - var response = await postJsonForResponse(url, jsonObject, - token: token, - queryParameters: queryParameters, - headers: _headers, - retryTimes: retryTimes, - isFormData: isFormData); + var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes, isFormData: isFormData); // try { if (!kReleaseMode) { logger.i("res: " + response.body); @@ -102,8 +90,7 @@ class ApiClient { return factoryConstructor(jsonData); } else { APIError? apiError; - apiError = - APIError(jsonData['ErrorCode'], jsonData['ErrorEndUserMessage']); + apiError = APIError(jsonData['ErrorCode'], jsonData['ErrorEndUserMessage']); throw APIException(APIException.BAD_REQUEST, error: apiError); } // } catch (ex) { @@ -116,11 +103,7 @@ class ApiClient { } Future postJsonForResponse(String url, T jsonObject, - {String? token, - Map? queryParameters, - Map? headers, - int retryTimes = 0, - bool isFormData = false}) async { + {String? token, Map? queryParameters, Map? headers, int retryTimes = 0, bool isFormData = false}) async { String? requestBody; late Map stringObj; if (jsonObject != null) { @@ -134,22 +117,13 @@ class ApiClient { if (isFormData) { headers = {'Content-Type': 'application/x-www-form-urlencoded'}; - stringObj = ((jsonObject ?? {}) as Map) - .map((key, value) => MapEntry(key, value?.toString() ?? "")); + stringObj = ((jsonObject ?? {}) as Map).map((key, value) => MapEntry(key, value?.toString() ?? "")); } - return await _postForResponse(url, isFormData ? stringObj : requestBody, - token: token, - queryParameters: queryParameters, - headers: headers, - retryTimes: retryTimes); + return await _postForResponse(url, isFormData ? stringObj : requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes); } - Future _postForResponse(String url, requestBody, - {String? token, - Map? queryParameters, - Map? headers, - int retryTimes = 0}) async { + Future _postForResponse(String url, requestBody, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { try { var _headers = {}; if (token != null) { @@ -164,9 +138,7 @@ class ApiClient { var queryString = new Uri(queryParameters: queryParameters).query; url = url + '?' + queryString; } - var response = - await _post(Uri.parse(url), body: requestBody, headers: _headers) - .timeout(Duration(seconds: 120)); + var response = await _post(Uri.parse(url), body: requestBody, headers: _headers).timeout(Duration(seconds: 120)); if (response.statusCode >= 200 && response.statusCode < 300) { return response; @@ -177,11 +149,7 @@ class ApiClient { if (retryTimes > 0) { print('will retry after 3 seconds...'); await Future.delayed(Duration(seconds: 3)); - return await _postForResponse(url, requestBody, - token: token, - queryParameters: queryParameters, - headers: headers, - retryTimes: retryTimes - 1); + return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); } else { throw APIException(APIException.OTHER, arguments: e); } @@ -189,11 +157,7 @@ class ApiClient { if (retryTimes > 0) { print('will retry after 3 seconds...'); await Future.delayed(Duration(seconds: 3)); - return await _postForResponse(url, requestBody, - token: token, - queryParameters: queryParameters, - headers: headers, - retryTimes: retryTimes - 1); + return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); } else { throw APIException(APIException.OTHER, arguments: e); } @@ -203,39 +167,23 @@ class ApiClient { if (retryTimes > 0) { print('will retry after 3 seconds...'); await Future.delayed(Duration(seconds: 3)); - return await _postForResponse(url, requestBody, - token: token, - queryParameters: queryParameters, - headers: headers, - retryTimes: retryTimes - 1); + return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); } else { throw APIException(APIException.OTHER, arguments: e); } } } - Future getJsonForResponse(String url, - {String? token, - Map? queryParameters, - Map? headers, - int retryTimes = 0}) async { + Future getJsonForResponse(String url, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { if (headers == null) { headers = {'Content-Type': 'application/json'}; } else { headers['Content-Type'] = 'application/json'; } - return await _getForResponse(url, - token: token, - queryParameters: queryParameters, - headers: headers, - retryTimes: retryTimes); + return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes); } - Future _getForResponse(String url, - {String? token, - Map? queryParameters, - Map? headers, - int retryTimes = 0}) async { + Future _getForResponse(String url, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { try { var _headers = {}; if (token != null) { @@ -250,8 +198,7 @@ class ApiClient { var queryString = new Uri(queryParameters: queryParameters).query; url = url + '?' + queryString; } - var response = await _get(Uri.parse(url), headers: _headers) - .timeout(Duration(seconds: 60)); + var response = await _get(Uri.parse(url), headers: _headers).timeout(Duration(seconds: 60)); if (response.statusCode >= 200 && response.statusCode < 300) { return response; @@ -262,11 +209,7 @@ class ApiClient { if (retryTimes > 0) { print('will retry after 3 seconds...'); await Future.delayed(Duration(seconds: 3)); - return await _getForResponse(url, - token: token, - queryParameters: queryParameters, - headers: headers, - retryTimes: retryTimes - 1); + return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); } else { throw APIException(APIException.OTHER, arguments: e); } @@ -274,11 +217,7 @@ class ApiClient { if (retryTimes > 0) { print('will retry after 3 seconds...'); await Future.delayed(Duration(seconds: 3)); - return await _getForResponse(url, - token: token, - queryParameters: queryParameters, - headers: headers, - retryTimes: retryTimes - 1); + return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); } else { throw APIException(APIException.OTHER, arguments: e); } @@ -288,19 +227,14 @@ class ApiClient { if (retryTimes > 0) { print('will retry after 3 seconds...'); await Future.delayed(Duration(seconds: 3)); - return await _getForResponse(url, - token: token, - queryParameters: queryParameters, - headers: headers, - retryTimes: retryTimes - 1); + return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); } else { throw APIException(APIException.OTHER, arguments: e); } } } - Future _get(url, {Map? headers}) => - _withClient((client) => client.get(url, headers: headers)); + Future _get(url, {Map? headers}) => _withClient((client) => client.get(url, headers: headers)); bool _certificateCheck(X509Certificate cert, String host, int port) => true; @@ -314,8 +248,5 @@ class ApiClient { } } - Future _post(url, - {Map? headers, body, Encoding? encoding}) => - _withClient((client) => - client.post(url, headers: headers, body: body, encoding: encoding)); + Future _post(url, {Map? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding)); } diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index 323c3d4..6355417 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -5,6 +5,9 @@ import 'package:http/http.dart'; import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/exceptions/api_exception.dart'; +import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as user; import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; @@ -83,13 +86,30 @@ class ChatApiClient { } Future unFavUser({required int userID, required int targetUserID}) async { - Response response = await ApiClient().postJsonForResponse( - "${ApiConsts.chatFavUser}deleteFavUser", - {"targetUserId": targetUserID, "userId": userID}, - token: AppState().chatDetails!.response!.token, - ); - fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); - return favoriteChatUser; + try { + Response response = await ApiClient().postJsonForResponse( + "${ApiConsts.chatFavUser}deleteFavUser", + {"targetUserId": targetUserID, "userId": userID}, + token: AppState().chatDetails!.response!.token, + ); + fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); + return favoriteChatUser; + } catch (e) { + e as APIException; + if (e.message == "api_common_unauthorized") { + logger.d("Token Generated On APIIIIII"); + user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken(); + if (userLoginResponse.response != null) { + AppState().setchatUserDetails = userLoginResponse; + unFavUser(userID: userID, targetUserID: targetUserID); + } else { + Utils.showToast( + userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr", + ); + } + } + throw e; + } } Future uploadMedia(String userId, File file) async { diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index dc98858..655de86 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -10,6 +10,7 @@ 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/consts.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/exceptions/api_exception.dart'; import 'package:mohem_flutter_app/main.dart'; 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'; @@ -586,6 +587,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future 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!) { if (user.id == favoriteChatUser.response!.targetUserId!) { @@ -596,6 +598,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { (ChatUser element) => element.id == targetUserID, ); } + notifyListeners(); } diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 2724683..cf6b8d2 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -46,105 +46,87 @@ class _ChatHomeScreenState extends State { builder: (BuildContext context, ChatProviderModel m, Widget? child) { return m.isLoading ? ChatHomeShimmer() - : ListView( - shrinkWrap: true, - physics: const AlwaysScrollableScrollPhysics(), + : Column( children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20), - child: TextField( - controller: m.search, - style: const TextStyle(color: MyColors.darkTextColor, fontWeight: FontWeight.w500, fontSize: 12), - onChanged: (String val) { - m.filter(val); - }, - decoration: InputDecoration( - border: fieldBorder(radius: 5, color: 0xFFE5E5E5), - focusedBorder: fieldBorder(radius: 5, color: 0xFFE5E5E5), - enabledBorder: fieldBorder(radius: 5, color: 0xFFE5E5E5), - contentPadding: const EdgeInsets.all(11), - hintText: LocaleKeys.searchfromchat.tr(), - hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic, fontWeight: FontWeight.w500, fontSize: 12), - filled: true, - fillColor: const Color(0xFFF7F7F7), - suffixIconConstraints: const BoxConstraints(), - suffixIcon: m.search.text.isNotEmpty - ? IconButton( - constraints: const BoxConstraints(), - onPressed: () { - m.clearSelections(); - }, - icon: const Icon(Icons.clear, size: 22), - color: MyColors.redA3Color, - ) - : null, - ), + TextField( + controller: m.search, + style: const TextStyle(color: MyColors.darkTextColor, fontWeight: FontWeight.w500, fontSize: 12), + onChanged: (String val) { + m.filter(val); + }, + decoration: InputDecoration( + border: fieldBorder(radius: 5, color: 0xFFE5E5E5), + focusedBorder: fieldBorder(radius: 5, color: 0xFFE5E5E5), + enabledBorder: fieldBorder(radius: 5, color: 0xFFE5E5E5), + contentPadding: const EdgeInsets.all(11), + hintText: LocaleKeys.searchfromchat.tr(), + hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic, fontWeight: FontWeight.w500, fontSize: 12), + filled: true, + fillColor: const Color(0xFFF7F7F7), + suffixIconConstraints: const BoxConstraints(), + suffixIcon: m.search.text.isNotEmpty + ? IconButton( + constraints: const BoxConstraints(), + onPressed: () { + m.clearSelections(); + }, + icon: const Icon(Icons.clear, size: 22), + color: MyColors.redA3Color, + ) + : null, ), - ), + ).paddingOnly(top: 20, bottom: 14), if (m.searchedChats != null) ListView.separated( itemCount: m.searchedChats!.length, - padding: const EdgeInsets.only(bottom: 80), shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), + physics: const ClampingScrollPhysics(), itemBuilder: (BuildContext context, int index) { + // todo @aamir, remove list tile, make a custom ui instead return SizedBox( height: 55, - // todo @aamir, remove list tile, make a custom ui instead - 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), + child: Row( + children: [ + 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!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").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].isLoadingCounter!) - // 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: CircularProgressIndicator(), - // ), - // ), - if (m.searchedChats![index].unreadMessageCount! > 0) - Flexible( - child: Container( - padding: EdgeInsets.zero, - alignment: Alignment.centerRight, + ) + ], + ), + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + (m.searchedChats![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor).paddingOnly(left: 11, top: 13), + ], + ).expanded, + SizedBox( + width: 60, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + if (m.searchedChats![index].unreadMessageCount! > 0) + Container( + alignment: Alignment.center, width: 18, height: 18, decoration: const BoxDecoration( @@ -158,18 +140,12 @@ class _ChatHomeScreenState extends State { color: MyColors.white, ) .center, - ), - ), - Flexible( - child: IconButton( - constraints: BoxConstraints(), - alignment: Alignment.centerRight, - padding: EdgeInsets.zero, - icon: Icon( - m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == false ? Icons.star_sharp : Icons.star_sharp, - ), + ).paddingOnly(right: 10).center, + Icon( + m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == false ? Icons.star_sharp : Icons.star_sharp, color: m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == true ? MyColors.yellowColor : MyColors.grey35Color, - onPressed: () { + ).onPress( + () { if (m.searchedChats![index].isFav == null || m.searchedChats![index].isFav == false) { m.favoriteUser( userID: AppState().chatDetails!.response!.id!, @@ -187,40 +163,18 @@ class _ChatHomeScreenState extends State { ); } }, - ), - ) - ], + ).center + ], + ), ), - ), - minVerticalPadding: 0, - onTap: () { - Navigator.pushNamed( - context, - AppRoutes.chatDetailed, - arguments: {"targetUser": m.searchedChats![index], "isNewChat": false}, - ).then((Object? value) { - // m.GetUserChatHistoryNotDeliveredAsync(userId: int.parse(AppState().chatDetails!.response!.id.toString())); - m.clearSelections(); - m.notifyListeners(); - }); - }, + ], ), ); }, - separatorBuilder: (BuildContext context, int index) => const Padding( - padding: EdgeInsets.only( - right: 10, - left: 70, - ), - child: Divider( - color: Color( - 0xFFE5E5E5, - ), - ), - ), - ), + separatorBuilder: (BuildContext context, int index) => const Divider(color: MyColors.lightGreyE5Color).paddingOnly(left: 59), + ).paddingOnly(bottom: 70).expanded, ], - ); + ).paddingOnly(left: 21, right: 21); }, ), floatingActionButton: FloatingActionButton( diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart index 8f303cd..88c8f9a 100644 --- a/lib/ui/chat/favorite_users_screen.dart +++ b/lib/ui/chat/favorite_users_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; @@ -26,81 +27,70 @@ class ChatFavoriteUsersScreen extends StatelessWidget { return m.favUsersList != null && m.favUsersList.isNotEmpty ? ListView.separated( itemCount: m.favUsersList!.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.favUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, - borderRadius: const BorderRadius.all( - Radius.circular(10), + child: Row( + children: [ + 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!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14( - color: MyColors.darkTextColor, - ), - 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], "isNewChat": false}, - ).then( - (Object? value) { - m.clearSelections(); - }, - ); - }, + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + (m.favUsersList![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor).paddingOnly(left: 11, top: 13), + ], + ).expanded, + SizedBox( + width: 60, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + Icon( + m.favUsersList![index].isFav! ? Icons.star : Icons.star_border, + color: m.favUsersList![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color, + ).onPress(() { + if (m.favUsersList![index].isFav!) { + m.unFavoriteUser( + userID: AppState().chatDetails!.response!.id!, + targetUserID: m.favUsersList![index].id!, + ); + } + }).center, + ], + ), + ), + ], ), ); }, - separatorBuilder: (BuildContext context, int index) => const Padding( - padding: EdgeInsets.only( - right: 10, - left: 70, - ), - child: Divider( - color: Color( - 0xFFE5E5E5, - ), - ), - ), - ) + separatorBuilder: (BuildContext context, int index) => const Divider(color: MyColors.lightGreyE5Color).paddingOnly(left: 70), + ).paddingAll(21) : Column( children: [ Utils.getNoDataWidget(context).expanded,