Merge branch 'master' into development_haroon

# Conflicts:
#	lib/classes/consts.dart
merge-requests/110/head
haroon amjad 3 years ago
commit b522aab685

@ -2,8 +2,8 @@ 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://erptstapp.srca.org.sa"; // SRCA server
static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server
// static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA 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

@ -102,13 +102,14 @@ extension EmailValidator on String {
decoration: isUnderLine ? TextDecoration.underline : null),
);
Widget toText16({Color? color, bool isUnderLine = false, bool isBold = false, int? maxlines}) => Text(
Widget toText16({Color? color, bool isUnderLine = false, bool isBold = false, int? maxlines, double? height}) => Text(
this,
maxLines: maxlines,
style: TextStyle(
color: color ?? MyColors.darkTextColor,
fontSize: 16,
letterSpacing: -0.64,
height: height,
fontWeight: isBold ? FontWeight.bold : FontWeight.w600,
decoration: isUnderLine ? TextDecoration.underline : null,
),

@ -48,7 +48,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
bool currentUserTyping = false;
int? cTypingUserId = 0;
//Chat
//Chat Home Page Counter
int chatUConvCounter = 0;
Future<void> getUserAutoLoginToken() async {
@ -291,14 +291,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void chatNotDelivered(List<Object?>? args) {
dynamic items = args!.toList();
for (dynamic item in items[0]) {
searchedChats!.forEach(
(ChatUser element) {
if (element.id == item["currentUserId"]) {
int? val = element.unreadMessageCount ?? 0;
element.unreadMessageCount = val! + 1;
}
},
);
for (ChatUser element in searchedChats!) {
if (element.id == item["currentUserId"]) {
int? val = element.unreadMessageCount ?? 0;
element.unreadMessageCount = val! + 1;
}
}
}
notifyListeners();
}
@ -378,20 +376,25 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
setMsgTune();
if (isChatScreenActive && data.first.currentUserId == receiverID) {
userChatHistory.insert(0, data.first);
}
if (searchedChats != null) {
for (ChatUser user in searchedChats!) {
if (user.id == data.first.currentUserId) {
int tempCount = user.unreadMessageCount ?? 0;
user.unreadMessageCount = tempCount + 1;
} else {
if (searchedChats != null) {
for (ChatUser user in searchedChats!) {
if (user.id == data.first.currentUserId) {
int tempCount = user.unreadMessageCount ?? 0;
user.unreadMessageCount = tempCount + 1;
}
}
sort();
}
sort();
}
List list = [
{"userChatHistoryId": data.first.userChatHistoryId, "TargetUserId": temp.first.targetUserId, "isDelivered": true, "isSeen": isChatScreenActive && data.first.currentUserId == receiverID ? true : false}
List<Object> list = [
{
"userChatHistoryId": data.first.userChatHistoryId,
"TargetUserId": temp.first.targetUserId,
"isDelivered": true,
"isSeen": isChatScreenActive && data.first.currentUserId == receiverID ? true : false
}
];
updateUserChatHistoryOnMsg(list);
invokeChatCounter(userId: AppState().chatDetails!.response!.id!);
@ -400,9 +403,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void sort() {
searchedChats!.sort(
(ChatUser a, ChatUser b) => b.unreadMessageCount!.compareTo(
a.unreadMessageCount!,
),
(ChatUser a, ChatUser b) => b.unreadMessageCount!.compareTo(a.unreadMessageCount!),
);
}
@ -540,28 +541,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
void sendChatMessage(BuildContext context, {required int targetUserId, required int userStatus, required String userEmail, required String targetUserName}) async {
dynamic contain = searchedChats!.where((ChatUser element) => element.id == targetUserId);
if (contain.isEmpty) {
List<String> emails = [];
emails.add(await EmailImageEncryption().encrypt(val: userEmail));
List<ChatUserImageModel> chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails);
searchedChats!.add(
ChatUser(
id: targetUserId,
userName: targetUserName,
unreadMessageCount: 0,
email: userEmail,
isImageLoading: false,
image: chatImages.first.profilePicture ?? "",
isImageLoaded: true,
isTyping: false,
isFav: false,
userStatus: userStatus,
userLocalDownlaodedImage: await downloadImageLocal(chatImages.first.profilePicture, targetUserId.toString()),
),
);
notifyListeners();
}
if (!isFileSelected && !isMsgReply) {
print("Normal Text Msg");
if (message.text == null || message.text.isEmpty) {
@ -621,6 +600,51 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isImageLoaded: true,
image: selectedFile.readAsBytesSync());
}
if (searchedChats != null) {
dynamic contain = searchedChats!.where((ChatUser element) => element.id == targetUserId);
if (contain.isEmpty) {
List<String> emails = [];
emails.add(await EmailImageEncryption().encrypt(val: userEmail));
List<ChatUserImageModel> chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails);
searchedChats!.add(
ChatUser(
id: targetUserId,
userName: targetUserName,
unreadMessageCount: 0,
email: userEmail,
isImageLoading: false,
image: chatImages.first.profilePicture ?? "",
isImageLoaded: true,
isTyping: false,
isFav: false,
userStatus: userStatus,
userLocalDownlaodedImage: await downloadImageLocal(chatImages.first.profilePicture, targetUserId.toString()),
),
);
notifyListeners();
}
} else {
List<String> emails = [];
emails.add(await EmailImageEncryption().encrypt(val: userEmail));
List<ChatUserImageModel> chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails);
searchedChats!.add(
ChatUser(
id: targetUserId,
userName: targetUserName,
unreadMessageCount: 0,
email: userEmail,
isImageLoading: false,
image: chatImages.first.profilePicture ?? "",
isImageLoaded: true,
isTyping: false,
isFav: false,
userStatus: userStatus,
userLocalDownlaodedImage: await downloadImageLocal(chatImages.first.profilePicture, targetUserId.toString()),
),
);
notifyListeners();
}
}
void selectImageToUpload(BuildContext context) {
@ -725,7 +749,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
for (ChatUser user in searchedChats!) {
if (user.id == favoriteChatUser.response!.targetUserId!) {
user.isFav = favoriteChatUser.response!.isFav;
favUsersList.add(user);
dynamic contain = favUsersList!.where((ChatUser element) => element.id == favoriteChatUser.response!.targetUserId!);
if (contain.isEmpty) {
favUsersList.add(user);
}
}
}
}
@ -764,6 +791,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
void clearAll() {
print("----------------- Disposed ---------------------------");
searchedChats = pChatHistory;
search.clear();
isChatScreenActive = false;
@ -775,6 +803,37 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
sFileType = "";
}
void disposeData() {
search.clear();
isChatScreenActive = false;
receiverID = 0;
paginationVal = 0;
message.text = '';
isFileSelected = false;
repliedMsg = [];
sFileType = "";
deleteData();
favUsersList.clear();
searchedChats!.clear();
pChatHistory!.clear();
chatHubConnection.stop();
AppState().chatDetails = null;
}
void deleteData() {
List<ChatUser> exists = [], unique = [];
exists.addAll(searchedChats!);
exists.addAll(favUsersList!);
Map<String, ChatUser> profileMap = {};
for (ChatUser item in exists) {
profileMap[item.email!] = item;
}
unique = profileMap.values.toList();
for (ChatUser element in unique!) {
deleteFile(element.id.toString());
}
}
void getUserImages() async {
List<String> emails = [];
List<ChatUser> exists = [], unique = [];
@ -885,4 +944,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
await chatHubConnection.invoke("GetChatCounversationCount", args: [userId]);
return "";
}
void userTypingInvoke({required int currentUser, required int reciptUser}) async {
logger.d([reciptUser, currentUser]);
await chatHubConnection.invoke("UserTypingAsync", args: [reciptUser, currentUser]);
}
}

@ -123,6 +123,7 @@ class ChatBubble extends StatelessWidget {
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 || fileTypeID == 2)
SvgPicture.asset(data.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 0, right: 10),
(cItem.contant ?? "").toText12().expanded,
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 || fileTypeID == 2) const Icon(Icons.remove_red_eye, size: 20)
],
),
Align(
@ -217,11 +218,9 @@ class ChatBubble extends StatelessWidget {
Row(
children: [
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 || fileTypeID == 2)
SvgPicture.asset(data.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(
left: 0,
right: 10,
),
SvgPicture.asset(data.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 0, right: 10),
(cItem.contant ?? "").toText12(color: Colors.white).expanded,
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 || fileTypeID == 2) const Icon(Icons.remove_red_eye, color: Colors.white, size: 20)
],
),
Align(

@ -233,6 +233,9 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
),
).paddingOnly(right: 21),
),
onChanged: (val) {
m.userTypingInvoke(currentUser: AppState().chatDetails!.response!.id!, reciptUser: params!.chatUser!.id!);
},
),
],
));

