From f4f9b442c857eccf75b8b49a3b41ea732825a8e9 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 21 Nov 2022 15:47:42 +0300 Subject: [PATCH 1/8] Chat Updates & Counter Event Modifications --- lib/api/chat/chat_provider_model.dart | 57 +++++++++++-------- lib/models/chat/call.dart | 8 +-- .../chat/get_search_user_chat_model.dart | 32 ++++++----- lib/ui/chat/chat_detailed_screen.dart | 44 +++++++------- lib/ui/chat/chat_home_screen.dart | 18 +++++- 5 files changed, 96 insertions(+), 63 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 7a27c1f..a019294 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -115,6 +115,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { searchedChats = pChatHistory; isLoading = false; + getUserChatHistoryNotDeliveredAsync( + userId: int.parse( + AppState().chatDetails!.response!.id.toString(), + ), + ); notifyListeners(); } @@ -122,6 +127,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { await hubConnection.invoke( "GetUserChatHistoryNotDeliveredAsync", args: [userId], + ).onError( + (Error error, StackTrace stackTrace) => { + logger.d(error), + }, ); return ""; } @@ -220,8 +229,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { '${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatMediaImageUploadUrl}', ), ); - request.fields.addAll({'userId': userId, 'fileSource': '1'}); - request.files.add(await MultipartFile.fromPath('files', file.path)); + request.fields.addAll( + {'userId': userId, 'fileSource': '1'}, + ); + request.files.add( + await MultipartFile.fromPath( + 'files', + file.path, + ), + ); request.headers.addAll( { 'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}', @@ -256,7 +272,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { options: httpOp, ) .withAutomaticReconnect( - retryDelays: [2000, 5000, 10000, 20000], + retryDelays: [ + 2000, + 5000, + 10000, + 20000, + ], ) .configureLogging( Logger("Loggin"), @@ -273,11 +294,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ); if (hubConnection.state != HubConnectionState.Connected) { await hubConnection.start(); - getUserChatHistoryNotDeliveredAsync( - userId: int.parse( - AppState().chatDetails!.response!.id.toString(), - ), - ); + print("Connnnnn Stablished"); hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); // hubConnection.on("OnSeenChatUserAsync", onChatSeen); @@ -343,21 +360,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void chatNotDelivered(List? args) { dynamic items = args!.toList(); for (dynamic item in items[0]) { - searchedChats!.forEach((element) { - if (element.id == item["currentUserId"]) { - var val = element.unreadMessageCount == null ? 0 : element.unreadMessageCount; - element.unreadMessageCount = val! + 1; - } - }); - // dynamic data = [ - // { - // "userChatHistoryId": item["userChatHistoryId"], - // "TargetUserId": item["targetUserId"], - // "isDelivered": true, - // "isSeen": true, - // } - // ]; - // updateUserChatHistoryStatusAsync(data); + searchedChats!.forEach( + (ChatUser element) { + if (element.id == item["currentUserId"]) { + int? val = element.unreadMessageCount ?? 0; + element.unreadMessageCount = val! + 1; + } + element.isLoadingCounter = false; + }, + ); } notifyListeners(); } diff --git a/lib/models/chat/call.dart b/lib/models/chat/call.dart index 20f6a79..7f8f6eb 100644 --- a/lib/models/chat/call.dart +++ b/lib/models/chat/call.dart @@ -7,7 +7,7 @@ import 'dart:convert'; class CallDataModel { CallDataModel({ this.callerId, - this.callReciverId, + this.callReceiverID, this.notificationForeground, this.message, this.title, @@ -27,7 +27,7 @@ class CallDataModel { }); String? callerId; - String? callReciverId; + String? callReceiverID; String? notificationForeground; String? message; String? title; @@ -51,7 +51,7 @@ class CallDataModel { factory CallDataModel.fromJson(Map json) => CallDataModel( callerId: json["callerID"] == null ? null : json["callerID"], - callReciverId: json["callReciverID"] == null ? null : json["callReciverID"], + callReceiverID: json["callReceiverID"] == null ? null : json["callReceiverID"], notificationForeground: json["notification_foreground"] == null ? null : json["notification_foreground"], message: json["message"] == null ? null : json["message"], title: json["title"] == null ? null : json["title"], @@ -78,7 +78,7 @@ class CallDataModel { Map toJson() => { "callerID": callerId == null ? null : callerId, - "callReciverID": callReciverId == null ? null : callReciverId, + "callReceiverID": callReceiverID == null ? null : callReceiverID, "notification_foreground": notificationForeground == null ? null : notificationForeground, "message": message == null ? null : message, "title": title == null ? null : title, diff --git a/lib/models/chat/get_search_user_chat_model.dart b/lib/models/chat/get_search_user_chat_model.dart index ceee0de..31d1085 100644 --- a/lib/models/chat/get_search_user_chat_model.dart +++ b/lib/models/chat/get_search_user_chat_model.dart @@ -19,21 +19,21 @@ class ChatUserModel { } class ChatUser { - ChatUser({ - this.id, - this.userName, - this.email, - this.phone, - this.title, - this.userStatus, - this.image, - this.unreadMessageCount, - this.userAction, - this.isPin, - this.isFav, - this.isAdmin, - this.isTyping, - }); + ChatUser( + {this.id, + this.userName, + this.email, + this.phone, + this.title, + this.userStatus, + this.image, + this.unreadMessageCount, + this.userAction, + this.isPin, + this.isFav, + this.isAdmin, + this.isTyping, + this.isLoadingCounter}); int? id; String? userName; @@ -48,6 +48,7 @@ class ChatUser { bool? isFav; bool? isAdmin; bool? isTyping; + bool? isLoadingCounter; factory ChatUser.fromJson(Map json) => ChatUser( id: json["id"] == null ? null : json["id"], @@ -63,6 +64,7 @@ class ChatUser { isFav: json["isFav"] == null ? null : json["isFav"], isAdmin: json["isAdmin"] == null ? null : json["isAdmin"], isTyping: false, + isLoadingCounter: true, ); Map toJson() => { diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 4a8e70c..1374608 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -38,13 +38,14 @@ class _ChatDetailScreenState extends State { void getMoreChat() async { if (userDetails != null) { data.paginationVal = data.paginationVal + 10; - if (userDetails != null) + if (userDetails != null) { data.getSingleUserChatHistory( senderUID: AppState().chatDetails!.response!.id!.toInt(), receiverUID: userDetails["targetUser"].id, loadMore: true, isNewChat: false, ); + } } await Future.delayed( const Duration( @@ -76,10 +77,10 @@ class _ChatDetailScreenState extends State { actions: [ IconButton( onPressed: () { - // makeCall( - // callType: "AUDIO", - // con: data.hubConnection, - // ); + makeCall( + callType: "AUDIO", + con: data.hubConnection, + ); }, icon: SvgPicture.asset( "assets/icons/chat/call.svg", @@ -89,10 +90,10 @@ class _ChatDetailScreenState extends State { ), IconButton( onPressed: () { - // makeCall( - // callType: "VIDEO", - // con: data.hubConnection, - // ); + makeCall( + callType: "VIDEO", + con: data.hubConnection, + ); }, icon: SvgPicture.asset( "assets/icons/chat/video_call.svg", @@ -357,38 +358,41 @@ class _ChatDetailScreenState extends State { void makeCall({required String callType, required HubConnection con}) async { print("================== Make call Triggered ============================"); - logger.d(jsonEncode(AppState().chatDetails!.response)); Map json = { "callerID": AppState().chatDetails!.response!.id!.toString(), - "callReciverID": userDetails["targetUser"].id.toString(), + "callReceiverID": userDetails["targetUser"].id.toString(), "notification_foreground": "true", - "message": "Aamir is calling ", + "message": "Aamir is calling", "title": "Video Call", "type": callType == "VIDEO" ? "Video" : "Audio", - "identity": "Aamir.Muhammad", - "name": "Aamir Saleem Ahmad", + "identity": AppState().chatDetails!.response!.userName, + "name": AppState().chatDetails!.response!.title, "is_call": "true", "is_webrtc": "true", - "contant": "Start video Call Aamir.Muhammad", + "contant": "Start video Call ${AppState().chatDetails!.response!.userName}", "contantNo": "775d1f11-62d9-6fcc-91f6-21f8c14559fb", "chatEventId": "3", "fileTypeId": null, - "currentUserId": "266642", + "currentUserId": AppState().chatDetails!.response!.id!.toString(), "chatSource": "1", "userChatHistoryLineRequestList": [ - {"isSeen": false, "isDelivered": false, "targetUserId": 341682, "targetUserStatus": 4} + { + "isSeen": false, + "isDelivered": false, + "targetUserId": userDetails["targetUser"].id, + "targetUserStatus": 4, + } ], // "server": "https://192.168.8.163:8086", "server": "https://livecareturn.hmg.com:8086", }; - - CallDataModel incomingCallData = CallDataModel.fromJson(json); + CallDataModel callData = CallDataModel.fromJson(json); await Navigator.push( context, MaterialPageRoute( builder: (BuildContext context) => OutGoingCall( isVideoCall: callType == "VIDEO" ? true : false, - OutGoingCallData: incomingCallData, + OutGoingCallData: callData, ), ), ); diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 816aaec..63523f5 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -135,6 +135,22 @@ class _ChatHomeScreenState extends State { 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( @@ -193,7 +209,7 @@ class _ChatHomeScreenState extends State { AppRoutes.chatDetailed, arguments: {"targetUser": m.searchedChats![index], "isNewChat": false}, ).then((Object? value) { - // m.GetUserChatHistoryNotDeliveredAsync(userId: int.parse(AppState().chatDetails!.response!.id.toString())); + // m.GetUserChatHistoryNotDeliveredAsync(userId: int.parse(AppState().chatDetails!.response!.id.toString())); m.clearSelections(); m.notifyListeners(); }); From 622404896cf1df7f1e23323476bb7d8f4db76d48 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 21 Nov 2022 16:44:23 +0300 Subject: [PATCH 2/8] Chat Updates & Counter Event Modifications --- lib/ui/chat/chat_detailed_screen.dart | 2 +- lib/ui/chat/chat_home.dart | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 1374608..787582d 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -69,7 +69,7 @@ class _ChatDetailScreenState extends State { } return Scaffold( - backgroundColor: const Color(0xFFF8F8F8), + backgroundColor: MyColors.backgroundColor, appBar: AppBarWidget(context, title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach, showHomeButton: false, diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index b2db98a..4286f52 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -36,6 +36,11 @@ class _ChatHomeState extends State { data = Provider.of(context, listen: false); data.getUserAutoLoginToken(context).whenComplete(() { data.getUserRecentChats(); + // GetUserChatHistoryNotDeliveredAsync( + // userId: int.parse( + // AppState().chatDetails!.response!.id.toString(), + // ), + // ); }); } From dc9d1715d9fa70619493fee3b5e32ee8ca1bc8ff Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 21 Nov 2022 16:44:55 +0300 Subject: [PATCH 3/8] Chat Updates & Counter Event Modifications --- lib/ui/chat/chat_home.dart | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 4286f52..b2db98a 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -36,11 +36,6 @@ class _ChatHomeState extends State { data = Provider.of(context, listen: false); data.getUserAutoLoginToken(context).whenComplete(() { data.getUserRecentChats(); - // GetUserChatHistoryNotDeliveredAsync( - // userId: int.parse( - // AppState().chatDetails!.response!.id.toString(), - // ), - // ); }); } From eb7e5a4837db77c29e3ebab6e7db435a92583734 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Tue, 22 Nov 2022 12:28:17 +0300 Subject: [PATCH 4/8] Chat Updates & Stability --- lib/api/chat/chat_api_client.dart | 103 ++++++++ lib/main.dart | 2 +- .../chat_provider_model.dart | 240 +++++------------- lib/provider/dashboard_provider_model.dart | 15 ++ lib/ui/chat/chat_detailed_screen.dart | 7 +- lib/ui/chat/chat_home.dart | 9 +- lib/ui/chat/chat_home_screen.dart | 44 ++-- lib/ui/chat/favorite_users_screen.dart | 2 +- lib/ui/landing/dashboard_screen.dart | 31 +++ .../search_employee_bottom_sheet.dart | 10 +- 10 files changed, 247 insertions(+), 216 deletions(-) create mode 100644 lib/api/chat/chat_api_client.dart rename lib/{api/chat => provider}/chat_provider_model.dart (73%) diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart new file mode 100644 index 0000000..0d1653d --- /dev/null +++ b/lib/api/chat/chat_api_client.dart @@ -0,0 +1,103 @@ +import 'dart:convert'; +import 'dart:io'; + +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/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; + +class ChatApiClient { + static final ChatApiClient _instance = ChatApiClient._internal(); + + ChatApiClient._internal(); + + factory ChatApiClient() => _instance; + + Future getUserLoginToken() async { + Response response = await ApiClient().postJsonForResponse( + "${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", + { + "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), + "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", + }, + ); + user.UserAutoLoginModel userLoginResponse = user.userAutoLoginModelFromJson( + response.body, + ); + return userLoginResponse; + } + + Future?> getChatMemberFromSearch(String sName, int cUserId) async { + Response response = await ApiClient().getJsonForResponse( + "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSearchMember}$sName/$cUserId", + token: AppState().chatDetails!.response!.token, + ); + return searchUserJsonModel(response.body); + } + + List searchUserJsonModel(String str) => List.from( + json.decode(str).map((x) => ChatUser.fromJson(x)), + ); + + Future getRecentChats() async { + Response response = await ApiClient().getJsonForResponse( + "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatRecentUrl}", + token: AppState().chatDetails!.response!.token, + ); + return ChatUserModel.fromJson( + json.decode(response.body), + ); + } + + Future getFavUsers() async { + Response favRes = await ApiClient().getJsonForResponse( + "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatFavoriteUsers}${AppState().chatDetails!.response!.id}", + token: AppState().chatDetails!.response!.token, + ); + return ChatUserModel.fromJson( + json.decode(favRes.body), + ); + } + + Future getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false, required int paginationVal}) async { + Response response = await ApiClient().getJsonForResponse( + "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal", + token: AppState().chatDetails!.response!.token, + ); + return response; + } + + Future favUser({required int userID, required int targetUserID}) async { + Response response = await ApiClient().postJsonForResponse( + "${ApiConsts.chatServerBaseApiUrl}FavUser/addFavUser", + { + "targetUserId": targetUserID, + "userId": userID, + }, + token: AppState().chatDetails!.response!.token); + fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); + return favoriteChatUser; + } + + Future unFavUser({required int userID, required int targetUserID}) async { + Response response = await ApiClient().postJsonForResponse( + "${ApiConsts.chatServerBaseApiUrl}FavUser/deleteFavUser", + {"targetUserId": targetUserID, "userId": userID}, + token: AppState().chatDetails!.response!.token, + ); + fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); + return favoriteChatUser; + } + + Future uploadMedia(String userId, File file) async { + dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatMediaImageUploadUrl}')); + request.fields.addAll({'userId': userId, 'fileSource': '1'}); + request.files.add(await MultipartFile.fromPath('files', file.path)); + request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'}); + StreamedResponse response = await request.send(); + return response; + } +} diff --git a/lib/main.dart b/lib/main.dart index a2ae0ae..4d686b8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,7 +3,7 @@ import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:logger/logger.dart'; -import 'package:mohem_flutter_app/api/chat/chat_provider_model.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/config/routes.dart'; import 'package:mohem_flutter_app/generated/codegen_loader.g.dart'; diff --git a/lib/api/chat/chat_provider_model.dart b/lib/provider/chat_provider_model.dart similarity index 73% rename from lib/api/chat/chat_provider_model.dart rename to lib/provider/chat_provider_model.dart index a019294..01eb0ad 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -1,21 +1,21 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; - 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/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/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'; 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/ui/landing/dashboard_screen.dart'; import 'package:mohem_flutter_app/widgets/image_picker.dart'; import 'package:signalr_netcore/signalr_client.dart'; import 'package:uuid/uuid.dart'; @@ -26,9 +26,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { TextEditingController search = TextEditingController(); List userChatHistory = []; List? pChatHistory, searchedChats; - late HubConnection hubConnection; - L.Logger logger = L.Logger(); - bool hubConInitialized = false; String chatCID = ''; bool isLoading = true; bool isChatScreenActive = false; @@ -40,56 +37,20 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List favUsersList = []; int paginationVal = 0; - Future getUserAutoLoginToken(BuildContext cxt) async { - Response response = await ApiClient().postJsonForResponse( - "${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", - { - "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", - }, - ); - login.UserAutoLoginModel userLoginResponse = login.userAutoLoginModelFromJson( - response.body, - ); - - if (userLoginResponse.response != null) { - hubConInitialized = true; - AppState().setchatUserDetails = userLoginResponse; - await buildHubConnection(); - } else { - Utils.showToast( - userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr", - ); - return; - } - } - - Future?> getChatMemberFromSearch(String sName, int cUserId) async { - Response response = await ApiClient().getJsonForResponse( - "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSearchMember}$sName/$cUserId", - token: AppState().chatDetails!.response!.token, - ); - return searchUserJsonModel(response.body); + void registerEvents() { + hubConnection.on("OnUpdateUserStatusAsync", changeStatus); + hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); + // hubConnection.on("OnSeenChatUserAsync", onChatSeen); + //hubConnection.on("OnUserTypingAsync", onUserTyping); + hubConnection.on("OnUserCountAsync", userCountAsync); + hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); + hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); + hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); } - List searchUserJsonModel(String str) => List.from( - json.decode(str).map( - (x) => ChatUser.fromJson(x), - ), - ); - void getUserRecentChats() async { - Response response = await ApiClient().getJsonForResponse( - "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatRecentUrl}", - token: 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, - ); - ChatUserModel favUList = userToList(favRes.body); + ChatUserModel recentChat = await ChatApiClient().getRecentChats(); + ChatUserModel favUList = await ChatApiClient().getFavUsers(); if (favUList.response != null && recentChat.response != null) { favUsersList = favUList.response!; @@ -108,14 +69,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } pChatHistory = recentChat.response ?? []; pChatHistory!.sort( - (ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo( - b.userName!.toLowerCase(), - ), + (ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase()), ); - searchedChats = pChatHistory; isLoading = false; - getUserChatHistoryNotDeliveredAsync( + await getUserChatHistoryNotDeliveredAsync( userId: int.parse( AppState().chatDetails!.response!.id.toString(), ), @@ -124,14 +82,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } Future getUserChatHistoryNotDeliveredAsync({required int userId}) async { - await hubConnection.invoke( - "GetUserChatHistoryNotDeliveredAsync", - args: [userId], - ).onError( - (Error error, StackTrace stackTrace) => { - logger.d(error), - }, - ); + // try { + await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]); + // } finally { + // hubConnection.off("OnGetUserChatHistoryNotDeliveredAsync", method: chatNotDelivered); + // } + return ""; } @@ -140,9 +96,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { if (isNewChat) userChatHistory = []; if (!loadMore) paginationVal = 0; isChatScreenActive = true; - Response response = await ApiClient().getJsonForResponse( - "${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal", - token: AppState().chatDetails!.response!.token, + Response response = await ChatApiClient().getSingleUserChatHistory( + senderUID: senderUID, + receiverUID: receiverUID, + loadMore: loadMore, + paginationVal: paginationVal, ); if (response.statusCode == 204) { if (isNewChat) { @@ -165,9 +123,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ).reversed.toList(); } } - await getUserChatHistoryNotDeliveredAsync( - userId: senderUID, - ); isLoading = false; notifyListeners(); markRead( @@ -184,16 +139,18 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void markRead(List data, reciverID) { for (SingleUserChatModel element in data!) { - if (!element.isSeen!) { - dynamic data = [ - { - "userChatHistoryId": element.userChatHistoryId, - "TargetUserId": element.targetUserId, - "isDelivered": true, - "isSeen": true, - } - ]; - updateUserChatHistoryStatusAsync(data); + if (element.isSeen != null) { + if (!element.isSeen!) { + dynamic data = [ + { + "userChatHistoryId": element.userChatHistoryId, + "TargetUserId": element.targetUserId, + "isDelivered": true, + "isSeen": true, + } + ]; + updateUserChatHistoryStatusAsync(data); + } } } for (ChatUser element in searchedChats!) { @@ -217,34 +174,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ), ); - ChatUserModel userToList(String str) => ChatUserModel.fromJson( - json.decode(str), - ); - Future uploadAttachments(String userId, File file) async { dynamic result; - dynamic request = MultipartRequest( - 'POST', - Uri.parse( - '${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatMediaImageUploadUrl}', - ), - ); - request.fields.addAll( - {'userId': userId, 'fileSource': '1'}, - ); - request.files.add( - await MultipartFile.fromPath( - 'files', - file.path, - ), - ); - request.headers.addAll( - { - 'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}', - }, - ); try { - StreamedResponse response = await request.send(); + StreamedResponse response = await ChatApiClient().uploadMedia(userId, file); if (response.statusCode == 200) { result = jsonDecode( await response.stream.bytesToString(), @@ -253,60 +186,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { result = []; } } catch (e) { - if (kDebugMode) { - print(e); - } + print(e); } ; return result; } - Future buildHubConnection() async { - HttpConnectionOptions httpOp = HttpConnectionOptions( - skipNegotiation: false, - logMessageContent: true, - ); - hubConnection = HubConnectionBuilder() - .withUrl( - ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", - options: httpOp, - ) - .withAutomaticReconnect( - retryDelays: [ - 2000, - 5000, - 10000, - 20000, - ], - ) - .configureLogging( - Logger("Loggin"), - ) - .build(); - hubConnection.onclose( - ({Exception? error}) {}, - ); - hubConnection.onreconnecting( - ({Exception? error}) {}, - ); - hubConnection.onreconnected( - ({String? connectionId}) {}, - ); - if (hubConnection.state != HubConnectionState.Connected) { - await hubConnection.start(); - print("Connnnnn Stablished"); - hubConnection.on("OnUpdateUserStatusAsync", changeStatus); - hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); - // hubConnection.on("OnSeenChatUserAsync", onChatSeen); - - //hubConnection.on("OnUserTypingAsync", onUserTyping); - hubConnection.on("OnUserCountAsync", userCountAsync); - hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); - hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); - hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); - } - } - void updateUserChatStatus(List? args) { dynamic items = args!.toList(); for (dynamic cItem in items[0]) { @@ -359,6 +244,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void chatNotDelivered(List? args) { dynamic items = args!.toList(); + logger.d(items); for (dynamic item in items[0]) { searchedChats!.forEach( (ChatUser element) { @@ -374,11 +260,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } void changeStatus(List? args) { - if (kDebugMode) { - // print("================= Status Online // Offline ===================="); - } dynamic items = args!.toList(); - // logger.d(items); for (ChatUser user in searchedChats!) { if (user.id == items.first["id"]) { user.userStatus = items.first["userStatus"]; @@ -413,14 +295,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { data.first.currentUserId = temp.first.targetUserId; data.first.currentUserName = temp.first.targetUserName; } + logger.d(jsonEncode(data)); userChatHistory.insert(0, data.first); - // searchedChats!.forEach((element) { - // if (element.id == data.first.currentUserId) { - // var val = element.unreadMessageCount == null ? 0 : element.unreadMessageCount; - // element.unreadMessageCount = val! + 1; - // } - // }); - var list = [ { "userChatHistoryId": data.first.userChatHistoryId, @@ -430,14 +306,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } ]; updateUserChatHistoryStatusAsync(list); - notifyListeners(); - // if (isChatScreenActive) scrollToBottom(); } void onUserTyping(List? parameters) { - // print("==================== Typing Active =================="); - // logger.d(parameters); for (ChatUser user in searchedChats!) { if (user.id == parameters![1] && parameters[0] == true) { user.isTyping = parameters[0] as bool?; @@ -572,7 +444,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } if (!isFileSelected && !isMsgReply) { - logger.d("Normal Text Message"); if (message.text == null || message.text.isEmpty) { return; } @@ -580,14 +451,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } if (isFileSelected && !isMsgReply) { Utils.showLoading(context); - //logger.d("Normal Attachment Message"); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); String? ext = getFileExtension(selectedFile.path); Utils.hideLoading(context); sendChatToServer(chatEventId: 2, fileTypeId: getFileType(ext.toString()), targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: true, chatReplyId: null, isReply: false); } if (!isFileSelected && isMsgReply) { - // logger.d("Normal Text Message With Reply"); if (message.text == null || message.text.isEmpty) { return; } @@ -595,7 +464,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, chatReplyId: repliedMsg.first.userChatHistoryId, isAttachment: false, isReply: true); } if (isFileSelected && isMsgReply) { - // logger.d("Attachment Message With Reply"); Utils.showLoading(context); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); String? ext = getFileExtension(selectedFile.path); @@ -708,9 +576,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } Future favoriteUser({required int userID, required int targetUserID}) async { - Response response = - await ApiClient().postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token); - fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); + fav.FavoriteChatUser favoriteChatUser = await ChatApiClient().favUser(userID: userID, targetUserID: targetUserID); if (favoriteChatUser.response != null) { for (ChatUser user in searchedChats!) { if (user.id == favoriteChatUser.response!.targetUserId!) { @@ -723,16 +589,16 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } Future unFavoriteUser({required int userID, required int targetUserID}) async { - Response response = await ApiClient() - .postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/deleteFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token); - fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); + fav.FavoriteChatUser favoriteChatUser = await ChatApiClient().unFavUser(userID: userID, targetUserID: targetUserID); 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.removeWhere((ChatUser element) => element.id == targetUserID); + favUsersList.removeWhere( + (ChatUser element) => element.id == targetUserID, + ); } notifyListeners(); } @@ -784,4 +650,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { curve: Curves.easeIn, ); } + +// void getUserChatHistoryNotDeliveredAsync({required int userId}) async { +// try { +// await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]); +// } finally { +// hubConnection.off("GetUserChatHistoryNotDeliveredAsync", method: chatNotDelivered); +// } +// } } diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index 948e5b4..e0c90c9 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -1,13 +1,16 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/api/chat/chat_api_client.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/api/offers_and_discounts_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/chat/chat_count_conversation_model.dart'; +import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart'; import 'package:mohem_flutter_app/models/dashboard/drawer_menu_item_model.dart'; import 'package:mohem_flutter_app/models/dashboard/get_accrual_balances_list_model.dart'; import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart'; @@ -287,6 +290,18 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } + Future getUserAutoLoginToken() async { + logger.d("Token Generated On Home"); + UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken(); + if (userLoginResponse.response != null) { + AppState().setchatUserDetails = userLoginResponse; + } else { + Utils.showToast( + userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr", + ); + } + } + void notify() { notifyListeners(); } diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 787582d..a3cf2e9 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -4,7 +4,7 @@ import 'dart:convert'; import 'package:easy_localization/easy_localization.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/provider/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/extensions/int_extensions.dart'; @@ -15,6 +15,7 @@ import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/chat/call.dart'; import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart'; import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart'; +import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:provider/provider.dart'; @@ -79,7 +80,7 @@ class _ChatDetailScreenState extends State { onPressed: () { makeCall( callType: "AUDIO", - con: data.hubConnection, + con: hubConnection, ); }, icon: SvgPicture.asset( @@ -92,7 +93,7 @@ class _ChatDetailScreenState extends State { onPressed: () { makeCall( callType: "VIDEO", - con: data.hubConnection, + con: hubConnection, ); }, icon: SvgPicture.asset( diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index b2db98a..3ad9b12 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -2,7 +2,7 @@ import 'dart:convert'; 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/provider/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'; @@ -31,21 +31,14 @@ class _ChatHomeState extends State { @override void initState() { - // TODO: implement initState super.initState(); data = Provider.of(context, listen: false); - data.getUserAutoLoginToken(context).whenComplete(() { - data.getUserRecentChats(); - }); } @override void dispose() { super.dispose(); data.clearAll(); - if (data.hubConInitialized) { - data.hubConnection.stop(); - } } @override diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 63523f5..a6f91b8 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -2,7 +2,7 @@ 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/provider/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'; @@ -21,6 +21,16 @@ class ChatHomeScreen extends StatefulWidget { class _ChatHomeScreenState extends State { TextEditingController search = TextEditingController(); + late ChatProviderModel data; + + @override + void initState() { + // TODO: implement initState + super.initState(); + data = Provider.of(context, listen: false); + data.registerEvents(); + data.getUserRecentChats(); + } @override void dispose() { @@ -135,22 +145,22 @@ class _ChatHomeScreenState extends State { 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].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( diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart index 7ef0f84..8f303cd 100644 --- a/lib/ui/chat/favorite_users_screen.dart +++ b/lib/ui/chat/favorite_users_screen.dart @@ -1,7 +1,7 @@ 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/provider/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'; diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 130c75b..52b5ade 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -7,6 +7,7 @@ import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_svg/flutter_svg.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/consts.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; @@ -26,6 +27,9 @@ import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart' import 'package:mohem_flutter_app/widgets/shimmer/offers_shimmer_widget.dart'; import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; +import 'package:signalr_netcore/signalr_client.dart'; + +late HubConnection hubConnection; class DashboardScreen extends StatefulWidget { DashboardScreen({Key? key}) : super(key: key); @@ -49,13 +53,40 @@ class _DashboardScreenState extends State { super.initState(); scheduleMicrotask(() { data = Provider.of(context, listen: false); + data.getUserAutoLoginToken().whenComplete(() { + buildHubConnection(); + }); + _onRefresh(); }); } + Future buildHubConnection() async { + logger.d("Connnnnn Statred"); + HttpConnectionOptions httpOp = HttpConnectionOptions( + skipNegotiation: false, + logMessageContent: true, + ); + hubConnection = HubConnectionBuilder() + .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp) + .withAutomaticReconnect(retryDelays: [2000, 5000, 10000, 20000]).build(); + hubConnection.onclose(({Exception? error}) { + logger.d("Con Closedddddd"); + }); + hubConnection.onreconnecting(({Exception? error}) {}); + hubConnection.onreconnected(({String? connectionId}) {}); + + if (hubConnection.state != HubConnectionState.Connected) { + await hubConnection.start(); + } + + + } + @override void dispose() { super.dispose(); + hubConnection.stop(); } void _onRefresh() async { diff --git a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart index b88b96f..32b501c 100644 --- a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart +++ b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart @@ -5,7 +5,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; +import 'package:mohem_flutter_app/api/chat/chat_api_client.dart'; import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; @@ -88,7 +88,12 @@ class _SearchEmployeeBottomSheetState extends State { void fetchChatUser({bool isNeedLoading = true}) async { try { Utils.showLoading(context); - chatUsersList = await ChatProviderModel().getChatMemberFromSearch(searchText, int.parse(AppState().chatDetails!.response!.id.toString())); + chatUsersList = await ChatApiClient().getChatMemberFromSearch( + searchText, + int.parse( + AppState().chatDetails!.response!.id.toString(), + ), + ); Utils.hideLoading(context); setState(() {}); } catch (e) { @@ -236,7 +241,6 @@ class _SearchEmployeeBottomSheetState extends State { arguments: {"targetUser": chatUsersList![index], "isNewChat": true}, ); }, - ), ); }, From 68ebecf98ab9f2effaf7b097257d5a7c0175cfa2 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Tue, 22 Nov 2022 12:49:42 +0300 Subject: [PATCH 5/8] Chat Updates & Stability --- lib/provider/dashboard_provider_model.dart | 14 ++++++++++++ lib/ui/landing/dashboard_screen.dart | 26 +++++----------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index e0c90c9..b785293 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -5,6 +5,7 @@ import 'package:mohem_flutter_app/api/chat/chat_api_client.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/api/offers_and_discounts_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/config/routes.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; @@ -24,6 +25,7 @@ import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/itg/itg_response_model.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; +import 'package:signalr_netcore/signalr_client.dart'; /// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool // ignore: prefer_mixin @@ -40,6 +42,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { //Chat bool isChatCounterLoding = true; + bool isChatHubLoding = true; int chatUConvCounter = 0; //Misssing Swipe @@ -100,6 +103,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { leaveBalanceAccrual = null; isChatCounterLoding = true; + isChatHubLoding = true; chatUConvCounter = 0; ticketBalance = 0; @@ -302,6 +306,16 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } + Future getHubConnection() async { + HubConnection hub; + HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); + hub = HubConnectionBuilder() + .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp) + .withAutomaticReconnect(retryDelays: [2000, 5000, 10000, 20000]).build(); + isChatHubLoding = false; + return hub; + } + void notify() { notifyListeners(); } diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 52b5ade..2de3310 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -56,31 +56,15 @@ class _DashboardScreenState extends State { data.getUserAutoLoginToken().whenComplete(() { buildHubConnection(); }); - _onRefresh(); }); } - Future buildHubConnection() async { - logger.d("Connnnnn Statred"); - HttpConnectionOptions httpOp = HttpConnectionOptions( - skipNegotiation: false, - logMessageContent: true, - ); - hubConnection = HubConnectionBuilder() - .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp) - .withAutomaticReconnect(retryDelays: [2000, 5000, 10000, 20000]).build(); - hubConnection.onclose(({Exception? error}) { - logger.d("Con Closedddddd"); - }); - hubConnection.onreconnecting(({Exception? error}) {}); - hubConnection.onreconnected(({String? connectionId}) {}); - - if (hubConnection.state != HubConnectionState.Connected) { - await hubConnection.start(); - } - - + void buildHubConnection() async { + logger.d("Connection In Progresssss"); + hubConnection = await data.getHubConnection(); + await hubConnection.start(); + logger.d("Connection Done"); } @override From ed15ce92b6759fb378956ee49cccacc6613288ec Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Tue, 22 Nov 2022 12:50:59 +0300 Subject: [PATCH 6/8] Chat Updates & Stability --- lib/ui/landing/dashboard_screen.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 2de3310..3007c88 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -61,10 +61,8 @@ class _DashboardScreenState extends State { } void buildHubConnection() async { - logger.d("Connection In Progresssss"); hubConnection = await data.getHubConnection(); await hubConnection.start(); - logger.d("Connection Done"); } @override From db3e1427c5299217bd4c21c5c0baca235a335b79 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Thu, 24 Nov 2022 16:29:28 +0300 Subject: [PATCH 7/8] Advertisement Image/ Video Module --- lib/classes/consts.dart | 4 +- lib/provider/chat_provider_model.dart | 47 +++--- lib/ui/chat/chat_bubble.dart | 12 +- lib/ui/landing/dashboard_screen.dart | 86 +++++------ .../itg/its_add_screen_video_image.dart | 138 ++++++++++++++++++ lib/ui/landing/itg/video_page.dart | 96 ------------ 6 files changed, 213 insertions(+), 170 deletions(-) create mode 100644 lib/ui/landing/itg/its_add_screen_video_image.dart delete mode 100644 lib/ui/landing/itg/video_page.dart 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/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index 01eb0ad..81cb8b5 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -73,7 +73,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ); searchedChats = pChatHistory; isLoading = false; - await getUserChatHistoryNotDeliveredAsync( + await invokeUserChatHistoryNotDeliveredAsync( userId: int.parse( AppState().chatDetails!.response!.id.toString(), ), @@ -81,13 +81,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } - Future getUserChatHistoryNotDeliveredAsync({required int userId}) async { - // try { + Future invokeUserChatHistoryNotDeliveredAsync({required int userId}) async { await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]); - // } finally { - // hubConnection.off("OnGetUserChatHistoryNotDeliveredAsync", method: chatNotDelivered); - // } - return ""; } @@ -137,26 +132,28 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { chatCID = uuid.v4(); } - void markRead(List data, reciverID) { - for (SingleUserChatModel element in data!) { - if (element.isSeen != null) { - if (!element.isSeen!) { - dynamic data = [ - { - "userChatHistoryId": element.userChatHistoryId, - "TargetUserId": element.targetUserId, - "isDelivered": true, - "isSeen": true, - } - ]; - updateUserChatHistoryStatusAsync(data); + void markRead(List data, int receiverID) { + if (data != null) { + for (SingleUserChatModel element in data!) { + if (element.isSeen != null) { + if (!element.isSeen!) { + dynamic data = [ + { + "userChatHistoryId": element.userChatHistoryId, + "TargetUserId": element.targetUserId, + "isDelivered": true, + "isSeen": true, + } + ]; + updateUserChatHistoryStatusAsync(data); + } } } - } - for (ChatUser element in searchedChats!) { - if (element.id == reciverID) { - element.unreadMessageCount = 0; - notifyListeners(); + for (ChatUser element in searchedChats!) { + if (element.id == receiverID) { + element.unreadMessageCount = 0; + notifyListeners(); + } } } } diff --git a/lib/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index 1696a49..1f6e5dd 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -132,12 +132,12 @@ class ChatBubble extends StatelessWidget { color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7), ), if (isCurrentUser) 5.width, - // if (isCurrentUser) - // Icon( - // isDelivered ? Icons.done_all : Icons.done_all, - // color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor, - // size: 14, - // ), + if (isCurrentUser) + Icon( + isDelivered ? Icons.done_all : Icons.done_all, + color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor, + size: 14, + ), ], ), ], diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 3007c88..d433e09 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -1,10 +1,12 @@ import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/api/dashboard_api_client.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/consts.dart'; @@ -17,6 +19,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; +import 'package:mohem_flutter_app/ui/landing/itg/its_add_screen_video_image.dart'; import 'package:mohem_flutter_app/ui/landing/widget/app_drawer.dart'; import 'package:mohem_flutter_app/ui/landing/widget/menus_widget.dart'; import 'package:mohem_flutter_app/ui/landing/widget/services_widget.dart'; @@ -53,9 +56,7 @@ class _DashboardScreenState extends State { super.initState(); scheduleMicrotask(() { data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().whenComplete(() { - buildHubConnection(); - }); + _bHubCon(); _onRefresh(); }); } @@ -71,6 +72,12 @@ class _DashboardScreenState extends State { hubConnection.stop(); } + void _bHubCon() { + data.getUserAutoLoginToken().whenComplete(() { + buildHubConnection(); + }); + } + void _onRefresh() async { data.initProvider(); // data.getITGNotification().then((value) { @@ -93,44 +100,41 @@ class _DashboardScreenState extends State { Widget build(BuildContext context) { return Scaffold( key: _scaffoldState, - // appBar: AppBar( - // actions: [ - // IconButton( - // onPressed: () { - // data.getITGNotification().then((value) { - // print("--------------------detail_1-----------------"); - // if (value!.result!.data != null) { - // print(value.result!.data!.notificationMasterId); - // print(value.result!.data!.notificationType); - // if (value.result!.data!.notificationType == "Survey") { - // Navigator.pushNamed(context, AppRoutes.survey, arguments: value.result!.data); - // } else { - // DashboardApiClient().getAdvertisementDetail(value.result!.data!.notificationMasterId ?? "").then( - // (value) { - // if (value!.mohemmItgResponseItem!.statusCode == 200) { - // if (value.mohemmItgResponseItem!.result!.data != null) { - // String? image64 = value.mohemmItgResponseItem!.result!.data!.advertisement!.viewAttachFileColl!.first.base64String; - // print(image64); - // var sp = image64!.split("base64,"); - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => MovieTheaterBody( - // encodedBytes: sp[1], - // ), - // ), - // ); - // } - // } - // }, - // ); - // } - // } - // }); - // }, - // icon: Icon(Icons.add)) - // ], - // ), + appBar: AppBar( + actions: [ + IconButton( + onPressed: () { + data.getITGNotification().then((value) { + if (value!.result!.data != null) { + if (value.result!.data!.notificationType == "Survey") { + Navigator.pushNamed(context, AppRoutes.survey, arguments: value.result!.data); + } else { + DashboardApiClient().getAdvertisementDetail(value.result!.data!.notificationMasterId ?? "").then( + (value) { + if (value!.mohemmItgResponseItem!.statusCode == 200) { + if (value.mohemmItgResponseItem!.result!.data != null) { + String? rFile = value.mohemmItgResponseItem!.result!.data!.advertisement!.viewAttachFileColl!.first.base64String; + String? rFileExt = value.mohemmItgResponseItem!.result!.data!.advertisement!.viewAttachFileColl!.first.fileName; + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => ITGAdsScreen( + encodedBytes: rFile!, + fileExtenshion: rFileExt!, + ), + ), + ); + } + } + }, + ); + } + } + }); + }, + icon: Icon(Icons.add)) + ], + ), body: Column( children: [ Row( diff --git a/lib/ui/landing/itg/its_add_screen_video_image.dart b/lib/ui/landing/itg/its_add_screen_video_image.dart new file mode 100644 index 0000000..1d9c41f --- /dev/null +++ b/lib/ui/landing/itg/its_add_screen_video_image.dart @@ -0,0 +1,138 @@ +import 'dart:convert'; +import 'dart:io' as Io; +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:video_player/video_player.dart'; + +class ITGAdsScreen extends StatefulWidget { + final String encodedBytes; + final String fileExtension; + + const ITGAdsScreen({required this.encodedBytes, required this.fileExtension}); + + @override + _ITGAdsScreenState createState() => _ITGAdsScreenState(); +} + +class _ITGAdsScreenState extends State { + late Future _futureController; + late VideoPlayerController _controller; + bool skip = false; + + Future createVideoPlayer() async { + try { + Uint8List decodedBytes = base64Decode(widget.encodedBytes.split("base64,").last); + Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1 + File file = Io.File("${appDocumentsDirectory.path}/myAdsVideo.mp4"); + file.writeAsBytesSync(decodedBytes); + VideoPlayerController controller = VideoPlayerController.file(file); + await controller.initialize(); + await controller.play(); + await controller.setVolume(1.0); + await controller.setLooping(false); + return controller; + } catch (e) { + return new VideoPlayerController.asset("dataSource"); + } + } + + void checkType(){ + + // getFileTypeDescription(value); + + + } + + String getFileTypeDescription(String value) { + switch (value) { + case ".pdf": + return "application/pdf"; + case ".png": + return "image/png"; + case ".txt": + return "text/plain"; + case ".jpg": + return "image/jpg"; + case ".jpeg": + return "image/jpeg"; + case ".ppt": + return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; + case ".pptx": + return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; + case ".doc": + return "application/vnd.openxmlformats-officedocument.wordprocessingm"; + case ".docx": + return "application/vnd.openxmlformats-officedocument.wordprocessingm"; + case ".xls": + return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + case ".xlsx": + return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + case ".zip": + return "application/octet-stream"; + case ".rar": + return "application/octet-stream"; + default: + return ""; + } + } + + @override + void initState() { + _futureController = createVideoPlayer(); + initTimer(); + super.initState(); + } + + void initTimer() { + Future.delayed(const Duration(milliseconds: 500), () { + setState(() { + skip = true; + }); + }); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + double height = MediaQuery.of(context).size.height * .25; + return Scaffold( + body: Column( + children: [ + SizedBox( + height: MediaQuery.of(context).size.height * .3, + child: FutureBuilder( + future: _futureController, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) { + _controller = snapshot.data as VideoPlayerController; + return AspectRatio( + aspectRatio: _controller.value.aspectRatio, + child: VideoPlayer(_controller), + ); + } else { + return const Center( + child: CircularProgressIndicator(), + ); + } + }, + ), + ), + if (skip) + ElevatedButton( + onPressed: () {}, + child: const Text("Go To Dashboard"), + ) + ], + ), + ); + } +} diff --git a/lib/ui/landing/itg/video_page.dart b/lib/ui/landing/itg/video_page.dart deleted file mode 100644 index 657d714..0000000 --- a/lib/ui/landing/itg/video_page.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'dart:convert'; -import 'dart:io' as Io; - -import 'package:flutter/material.dart'; -import 'package:video_player/video_player.dart'; - -class MovieTheaterBody extends StatefulWidget { - final String encodedBytes; - - const MovieTheaterBody({required this.encodedBytes}); - - @override - _MovieTheaterBodyState createState() => _MovieTheaterBodyState(); -} - -class _MovieTheaterBodyState extends State { - late Future _futureController; - late VideoPlayerController _controller; - - Future createVideoPlayer() async { - try { - var decodedBytes = base64Decode(widget.encodedBytes); - - var file = Io.File("decodedBezkoder.mp4"); - file.writeAsBytesSync(decodedBytes); - - VideoPlayerController controller = VideoPlayerController.file(file); - await controller.initialize(); - await controller.setLooping(true); - return controller; - } catch (e) { - print("object0000000"); - print(e); - return new VideoPlayerController.asset("dataSource"); - } - } - - @override - void initState() { - _futureController = createVideoPlayer(); - super.initState(); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Expanded( - child: FutureBuilder( - future: _futureController, - builder: (context, snapshot) { - //UST: 05/2021 - MovieTheaterBody - id:11 - 2pts - Criação - if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) { - _controller = snapshot.data as VideoPlayerController; - return Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AspectRatio( - aspectRatio: _controller.value.aspectRatio, - child: VideoPlayer(_controller), - ), - const SizedBox( - height: 50, - ), - FloatingActionButton( - onPressed: () { - setState(() { - if (_controller.value.isPlaying) { - _controller.pause(); - } else { - // If the video is paused, play it. - _controller.play(); - } - }); - }, - backgroundColor: Colors.green[700], - child: Icon( - _controller.value.isPlaying ? Icons.pause : Icons.play_arrow, - ), - ) - ], - ); - } else { - return const Center(child: CircularProgressIndicator()); - } - }, - ), - ), - ); - } -} From fa7e08c215860c6a6d106766a2def51858a46eb5 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Sun, 27 Nov 2022 10:23:02 +0300 Subject: [PATCH 8/8] Advertisement Image/ Video Module --- lib/api/dashboard_api_client.dart | 14 ++ lib/ui/landing/dashboard_screen.dart | 68 +++++---- .../itg/its_add_screen_video_image.dart | 132 +++++++++--------- 3 files changed, 112 insertions(+), 102 deletions(-) diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index 9747e5c..69c2e82 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -186,4 +186,18 @@ class DashboardApiClient { ); return chatUnreadCovnCountModelFromJson(response.body); } + + // Future setAdvertisementViewed(String masterID, int advertisementId) async { + // String url = "${ApiConsts.cocRest}Mohemm_ITG_UpdateAdvertisementAsViewed"; + // + // Map postParams = { + // "ItgNotificationMasterId": masterID, + // "ItgAdvertisement": {"advertisementId": advertisementId, "acknowledgment": true} //Mobile Id + // }; + // postParams.addAll(AppState().postParamsJson); + // return await ApiClient().postJsonForObject((json) { + // // ItgMainRes responseData = ItgMainRes.fromJson(json); + // return json; + // }, url, postParams); + // } } diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index d433e09..c8cdcef 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -100,41 +100,39 @@ class _DashboardScreenState extends State { Widget build(BuildContext context) { return Scaffold( key: _scaffoldState, - appBar: AppBar( - actions: [ - IconButton( - onPressed: () { - data.getITGNotification().then((value) { - if (value!.result!.data != null) { - if (value.result!.data!.notificationType == "Survey") { - Navigator.pushNamed(context, AppRoutes.survey, arguments: value.result!.data); - } else { - DashboardApiClient().getAdvertisementDetail(value.result!.data!.notificationMasterId ?? "").then( - (value) { - if (value!.mohemmItgResponseItem!.statusCode == 200) { - if (value.mohemmItgResponseItem!.result!.data != null) { - String? rFile = value.mohemmItgResponseItem!.result!.data!.advertisement!.viewAttachFileColl!.first.base64String; - String? rFileExt = value.mohemmItgResponseItem!.result!.data!.advertisement!.viewAttachFileColl!.first.fileName; - Navigator.push( - context, - MaterialPageRoute( - builder: (BuildContext context) => ITGAdsScreen( - encodedBytes: rFile!, - fileExtenshion: rFileExt!, - ), - ), - ); - } - } - }, - ); - } - } - }); - }, - icon: Icon(Icons.add)) - ], - ), + // appBar: AppBar( + // actions: [ + // IconButton( + // onPressed: () { + // data.getITGNotification().then((val) { + // if (val!.result!.data != null) { + // if (val.result!.data!.notificationType == "Survey") { + // Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data); + // } else { + // DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then( + // (value) { + // if (value!.mohemmItgResponseItem!.statusCode == 200) { + // if (value.mohemmItgResponseItem!.result!.data != null) { + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (BuildContext context) => ITGAdsScreen( + // addMasterId: val.result!.data!.notificationMasterId!, + // advertisement: value.mohemmItgResponseItem!.result!.data!.advertisement!, + // ), + // ), + // ); + // } + // } + // }, + // ); + // } + // } + // }); + // }, + // icon: Icon(Icons.add)) + // ], + // ), body: Column( children: [ Row( diff --git a/lib/ui/landing/itg/its_add_screen_video_image.dart b/lib/ui/landing/itg/its_add_screen_video_image.dart index 1d9c41f..4b2e358 100644 --- a/lib/ui/landing/itg/its_add_screen_video_image.dart +++ b/lib/ui/landing/itg/its_add_screen_video_image.dart @@ -2,17 +2,20 @@ import 'dart:convert'; import 'dart:io' as Io; import 'dart:io'; import 'dart:typed_data'; - import 'package:flutter/material.dart'; +import 'package:just_audio/just_audio.dart'; +import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/main.dart'; +import 'package:mohem_flutter_app/models/itg/advertisement.dart' as ads; import 'package:path_provider/path_provider.dart'; import 'package:video_player/video_player.dart'; class ITGAdsScreen extends StatefulWidget { - final String encodedBytes; - final String fileExtension; + final String addMasterId; + final ads.Advertisement advertisement; - const ITGAdsScreen({required this.encodedBytes, required this.fileExtension}); + const ITGAdsScreen({required this.addMasterId, required this.advertisement}); @override _ITGAdsScreenState createState() => _ITGAdsScreenState(); @@ -22,10 +25,39 @@ class _ITGAdsScreenState extends State { late Future _futureController; late VideoPlayerController _controller; bool skip = false; + bool isVideo = false; + bool isImage = false; + String ext = ''; + late File imageFile; + + void checkFileType() async { + String? rFile = widget.advertisement!.viewAttachFileColl!.first.base64String; + String? rFileExt = widget.advertisement!.viewAttachFileColl!.first.fileName; + ext = "." + rFileExt!.split(".").last.toLowerCase(); + if (ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".gif") { + await processImage(rFile!); + isImage = true; + } else { + isVideo = true; + _futureController = createVideoPlayer(rFile!); + } + setState(() {}); + } + + Future processImage(String encodedBytes) async { + try { + Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last); + Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1 + imageFile = Io.File("${appDocumentsDirectory.path}/addImage$ext"); + imageFile.writeAsBytesSync(decodedBytes); + } catch (e) { + logger.d(e); + } + } - Future createVideoPlayer() async { + Future createVideoPlayer(String encodedBytes) async { try { - Uint8List decodedBytes = base64Decode(widget.encodedBytes.split("base64,").last); + Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last); Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1 File file = Io.File("${appDocumentsDirectory.path}/myAdsVideo.mp4"); file.writeAsBytesSync(decodedBytes); @@ -40,55 +72,15 @@ class _ITGAdsScreenState extends State { } } - void checkType(){ - - // getFileTypeDescription(value); - - - } - - String getFileTypeDescription(String value) { - switch (value) { - case ".pdf": - return "application/pdf"; - case ".png": - return "image/png"; - case ".txt": - return "text/plain"; - case ".jpg": - return "image/jpg"; - case ".jpeg": - return "image/jpeg"; - case ".ppt": - return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; - case ".pptx": - return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; - case ".doc": - return "application/vnd.openxmlformats-officedocument.wordprocessingm"; - case ".docx": - return "application/vnd.openxmlformats-officedocument.wordprocessingm"; - case ".xls": - return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; - case ".xlsx": - return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; - case ".zip": - return "application/octet-stream"; - case ".rar": - return "application/octet-stream"; - default: - return ""; - } - } - @override void initState() { - _futureController = createVideoPlayer(); + checkFileType(); initTimer(); super.initState(); } void initTimer() { - Future.delayed(const Duration(milliseconds: 500), () { + Future.delayed(const Duration(seconds: 5), () { setState(() { skip = true; }); @@ -107,28 +99,34 @@ class _ITGAdsScreenState extends State { return Scaffold( body: Column( children: [ - SizedBox( - height: MediaQuery.of(context).size.height * .3, - child: FutureBuilder( - future: _futureController, - builder: (BuildContext context, AsyncSnapshot snapshot) { - if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) { - _controller = snapshot.data as VideoPlayerController; - return AspectRatio( - aspectRatio: _controller.value.aspectRatio, - child: VideoPlayer(_controller), - ); - } else { - return const Center( - child: CircularProgressIndicator(), - ); - } - }, + if (isVideo) + SizedBox( + height: MediaQuery.of(context).size.height * .3, + child: FutureBuilder( + future: _futureController, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) { + _controller = snapshot.data as VideoPlayerController; + return AspectRatio( + aspectRatio: _controller.value.aspectRatio, + child: VideoPlayer(_controller), + ); + } else { + return const Center( + child: CircularProgressIndicator(), + ); + } + }, + ), ), - ), + if (isImage) Image.file(imageFile), if (skip) ElevatedButton( - onPressed: () {}, + onPressed: () async { + // DashboardApiClient().setAdvertisementViewed(widget.addMasterId, widget.advertisement!.advertisementId!).then((value) { + // logger.d(value); + // }); + }, child: const Text("Go To Dashboard"), ) ],