From f6f801f9cff59303cc5675677fa5a7710adc5e4a Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Sun, 4 Dec 2022 16:15:47 +0300 Subject: [PATCH 1/9] Chat Fixes & User Chat Counter --- lib/classes/consts.dart | 4 +- lib/classes/encryption.dart | 188 ++++++++++++++++++ lib/provider/chat_provider_model.dart | 17 +- lib/provider/dashboard_provider_model.dart | 20 +- lib/ui/chat/chat_bubble.dart | 32 ++- lib/ui/chat/chat_full_image_preview.dart | 57 +++--- lib/ui/chat/chat_home_screen.dart | 142 +------------ lib/ui/landing/dashboard_screen.dart | 11 + .../itg/its_add_screen_video_image.dart | 37 ++-- pubspec.yaml | 5 - 10 files changed, 304 insertions(+), 209 deletions(-) create mode 100644 lib/classes/encryption.dart diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 13c4258..841f29c 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,7 +3,7 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; 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://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/"; @@ -12,8 +12,6 @@ class ApiConsts { static String user = baseUrlServices + "api/User/"; static String cocRest = baseUrlServices + "COCWS.svc/REST/"; - // todo @aamir move api end point last repo to concerned method. - //Chat static String chatServerBaseUrl = "https://apiderichat.hmg.com/"; static String chatServerBaseApiUrl = chatServerBaseUrl + "api/"; diff --git a/lib/classes/encryption.dart b/lib/classes/encryption.dart new file mode 100644 index 0000000..67466fe --- /dev/null +++ b/lib/classes/encryption.dart @@ -0,0 +1,188 @@ +// import 'dart:convert'; +// +// import 'package:encrypt/encrypt.dart'; +// import 'package:crypto/crypto.dart'; +// +// class Encryption { +// static final Encryption instance = Encryption._(); +// +// late IV _iv; +// late Encrypter _encrypter; +// +// Encryption._() { +// const mykey = 'PeShVmYp'; +// const myiv = 'j70IbWYn'; +// var keyUtf8 = utf8.encode(mykey); +// var ivUtf8 = utf8.encode(myiv); +// var key = sha256.convert(keyUtf8).toString().substring(0, 32); +// var iv = sha256.convert(ivUtf8).toString().substring(0, 16); +// _iv = IV.fromUtf8(iv); +// +// _encrypter = Encrypter(AES(Key.fromUtf8(key), mode: AESMode.cbc)); +// } +// +// String encrypt(String value) { +// return _encrypter.encrypt(value, iv: _iv).base64; +// } +// +// String decrypt(String base64value) { +// var encrypted = Encrypted.fromBase64(base64value); +// return _encrypter.decrypt(encrypted, iv: _iv); +// } +// +// // +// // void passEncrypt(String text, String pass) async { +// // var salt = randomUint8List(8); +// // var keyndIV = deriveKeyAndIV(pass, salt); +// // var key = encrypt.Key(keyndIV.item1); +// // var iv = encrypt.IV(keyndIV.item2); +// // var encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: "PKCS7")); +// // var encrypted = encrypter.encrypt(text, iv: iv); +// // Uint8List encryptedBytesWithSalt = Uint8List.fromList(createUint8ListFromString("Salted__") + salt + encrypted.bytes); +// // var resulttt = base64.encode(encryptedBytesWithSalt); +// // print("Enc : " + resulttt); +// // +// // decryptAESCryptoJS(resulttt, pass); +// // } +// // +// // Uint8List randomUint8List(int length) { +// // assert(length > 0); +// // var random = Random(); +// // var ret = Uint8List(length); +// // for (var i = 0; i < length; i++) { +// // ret[i] = random.nextInt(256); +// // } +// // return ret; +// // } +// // +// // void decryptAESCryptoJS(String encrypted, String passphrase) { +// // try { +// // Uint8List encryptedBytesWithSalt = base64.decode(encrypted); +// // Uint8List encryptedBytes = encryptedBytesWithSalt.sublist(16, encryptedBytesWithSalt.length); +// // var salt = encryptedBytesWithSalt.sublist(8, 16); +// // var keyndIV = deriveKeyAndIV(passphrase, salt); +// // var key = encrypt.Key(keyndIV.item1); +// // var iv = encrypt.IV(keyndIV.item2); +// // var encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: "PKCS7")); +// // var decrypted = encrypter.decrypt64(base64.encode(encryptedBytes), iv: iv); +// // print("Dec : " + decrypted); +// // // return decrypted; +// // } catch (error) { +// // throw error; +// // } +// // } +// // +// // Future enc(String input) async { +// // var ekey = "PeShVmYpPeShVmYp"; +// // var eIV = "j70IbWYnj70IbWYn"; +// // +// // var abc = Encryption.instance.encrypt(input); +// // // +// // // var inputByt = utf8.encode(input); +// // // final encrypted = encrypter.encrypt(plainText); +// // // final decrypted = encrypter.decrypt(encrypted); +// // // +// // // print(decrypted); // Lorem ipsum dolor sit amet, consectetur adipiscing elit +// // // print(encrypted.base64); // R4PxiU3h8YoIRqVowBXm36ZcCeNeZ4s1OvVBTfFlZRdmohQqOpPQqD1YecJeZMAop/hZ4OxqgC1WtwvX/hP9mw== +// // // /// +// // +// // var key = encrypt.Key.fromUtf8(ekey.substring(0, 8)); +// // var iv = encrypt.IV.fromLength(8); +// // var encrypter = Encrypter(AES(key)); +// // var encrypted = encrypter.encrypt(input, iv: iv); +// // var decrypted = encrypter.decrypt(encrypted, iv: iv); +// // print("====== ORI =========="); +// // print("e4PTDencHsiLJv0XcbT2I4tafb7dqJP9c72PEnhp1Uv6U2GZ/gODtA=="); +// // print("====== ENC =========="); +// // print(encrypted.base64); +// // print("====== DEC =========="); +// // print(decrypted); +// // print("====== B64 =========="); +// // String bs64 = base64.encode(utf8.encode(input)); +// // print(bs64); +// // +// // // try { +// // // var cipher = _cipher; +// // // var secretBox = await cipher.encrypt( +// // // iByt, +// // // secretKey: SecretKeyData(eByt), +// // // nonce: eIvByt, +// // // ); +// // // print(utf8.decode(secretBox.cipherText)); +// // // } catch (error) { +// // // print(error); +// // // return; +// // // } +// // } +// // ///Accepts encrypted data and decrypt it. Returns plain text +// // String decryptWithAES(String key, Encrypted encryptedData) { +// // var cipherKey = encrypt.Key.fromUtf8(key); +// // var encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc,padding: null)); +// // var initVector = IV.fromUtf8(key.substring(0, 16)); +// // return encryptService.decrypt(encryptedData, iv: initVector); +// // } +// // +// // ///Encrypts the given plainText using the key. Returns encrypted data +// // Encrypted encryptWithAES(String key, String plainText) { +// // var cipherKey = encrypt.Key.fromUtf8(key); +// // var encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc,padding: null)); +// // var initVector = IV.fromUtf8("j70IbWYn"); +// // Encrypted encryptedData = encryptService.encrypt(plainText, iv: initVector); +// // print(encryptedData.base64); +// // return encryptedData; +// // } +// // +// // Tuple2 deriveKeyAndIV(String passphrase, Uint8List salt) { +// // var password = createUint8ListFromString(passphrase); +// // Uint8List concatenatedHashes = Uint8List(0); +// // Uint8List currentHash = Uint8List(0); +// // bool enoughBytesForKey = false; +// // Uint8List preHash = Uint8List(0); +// // +// // while (!enoughBytesForKey) { +// // int preHashLength = currentHash.length + password.length + salt.length; +// // if (currentHash.length > 0) +// // preHash = Uint8List.fromList(currentHash + password + salt); +// // else +// // preHash = Uint8List.fromList(password + salt); +// // +// // currentHash = preHash; +// // concatenatedHashes = Uint8List.fromList(concatenatedHashes + currentHash); +// // if (concatenatedHashes.length >= 48) enoughBytesForKey = true; +// // } +// // +// // var keyBtyes = concatenatedHashes.sublist(0, 32); +// // var ivBtyes = concatenatedHashes.sublist(32, 48); +// // return new Tuple2(keyBtyes, ivBtyes); +// // } +// // +// // Uint8List createUint8ListFromString(String s) { +// // var ret = new Uint8List(s.length); +// // for (var i = 0; i < s.length; i++) { +// // ret[i] = s.codeUnitAt(i); +// // } +// // return ret; +// // } +// // +// // Uint8List genRandomWithNonZero(int seedLength) { +// // var random = Random.secure(); +// // const int randomMax = 245; +// // Uint8List uint8list = Uint8List(seedLength); +// // for (int i = 0; i < seedLength; i++) { +// // uint8list[i] = random.nextInt(randomMax) + 1; +// // } +// // return uint8list; +// // } +// // +// // +// // +// // void test(String text, String kk) { +// // Uint8List key = Uint8List.fromList(utf8.encode(kk)); +// // PaddedBlockCipher cipher = exp.PaddedBlockCipherImpl(exp.PKCS7Padding(), exp.ECBBlockCipher(exp.AESEngine())); +// // cipher.init(true, PaddedBlockCipherParameters(KeyParameter(key), null)); +// // var byte = Uint8List.fromList(utf8.encode(text)); +// // var data = cipher.process(byte); +// // print(data); +// // } +// +// } diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index f3821f3..886951c 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -120,7 +120,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { if (element.isSeen != null) { if (!element.isSeen!) { print("Found Un Read"); - logger.d(jsonEncode(element)); + element.isSeen = true; dynamic data = [ {"userChatHistoryId": element.userChatHistoryId, "TargetUserId": element.targetUserId, "isDelivered": true, "isSeen": true} ]; @@ -131,9 +131,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { for (ChatUser element in searchedChats!) { if (element.id == receiverID) { element.unreadMessageCount = 0; - notifyListeners(); + // notifyListeners(); } } + notifyListeners(); } } @@ -223,7 +224,6 @@ 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) { @@ -288,8 +288,16 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } userChatHistory.insert(0, data.first); + if (searchedChats != null) { + for (ChatUser user in searchedChats!) { + if (user.id == data.first.currentUserId) { + var tempCount = user.unreadMessageCount ?? 0; + user.unreadMessageCount = tempCount + 1; + } + } + } - var list = [ + List list = [ {"userChatHistoryId": data.first.userChatHistoryId, "TargetUserId": temp.first.targetUserId, "isDelivered": true, "isSeen": isChatScreenActive ? true : false} ]; updateUserChatHistoryOnMsg(list); @@ -624,7 +632,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } void clearSelections() { - print("Hereee i am "); searchedChats = pChatHistory; search.clear(); isChatScreenActive = false; diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index 59b62b6..461196f 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -307,13 +307,21 @@ 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; + try { + 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; + } catch (e) { + getUserAutoLoginToken().whenComplete(() { + getHubConnection(); + }); + throw e; + } } + void notify() { notifyListeners(); } diff --git a/lib/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index 8995da1..ec772f6 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -28,6 +28,7 @@ class ChatBubble extends StatelessWidget { String? fileTypeDescription; bool isDelivered = false; String userName = ''; + late Offset screenOffset; void makeAssign() { isCurrentUser = cItem.currentUserId == AppState().chatDetails!.response!.id ? true : false; @@ -41,6 +42,8 @@ class ChatBubble extends StatelessWidget { @override Widget build(BuildContext context) { + Size windowSize = MediaQuery.of(context).size; + screenOffset = Offset(windowSize.width / 2, windowSize.height / 2); makeAssign(); return isCurrentUser ? currentUser(context) : receiptUser(context); } @@ -108,7 +111,11 @@ class ChatBubble extends StatelessWidget { ).paddingOnly(right: 5, bottom: 7), if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3) showImage(isReplyPreview: false, fileName: cItem.contant!, fileTypeDescription: cItem.fileTypeResponse!.fileTypeDescription).paddingOnly(right: 5).onPress(() { - showDialog(context: context, builder: (BuildContext context) => ChatImagePreviewScreen(imgTitle: cItem.contant!, img: cItem.image!)); + showDialog( + context: context, + anchorPoint: screenOffset, + builder: (BuildContext context) => ChatImagePreviewScreen(imgTitle: cItem.contant!, img: cItem.image!), + ); }), cItem.contant!.toText12(), Align( @@ -172,23 +179,28 @@ class ChatBubble extends StatelessWidget { ClipRRect( borderRadius: BorderRadius.circular(8.0), child: SizedBox( - height: 32, - width: 32, - child: showImage( - isReplyPreview: true, - fileName: cItem.userChatReplyResponse!.contant!, - fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg")), + height: 32, + width: 32, + child: showImage( + isReplyPreview: true, + fileName: cItem.userChatReplyResponse!.contant!, + fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg"), + ), ).paddingOnly(left: 10, right: 10, bottom: 16, top: 16) ], ), ), ).paddingOnly(right: 5, bottom: 7), if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3) - showImage(isReplyPreview: false, fileName: cItem.contant!, fileTypeDescription: cItem.fileTypeResponse!.fileTypeDescription ?? "image/jpg").paddingOnly(right: 5).onPress(() { - showDialog(context: context, builder: (BuildContext context) => ChatImagePreviewScreen(imgTitle: cItem.contant!, img: cItem.image!)); + showImage(isReplyPreview: false, fileName: cItem.contant ?? "", fileTypeDescription: cItem.fileTypeResponse!.fileTypeDescription ?? "image/jpg").paddingOnly(right: 5).onPress(() { + showDialog( + context: context, + anchorPoint: screenOffset, + builder: (BuildContext context) => ChatImagePreviewScreen(imgTitle: cItem.contant ?? "", img: cItem.image!), + ); }) else - (cItem.contant! ?? "").toText12(color: Colors.white), + (cItem.contant ?? "").toText12(color: Colors.white), Align( alignment: Alignment.centerRight, child: dateTime.toText10(color: Colors.white.withOpacity(.71)), diff --git a/lib/ui/chat/chat_full_image_preview.dart b/lib/ui/chat/chat_full_image_preview.dart index 26364c5..c731c25 100644 --- a/lib/ui/chat/chat_full_image_preview.dart +++ b/lib/ui/chat/chat_full_image_preview.dart @@ -12,29 +12,40 @@ class ChatImagePreviewScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return GestureDetector( - onTap: () { - Navigator.of(context).pop(); - }, - child: Dialog( - backgroundColor: Colors.transparent, - insetPadding: const EdgeInsets.all(10), - child: Stack( - alignment: Alignment.center, - children: [ - Image.memory( - img, - fit: BoxFit.cover, - height: 400, - width: double.infinity, - ).paddingAll(10), - const Positioned( - right: 0, - top: 0, - child: Icon(Icons.cancel, color: MyColors.redA3Color, size: 35), - ) - ], - ), + return Dialog( + backgroundColor: Colors.transparent, + insetPadding: const EdgeInsets.all(10), + child: Stack( + alignment: Alignment.center, + fit: StackFit.loose, + children: [ + Image.memory( + img, + fit: BoxFit.cover, + height: 400, + width: double.infinity, + ).paddingAll(15), + Positioned( + right: 0, + top: 0, + child: Container( + width: 30, + height: 30, + alignment: Alignment.center, + padding: EdgeInsets.zero, + margin: EdgeInsets.zero, + constraints: const BoxConstraints(), + color: MyColors.white, + child: const Icon( + Icons.cancel, + color: MyColors.redA3Color, + size: 30, + ), + ).onPress(() { + Navigator.of(context).pop(); + }).circle(35), + ) + ], ), ); } diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index cd2245d..e2f2dc2 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -63,7 +63,7 @@ class _ChatHomeScreenState extends State { hintText: LocaleKeys.searchfromchat.tr(), hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic, fontWeight: FontWeight.w500, fontSize: 12), filled: true, - fillColor: const Color(0xFFF7F7F7), + fillColor: MyColors.greyF7Color, suffixIconConstraints: const BoxConstraints(), suffixIcon: m.search.text.isNotEmpty ? IconButton( @@ -83,7 +83,6 @@ class _ChatHomeScreenState extends State { shrinkWrap: true, physics: const ClampingScrollPhysics(), itemBuilder: (BuildContext context, int index) { - // todo @aamir, remove list tile, make a custom ui instead return SizedBox( height: 55, child: Row( @@ -103,11 +102,8 @@ class _ChatHomeScreenState extends State { height: 10, decoration: BoxDecoration( color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, - borderRadius: const BorderRadius.all( - Radius.circular(10), - ), ), - ), + ).circle(10), ) ], ), @@ -211,9 +207,6 @@ class _ChatHomeScreenState extends State { ), ), onPressed: () async { - // String plainText = 'Muhamad.Alam@cloudsolutions.com.sa'; - // String key = "PeShVmYp"; - // passEncrypt(plainText, "PeShVmYp"); showMyBottomSheet( context, callBackFunc: () {}, @@ -231,137 +224,10 @@ class _ChatHomeScreenState extends State { OutlineInputBorder fieldBorder({required double radius, required int color}) { return OutlineInputBorder( - borderRadius: BorderRadius.circular( - radius, - ), + borderRadius: BorderRadius.circular(radius), borderSide: BorderSide( - color: Color( - color, - ), + color: Color(color), ), ); } - // - // void passEncrypt(String text, String pass) async { - // var salt = randomUint8List(8); - // var keyndIV = deriveKeyAndIV(pass, salt); - // var key = encrypt.Key(keyndIV.item1); - // var iv = encrypt.IV(keyndIV.item2); - // var encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: "PKCS7")); - // var encrypted = encrypter.encrypt(text, iv: iv); - // Uint8List encryptedBytesWithSalt = Uint8List.fromList(createUint8ListFromString("Salted__") + salt + encrypted.bytes); - // var resulttt = base64.encode(encryptedBytesWithSalt); - // print("Enc : " + resulttt); - // - // decryptAESCryptoJS(resulttt, pass); - // } - // - // Uint8List randomUint8List(int length) { - // assert(length > 0); - // var random = Random(); - // var ret = Uint8List(length); - // for (var i = 0; i < length; i++) { - // ret[i] = random.nextInt(256); - // } - // return ret; - // } - // - // void decryptAESCryptoJS(String encrypted, String passphrase) { - // try { - // Uint8List encryptedBytesWithSalt = base64.decode(encrypted); - // Uint8List encryptedBytes = encryptedBytesWithSalt.sublist(16, encryptedBytesWithSalt.length); - // var salt = encryptedBytesWithSalt.sublist(8, 16); - // var keyndIV = deriveKeyAndIV(passphrase, salt); - // var key = encrypt.Key(keyndIV.item1); - // var iv = encrypt.IV(keyndIV.item2); - // var encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: "PKCS7")); - // var decrypted = encrypter.decrypt64(base64.encode(encryptedBytes), iv: iv); - // print("Dec : " + decrypted); - // // return decrypted; - // } catch (error) { - // throw error; - // } - // } - - void enc(String input) { - var ekey = "PeShVmYp"; - var eIV = "j70IbWYn"; - List eByt = utf8.encode(ekey); - List eIvByt = utf8.encode(eIV); - List iByt = utf8.encode(input); - - - - } - - // ///Accepts encrypted data and decrypt it. Returns plain text - // String decryptWithAES(String key, Encrypted encryptedData) { - // var cipherKey = encrypt.Key.fromUtf8(key); - // var encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc,padding: null)); - // var initVector = IV.fromUtf8(key.substring(0, 16)); - // return encryptService.decrypt(encryptedData, iv: initVector); - // } - // - // ///Encrypts the given plainText using the key. Returns encrypted data - // Encrypted encryptWithAES(String key, String plainText) { - // var cipherKey = encrypt.Key.fromUtf8(key); - // var encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc,padding: null)); - // var initVector = IV.fromUtf8("j70IbWYn"); - // Encrypted encryptedData = encryptService.encrypt(plainText, iv: initVector); - // print(encryptedData.base64); - // return encryptedData; - // } - // - // Tuple2 deriveKeyAndIV(String passphrase, Uint8List salt) { - // var password = createUint8ListFromString(passphrase); - // Uint8List concatenatedHashes = Uint8List(0); - // Uint8List currentHash = Uint8List(0); - // bool enoughBytesForKey = false; - // Uint8List preHash = Uint8List(0); - // - // while (!enoughBytesForKey) { - // int preHashLength = currentHash.length + password.length + salt.length; - // if (currentHash.length > 0) - // preHash = Uint8List.fromList(currentHash + password + salt); - // else - // preHash = Uint8List.fromList(password + salt); - // - // currentHash = preHash; - // concatenatedHashes = Uint8List.fromList(concatenatedHashes + currentHash); - // if (concatenatedHashes.length >= 48) enoughBytesForKey = true; - // } - // - // var keyBtyes = concatenatedHashes.sublist(0, 32); - // var ivBtyes = concatenatedHashes.sublist(32, 48); - // return new Tuple2(keyBtyes, ivBtyes); - // } - // - // Uint8List createUint8ListFromString(String s) { - // var ret = new Uint8List(s.length); - // for (var i = 0; i < s.length; i++) { - // ret[i] = s.codeUnitAt(i); - // } - // return ret; - // } - // - // Uint8List genRandomWithNonZero(int seedLength) { - // var random = Random.secure(); - // const int randomMax = 245; - // Uint8List uint8list = Uint8List(seedLength); - // for (int i = 0; i < seedLength; i++) { - // uint8list[i] = random.nextInt(randomMax) + 1; - // } - // return uint8list; - // } - // - // - // - // void test(String text, String kk) { - // Uint8List key = Uint8List.fromList(utf8.encode(kk)); - // PaddedBlockCipher cipher = exp.PaddedBlockCipherImpl(exp.PKCS7Padding(), exp.ECBBlockCipher(exp.AESEngine())); - // cipher.init(true, PaddedBlockCipherParameters(KeyParameter(key), null)); - // var byte = Uint8List.fromList(utf8.encode(text)); - // var data = cipher.process(byte); - // print(data); - // } } diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 7cf28cf..b449bd1 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -6,6 +6,7 @@ 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/utils.dart'; @@ -63,6 +64,14 @@ class _DashboardScreenState extends State { void buildHubConnection() async { hubConnection = await data.getHubConnection(); await hubConnection.start(); + hubConnection.onreconnecting(({Exception? error}) { + print("============== Reconnecting ======================"); + if (hubConnection.state != HubConnectionState.Connected) { + data.getUserAutoLoginToken().whenComplete(() { + buildHubConnection(); + }); + } + }); } @override @@ -106,9 +115,11 @@ class _DashboardScreenState extends State { // onPressed: () { // data.getITGNotification().then((val) { // if (val!.result!.data != null) { + // print("-------------------- Survey ----------------------------"); // if (val.result!.data!.notificationType == "Survey") { // Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data); // } else { + // print("------------------------------------------- Ads --------------------"); // DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then( // (value) { // if (value!.mohemmItgResponseItem!.statusCode == 200) { 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 a71a71b..bcb9ed4 100644 --- a/lib/ui/landing/itg/its_add_screen_video_image.dart +++ b/lib/ui/landing/itg/its_add_screen_video_image.dart @@ -69,7 +69,7 @@ class _ITGAdsScreenState extends State { await controller.setLooping(false); return controller; } catch (e) { - return new VideoPlayerController.asset("dataSource"); + return VideoPlayerController.asset("dataSource"); } } @@ -94,29 +94,28 @@ class _ITGAdsScreenState extends State { if (advertisementData != null) { checkFileType(); } - double height = MediaQuery.of(context).size.height * .25; + // double height = MediaQuery.of(context).size.height * .25; return Scaffold( - body: Column( + body: Stack( children: [ 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( + FutureBuilder( + future: _futureController, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) { + _controller = snapshot.data as VideoPlayerController; + return Positioned.fill( + child: AspectRatio( aspectRatio: _controller.value.aspectRatio, child: VideoPlayer(_controller), - ); - } else { - return const Center( - child: CircularProgressIndicator(), - ); - } - }, - ), + ), + ); + } else { + return const Center( + child: CircularProgressIndicator(), + ); + } + }, ), if (isImage) Image.file(imageFile), if (skip) diff --git a/pubspec.yaml b/pubspec.yaml index a2efb36..f17ce5f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -94,11 +94,6 @@ dependencies: camera: ^0.10.0+4 - #Encryption - cryptography: ^2.0.5 - cryptography_flutter: ^2.0.2 - - video_player: ^2.4.7 just_audio: ^0.9.30 From a08f1c6d77a92be0e0ed198e0c78a807c783b523 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Sun, 4 Dec 2022 16:53:11 +0300 Subject: [PATCH 2/9] Chat Fixes & User Chat Counter --- lib/provider/chat_provider_model.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index 886951c..b48d845 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -36,7 +36,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void registerEvents() { hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); - // hubConnection.on("OnSeenChatUserAsync", onChatSeen); + hubConnection.on("OnSeenChatUserAsync", onChatSeen); //hubConnection.on("OnUserTypingAsync", onUserTyping); hubConnection.on("OnUserCountAsync", userCountAsync); hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); @@ -119,12 +119,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { for (SingleUserChatModel element in data!) { if (element.isSeen != null) { if (!element.isSeen!) { - print("Found Un Read"); element.isSeen = true; dynamic data = [ - {"userChatHistoryId": element.userChatHistoryId, "TargetUserId": element.targetUserId, "isDelivered": true, "isSeen": true} + {"userChatHistoryId": element.userChatHistoryId, "TargetUserId": element.currentUserId, "isDelivered": true, "isSeen": true} ]; updateUserChatHistoryStatusAsync(data); + notifyListeners(); } } } @@ -288,7 +288,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } userChatHistory.insert(0, data.first); - if (searchedChats != null) { + + if (searchedChats != null && !isChatScreenActive) { for (ChatUser user in searchedChats!) { if (user.id == data.first.currentUserId) { var tempCount = user.unreadMessageCount ?? 0; From 3e666eb6be1efb8ccd14c6bc29945d89dcd34ed3 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 5 Dec 2022 11:30:10 +0300 Subject: [PATCH 3/9] Chat Fixes & User Chat Counter --- lib/api/chat/chat_api_client.dart | 11 +- lib/classes/encryption.dart | 216 +++--------------- lib/models/chat/chat_user_image_model.dart | 33 +++ .../chat/get_search_user_chat_model.dart | 38 +-- lib/provider/chat_provider_model.dart | 35 ++- lib/ui/chat/chat_detailed_screen.dart | 3 +- lib/ui/chat/chat_home.dart | 2 + lib/ui/chat/chat_home_screen.dart | 33 ++- lib/ui/chat/favorite_users_screen.dart | 31 ++- lib/widgets/app_bar_widget.dart | 13 +- pubspec.yaml | 2 + 11 files changed, 183 insertions(+), 234 deletions(-) create mode 100644 lib/models/chat/chat_user_image_model.dart diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index 1f97b1f..bea5b7c 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -9,6 +9,7 @@ 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/chat_user_image_model.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; @@ -152,16 +153,12 @@ class ChatApiClient { return data; } - Future getUsersImages({required List encryptedEmails}) async { + Future> getUsersImages({required List encryptedEmails}) async { Response response = await ApiClient().postJsonForResponse( "${ApiConsts.chatUserImages}images", - { - "encryptedEmails": ["/g8Rc+s6eEOdci41PwJuV5dX+gXe51G9OTHzb9ahcVlHCmVvNhxReirudF79+hdxVSkCnQ6wC5DBFV8xnJlC74X6157PxF7mNYrAYuHRgp4="], - "fromClient": true - }, + {"encryptedEmails": encryptedEmails, "fromClient": false}, token: AppState().chatDetails!.response!.token, ); - logger.d(response.body); - // Uint8List data = Uint8List.fromList(response.body); + return chatUserImageModelFromJson(response.body); } } diff --git a/lib/classes/encryption.dart b/lib/classes/encryption.dart index 67466fe..f26c92b 100644 --- a/lib/classes/encryption.dart +++ b/lib/classes/encryption.dart @@ -1,188 +1,28 @@ -// import 'dart:convert'; -// -// import 'package:encrypt/encrypt.dart'; -// import 'package:crypto/crypto.dart'; -// -// class Encryption { -// static final Encryption instance = Encryption._(); -// -// late IV _iv; -// late Encrypter _encrypter; -// -// Encryption._() { -// const mykey = 'PeShVmYp'; -// const myiv = 'j70IbWYn'; -// var keyUtf8 = utf8.encode(mykey); -// var ivUtf8 = utf8.encode(myiv); -// var key = sha256.convert(keyUtf8).toString().substring(0, 32); -// var iv = sha256.convert(ivUtf8).toString().substring(0, 16); -// _iv = IV.fromUtf8(iv); -// -// _encrypter = Encrypter(AES(Key.fromUtf8(key), mode: AESMode.cbc)); -// } -// -// String encrypt(String value) { -// return _encrypter.encrypt(value, iv: _iv).base64; -// } -// -// String decrypt(String base64value) { -// var encrypted = Encrypted.fromBase64(base64value); -// return _encrypter.decrypt(encrypted, iv: _iv); -// } -// -// // -// // void passEncrypt(String text, String pass) async { -// // var salt = randomUint8List(8); -// // var keyndIV = deriveKeyAndIV(pass, salt); -// // var key = encrypt.Key(keyndIV.item1); -// // var iv = encrypt.IV(keyndIV.item2); -// // var encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: "PKCS7")); -// // var encrypted = encrypter.encrypt(text, iv: iv); -// // Uint8List encryptedBytesWithSalt = Uint8List.fromList(createUint8ListFromString("Salted__") + salt + encrypted.bytes); -// // var resulttt = base64.encode(encryptedBytesWithSalt); -// // print("Enc : " + resulttt); -// // -// // decryptAESCryptoJS(resulttt, pass); -// // } -// // -// // Uint8List randomUint8List(int length) { -// // assert(length > 0); -// // var random = Random(); -// // var ret = Uint8List(length); -// // for (var i = 0; i < length; i++) { -// // ret[i] = random.nextInt(256); -// // } -// // return ret; -// // } -// // -// // void decryptAESCryptoJS(String encrypted, String passphrase) { -// // try { -// // Uint8List encryptedBytesWithSalt = base64.decode(encrypted); -// // Uint8List encryptedBytes = encryptedBytesWithSalt.sublist(16, encryptedBytesWithSalt.length); -// // var salt = encryptedBytesWithSalt.sublist(8, 16); -// // var keyndIV = deriveKeyAndIV(passphrase, salt); -// // var key = encrypt.Key(keyndIV.item1); -// // var iv = encrypt.IV(keyndIV.item2); -// // var encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: "PKCS7")); -// // var decrypted = encrypter.decrypt64(base64.encode(encryptedBytes), iv: iv); -// // print("Dec : " + decrypted); -// // // return decrypted; -// // } catch (error) { -// // throw error; -// // } -// // } -// // -// // Future enc(String input) async { -// // var ekey = "PeShVmYpPeShVmYp"; -// // var eIV = "j70IbWYnj70IbWYn"; -// // -// // var abc = Encryption.instance.encrypt(input); -// // // -// // // var inputByt = utf8.encode(input); -// // // final encrypted = encrypter.encrypt(plainText); -// // // final decrypted = encrypter.decrypt(encrypted); -// // // -// // // print(decrypted); // Lorem ipsum dolor sit amet, consectetur adipiscing elit -// // // print(encrypted.base64); // R4PxiU3h8YoIRqVowBXm36ZcCeNeZ4s1OvVBTfFlZRdmohQqOpPQqD1YecJeZMAop/hZ4OxqgC1WtwvX/hP9mw== -// // // /// -// // -// // var key = encrypt.Key.fromUtf8(ekey.substring(0, 8)); -// // var iv = encrypt.IV.fromLength(8); -// // var encrypter = Encrypter(AES(key)); -// // var encrypted = encrypter.encrypt(input, iv: iv); -// // var decrypted = encrypter.decrypt(encrypted, iv: iv); -// // print("====== ORI =========="); -// // print("e4PTDencHsiLJv0XcbT2I4tafb7dqJP9c72PEnhp1Uv6U2GZ/gODtA=="); -// // print("====== ENC =========="); -// // print(encrypted.base64); -// // print("====== DEC =========="); -// // print(decrypted); -// // print("====== B64 =========="); -// // String bs64 = base64.encode(utf8.encode(input)); -// // print(bs64); -// // -// // // try { -// // // var cipher = _cipher; -// // // var secretBox = await cipher.encrypt( -// // // iByt, -// // // secretKey: SecretKeyData(eByt), -// // // nonce: eIvByt, -// // // ); -// // // print(utf8.decode(secretBox.cipherText)); -// // // } catch (error) { -// // // print(error); -// // // return; -// // // } -// // } -// // ///Accepts encrypted data and decrypt it. Returns plain text -// // String decryptWithAES(String key, Encrypted encryptedData) { -// // var cipherKey = encrypt.Key.fromUtf8(key); -// // var encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc,padding: null)); -// // var initVector = IV.fromUtf8(key.substring(0, 16)); -// // return encryptService.decrypt(encryptedData, iv: initVector); -// // } -// // -// // ///Encrypts the given plainText using the key. Returns encrypted data -// // Encrypted encryptWithAES(String key, String plainText) { -// // var cipherKey = encrypt.Key.fromUtf8(key); -// // var encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc,padding: null)); -// // var initVector = IV.fromUtf8("j70IbWYn"); -// // Encrypted encryptedData = encryptService.encrypt(plainText, iv: initVector); -// // print(encryptedData.base64); -// // return encryptedData; -// // } -// // -// // Tuple2 deriveKeyAndIV(String passphrase, Uint8List salt) { -// // var password = createUint8ListFromString(passphrase); -// // Uint8List concatenatedHashes = Uint8List(0); -// // Uint8List currentHash = Uint8List(0); -// // bool enoughBytesForKey = false; -// // Uint8List preHash = Uint8List(0); -// // -// // while (!enoughBytesForKey) { -// // int preHashLength = currentHash.length + password.length + salt.length; -// // if (currentHash.length > 0) -// // preHash = Uint8List.fromList(currentHash + password + salt); -// // else -// // preHash = Uint8List.fromList(password + salt); -// // -// // currentHash = preHash; -// // concatenatedHashes = Uint8List.fromList(concatenatedHashes + currentHash); -// // if (concatenatedHashes.length >= 48) enoughBytesForKey = true; -// // } -// // -// // var keyBtyes = concatenatedHashes.sublist(0, 32); -// // var ivBtyes = concatenatedHashes.sublist(32, 48); -// // return new Tuple2(keyBtyes, ivBtyes); -// // } -// // -// // Uint8List createUint8ListFromString(String s) { -// // var ret = new Uint8List(s.length); -// // for (var i = 0; i < s.length; i++) { -// // ret[i] = s.codeUnitAt(i); -// // } -// // return ret; -// // } -// // -// // Uint8List genRandomWithNonZero(int seedLength) { -// // var random = Random.secure(); -// // const int randomMax = 245; -// // Uint8List uint8list = Uint8List(seedLength); -// // for (int i = 0; i < seedLength; i++) { -// // uint8list[i] = random.nextInt(randomMax) + 1; -// // } -// // return uint8list; -// // } -// // -// // -// // -// // void test(String text, String kk) { -// // Uint8List key = Uint8List.fromList(utf8.encode(kk)); -// // PaddedBlockCipher cipher = exp.PaddedBlockCipherImpl(exp.PKCS7Padding(), exp.ECBBlockCipher(exp.AESEngine())); -// // cipher.init(true, PaddedBlockCipherParameters(KeyParameter(key), null)); -// // var byte = Uint8List.fromList(utf8.encode(text)); -// // var data = cipher.process(byte); -// // print(data); -// // } -// -// } +import 'dart:convert'; + +import 'package:flutter/services.dart'; + +class Encryption { + static final Encryption _instance = Encryption._internal(); + static const MethodChannel _channel = MethodChannel('flutter_des'); + static const key = "PeShVmYp"; + static const iv = "j70IbWYn"; + + Encryption._internal(); + + factory Encryption() => _instance; + + Future encrypt({required String val}) async { + Uint8List? crypt = await _channel.invokeMethod('encrypt', [val, key, iv]); + String data = base64Encode(crypt!.toList()); + print("Base64Enc: " + data); + return data; + } + + Future decrypt({required String encodedVal}) async { + var deco = base64Decode(encodedVal); + String? decCrypt = await _channel.invokeMethod('decrypt', [deco, key, iv]); + print("Base64ToStringDec: " + decCrypt!); + return decCrypt!; + } +} diff --git a/lib/models/chat/chat_user_image_model.dart b/lib/models/chat/chat_user_image_model.dart new file mode 100644 index 0000000..cdee33d --- /dev/null +++ b/lib/models/chat/chat_user_image_model.dart @@ -0,0 +1,33 @@ +// To parse this JSON data, do +// +// final chatUserImageModel = chatUserImageModelFromJson(jsonString); + +import 'dart:convert'; + +List chatUserImageModelFromJson(String str) => List.from(json.decode(str).map((x) => ChatUserImageModel.fromJson(x))); + +String chatUserImageModelToJson(List data) => json.encode(List.from(data.map((x) => x.toJson()))); + +class ChatUserImageModel { + ChatUserImageModel({ + this.email, + this.profilePicture, + this.mobileNumber, + }); + + String? email; + String? profilePicture; + String? mobileNumber; + + factory ChatUserImageModel.fromJson(Map json) => ChatUserImageModel( + email: json["email"] == null ? null : json["email"], + profilePicture: json["profilePicture"] == null ? null : json["profilePicture"], + mobileNumber: json["mobileNumber"] == null ? null : json["mobileNumber"], + ); + + Map toJson() => { + "email": email == null ? null : email, + "profilePicture": profilePicture == null ? null : profilePicture, + "mobileNumber": mobileNumber == null ? null : mobileNumber, + }; +} diff --git a/lib/models/chat/get_search_user_chat_model.dart b/lib/models/chat/get_search_user_chat_model.dart index 31d1085..fe87061 100644 --- a/lib/models/chat/get_search_user_chat_model.dart +++ b/lib/models/chat/get_search_user_chat_model.dart @@ -19,21 +19,23 @@ 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, - this.isLoadingCounter}); + 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.isImageLoaded, + this.isImageLoading, + }); int? id; String? userName; @@ -48,7 +50,8 @@ class ChatUser { bool? isFav; bool? isAdmin; bool? isTyping; - bool? isLoadingCounter; + bool? isImageLoaded; + bool? isImageLoading; factory ChatUser.fromJson(Map json) => ChatUser( id: json["id"] == null ? null : json["id"], @@ -64,7 +67,8 @@ class ChatUser { isFav: json["isFav"] == null ? null : json["isFav"], isAdmin: json["isAdmin"] == null ? null : json["isAdmin"], isTyping: false, - isLoadingCounter: true, + isImageLoaded: false, + isImageLoading: true, ); Map toJson() => { diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index b48d845..c56241f 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -7,8 +7,10 @@ import 'package:flutter/foundation.dart'; import 'package:http/http.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/encryption.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/main.dart'; +import 'package:mohem_flutter_app/models/chat/chat_user_image_model.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/make_user_favotire_unfavorite_chat_model.dart' as fav; @@ -75,6 +77,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ), ); notifyListeners(); + getUserImages(); } Future invokeUserChatHistoryNotDeliveredAsync({required int userId}) async { @@ -105,7 +108,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } isLoading = false; notifyListeners(); - markRead(userChatHistory, receiverUID); + // markRead(userChatHistory, receiverUID); generateConvId(); } @@ -231,7 +234,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { int? val = element.unreadMessageCount ?? 0; element.unreadMessageCount = val! + 1; } - element.isLoadingCounter = false; }, ); } @@ -698,4 +700,33 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { // } // } + void getUserImages() async { + List emails = []; + for (ChatUser element in searchedChats!) { + var encMail = await Encryption().encrypt(val: element.email!); + emails.add(encMail); + } + List chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails); + for (ChatUser user in searchedChats!) { + for (ChatUserImageModel uImage in chatImages) { + if (user.email == uImage.email) { + user.image = uImage.profilePicture ?? ""; + user.isImageLoading = false; + user.isImageLoaded = true; + notifyListeners(); + } + } + } + + for (ChatUser favUser in favUsersList) { + for (ChatUserImageModel uImage in chatImages) { + if (favUser.email == uImage.email) { + favUser.image = uImage.profilePicture ?? ""; + favUser.isImageLoading = false; + favUser.isImageLoaded = true; + notifyListeners(); + } + } + } + } } diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 1d220bc..6f9e4cf 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -68,6 +68,7 @@ class _ChatDetailScreenState extends State { isNewChat: userDetails["isNewChat"], ); } + print("Img: "+ userDetails["targetUser"].image); return Scaffold( backgroundColor: MyColors.backgroundColor, @@ -75,7 +76,7 @@ class _ChatDetailScreenState extends State { context, title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach, showHomeButton: false, - image: userDetails["targetUser"].image, + image: userDetails["targetUser"].image.isEmpty ? null : userDetails["targetUser"].image, actions: [ SvgPicture.asset("assets/icons/chat/call.svg", width: 21, height: 23).onPress(() { // makeCall(callType: "AUDIO", con: hubConnection); diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 3bf8cda..1ae3252 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -27,6 +27,8 @@ class _ChatHomeState extends State { void initState() { super.initState(); data = Provider.of(context, listen: false); + data.registerEvents(); + data.getUserRecentChats(); } @override diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index e2f2dc2..5ccc6ad 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -1,10 +1,14 @@ import 'dart:convert'; +import 'dart:typed_data'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_des/flutter_des.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/encryption.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; @@ -12,6 +16,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_sheet.dart'; +import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:provider/provider.dart'; @@ -26,11 +31,8 @@ class _ChatHomeScreenState extends State { @override void initState() { - // TODO: implement initState super.initState(); data = Provider.of(context, listen: false); - data.registerEvents(); - data.getUserRecentChats(); } @override @@ -89,11 +91,26 @@ class _ChatHomeScreenState extends State { children: [ Stack( children: [ - SvgPicture.asset( - "assets/images/user.svg", - height: 48, - width: 48, - ), + if (m.searchedChats![index].isImageLoading!) + const SizedBox( + height: 48, + width: 48, + child: Center(child: CircularProgressIndicator()), + ), + if (m.searchedChats![index].isImageLoaded! && m.searchedChats![index].image != null && m.searchedChats![index].image.isNotEmpty) + CircularAvatar( + radius: 20, + height: 48, + width: 48, + url: m.searchedChats![index].image, + isImageBase64: true, + ), + if (!m.searchedChats![index].isImageLoading! && m.searchedChats![index].isImageLoaded! && m.searchedChats![index].image.isEmpty) + SvgPicture.asset( + "assets/images/user.svg", + height: 48, + width: 48, + ), Positioned( right: 5, bottom: 1, diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart index 6bc0040..8bfcc4a 100644 --- a/lib/ui/chat/favorite_users_screen.dart +++ b/lib/ui/chat/favorite_users_screen.dart @@ -9,6 +9,7 @@ import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:provider/provider.dart'; @@ -36,11 +37,26 @@ class ChatFavoriteUsersScreen extends StatelessWidget { children: [ Stack( children: [ - SvgPicture.asset( - "assets/images/user.svg", - height: 48, - width: 48, - ), + if (m.favUsersList![index].isImageLoading!) + const SizedBox( + height: 48, + width: 48, + child: Center(child: CircularProgressIndicator()), + ), + if (m.favUsersList![index].isImageLoaded! && m.favUsersList![index].image != null && m.favUsersList![index].image.isNotEmpty) + CircularAvatar( + radius: 20, + height: 48, + width: 48, + url: m.favUsersList![index].image, + isImageBase64: true, + ), + if (!m.favUsersList![index].isImageLoading! && m.favUsersList![index].isImageLoaded! && m.favUsersList![index].image.isEmpty) + SvgPicture.asset( + "assets/images/user.svg", + height: 48, + width: 48, + ), Positioned( right: 5, bottom: 1, @@ -49,11 +65,8 @@ class ChatFavoriteUsersScreen extends StatelessWidget { height: 10, decoration: BoxDecoration( color: m.favUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, - borderRadius: const BorderRadius.all( - Radius.circular(10), - ), ), - ), + ).circle(10), ) ], ), diff --git a/lib/widgets/app_bar_widget.dart b/lib/widgets/app_bar_widget.dart index c2129c1..9cd7e27 100644 --- a/lib/widgets/app_bar_widget.dart +++ b/lib/widgets/app_bar_widget.dart @@ -5,6 +5,7 @@ import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; AppBar AppBarWidget(BuildContext context, {required String title, bool showHomeButton = true, bool showNotificationButton = false, bool showMemberButton = false, String? image, List? actions}) { @@ -25,12 +26,20 @@ AppBar AppBarWidget(BuildContext context, ), 4.width, if (image != null) + CircularAvatar( + url: image, + height: 40, + width: 40, + isImageBase64: true, + ), + if (image == null) SvgPicture.asset( - image, + "assets/images/user.svg", height: 40, width: 40, ), if (image != null) 14.width, + if (image == null) 14.width, title.toText24(color: MyColors.darkTextColor, isBold: true).expanded, ], ), @@ -59,7 +68,7 @@ AppBar AppBarWidget(BuildContext context, }, icon: const Icon(Icons.people, color: MyColors.textMixColor), ), - ...actions??[] + ...actions ?? [] ], ); } diff --git a/pubspec.yaml b/pubspec.yaml index f17ce5f..4fc00c8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -93,6 +93,8 @@ dependencies: flutter_webrtc: ^0.9.16 camera: ^0.10.0+4 + #Encryption + flutter_des: ^2.1.0 video_player: ^2.4.7 just_audio: ^0.9.30 From 13a7f60d675c94527ca9d24488389ad74823fe9d Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 5 Dec 2022 11:59:23 +0300 Subject: [PATCH 4/9] Chat Fixes & User Chat Counter --- lib/classes/encryption.dart | 16 +++++++--------- lib/provider/chat_provider_model.dart | 4 +--- lib/ui/chat/chat_detailed_screen.dart | 1 - lib/ui/chat/chat_home.dart | 4 +++- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/lib/classes/encryption.dart b/lib/classes/encryption.dart index f26c92b..a4ab6be 100644 --- a/lib/classes/encryption.dart +++ b/lib/classes/encryption.dart @@ -2,27 +2,25 @@ import 'dart:convert'; import 'package:flutter/services.dart'; -class Encryption { - static final Encryption _instance = Encryption._internal(); +class EmailImageEncryption { + static final EmailImageEncryption _instance = EmailImageEncryption._internal(); static const MethodChannel _channel = MethodChannel('flutter_des'); static const key = "PeShVmYp"; static const iv = "j70IbWYn"; - Encryption._internal(); + EmailImageEncryption._internal(); - factory Encryption() => _instance; + factory EmailImageEncryption() => _instance; Future encrypt({required String val}) async { Uint8List? crypt = await _channel.invokeMethod('encrypt', [val, key, iv]); - String data = base64Encode(crypt!.toList()); - print("Base64Enc: " + data); - return data; + String enc = base64Encode(crypt!.toList()); + return enc; } Future decrypt({required String encodedVal}) async { - var deco = base64Decode(encodedVal); + Uint8List deco = base64Decode(encodedVal); String? decCrypt = await _channel.invokeMethod('decrypt', [deco, key, iv]); - print("Base64ToStringDec: " + decCrypt!); return decCrypt!; } } diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index c56241f..535dc2e 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -460,7 +460,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { print("Normal Attachment Msg"); Utils.showLoading(context); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); - logger.d(value); String? ext = getFileExtension(selectedFile.path); Utils.hideLoading(context); sendChatToServer( @@ -703,8 +702,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void getUserImages() async { List emails = []; for (ChatUser element in searchedChats!) { - var encMail = await Encryption().encrypt(val: element.email!); - emails.add(encMail); + emails.add(await EmailImageEncryption().encrypt(val: element.email!)); } List chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails); for (ChatUser user in searchedChats!) { diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 6f9e4cf..345884f 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -68,7 +68,6 @@ class _ChatDetailScreenState extends State { isNewChat: userDetails["isNewChat"], ); } - print("Img: "+ userDetails["targetUser"].image); return Scaffold( backgroundColor: MyColors.backgroundColor, diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 1ae3252..0438dc6 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -28,7 +28,9 @@ class _ChatHomeState extends State { super.initState(); data = Provider.of(context, listen: false); data.registerEvents(); - data.getUserRecentChats(); + if (data.searchedChats == null || data.searchedChats!.isEmpty) { + data.getUserRecentChats(); + } } @override From 6a3c6a25d0c9fd7d833e220846ab308b2575137f Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 5 Dec 2022 12:40:56 +0300 Subject: [PATCH 5/9] Chat Fixes & User Chat Counter --- lib/provider/chat_provider_model.dart | 15 +++++++++------ lib/ui/chat/chat_home_screen.dart | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index 535dc2e..fd908a1 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -38,10 +38,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void registerEvents() { hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); - hubConnection.on("OnSeenChatUserAsync", onChatSeen); + // hubConnection.on("OnSeenChatUserAsync", onChatSeen); //hubConnection.on("OnUserTypingAsync", onUserTyping); hubConnection.on("OnUserCountAsync", userCountAsync); - hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); + // hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow); hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); } @@ -108,7 +108,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } isLoading = false; notifyListeners(); - // markRead(userChatHistory, receiverUID); + markRead(userChatHistory, receiverUID); generateConvId(); } @@ -124,7 +124,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { if (!element.isSeen!) { element.isSeen = true; dynamic data = [ - {"userChatHistoryId": element.userChatHistoryId, "TargetUserId": element.currentUserId, "isDelivered": true, "isSeen": true} + { + "userChatHistoryId": element.userChatHistoryId, + "TargetUserId": element.currentUserId == receiverID ? element.currentUserId : element.targetUserId, + "isDelivered": true, + "isSeen": true, + } ]; updateUserChatHistoryStatusAsync(data); notifyListeners(); @@ -190,8 +195,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void onChatSeen(List? args) { dynamic items = args!.toList(); - logger.d("---------------------------------Chat Seen -------------------------------------"); - logger.d(items); // for (var user in searchedChats!) { // if (user.id == items.first["id"]) { // user.userStatus = items.first["userStatus"]; diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 5ccc6ad..73c084a 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -84,6 +84,7 @@ class _ChatHomeScreenState extends State { itemCount: m.searchedChats!.length, shrinkWrap: true, physics: const ClampingScrollPhysics(), + padding: EdgeInsets.only(bottom: 80.0), itemBuilder: (BuildContext context, int index) { return SizedBox( height: 55, @@ -189,14 +190,13 @@ 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.clearSelections(); m.notifyListeners(); }); }); }, separatorBuilder: (BuildContext context, int index) => const Divider(color: MyColors.lightGreyE5Color).paddingOnly(left: 59), - ).paddingOnly(bottom: 70).expanded, + ).expanded, ], ).paddingOnly(left: 21, right: 21); }, From fb97319164d030fee3b52146e9fc315a1f4f1d30 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 5 Dec 2022 14:36:57 +0300 Subject: [PATCH 6/9] Chat Fixes & User Chat Counter --- lib/provider/chat_provider_model.dart | 46 +-------------------------- lib/ui/landing/dashboard_screen.dart | 4 +-- 2 files changed, 3 insertions(+), 47 deletions(-) diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index fd908a1..385c64a 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -660,48 +660,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { sFileType = ""; } - // void scrollListener() { - // _firstAutoscrollExecuted = true; - // if (scrollController.hasClients && scrollController.position.pixels == scrollController.position.maxScrollExtent) { - // _shouldAutoscroll = true; - // } else { - // _shouldAutoscroll = false; - // } - // } - // - // void scrollToBottom() { - // scrollController.animateTo( - // scrollController.position.maxScrollExtent + 100, - // duration: const Duration(milliseconds: 500), - // curve: Curves.easeIn, - // ); - // } - - void msgScroll() { - // scrollController.animateTo( - // // index: 150, - // duration: Duration(seconds: 2), - // curve: Curves.easeInOutCubic); - // scrollController.animateTo( - // scrollController.position.minScrollExtent - 100, - // duration: const Duration(milliseconds: 500), - // curve: Curves.easeIn, - // ); - } - -// Future getDownLoadFile(String fileName) async { -// var data = await ChatApiClient().downloadURL(fileName: "data"); -// Image.memory(data); -// } - -// void getUserChatHistoryNotDeliveredAsync({required int userId}) async { -// try { -// await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]); -// } finally { -// hubConnection.off("GetUserChatHistoryNotDeliveredAsync", method: chatNotDelivered); -// } -// } - void getUserImages() async { List emails = []; for (ChatUser element in searchedChats!) { @@ -714,20 +672,18 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { user.image = uImage.profilePicture ?? ""; user.isImageLoading = false; user.isImageLoaded = true; - notifyListeners(); } } } - for (ChatUser favUser in favUsersList) { for (ChatUserImageModel uImage in chatImages) { if (favUser.email == uImage.email) { favUser.image = uImage.profilePicture ?? ""; favUser.isImageLoading = false; favUser.isImageLoaded = true; - notifyListeners(); } } } + notifyListeners(); } } diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index b449bd1..954b647 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -66,11 +66,11 @@ class _DashboardScreenState extends State { await hubConnection.start(); hubConnection.onreconnecting(({Exception? error}) { print("============== Reconnecting ======================"); - if (hubConnection.state != HubConnectionState.Connected) { + //if (hubConnection.state != HubConnectionState.Connected) { data.getUserAutoLoginToken().whenComplete(() { buildHubConnection(); }); - } + //} }); } From 0db4a5a7cd3b88863e58c8d6c000b19bcc430d54 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 5 Dec 2022 14:38:57 +0300 Subject: [PATCH 7/9] Chat Fixes & User Chat Counter --- lib/ui/landing/dashboard_screen.dart | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 954b647..e1250b4 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -66,11 +66,10 @@ class _DashboardScreenState extends State { await hubConnection.start(); hubConnection.onreconnecting(({Exception? error}) { print("============== Reconnecting ======================"); - //if (hubConnection.state != HubConnectionState.Connected) { - data.getUserAutoLoginToken().whenComplete(() { - buildHubConnection(); - }); - //} + data.getUserAutoLoginToken().whenComplete(() { + buildHubConnection(); + data.notifyListeners(); + }); }); } From 0f13ab65d67473fe808482bde87c105c1b65175d Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 5 Dec 2022 16:02:21 +0300 Subject: [PATCH 8/9] Chat Fixes & User Chat Counter --- lib/provider/dashboard_provider_model.dart | 26 +++---- lib/ui/chat/chat_detailed_screen.dart | 2 +- lib/ui/chat/chat_full_image_preview.dart | 6 +- lib/ui/chat/chat_home_screen.dart | 9 ++- lib/ui/chat/favorite_users_screen.dart | 5 +- lib/widgets/app_bar_widget.dart | 7 -- .../shimmer/dashboard_shimmer_widget.dart | 76 ++++++++++--------- 7 files changed, 64 insertions(+), 67 deletions(-) diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index 461196f..5d6a53e 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -307,19 +307,19 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future getHubConnection() async { HubConnection hub; - try { - 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; - } catch (e) { - getUserAutoLoginToken().whenComplete(() { - getHubConnection(); - }); - throw e; - } + // try { + 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; + // } catch (e) { + // getUserAutoLoginToken().whenComplete(() { + // getHubConnection(); + // }); + // throw e; + // } } void notify() { diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 345884f..905bffa 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -90,7 +90,7 @@ class _ChatDetailScreenState extends State { body: Consumer( builder: (BuildContext context, ChatProviderModel m, Widget? child) { return (m.isLoading - ? ChatHomeShimmer() + ? ChatHomeShimmer(isDetailedScreen: true,) : Column( children: [ SmartRefresher( diff --git a/lib/ui/chat/chat_full_image_preview.dart b/lib/ui/chat/chat_full_image_preview.dart index c731c25..6c8073f 100644 --- a/lib/ui/chat/chat_full_image_preview.dart +++ b/lib/ui/chat/chat_full_image_preview.dart @@ -21,9 +21,9 @@ class ChatImagePreviewScreen extends StatelessWidget { children: [ Image.memory( img, - fit: BoxFit.cover, - height: 400, - width: double.infinity, + fit: BoxFit.fill, + height:500, + width: 500, ).paddingAll(15), Positioned( right: 0, diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 73c084a..641c13d 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -21,6 +21,8 @@ import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart' import 'package:provider/provider.dart'; class ChatHomeScreen extends StatefulWidget { + const ChatHomeScreen({Key? key}) : super(key: key); + @override State createState() => _ChatHomeScreenState(); } @@ -48,7 +50,7 @@ class _ChatHomeScreenState extends State { body: Consumer( builder: (BuildContext context, ChatProviderModel m, Widget? child) { return m.isLoading - ? ChatHomeShimmer() + ? ChatHomeShimmer(isDetailedScreen: false,) : Column( children: [ TextField( @@ -84,7 +86,7 @@ class _ChatHomeScreenState extends State { itemCount: m.searchedChats!.length, shrinkWrap: true, physics: const ClampingScrollPhysics(), - padding: EdgeInsets.only(bottom: 80.0), + padding: const EdgeInsets.only(bottom: 80.0), itemBuilder: (BuildContext context, int index) { return SizedBox( height: 55, @@ -96,8 +98,7 @@ class _ChatHomeScreenState extends State { const SizedBox( height: 48, width: 48, - child: Center(child: CircularProgressIndicator()), - ), + ).toShimmer().circle(30), if (m.searchedChats![index].isImageLoaded! && m.searchedChats![index].image != null && m.searchedChats![index].image.isNotEmpty) CircularAvatar( radius: 20, diff --git a/lib/ui/chat/favorite_users_screen.dart b/lib/ui/chat/favorite_users_screen.dart index 8bfcc4a..6034151 100644 --- a/lib/ui/chat/favorite_users_screen.dart +++ b/lib/ui/chat/favorite_users_screen.dart @@ -23,7 +23,7 @@ class ChatFavoriteUsersScreen extends StatelessWidget { body: Consumer( builder: (BuildContext context, ChatProviderModel m, Widget? child) { if (m.isLoading) { - return ChatHomeShimmer(); + return ChatHomeShimmer(isDetailedScreen: false,); } else { return m.favUsersList != null && m.favUsersList.isNotEmpty ? ListView.separated( @@ -41,8 +41,7 @@ class ChatFavoriteUsersScreen extends StatelessWidget { const SizedBox( height: 48, width: 48, - child: Center(child: CircularProgressIndicator()), - ), + ).toShimmer().circle(30), if (m.favUsersList![index].isImageLoaded! && m.favUsersList![index].image != null && m.favUsersList![index].image.isNotEmpty) CircularAvatar( radius: 20, diff --git a/lib/widgets/app_bar_widget.dart b/lib/widgets/app_bar_widget.dart index d18d7e6..29c94d2 100644 --- a/lib/widgets/app_bar_widget.dart +++ b/lib/widgets/app_bar_widget.dart @@ -32,14 +32,7 @@ AppBar AppBarWidget(BuildContext context, width: 40, isImageBase64: true, ), - if (image == null) - SvgPicture.asset( - "assets/images/user.svg", - height: 40, - width: 40, - ), if (image != null) 14.width, - if (image == null) 14.width, title.toText24(color: MyColors.darkTextColor, isBold: true).expanded, ], ), diff --git a/lib/widgets/shimmer/dashboard_shimmer_widget.dart b/lib/widgets/shimmer/dashboard_shimmer_widget.dart index 6fe5a03..fc243f0 100644 --- a/lib/widgets/shimmer/dashboard_shimmer_widget.dart +++ b/lib/widgets/shimmer/dashboard_shimmer_widget.dart @@ -188,7 +188,6 @@ class ServicesMenuShimmer extends StatelessWidget { } } - class MarathonBannerShimmer extends StatelessWidget { const MarathonBannerShimmer({Key? key}) : super(key: key); @@ -236,6 +235,11 @@ class MarathonBannerShimmer extends StatelessWidget { } class ChatHomeShimmer extends StatelessWidget { + bool isDetailedScreen; + + ChatHomeShimmer({Key? key, required this.isDetailedScreen}) : super(key: key); + + @override @override Widget build(BuildContext context) { return Container( @@ -254,42 +258,42 @@ class ChatHomeShimmer extends StatelessWidget { child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - width: 48.0, - height: 48.0, - decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(40))), - ), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 8.0), - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: double.infinity, - height: 8.0, - color: Colors.white, - ), - const Padding( - padding: EdgeInsets.symmetric(vertical: 2.0), - ), - Container( - width: double.infinity, - height: 8.0, - color: Colors.white, - ), - const Padding( - padding: EdgeInsets.symmetric(vertical: 2.0), - ), - Container( - width: 40.0, - height: 8.0, - color: Colors.white, - ), - ], + if (!isDetailedScreen) + Container( + width: 48.0, + height: 48.0, + decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(40))), + ), + if (!isDetailedScreen) + const Padding( + padding: EdgeInsets.symmetric(horizontal: 8.0), ), - ) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + height: 8.0, + color: Colors.white, + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 2.0), + ), + Container( + width: double.infinity, + height: 8.0, + color: Colors.white, + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 2.0), + ), + Container( + width: 40.0, + height: 8.0, + color: Colors.white, + ), + ], + ).expanded ], ), ), From 4e961082075831cabb218eebad7aa75569e83372 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 5 Dec 2022 16:03:46 +0300 Subject: [PATCH 9/9] Chat Fixes & User Chat Counter --- lib/ui/landing/dashboard_screen.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index e1250b4..8c1bdfe 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -65,10 +65,9 @@ class _DashboardScreenState extends State { hubConnection = await data.getHubConnection(); await hubConnection.start(); hubConnection.onreconnecting(({Exception? error}) { - print("============== Reconnecting ======================"); + print("============== Reconnecting Hub ======================"); data.getUserAutoLoginToken().whenComplete(() { buildHubConnection(); - data.notifyListeners(); }); }); }