@ -47,6 +47,7 @@ class _ChatHomeState extends State<ChatHome> {
return;
}
if (data.searchedChats == null || data.searchedChats!.isEmpty) {
data.isLoading = true;
data.getUserRecentChats();
}
}

@ -11,6 +11,7 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/dashboard/drawer_menu_item_model.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/ui/dialogs/id/business_card_dialog.dart';
import 'package:mohem_flutter_app/ui/dialogs/id/employee_digital_id_dialog.dart';
@ -28,6 +29,13 @@ class AppDrawer extends StatefulWidget {
class _AppDrawerState extends State<AppDrawer> {
List<DrawerMenuItem> drawerMenuItemList = [];
late ChatProviderModel chatData;
@override
void initState() {
super.initState();
chatData = Provider.of<ChatProviderModel>(context, listen: false);
}
@override
Widget build(BuildContext context) {
@ -171,6 +179,7 @@ class _AppDrawerState extends State<AppDrawer> {
AppState().isAuthenticated = false;
AppState().isLogged = false;
AppState().setPostParamsInitConfig();
chatData.disposeData();
// SharedPreferences prefs = await SharedPreferences.getInstance();
// await prefs.clear();
Navigator.pushNamedAndRemoveUntil(context, AppRoutes.login, (Route<dynamic> route) => false, arguments: null);

@ -289,7 +289,7 @@ class _VerifyLastLoginScreenState extends State<VerifyLastLoginScreen> {
width: 38,
color: isDisable ? MyColors.darkTextColor.withOpacity(0.7) : null,
),
_title.toText16()
_title.toText16(height: 20/16)
],
),
),

@ -572,7 +572,7 @@ class _VerifyLoginScreenState extends State<VerifyLoginScreen> {
width: 38,
color: isDisable ? MyColors.darkTextColor.withOpacity(0.7) : null,
),
_title.toText16()
_title.toText16(height: 20/16)
],
),
),

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_layout_grid/flutter_layout_grid.dart';
import 'package:mohem_flutter_app/api/my_attendance_api_client.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
@ -22,7 +23,8 @@ class DynamicListViewParams {
List<CollectionNotificationEit>? collectionNotificationList;
final String selectedEmp;
DynamicListViewParams(this.title, this.dynamicId, {this.selectedEmp ='', this.uRL = 'GET_EIT_DFF_STRUCTURE', this.requestID = '', this.colsURL = '', this.isUpdate = false, this.collectionNotificationList});
DynamicListViewParams(this.title, this.dynamicId,
{this.selectedEmp = '', this.uRL = 'GET_EIT_DFF_STRUCTURE', this.requestID = '', this.colsURL = '', this.isUpdate = false, this.collectionNotificationList});
}
class DynamicListViewScreen extends StatefulWidget {
@ -37,6 +39,7 @@ class DynamicListViewScreen extends StatefulWidget {
class _DynamicListViewScreenState extends State<DynamicListViewScreen> {
List<GetEITTransactionList>? getEITTransactionList;
DynamicListViewParams? dynamicParams;
// String? empId;
@override
@ -99,47 +102,19 @@ class _DynamicListViewScreenState extends State<DynamicListViewScreen> {
: ListView.separated(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (cxt, int parentIndex) => getEITTransactionList![parentIndex].collectionTransaction!.isEmpty
? const SizedBox()
: GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 1.0 / 0.75),
padding: const EdgeInsets.only(left: 12,right: 21,top: 12),
shrinkWrap: true,
primary: false,
physics: const ScrollPhysics(),
children: getEITWidgetsList(getEITTransactionList![parentIndex].collectionTransaction),
).objectContainerView(),
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisSize: MainAxisSize.min,
// children: [
// for (int t = 0; t < (getEITTransactionList![parentIndex].collectionTransaction ?? []).length; t++)
// if (getEITTransactionList![parentIndex].collectionTransaction![t].dISPLAYFLAG == "Y")
// // ItemDetailView(getEITTransactionList![parentIndex].collectionTransaction![t].sEGMENTPROMPT!,
// // getEITTransactionList![parentIndex].collectionTransaction![t].sEGMENTVALUEDSP ?? ""),
// // GridView(
// // gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
// // padding: const EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 12),
// // shrinkWrap: true,
// // primary: false,
// // physics: const ScrollPhysics(),
// // children: getEITWidgetsList(getEITTransactionList![parentIndex].collectionTransaction),
// // )
// // ItemDetailViewCol(getEITTransactionList![parentIndex].collectionTransaction![t].sEGMENTPROMPT!,
// // getEITTransactionList![parentIndex].collectionTransaction![t].sEGMENTVALUEDSP ?? ""),
//
// // GridView(
// // gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
// // padding: const EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 12),
// // shrinkWrap: true,
// // primary: false,
// // physics: const ScrollPhysics(),
// // children: getEITWidgetsList(getEITTransactionList![parentIndex].collectionTransaction),
// // )
// // ItemDetailView(getEITTransactionList![parentIndex].collectionTransaction![t].sEGMENTPROMPT!,
// // getEITTransactionList![parentIndex].collectionTransaction![t].sEGMENTVALUEDSP ?? ""),
// ],
// ).objectContainerView(),
itemBuilder: (cxt, int parentIndex) {
if (getEITTransactionList![parentIndex].collectionTransaction!.isEmpty) {
return const SizedBox();
}
int count = getEITTransactionList![parentIndex].collectionTransaction!.length;
return LayoutGrid(
columnSizes: [1.fr, 1.fr],
rowSizes: [for (int i = 0; i < (count / 2).round(); i++) auto],
columnGap: 8,
rowGap: 12,
children: getEITWidgetsList(getEITTransactionList![parentIndex].collectionTransaction),
).objectContainerView();
},
separatorBuilder: (cxt, index) => 12.height,
itemCount: getEITTransactionList!.length)),
],

