Chat Fixes & User Chat Counter

sultan-dev
Aamir Muhammad 2 years ago
parent a08f1c6d77
commit 3e666eb6be

@ -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<List<ChatUserImageModel>> getUsersImages({required List<String> 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);
}
}

@ -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<void> 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<Uint8List, Uint8List> 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<CipherParameters, CipherParameters>(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<String> 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<String> decrypt({required String encodedVal}) async {
var deco = base64Decode(encodedVal);
String? decCrypt = await _channel.invokeMethod('decrypt', [deco, key, iv]);
print("Base64ToStringDec: " + decCrypt!);
return decCrypt!;
}
}

@ -0,0 +1,33 @@
// To parse this JSON data, do
//
// final chatUserImageModel = chatUserImageModelFromJson(jsonString);
import 'dart:convert';
List<ChatUserImageModel> chatUserImageModelFromJson(String str) => List<ChatUserImageModel>.from(json.decode(str).map((x) => ChatUserImageModel.fromJson(x)));
String chatUserImageModelToJson(List<ChatUserImageModel> data) => json.encode(List<dynamic>.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<String, dynamic> json) => ChatUserImageModel(
email: json["email"] == null ? null : json["email"],
profilePicture: json["profilePicture"] == null ? null : json["profilePicture"],
mobileNumber: json["mobileNumber"] == null ? null : json["mobileNumber"],
);
Map<String, dynamic> toJson() => {
"email": email == null ? null : email,
"profilePicture": profilePicture == null ? null : profilePicture,
"mobileNumber": mobileNumber == null ? null : mobileNumber,
};
}

@ -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<String, dynamic> 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<String, dynamic> toJson() => {

@ -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<String> emails = [];
for (ChatUser element in searchedChats!) {
var encMail = await Encryption().encrypt(val: element.email!);
emails.add(encMail);
}
List<ChatUserImageModel> 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();
}
}
}
}
}

@ -68,6 +68,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
isNewChat: userDetails["isNewChat"],
);
}
print("Img: "+ userDetails["targetUser"].image);
return Scaffold(
backgroundColor: MyColors.backgroundColor,
@ -75,7 +76,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
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);

@ -27,6 +27,8 @@ class _ChatHomeState extends State<ChatHome> {
void initState() {
super.initState();
data = Provider.of<ChatProviderModel>(context, listen: false);
data.registerEvents();
data.getUserRecentChats();
}
@override

@ -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<ChatHomeScreen> {
@override
void initState() {
// TODO: implement initState
super.initState();
data = Provider.of<ChatProviderModel>(context, listen: false);
data.registerEvents();
data.getUserRecentChats();
}
@override
@ -89,11 +91,26 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
children: [
Stack(
children: <Widget>[
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,

@ -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: <Widget>[
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),
)
],
),

@ -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<Widget>? 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 ?? []
],
);
}

@ -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

Loading…
Cancel
Save