diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 9daee21..43841a1 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -383,7 +383,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 3A359E86ZF; + DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; @@ -520,7 +520,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 3A359E86ZF; + DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; @@ -549,7 +549,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 3A359E86ZF; + DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index fb9e6c5..0f0e94c 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -1,10 +1,12 @@ +import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'dart:math'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart'; +import 'package:logger/logger.dart' as L; import 'package:logging/logging.dart'; import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; @@ -15,17 +17,17 @@ import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.da import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as login; import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; import 'package:mohem_flutter_app/widgets/image_picker.dart'; -import 'package:path_provider/path_provider.dart'; import 'package:signalr_netcore/signalr_client.dart'; -import 'package:logger/logger.dart' as L; import 'package:uuid/uuid.dart'; class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { + ScrollController scrollController = ScrollController(); + TextEditingController message = TextEditingController(); List userChatHistory = []; List? pChatHistory, searchedChats; late HubConnection hubConnection; L.Logger logger = L.Logger(); - TextEditingController message = TextEditingController(); + bool isLoading = true; bool isChatScreenActive = false; late File selectedFile; @@ -36,6 +38,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List favUsersList = []; int paginationVal = 0; + //Scroll + bool _firstAutoscrollExecuted = false; + bool _shouldAutoscroll = false; + Future getUserAutoLoginToken() async { String userName = AppState().memberInformationList!.eMPLOYEEEMAILADDRESS!.split("@").first.toString(); Response response = @@ -87,12 +93,20 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void getSingleUserChatHistory({required String senderUID, required int receiverUID, required bool loadMore}) async { isLoading = true; + print(loadMore); + print(senderUID); + print(receiverUID); if (!loadMore) paginationVal = 0; + print(paginationVal); isChatScreenActive = true; Response response = await ApiClient().getJsonForResponse( "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal", token: AppState().chatDetails!.response!.token, ); + logger.d("${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal"); + logger.d("${AppState().chatDetails!.response!.token}"); + logger.d(jsonEncode(response.body)); + logger.d(jsonEncode(response.statusCode)); if (response.statusCode == 204) { if (!loadMore) userChatHistory = []; Utils.showToast("No More Data To Load"); @@ -105,7 +119,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } isLoading = false; + //Timer(const Duration(milliseconds: 100),() => scrollToBottom()); notifyListeners(); + + // scrollToBottom(); } List getSingleUserChatModel(String str) => List.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); @@ -218,9 +235,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } void changeStatus(List? args) { - if (kDebugMode) { - // print("================= Status Online // Offline ===================="); - } + if (kDebugMode) { + // print("================= Status Online // Offline ===================="); + } dynamic items = args!.toList(); // logger.d(items); for (ChatUser user in searchedChats!) { @@ -258,6 +275,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { data.first.currentUserName = temp.first.targetUserName; } userChatHistory.add(data.first); + scrollToBottom(); notifyListeners(); // if (isChatScreenActive) scrollDown(); } @@ -356,7 +374,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { // } Future 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}) async { Uuid uuid = const Uuid(); SingleUserChatModel data = SingleUserChatModel( chatEventId: chatEventId, @@ -390,6 +408,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { isMsgReply = false; sFileType = ""; message.clear(); + scrollToBottom(); notifyListeners(); } @@ -575,4 +594,33 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { repliedMsg = []; sFileType = ""; } + + void scrollListener() { + _firstAutoscrollExecuted = true; + if (scrollController.hasClients && scrollController.position.pixels == scrollController.position.maxScrollExtent) { + _shouldAutoscroll = true; + } else { + _shouldAutoscroll = false; + } + } + + void scrollToBottom() { + //scrollController.jumpTo(scrollController.position.maxScrollExtent + 100 ); + scrollController.animateTo( + scrollController.position.maxScrollExtent + 100, + duration: const Duration(milliseconds: 500), + curve: Curves.easeIn, + ); + } + +// void scrollToMaxExtent() { +// WidgetsBinding.instance.addPostFrameCallback((_) { +// scrollController.animateTo( +// scrollController.position.maxScrollExtent, +// duration: const Duration(milliseconds: 100), +// curve: Curves.easeIn, +// ); +// }); +// } + } 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/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index d9bd599..c638b34 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -89,7 +89,7 @@ class ChatBubble extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, children: [ - dateTime.toText12(color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.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 e2d0bd7..b4838f3 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:convert'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -17,23 +16,14 @@ import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:swipe_to/swipe_to.dart'; -class ChatDetailScreen extends StatefulWidget { +class ChatDetailScreen extends StatelessWidget { // ignore: prefer_const_constructors_in_immutables ChatDetailScreen({Key? key}) : super(key: key); - @override - State createState() => _ChatDetailScreenState(); -} - -class _ChatDetailScreenState extends State { dynamic userDetails; - bool _firstAutoscrollExecuted = false; - bool _shouldAutoscroll = false; late ChatProviderModel data; - ScrollController scrollController = ScrollController(); - final RefreshController _refreshController = RefreshController(initialRefresh: false); void getMoreChat() async { @@ -44,53 +34,13 @@ class _ChatDetailScreenState extends State { await Future.delayed(const Duration(milliseconds: 1000)); _refreshController.refreshCompleted(); } - // - // void _scrollListener() { - // _firstAutoscrollExecuted = true; - // if (scrollController.hasClients && scrollController.position.pixels == scrollController.position.maxScrollExtent) { - // _shouldAutoscroll = true; - // } else { - // _shouldAutoscroll = false; - // } - // } - // - // void _scrollToBottom() { - // scrollController.jumpTo(scrollController.position.maxScrollExtent); - // } - - // void scrollToMaxExtent() { - // WidgetsBinding.instance.addPostFrameCallback((_) { - // scrollController.animateTo( - // scrollController.position.maxScrollExtent, - // duration: const Duration(milliseconds: 100), - // curve: Curves.easeIn, - // ); - // }); - // } - - - - @override - void initState() { - // TODO: implement initState - super.initState(); - //scrollToMaxExtent(); - - // scrollController.addListener(_scrollListener); - } - - @override - void dispose() { - // TODO: implement dispose - //scrollController.removeListener(_scrollListener); - super.dispose(); - } @override Widget build(BuildContext context) { userDetails = ModalRoute.of(context)!.settings.arguments; data = Provider.of(context, listen: false); if (userDetails != null) data.getSingleUserChatHistory(senderUID: AppState().chatDetails!.response!.id.toString(), receiverUID: userDetails["targetUser"].id, loadMore: false); + data.scrollController.addListener(data.scrollListener); return Scaffold( backgroundColor: const Color(0xFFF8F8F8), appBar: AppBarWidget(context, title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach, showHomeButton: false, image: userDetails["targetUser"].image), @@ -111,7 +61,7 @@ class _ChatDetailScreenState extends State { controller: _refreshController, onRefresh: getMoreChat, child: ListView.builder( - controller: scrollController, + controller: m.scrollController, shrinkWrap: true, reverse: false, itemCount: m.userChatHistory.length, @@ -150,7 +100,9 @@ class _ChatDetailScreenState extends State { height: 80, color: MyColors.black.withOpacity(0.10), child: ListTile( - title: (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString() ? "You" : m.repliedMsg.first.currentUserName.toString().replaceAll(".", " ")) + title: (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString() + ? "You" + : m.repliedMsg.first.currentUserName.toString().replaceAll(".", " ")) .toText14(color: MyColors.lightGreenColor), subtitle: (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(color: MyColors.white, maxLine: 2), trailing: GestureDetector( diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 5176273..d3c4d62 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -1,5 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/api/chat/chat_provider_model.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'; @@ -11,6 +12,7 @@ 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:provider/provider.dart'; class ChatHome extends StatefulWidget { const ChatHome({Key? key}) : super(key: key); @@ -22,9 +24,13 @@ class ChatHome extends StatefulWidget { class _ChatHomeState extends State { int tabIndex = 0; PageController controller = PageController(); + late ChatProviderModel data; + @override Widget build(BuildContext context) { + data = Provider.of(context, listen: false); + data.getUserAutoLoginToken().whenComplete(() => null); return Scaffold( backgroundColor: MyColors.white, appBar: AppBarWidget( diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 32f97fa..e55f018 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -29,9 +29,7 @@ class _ChatHomeScreenState extends State { void initState() { super.initState(); data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().whenComplete(() { - data.getUserRecentChats(); - }); + data.getUserRecentChats(); } @override diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart index 8b5eba0..29d4ffa 100644 --- a/lib/ui/chat/favorite_users_screen.dart +++ b/lib/ui/chat/favorite_users_screen.dart @@ -56,7 +56,7 @@ class ChatFavoriteUsersScreen extends StatelessWidget { ) ], ), - title: (m.searchedChats![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor), + title: (m.favUsersList![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor), trailing: IconButton( alignment: Alignment.centerRight, padding: EdgeInsets.zero,