@ -533,7 +533,7 @@ class _ItgDetailScreenState extends State<ItgDetailScreen> {
Utils.hideLoading(context);
Utils.showToast(LocaleKeys.yourChangeHasBeenSavedSuccessfully.tr());
// Navigator.pop(context, "delegate_reload");
animationIndex=animationIndex+1;
animationIndex = animationIndex + 1;
AppState().requestAllList!.removeAt(AppState().itgWorkListIndex!);
if (AppState().requestAllList!.isEmpty) {
Navigator.pop(context, "delegate_reload");

@ -215,11 +215,7 @@ class _WorkListScreenState extends State<WorkListScreen> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBarWidget(
context,
title: LocaleKeys.workList.tr(),
showNotificationButton: true,
),
appBar: AppBarWidget(context, title: LocaleKeys.workList.tr(), showWorkListSettingButton: true),
body: SizedBox(
width: double.infinity,
height: double.infinity,
@ -284,31 +280,33 @@ class _WorkListScreenState extends State<WorkListScreen> {
physics: const BouncingScrollPhysics(),
child: itgRequestTypeIndex != null
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 40,
child: ListView.separated(
itemBuilder: (context, index) {
RequestType type = itgFormsModel!.requestType![index];
return Container(
padding: const EdgeInsets.only(left: 21, right: 21, top: 8, bottom: 8),
alignment: Alignment.center,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: itgRequestTypeIndex == index ? MyColors.darkIconColor : MyColors.lightGreyEAColor),
child: ("${type.requestTypeName}").toText12(color: itgRequestTypeIndex == index ? MyColors.white : MyColors.black),
).onPress(() {
if (itgRequestTypeIndex != index) {
itgRequestTypeIndex = index;
setState(() {});
}
});
},
separatorBuilder: (context, index) => 8.width,
shrinkWrap: true,
itemCount: itgFormsModel?.requestType?.length ?? 0,
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.only(left: 21, right: 21),
),
).paddingOnly(top: 16, bottom: 16),
// todo this is commented for temporary purpose, have issue when selecting any itg category and click any item showing wrong details
// SizedBox(
// height: 40,
// child: ListView.separated(
// itemBuilder: (context, index) {
// RequestType type = itgFormsModel!.requestType![index];
// return Container(
// padding: const EdgeInsets.only(left: 21, right: 21, top: 8, bottom: 8),
// alignment: Alignment.center,
// decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: itgRequestTypeIndex == index ? MyColors.darkIconColor : MyColors.lightGreyEAColor),
// child: ("${type.requestTypeName}").toText12(color: itgRequestTypeIndex == index ? MyColors.white : MyColors.black),
// ).onPress(() {
// if (itgRequestTypeIndex != index) {
// itgRequestTypeIndex = index;
// setState(() {});
// }
// });
// },
// separatorBuilder: (context, index) => 8.width,
// shrinkWrap: true,
// itemCount: itgFormsModel?.requestType?.length ?? 0,
// scrollDirection: Axis.horizontal,
// padding: const EdgeInsets.only(left: 21, right: 21),
// ),
// ).paddingOnly(top: 16, bottom: 16),
ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
@ -429,7 +427,7 @@ class _WorkListScreenState extends State<WorkListScreen> {
void openBottomSheet(BuildContext context) {
showMyBottomSheet(
context,
callBackFunc: (){},
callBackFunc: () {},
child: WorkListAdvanceSearch((selectedViewID, selectedItemTypeID, searchByInput, searchByDate) async {
itgRequestTypeIndex = null;
pNotificationType = selectedViewID;

@ -12,7 +12,7 @@ import 'package:provider/provider.dart';
AppBar AppBarWidget(BuildContext context,
{required String title,
bool showHomeButton = true,
bool showNotificationButton = false,
bool showWorkListSettingButton = false,
bool showMemberButton = false,
List<Widget>? actions,
void Function()? onHomeTapped,
@ -43,12 +43,12 @@ AppBar AppBarWidget(BuildContext context,
},
icon: const Icon(Icons.home, color: MyColors.darkIconColor),
),
if (showNotificationButton)
if (showWorkListSettingButton)
IconButton(
onPressed: () {
Navigator.pushNamed(context, AppRoutes.worklistSettings);
},
icon: const Icon(Icons.notifications, color: MyColors.textMixColor),
icon: const Icon(Icons.settings_rounded, color: MyColors.darkIconColor),
),
if (showMemberButton)
IconButton(

@ -36,6 +36,7 @@ class ItemDetailViewCol extends StatelessWidget {
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
"$title:".toText12(isBold: true, color: const Color(0xff2BB8A6), maxLine: 2),
4.width,

@ -68,7 +68,7 @@ dependencies:
month_picker_dialog_2: 0.5.5
open_file: ^3.2.1
wifi_iot: ^0.3.16
flutter_html: ^2.2.1
flutter_html: ^3.0.0-alpha.6
# flutter_barcode_scanner: ^2.0.0
qr_code_scanner: ^1.0.0
qr_flutter: ^4.0.0
@ -100,6 +100,7 @@ dependencies:
video_player: ^2.4.7
just_audio: ^0.9.30
safe_device: ^1.1.2
flutter_layout_grid: ^2.0.1
dev_dependencies:
flutter_test:

Loading…
Cancel
Save