Merge pull request 'development_haroon' (#5) from development_haroon into master

Reviewed-on: http://34.17.52.79/Haroon6138/mohemm-flutter-app/pulls/5
master
Haroon6138 1 year ago
commit 0589a55c8d

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path id="delete_1_" data-name="delete (1)" d="M13.657,2.343A8,8,0,0,0,2.343,13.657,8,8,0,0,0,13.657,2.343Zm-2.2,8.012a.781.781,0,1,1-1.1,1.1L8,9.1,5.645,11.46a.781.781,0,0,1-1.1-1.1L6.9,8,4.54,5.645a.781.781,0,0,1,1.1-1.1L8,6.9,10.355,4.54a.781.781,0,0,1,1.1,1.1L9.1,8Zm0,0" fill="#ca3332"/>
</svg>

After

Width:  |  Height:  |  Size: 386 B

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 392.601 392.601" xml:space="preserve">
<g>
<g>
<path d="M117.659,132.85c-29.479,0-53.463,23.984-53.463,53.463s23.984,53.463,53.463,53.463
c29.543,0,53.463-23.984,53.463-53.463S147.138,132.85,117.659,132.85z M117.659,217.989c-17.455,0-31.677-14.222-31.677-31.677
s14.222-31.677,31.677-31.677s31.677,14.222,31.677,31.677S135.114,217.989,117.659,217.989z"/>
</g>
</g>
<g>
<g>
<path d="M301.32,192.842c-23.531,0-42.731,19.2-42.731,42.731c0,23.596,19.135,42.731,42.731,42.731
c23.596,0,42.731-19.135,42.731-42.731C344.051,211.977,324.916,192.842,301.32,192.842z M301.32,256.518
c-11.507,0-20.945-9.374-20.945-20.945s9.438-20.945,20.945-20.945c11.572,0,20.945,9.374,20.945,20.945
C322.265,247.08,312.891,256.518,301.32,256.518z"/>
</g>
</g>
<g>
<g>
<path d="M301.32,292.591c-32.194,0-60.832,17.325-76.994,43.119c-18.554-40.792-59.604-69.495-106.731-69.495
c-63.547,0-116.234,51.717-117.592,115.2c-0.065,2.909,1.099,5.818,3.103,7.887c2.069,2.069,4.848,3.232,7.822,3.232h370.166
c2.909,0,5.689-1.164,7.822-3.232c2.133-2.069,3.168-4.978,3.103-7.887C390.984,332.478,350.257,292.591,301.32,292.591z
M22.758,370.813c6.465-46.545,46.998-82.683,94.901-82.683c47.903,0,88.372,36.137,94.901,82.683H22.758z M233.57,370.813
c6.012-31.935,34.327-56.307,67.685-56.307s61.737,24.436,67.685,56.307H233.57z"/>
</g>
</g>
<g>
<g>
<path d="M274.427,0.066c-65.164,0-118.174,36.913-118.174,82.36c0,22.109,12.541,43.184,34.844,58.505v44.865
c0,3.685,1.875,7.111,4.913,9.115c2.78,1.875,7.24,2.069,10.343,0.84l70.4-31.095c64.065-0.776,115.846-37.43,115.846-82.23
C392.601,36.979,339.59,0.066,274.427,0.066z M274.427,142.87c-1.552,0-3.038,0.323-4.396,0.905l-57.212,25.277v-34.069
c0-3.814-2.004-7.37-5.236-9.244c-18.747-11.507-29.608-27.281-29.608-43.378c0.065-32.776,44.218-60.509,96.452-60.509
s96.388,27.733,96.388,60.509C370.815,115.201,326.661,142.87,274.427,142.87z"/>
</g>
</g>
<g>
<g>
<path d="M219.671,69.238h-5.107c-6.012,0-10.925,4.849-10.925,10.925c0.065,6.077,4.913,10.925,10.925,10.925h5.107
c6.012,0,10.925-4.849,10.925-10.925C230.597,74.151,225.748,69.238,219.671,69.238z"/>
</g>
</g>
<g>
<g>
<path d="M276.948,69.238h-5.107c-6.012,0-10.925,4.849-10.925,10.925c0,6.077,4.978,10.925,10.925,10.925h5.107
c6.012,0,10.925-4.849,10.925-10.925C287.873,74.151,283.025,69.238,276.948,69.238z"/>
</g>
</g>
<g>
<g>
<path d="M334.289,69.238h-5.107c-6.012,0-10.925,4.849-10.925,10.925c0,6.077,4.913,10.925,10.925,10.925h5.107
c6.012,0,10.925-4.849,10.925-10.925C345.215,74.151,340.366,69.238,334.289,69.238z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

@ -527,6 +527,8 @@
"noWinner": "حزين! لم يفز أحد اليوم.",
"myTeam": "فريقي",
"youCanPlayDemo": "لكن يمكنك لعب العرض",
"group" : "مجموعة",
"searchGroup": "مجموعة البحث",
"connectHmgWifi": "قم بتوصيل HMG WIFI",
"connectedHmgWifi": "اتصال HMG WIFI",
"itgForms": "نماذج (ITG)",

@ -527,6 +527,8 @@
"noWinner": "Sad! No one won today.",
"myTeam": "My Team",
"youCanPlayDemo": "But you can play demo",
"group": "Groups",
"searchGroup": "Search Group",
"connectHmgWifi": "Connect HMG WIFI",
"connectedHmgWifi": "Connected HMG WIFI",
"itgForms": "ITG Forms",
@ -538,4 +540,24 @@
"expiredDocuments": "Expired\nDocuments",
"missingDocuments": "Missing\nDocuments",
"uploadedDocuments": "Uploaded\nDocuments"
"resetAdPassword": "Reset AD Password"
"manage": "Manage",
"members": "Members",
"areYouSureWantTodelete": "Are you sure want to delete?",
"groupMembers": "Group Members",
"manageGroup": "Manage Group",
"admin": "Admin",
"addUsers": "Add users to the group",
"editGroups":"Edit Group",
"groupNameshouldbe": "Group name should be minimum 10 character long",
"enterGroupName": "Please enter valid group Name",
"groupName": "Group Name",
"enterGroupNamePlease": "Please enter group name",
"audioCall": "Audio Call",
"videoCall": "Video Call",
"shareScreen": "Share Screen",
"searchByUserName": "Search By Username",
"userSearch": "User Search",
"userName": "User Name",
"userId": "UserID"
}

@ -65,7 +65,6 @@
<array>
<string>fetch</string>
<string>remote-notification</string>
<string>voip</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>

@ -12,9 +12,17 @@ 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/create_group_request.dart'
as createGroup;
import 'package:mohem_flutter_app/models/chat/get_group_chat_history.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;
import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart'
as groups;
import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart'
as user;
import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart'
as fav;
class ChatApiClient {
static final ChatApiClient _instance = ChatApiClient._internal();
@ -28,10 +36,13 @@ class ChatApiClient {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatLoginTokenUrl}externaluserlogin",
{
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
"employeeNumber":
AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
"isMobile": true,
"deviceToken":AppState().getIsHuawei ? AppState().getHuaweiPushToken : AppState().getDeviceToken,
"deviceToken": AppState().getIsHuawei
? AppState().getHuaweiPushToken
: AppState().getDeviceToken,
"isHuaweiDevice": AppState().getIsHuawei,
},
);
@ -41,7 +52,10 @@ class ChatApiClient {
}
if (response.statusCode == 200) {
userLoginResponse = user.userAutoLoginModelFromJson(response.body);
} else if (response.statusCode == 501 || response.statusCode == 502 || response.statusCode == 503 || response.statusCode == 504) {
} else if (response.statusCode == 501 ||
response.statusCode == 502 ||
response.statusCode == 503 ||
response.statusCode == 504) {
getUserLoginToken();
} else {
userLoginResponse = user.userAutoLoginModelFromJson(response.body);
@ -50,9 +64,16 @@ class ChatApiClient {
return userLoginResponse;
}
Future<ChatUserModel> getChatMemberFromSearch(String searchParam, int cUserId, int pageNo) async {
Future<ChatUserModel> getChatMemberFromSearch(
String searchParam, int cUserId, int pageNo) async {
ChatUserModel chatUserModel;
Response response = await ApiClient().postJsonForResponse("${ApiConsts.chatLoginTokenUrl}getUserWithStatusAndFavAsync", {"employeeNumber": cUserId, "userName": searchParam, "pageNumber": pageNo},
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatLoginTokenUrl}getUserWithStatusAndFavAsync",
{
"employeeNumber": cUserId,
"userName": searchParam,
"pageNumber": pageNo
},
token: AppState().chatDetails!.response!.token);
if (!kReleaseMode) {
logger.i("res: " + response.body);
@ -92,7 +113,12 @@ class ChatApiClient {
}
//Get User Chat History
Future<Response> getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false, required int paginationVal}) async {
Future<Response> getSingleUserChatHistory(
{required int senderUID,
required int receiverUID,
required bool loadMore,
bool isNewChat = false,
required int paginationVal}) async {
try {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatSingleUserHistoryUrl}GetUserChatHistory/$senderUID/$receiverUID/$paginationVal",
@ -103,23 +129,33 @@ class ChatApiClient {
}
return response;
} catch (e) {
getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore, paginationVal: paginationVal);
getSingleUserChatHistory(
senderUID: senderUID,
receiverUID: receiverUID,
loadMore: loadMore,
paginationVal: paginationVal);
throw e;
}
}
//Favorite Users
Future<fav.FavoriteChatUser> favUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient().postJsonForResponse("${ApiConsts.chatFavUser}addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token);
Future<fav.FavoriteChatUser> favUser(
{required int userID, required int targetUserID}) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatFavUser}addFavUser",
{"targetUserId": targetUserID, "userId": userID},
token: AppState().chatDetails!.response!.token);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
fav.FavoriteChatUser favoriteChatUser =
fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser;
}
//UnFavorite Users
Future<fav.FavoriteChatUser> unFavUser({required int userID, required int targetUserID}) async {
Future<fav.FavoriteChatUser> unFavUser(
{required int userID, required int targetUserID}) async {
try {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatFavUser}deleteFavUser",
@ -129,7 +165,8 @@ class ChatApiClient {
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
fav.FavoriteChatUser favoriteChatUser =
fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser;
} catch (e) {
e as APIException;
@ -144,10 +181,12 @@ class ChatApiClient {
print(AppState().chatDetails!.response!.token);
}
dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatMediaImageUploadUrl}upload'));
dynamic request = MultipartRequest(
'POST', Uri.parse('${ApiConsts.chatMediaImageUploadUrl}upload'));
request.fields.addAll({'userId': userId, 'fileSource': '1'});
request.files.add(await MultipartFile.fromPath('files', file.path));
request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'});
request.headers.addAll(
{'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'});
StreamedResponse response = await request.send();
String data = await response.stream.bytesToString();
if (!kReleaseMode) {
@ -157,7 +196,8 @@ class ChatApiClient {
}
// Download File For Chat
Future<Uint8List> downloadURL({required String fileName, required String fileTypeDescription}) async {
Future<Uint8List> downloadURL(
{required String fileName, required String fileTypeDescription}) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatMediaImageUploadUrl}download",
{"fileType": fileTypeDescription, "fileName": fileName, "fileSource": 1},
@ -168,7 +208,8 @@ class ChatApiClient {
}
//Get Chat Users & Favorite Images
Future<List<ChatUserImageModel>> getUsersImages({required List<String> encryptedEmails}) async {
Future<List<ChatUserImageModel>> getUsersImages(
{required List<String> encryptedEmails}) async {
List<ChatUserImageModel> imagesData = [];
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatUserImages}images",
@ -188,4 +229,128 @@ class ChatApiClient {
}
return imagesData;
}
//group chat apis start here.
Future<groups.GetUserGroups> getGroupsByUserId() async {
try {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.getGroupByUserId}${AppState().chatDetails!.response!.id}",
token: AppState().chatDetails!.response!.token,
);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
return groups.GetUserGroups.fromRawJson(response.body);
} catch (e) {
//if fail api returning 500 hence just printing here
print(e);
throw e;
}
}
Future<Response> deleteGroup(int? groupId) async {
try {
Response response = await ApiClient().postJsonForResponse(
ApiConsts.deleteGroup,
{"groupId":groupId},
token: AppState().chatDetails!.response!.token,
);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
return response;
} catch (e) {
//if fail api returning 500 hence just printing here
print(e);
throw e;
}
}
Future<Response> updateGroupAdmin(
int? groupId, List<GroupUserList> groupList) async {
try {
Response response = await ApiClient().postJsonForResponse(
ApiConsts.updateGroupAdmin,
{"groupId": groupId, "groupUserList": groupList},
token: AppState().chatDetails!.response!.token,
);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
return response;
} catch (e) {
//if fail api returning 500 hence just printing here
print(e);
throw e;
}
}
Future<List<GetGroupChatHistoryAsync>> getGroupChatHistory(
int? groupId, List<GroupUserList> groupList) async {
try {
Response response = await ApiClient().postJsonForResponse(
ApiConsts.getGroupChatHistoryAsync,
{
"groupId": groupId,
"targetUserList": groupList,
"CurrentId": AppState().chatDetails!.response!.id
},
token: AppState().chatDetails!.response!.token,
);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
List<GetGroupChatHistoryAsync> groupChat = [];
List groupChatData = json.decode(response.body);
for (var i in groupChatData) {
groupChat.add(GetGroupChatHistoryAsync.fromJson(i));
}
groupChat.sort((a, b) => b.createdDate!.compareTo(a.createdDate!));
return groupChat;
// for(GetGroupChatHistoryAsync i in groupChat) {
// return GetGroupChatHistoryAsync.fromJson(jsonEncode(i));
// }
} catch (e) {
//if fail api returning 500 hence just printing here
print(e);
throw e;
}
}
Future addGroupAndUsers(createGroup.CreateGroupRequest request) async {
try {
Response response = await ApiClient().postJsonForResponse(
ApiConsts.addGroupsAndUsers,
request,
token: AppState().chatDetails!.response!.token,
);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
return response.body;
} catch (e) {
//if fail api returning 500 hence just printing here
print(e);
throw e;
}
}
Future updateGroupAndUsers(createGroup.CreateGroupRequest request) async {
try {
Response response = await ApiClient().postJsonForResponse(
ApiConsts.updateGroupsAndUsers,
request,
token: AppState().chatDetails!.response!.token,
);
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
return response.body;
} catch (e) {
//if fail api returning 500 hence just printing here
print(e);
throw e;
}
}
}

@ -201,7 +201,7 @@ class DashboardApiClient {
}, url, postParams);
}
Future setAdvertisementViewed(String masterID, int advertisementId, String ackValue) async {
Future setAdvertisementViewed(String masterID, int advertisementId, String? ackValue) async {
String url = "${ApiConsts.cocRest}Mohemm_ITG_UpdateAdvertisementAsViewed";
Map<String, dynamic> postParams = {

@ -180,7 +180,7 @@ class ProfileApiClient {
],
"P_CONTACT_RELATIONSHIP_ID": contactRelationId,
"P_ACTION": actionType,
"PayrollCodeStr": "CS",
"PayrollCodeStr": "HMG",
"LegislationCodeStr": "SA",
};
postParams.addAll(AppState().postParamsJson);

@ -90,7 +90,7 @@ class AppState {
String get getHuaweiPushToken => _huaweiPushToken;
final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.9, mobileType: Platform.isAndroid ? "android" : "ios");
final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 5.0, mobileType: Platform.isAndroid ? "android" : "ios");
void setPostParamsInitConfig() {
isAuthenticated = false;

@ -20,6 +20,14 @@ class ApiConsts {
static String chatLoginTokenUrl = chatServerBaseApiUrl + "user/";
static String chatHubConnectionUrl = chatServerBaseUrl + "ConnectionChatHub";
//Groups
static String getGroupByUserId = chatServerBaseApiUrl + "group/getgroupsbyuserid/";
static String deleteGroup = chatServerBaseApiUrl + "group/updateGroupIsDeleted/";
static String updateGroupAdmin = chatServerBaseApiUrl + "group/updateGroupAdmin/";
static String getGroupChatHistoryAsync = chatServerBaseApiUrl + "GroupChat/GetGroupChatHistoryAsync/";
static String addGroupsAndUsers = chatServerBaseApiUrl + "group/addgroupandusers/";
static String updateGroupsAndUsers = chatServerBaseApiUrl + "group/updategroupandusers/";
// static String chatSearchMember = chatLoginTokenUrl + "user/";
static String chatRecentUrl = chatServerBaseApiUrl + "UserChatHistory/"; //For a Mem
static String chatSingleUserHistoryUrl = chatServerBaseApiUrl + "UserChatHistory/";

@ -109,7 +109,10 @@ class AppNotifications {
debugPrint("HUAWEI PUSH TOKEN: $_huaweiToken");
}
void _onTokenError(Object error) {}
void _onTokenError(Object error) {
debugPrint("HUAWEI PUSH TOKEN ERROR: $error");
Utils.hideLoading(context);
}
Future<void> initTokenStream(Function loginCallback) async {
huawei_push.Push.getTokenStream.listen(_onTokenEvent, onError: _onTokenError).onData((data) {

@ -349,7 +349,7 @@ class Utils {
}
static Future<DateTime> selectDate(BuildContext context, DateTime selectedDate) async {
if (Platform.isIOS) {
if (!Platform.isIOS) {
await showCupertinoModalPopup(
context: context,
builder: (BuildContext cxt) => Container(
@ -401,7 +401,6 @@ class Utils {
}
return false;
}
static bool isDate(String input, String format) {
try {
DateTime d = DateFormat(format).parseStrict(input);

@ -8,6 +8,9 @@ import 'package:mohem_flutter_app/ui/bottom_sheets/attendence_details_bottom_she
import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart';
import 'package:mohem_flutter_app/ui/chat/chat_home.dart';
import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart';
import 'package:mohem_flutter_app/ui/chat/group_chat_detaied_screen.dart';
import 'package:mohem_flutter_app/ui/chat/group_members.dart';
import 'package:mohem_flutter_app/ui/chat/manage_group.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/ui/landing/itg/change_itg_ad_password_screen.dart';
import 'package:mohem_flutter_app/ui/landing/itg/its_add_screen_video_image.dart';
@ -190,6 +193,10 @@ class AppRoutes {
static const String chatDetailed = "/chatDetailed";
static const String chatFavoriteUsers = "/chatFavoriteUsers";
//Group Chat
static const String manageGroup = "/manageGroup";
static const String groupMembers = "/groupmembers";
static const String groupChatDetailed = "/groupChatDetailed";
//Marathon
static const String marathonIntroScreen = "/marathonIntroScreen";
static const String marathonScreen = "/marathonScreen";
@ -302,6 +309,11 @@ class AppRoutes {
chatDetailed: (BuildContext context) => ChatDetailScreen(),
chatFavoriteUsers: (BuildContext context) => ChatFavoriteUsersScreen(),
//Group Chat
manageGroup: (BuildContext context) => ManageGroupScreen(),
groupMembers: (BuildContext context) => GroupMembersScreen(),
groupChatDetailed: (BuildContext context) => GroupChatDetailScreen(),
// Marathon
marathonIntroScreen: (BuildContext context) => MarathonIntroScreen(),
marathonScreen: (BuildContext context) => MarathonScreen(),

@ -10,6 +10,4 @@ extension IntExtensions on int {
Widget get divider => Divider(height: toDouble(), thickness: toDouble(), color: MyColors.lightGreyEFColor);
Widget get makeItSquare => SizedBox(width: toDouble(), height: toDouble());
}

@ -543,6 +543,8 @@ class CodegenLoader extends AssetLoader{
"noWinner": "حزين! لم يفز أحد اليوم.",
"myTeam": "فريقي",
"youCanPlayDemo": "لكن يمكنك لعب العرض",
"group": "مجموعة",
"searchGroup": "مجموعة البحث",
"connectHmgWifi": "قم بتوصيل HMG WIFI",
"connectedHmgWifi": "اتصال HMG WIFI",
"itgForms": "نماذج (ITG)",
@ -1084,6 +1086,8 @@ static const Map<String,dynamic> en_US = {
"noWinner": "Sad! No one won today.",
"myTeam": "My Team",
"youCanPlayDemo": "But you can play demo",
"group": "Groups",
"searchGroup": "Search Group",
"connectHmgWifi": "Connect HMG WIFI",
"connectedHmgWifi": "Connected HMG WIFI",
"itgForms": "ITG Forms",
@ -1094,7 +1098,26 @@ static const Map<String,dynamic> en_US = {
"allDocuments": "All\nDocuments",
"expiredDocuments": "Expired\nDocuments",
"missingDocuments": "Missing\nDocuments",
"uploadedDocuments": "Uploaded\nDocuments"
"uploadedDocuments": "Uploaded\nDocuments",
"manage": "Manage",
"members": "Members",
"areYouSureWantTodelete": "Are you sure want to delete?",
"groupMembers": "Group Members",
"manageGroup": "Manage Group",
"admin": "Admin",
"addUsers": "Add users to the group",
"editGroups": "Edit Group",
"groupNameshouldbe": "Group name should be minimum 10 character long",
"enterGroupName": "Please enter valid group Name",
"groupName": "Group Name",
"enterGroupNamePlease": "Please enter group name",
"audioCall": "Audio Call",
"videoCall": "Video Call",
"shareScreen": "Share Screen",
"searchByUserName": "Search By Username",
"userSearch": "User Search",
"userName": "User Name",
"userId": "UserID"
};
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
}

@ -513,6 +513,8 @@ abstract class LocaleKeys {
static const noWinner = 'noWinner';
static const myTeam = 'myTeam';
static const youCanPlayDemo = 'youCanPlayDemo';
static const group = 'group';
static const searchGroup = 'searchGroup';
static const connectHmgWifi = 'connectHmgWifi';
static const connectedHmgWifi = 'connectedHmgWifi';
static const itgForms = 'itgForms';
@ -525,4 +527,23 @@ abstract class LocaleKeys {
static const missingDocuments = 'missingDocuments';
static const uploadedDocuments = 'uploadedDocuments';
static const manage = 'manage';
static const members = 'members';
static const areYouSureWantTodelete = 'areYouSureWantTodelete';
static const groupMembers = "groupMembers";
static const manageGroup = "manageGroup";
static const admin = "admin";
static const addUsers ="addUsers";
static const editGroups ="editGroups";
static const groupNameshouldbe ="groupNameshouldbe";
static const enterGroupName ="enterGroupName";
static const groupName ="groupName";
static const enterGroupNamePlease ="enterGroupNamePlease";
static const audioCall = 'audioCall';
static const videoCall ='videoCall';
static const shareScreen ='shareScreen';
static const searchByUserName ='searchByUserName';
static const userSearch ='userSearch';
static const userName ='userName';
static const userId ='userId';
}

@ -16,7 +16,7 @@ import 'package:geolocator_web/geolocator_web.dart';
import 'package:google_maps_flutter_web/google_maps_flutter_web.dart';
import 'package:image_picker_for_web/image_picker_for_web.dart';
import 'package:just_audio_web/just_audio_web.dart';
import 'package:record_web/record_web.dart';
// import 'package:record_web/record_web.dart';
import 'package:shared_preferences_web/shared_preferences_web.dart';
import 'package:url_launcher_web/url_launcher_web.dart';
import 'package:video_player_web/video_player_web.dart';
@ -35,7 +35,7 @@ void registerPlugins(Registrar registrar) {
GoogleMapsPlugin.registerWith(registrar);
ImagePickerPlugin.registerWith(registrar);
JustAudioPlugin.registerWith(registrar);
RecordPluginWeb.registerWith(registrar);
//RecordPluginWeb.registerWith(registrar);
SharedPreferencesPlugin.registerWith(registrar);
UrlLauncherPlugin.registerWith(registrar);
VideoPlayerPlugin.registerWith(registrar);

@ -0,0 +1,159 @@
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
class CreateGroupRequest {
String? groupName;
int? adminUserId;
List<ChatUser>? groupUserList;
bool? canAttach;
bool? canAudioC;
bool? canShareS;
bool? canVideoC;
bool? isMeeting;
bool? canArchive;
int? groupId;
CreateGroupRequest(
{this.groupName,
this.adminUserId,
this.groupUserList,
this.canAttach,
this.canAudioC,
this.canShareS,
this.canVideoC,
this.isMeeting,
this.canArchive,
this.groupId
});
CreateGroupRequest.fromJson(Map<String, dynamic> json) {
groupName = json['groupName'];
adminUserId = json['adminUserId'];
if (json['groupUserList'] != null) {
groupUserList = <ChatUser>[];
json['groupUserList'].forEach((v) {
groupUserList!.add(new ChatUser.fromJson(v));
});
}
canAttach = json['canAttach'];
canAudioC = json['canAudioC'];
canShareS = json['canShareS'];
canVideoC = json['canVideoC'];
isMeeting = json['isMeeting'];
canArchive = json['canArchive'];
groupId = json['groupId'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['groupName'] = this.groupName;
data['adminUserId'] = this.adminUserId;
if (this.groupUserList != null) {
data['groupUserList'] =
this.groupUserList!.map((v) => v.toJson()).toList();
}
data['canAttach'] = this.canAttach;
data['canAudioC'] = this.canAudioC;
data['canShareS'] = this.canShareS;
data['canVideoC'] = this.canVideoC;
data['isMeeting'] = this.isMeeting;
data['canArchive'] = this.canArchive;
data['groupId'] = this.groupId;
return data;
}
}
class GroupUserList {
int? id;
String? userName;
String? email;
dynamic? phone;
String? title;
int? userStatus;
String? image;
int? unreadMessageCount;
int? userAction;
bool? isPin;
bool? isFav;
bool? isAdmin;
Null? rKey;
int? totalCount;
bool? isHuaweiDevice;
Null? deviceToken;
String? token;
bool? isDomainUser;
bool? isActiveCode;
String? encryptedUserId;
String? encryptedUserName;
GroupUserList(
{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.rKey,
this.totalCount,
this.isHuaweiDevice,
this.deviceToken,
this.token,
this.isDomainUser,
this.isActiveCode,
this.encryptedUserId,
this.encryptedUserName});
GroupUserList.fromJson(Map<String, dynamic> json) {
id = json['id'];
userName = json['userName'];
email = json['email'];
phone = json['phone'];
title = json['title'];
userStatus = json['userStatus'];
image = json['image'];
unreadMessageCount = json['unreadMessageCount'];
userAction = json['userAction'];
isPin = json['isPin'];
isFav = json['isFav'];
isAdmin = json['isAdmin'];
rKey = json['rKey'];
totalCount = json['totalCount'];
isHuaweiDevice = json['isHuaweiDevice'];
deviceToken = json['deviceToken'];
token = json['token'];
isDomainUser = json['isDomainUser'];
isActiveCode = json['isActiveCode'];
encryptedUserId = json['encryptedUserId'];
encryptedUserName = json['encryptedUserName'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['userName'] = this.userName;
data['email'] = this.email;
data['phone'] = this.phone;
data['title'] = this.title;
data['userStatus'] = this.userStatus;
data['image'] = this.image;
data['unreadMessageCount'] = this.unreadMessageCount;
data['userAction'] = this.userAction;
data['isPin'] = this.isPin;
data['isFav'] = this.isFav;
data['isAdmin'] = this.isAdmin;
data['rKey'] = this.rKey;
data['totalCount'] = this.totalCount;
data['isHuaweiDevice'] = this.isHuaweiDevice;
data['deviceToken'] = this.deviceToken;
data['token'] = this.token;
data['isDomainUser'] = this.isDomainUser;
data['isActiveCode'] = this.isActiveCode;
data['encryptedUserId'] = this.encryptedUserId;
data['encryptedUserName'] = this.encryptedUserName;
return data;
}
}

@ -0,0 +1,264 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:just_audio/just_audio.dart';
class GetGroupChatHistoryAsync {
int? groupChatHistoryId;
String? contant;
String? contantNo;
int? chatEventId;
dynamic? fileTypeId;
bool? isSeen;
bool? isDelivered;
String? createdDate;
int? chatSource;
int? currentUserId;
String? currentUserName;
int? groupId;
String? groupName;
dynamic? encryptedGroupId;
dynamic? encryptedGroupName;
dynamic? callStatus;
String? conversationId;
List<GroupChatHistoryTargetUserList>? groupChatHistoryTargetUserList;
FileTypeResponse? fileTypeResponse;
GroupChatReplyResponse? groupChatReplyResponse;
bool? isReplied;
bool? isImageLoaded;
Uint8List? image;
File? voice;
AudioPlayer? voiceController;
GetGroupChatHistoryAsync(
{this.groupChatHistoryId,
this.contant,
this.contantNo,
this.chatEventId,
this.fileTypeId,
this.isSeen,
this.isDelivered,
this.createdDate,
this.chatSource,
this.currentUserId,
this.currentUserName,
this.groupId,
this.groupName,
this.encryptedGroupId,
this.encryptedGroupName,
this.callStatus,
this.conversationId,
this.groupChatHistoryTargetUserList,
this.fileTypeResponse,
this.groupChatReplyResponse,
this.image,
this.isImageLoaded,
this.isReplied,
this.voice,
this.voiceController
});
GetGroupChatHistoryAsync.fromJson(Map<String, dynamic> json) {
groupChatHistoryId = json['groupChatHistoryId'];
contant = json['contant'];
contantNo = json['contantNo'];
chatEventId = json['chatEventId'];
fileTypeId = json['fileTypeId'];
isSeen = json['isSeen'];
isDelivered = json['isDelivered'];
createdDate = json['createdDate'];
chatSource = json['chatSource'];
currentUserId = json['currentUserId'];
currentUserName = json['currentUserName'];
groupId = json['groupId'];
groupName = json['groupName'];
encryptedGroupId = json['encryptedGroupId'];
encryptedGroupName = json['encryptedGroupName'];
callStatus = json['callStatus'];
conversationId = json['conversationId'];
if (json['groupChatHistoryTargetUserList'] != null) {
groupChatHistoryTargetUserList = <GroupChatHistoryTargetUserList>[];
json['groupChatHistoryTargetUserList'].forEach((v) {
groupChatHistoryTargetUserList!
.add(new GroupChatHistoryTargetUserList.fromJson(v));
});
}
fileTypeResponse = json['fileTypeResponse'] != null
? new FileTypeResponse.fromJson(json['fileTypeResponse'])
: null;
groupChatReplyResponse = json["groupChatReplyResponse"] == null ? null : GroupChatReplyResponse.fromJson(json["groupChatReplyResponse"]);
isReplied= json['isReplied'];
isImageLoaded= json['isImageLoaded'] ??false;
image= json['image'];
voice= json['voice'];
voiceController = json["fileTypeId"] == 13 ? AudioPlayer() : null;
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['groupChatHistoryId'] = this.groupChatHistoryId;
data['contant'] = this.contant;
data['contantNo'] = this.contantNo;
data['chatEventId'] = this.chatEventId;
data['fileTypeId'] = this.fileTypeId;
data['isSeen'] = this.isSeen;
data['isDelivered'] = this.isDelivered;
data['createdDate'] = this.createdDate;
data['chatSource'] = this.chatSource;
data['currentUserId'] = this.currentUserId;
data['currentUserName'] = this.currentUserName;
data['groupId'] = this.groupId;
data['groupName'] = this.groupName;
data['encryptedGroupId'] = this.encryptedGroupId;
data['encryptedGroupName'] = this.encryptedGroupName;
data['callStatus'] = this.callStatus;
data['conversationId'] = this.conversationId;
if (this.groupChatHistoryTargetUserList != null) {
data['groupChatHistoryTargetUserList'] =
this.groupChatHistoryTargetUserList!.map((v) => v.toJson()).toList();
}
if (this.fileTypeResponse != null) {
data['fileTypeResponse'] = this.fileTypeResponse!.toJson();
}
if(this.groupChatReplyResponse !=null) {
data['groupChatReplyResponse'] = this.groupChatReplyResponse;
}
data['isReplied'] =isReplied;
data['isImageLoaded'] = isImageLoaded ?? false;
data['image'] = image;
data['voice'] = voice;
data["fileTypeId"] == 13 ? AudioPlayer() : null;
return data;
}
}
class GroupChatHistoryTargetUserList {
int? groupChatHistoryLineId;
bool? isSeen;
bool? isDelivered;
int? targetUserId;
String? targetUserName;
dynamic? userAction;
GroupChatHistoryTargetUserList(
{this.groupChatHistoryLineId,
this.isSeen,
this.isDelivered,
this.targetUserId,
this.targetUserName,
this.userAction});
GroupChatHistoryTargetUserList.fromJson(Map<String, dynamic> json) {
groupChatHistoryLineId = json['groupChatHistoryLineId'];
isSeen = json['isSeen'];
isDelivered = json['isDelivered'];
targetUserId = json['targetUserId'];
targetUserName = json['targetUserName'];
userAction = json['userAction'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['groupChatHistoryLineId'] = this.groupChatHistoryLineId;
data['isSeen'] = this.isSeen;
data['isDelivered'] = this.isDelivered;
data['targetUserId'] = this.targetUserId;
data['targetUserName'] = this.targetUserName;
data['userAction'] = this.userAction;
return data;
}
}
class FileTypeResponse {
int? fileTypeId;
dynamic? fileTypeName;
dynamic? fileTypeDescription;
dynamic? fileKind;
dynamic? fileName;
FileTypeResponse(
{this.fileTypeId,
this.fileTypeName,
this.fileTypeDescription,
this.fileKind,
this.fileName});
FileTypeResponse.fromJson(Map<String, dynamic> json) {
fileTypeId = json['fileTypeId'];
fileTypeName = json['fileTypeName'];
fileTypeDescription = json['fileTypeDescription'];
fileKind = json['fileKind'];
fileName = json['fileName'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['fileTypeId'] = this.fileTypeId;
data['fileTypeName'] = this.fileTypeName;
data['fileTypeDescription'] = this.fileTypeDescription;
data['fileKind'] = this.fileKind;
data['fileName'] = this.fileName;
return data;
}
}
class GroupChatReplyResponse {
GroupChatReplyResponse(
{this.userChatHistoryId,
this.chatEventId,
this.contant,
this.contantNo,
this.fileTypeId,
this.createdDate,
this.targetUserId,
this.targetUserName,
this.fileTypeResponse,
this.isImageLoaded,
this.image,
this.voice});
int? userChatHistoryId;
int? chatEventId;
String? contant;
String? contantNo;
dynamic? fileTypeId;
DateTime? createdDate;
int? targetUserId;
String? targetUserName;
FileTypeResponse? fileTypeResponse;
bool? isImageLoaded;
Uint8List? image;
Uint8List? voice;
factory GroupChatReplyResponse.fromJson(Map<String, dynamic> json) => GroupChatReplyResponse(
userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"],
chatEventId: json["chatEventId"] == null ? null : json["chatEventId"],
contant: json["contant"] == null ? null : json["contant"],
contantNo: json["contantNo"] == null ? null : json["contantNo"],
fileTypeId: json["fileTypeId"],
createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]),
targetUserId: json["targetUserId"] == null ? null : json["targetUserId"],
targetUserName: json["targetUserName"] == null ? null : json["targetUserName"],
fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]),
isImageLoaded: false,
image: null,
voice: null,
);
Map<String, dynamic> toJson() => {
"userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId,
"chatEventId": chatEventId == null ? null : chatEventId,
"contant": contant == null ? null : contant,
"contantNo": contantNo == null ? null : contantNo,
"fileTypeId": fileTypeId,
"createdDate": createdDate == null ? null : createdDate!.toIso8601String(),
"targetUserId": targetUserId == null ? null : targetUserId,
"targetUserName": targetUserName == null ? null : targetUserName,
"fileTypeResponse": fileTypeResponse == null ? null : fileTypeResponse!.toJson(),
};
}

@ -69,6 +69,7 @@ class ChatUser {
this.isImageLoaded,
this.isImageLoading,
this.userLocalDownlaodedImage,
this.isChecked
});
int? id;
@ -89,7 +90,7 @@ class ChatUser {
bool? isImageLoaded;
bool? isImageLoading;
File? userLocalDownlaodedImage;
bool? isChecked;
factory ChatUser.fromRawJson(String str) => ChatUser.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
@ -112,7 +113,9 @@ class ChatUser {
isTyping: false,
isImageLoaded: false,
isImageLoading: true,
userLocalDownlaodedImage: null);
userLocalDownlaodedImage: null,
isChecked: false
);
Map<String, dynamic> toJson() => {
"id": id == null ? null : id,
@ -129,5 +132,6 @@ class ChatUser {
"isAdmin": isAdmin == null ? null : isAdmin,
"rKey": rKey,
"totalCount": totalCount == null ? null : totalCount,
"isChecked":isChecked
};
}

@ -0,0 +1,261 @@
import 'dart:convert';
class GetUserGroups {
List<GroupResponse>? groupresponse;
Null? errorResponses;
GetUserGroups({this.groupresponse, this.errorResponses});
factory GetUserGroups.fromRawJson(String str) => GetUserGroups.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
GetUserGroups.fromJson(Map<String, dynamic> json) {
if (json['response'] != null) {
groupresponse = <GroupResponse>[];
json['response'].forEach((v) {
if(v['isDeleted'] == false)
groupresponse!.add(new GroupResponse.fromJson(v));
});
}
errorResponses = json['errorResponses'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
if (this.groupresponse != null) {
data['response'] = this.groupresponse!.map((v) => v.toJson()).toList();
}
data['errorResponses'] = this.errorResponses;
return data;
}
}
class GroupResponse {
int? groupId;
String? groupName;
Null? groupIcon;
bool? isDeleted;
bool? isAdmin;
bool? canVideoC;
bool? canAudioC;
bool? canShareS;
bool? canAttach;
bool? canArchive;
bool? isMeeting;
Null? meetingTime;
Null? extUserLink;
int? callStatus;
int? groupUnreadMessageCount;
AdminUser? adminUser;
List<GroupUserList>? groupUserList;
GroupResponse(
{this.groupId,
this.groupName,
this.groupIcon,
this.isDeleted,
this.isAdmin,
this.canVideoC,
this.canAudioC,
this.canShareS,
this.canAttach,
this.canArchive,
this.isMeeting,
this.meetingTime,
this.extUserLink,
this.callStatus,
this.groupUnreadMessageCount,
this.adminUser,
this.groupUserList});
GroupResponse.fromJson(Map<String, dynamic> json) {
groupId = json['groupId'];
groupName = json['groupName'];
groupIcon = json['groupIcon'];
isDeleted = json['isDeleted'];
isAdmin = json['isAdmin'];
canVideoC = json['canVideoC'];
canAudioC = json['canAudioC'];
canShareS = json['canShareS'];
canAttach = json['canAttach'];
canArchive = json['canArchive'];
isMeeting = json['isMeeting'];
meetingTime = json['meetingTime'];
extUserLink = json['extUserLink'];
callStatus = json['callStatus'];
groupUnreadMessageCount = json['groupUnreadMessageCount'];
adminUser = json['adminUser'] != null
? new AdminUser.fromJson(json['adminUser'])
: null;
if (json['groupUserList'] != null) {
groupUserList = <GroupUserList>[];
json['groupUserList'].forEach((v) {
groupUserList!.add(new GroupUserList.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['groupId'] = this.groupId;
data['groupName'] = this.groupName;
data['groupIcon'] = this.groupIcon;
data['isDeleted'] = this.isDeleted;
data['isAdmin'] = this.isAdmin;
data['canVideoC'] = this.canVideoC;
data['canAudioC'] = this.canAudioC;
data['canShareS'] = this.canShareS;
data['canAttach'] = this.canAttach;
data['canArchive'] = this.canArchive;
data['isMeeting'] = this.isMeeting;
data['meetingTime'] = this.meetingTime;
data['extUserLink'] = this.extUserLink;
data['callStatus'] = this.callStatus;
data['groupUnreadMessageCount'] = this.groupUnreadMessageCount;
if (this.adminUser != null) {
data['adminUser'] = this.adminUser!.toJson();
}
if (this.groupUserList != null) {
data['groupUserList'] =
this.groupUserList!.map((v) => v.toJson()).toList();
}
return data;
}
}
class AdminUser {
int? id;
String? userName;
String? email;
Null? phone;
String? title;
int? userStatus;
Null? image;
int? unreadMessageCount;
Null? userAction;
bool? isPin;
bool? isFav;
bool? isAdmin;
Null? rKey;
int? totalCount;
AdminUser(
{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.rKey,
this.totalCount});
AdminUser.fromJson(Map<String, dynamic> json) {
id = json['id'];
userName = json['userName'];
email = json['email'];
phone = json['phone'];
title = json['title'];
userStatus = json['userStatus'];
image = json['image'];
unreadMessageCount = json['unreadMessageCount'];
userAction = json['userAction'];
isPin = json['isPin'];
isFav = json['isFav'];
isAdmin = json['isAdmin'];
rKey = json['rKey'];
totalCount = json['totalCount'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['userName'] = this.userName;
data['email'] = this.email;
data['phone'] = this.phone;
data['title'] = this.title;
data['userStatus'] = this.userStatus;
data['image'] = this.image;
data['unreadMessageCount'] = this.unreadMessageCount;
data['userAction'] = this.userAction;
data['isPin'] = this.isPin;
data['isFav'] = this.isFav;
data['isAdmin'] = this.isAdmin;
data['rKey'] = this.rKey;
data['totalCount'] = this.totalCount;
return data;
}
}
class GroupUserList {
int? id;
String? userName;
String? email;
Null? phone;
String? title;
int? userStatus;
Null? image;
int? unreadMessageCount;
int? userAction;
bool? isPin;
bool? isFav;
bool? isAdmin;
Null? rKey;
int? totalCount;
GroupUserList(
{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.rKey,
this.totalCount});
GroupUserList.fromJson(Map<String, dynamic> json) {
id = json['id'];
userName = json['userName'];
email = json['email'];
phone = json['phone'];
title = json['title'];
userStatus = json['userStatus'];
image = json['image'];
unreadMessageCount = json['unreadMessageCount'];
userAction = json['userAction'];
isPin = json['isPin'];
isFav = json['isFav'];
isAdmin = json['isAdmin'];
rKey = json['rKey'];
totalCount = json['totalCount'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['userName'] = this.userName;
data['email'] = this.email;
data['phone'] = this.phone;
data['title'] = this.title;
data['userStatus'] = this.userStatus;
data['image'] = this.image;
data['unreadMessageCount'] = this.unreadMessageCount;
data['userAction'] = this.userAction;
data['isPin'] = this.isPin;
data['isFav'] = this.isFav;
data['isAdmin'] = this.isAdmin;
data['rKey'] = this.rKey;
data['totalCount'] = this.totalCount;
return data;
}
}

@ -0,0 +1,32 @@
class TargetUsers {
bool? isSeen;
bool? isDelivered;
int? targetUserId;
int? userAction;
int? userStatus;
TargetUsers(
{this.isSeen,
this.isDelivered,
this.targetUserId,
this.userAction,
this.userStatus});
TargetUsers.fromJson(Map<String, dynamic> json) {
isSeen = json['isSeen'];
isDelivered = json['isDelivered'];
targetUserId = json['targetUserId'];
userAction = json['userAction'];
userStatus = json['userStatus'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['isSeen'] = this.isSeen;
data['isDelivered'] = this.isDelivered;
data['targetUserId'] = this.targetUserId;
data['userAction'] = this.userAction;
data['userStatus'] = this.userStatus;
return data;
}
}

@ -1,108 +1,156 @@
class Advertisement {
int? advertisementId;
String? advertisementTitle;
int? durationInSeconds;
bool? showDelete;
dynamic acknowledgment;
late bool isOptional;
List<ViewAttachFileColl>? viewAttachFileColl;
int? skipButtonId;
List<ActionButtonsColl>? actionButtonsColl;
bool? isActive;
num? pageSize;
num? pageNo;
num? languageId;
Advertisement({
this.advertisementId,
this.advertisementTitle,
this.durationInSeconds,
this.showDelete,
this.acknowledgment,
required this.isOptional,
// this.skipBtnTextEn,
// this.skipBtnTextAr,
this.viewAttachFileColl,
this.skipButtonId,
this.actionButtonsColl,
this.isActive,
this.pageSize,
this.pageNo,
this.languageId,
this.isOptional,
this.skipButtonTextEn,
this.skipButtonTextAr,
});
final int? advertisementId;
final String? advertisementTitle;
final int? durationInSeconds;
final bool? showDelete;
final dynamic acknowledgment;
final List<ViewAttachFileColl>? viewAttachFileColl;
final bool? isActive;
final dynamic pageSize;
final dynamic pageNo;
final dynamic languageId;
final bool? isOptional;
final String? skipButtonTextEn;
final String? skipButtonTextAr;
factory Advertisement.fromJson(Map<String, dynamic> json) => Advertisement(
advertisementId: json["advertisementId"] == null ? null : json["advertisementId"],
advertisementTitle: json["advertisementTitle"] == null ? null : json["advertisementTitle"],
durationInSeconds: json["durationInSeconds"] == null ? null : json["durationInSeconds"],
showDelete: json["showDelete"] == null ? null : json["showDelete"],
acknowledgment: json["acknowledgment"],
viewAttachFileColl: json["viewAttachFileColl"] == null ? null : List<ViewAttachFileColl>.from(json["viewAttachFileColl"].map((x) => ViewAttachFileColl.fromJson(x))),
isActive: json["isActive"] == null ? null : json["isActive"],
pageSize: json["pageSize"],
pageNo: json["pageNo"],
languageId: json["languageId"],
isOptional: json["isOptional"] == null ? null : json["isOptional"],
skipButtonTextEn: json["skipBtnTextEn"] == null ? null : json["skipBtnTextEn"],
skipButtonTextAr: json["skipBtnTextAr"] == null ? null : json["skipBtnTextAr"],
);
Advertisement.fromJson(Map<String, dynamic> json) {
advertisementId = json['advertisementId'];
advertisementTitle = json['advertisementTitle'];
durationInSeconds = json['durationInSeconds'];
showDelete = json['showDelete'];
acknowledgment = json['acknowledgment'];
isOptional = json['isOptional'];
// skipBtnTextEn = json['skipBtnTextEn'];
// skipBtnTextAr = json['skipBtnTextAr'];
if (json['viewAttachFileColl'] != null) {
viewAttachFileColl = <ViewAttachFileColl>[];
json['viewAttachFileColl'].forEach((v) {
viewAttachFileColl!.add(ViewAttachFileColl.fromJson(v));
});
}
skipButtonId = json['skipButtonId'];
if (json['actionButtonsColl'] != null) {
actionButtonsColl = <ActionButtonsColl>[];
json['actionButtonsColl'].forEach((v) {
actionButtonsColl!.add(ActionButtonsColl.fromJson(v));
});
}
isActive = json['isActive'];
pageSize = json['pageSize'];
pageNo = json['pageNo'];
languageId = json['languageId'];
}
Map<String, dynamic> toJson() => {
"advertisementId": advertisementId == null ? null : advertisementId,
"advertisementTitle": advertisementTitle == null ? null : advertisementTitle,
"durationInSeconds": durationInSeconds == null ? null : durationInSeconds,
"showDelete": showDelete == null ? null : showDelete,
"acknowledgment": acknowledgment,
"viewAttachFileColl": viewAttachFileColl == null ? null : List<dynamic>.from(viewAttachFileColl!.map((x) => x.toJson())),
"isActive": isActive == null ? null : isActive,
"pageSize": pageSize,
"pageNo": pageNo,
"languageId": languageId,
};
Map<String, dynamic> toJson() {
Map<String, dynamic> data = Map<String, dynamic>();
data['advertisementId'] = this.advertisementId;
data['advertisementTitle'] = this.advertisementTitle;
data['durationInSeconds'] = this.durationInSeconds;
data['showDelete'] = this.showDelete;
data['acknowledgment'] = this.acknowledgment;
data['isOptional'] = this.isOptional;
// data['skipBtnTextEn'] = this.skipBtnTextEn;
// data['skipBtnTextAr'] = this.skipBtnTextAr;
if (this.viewAttachFileColl != null) {
data['viewAttachFileColl'] = this.viewAttachFileColl!.map((v) => v.toJson()).toList();
}
data['skipButtonId'] = this.skipButtonId;
if (this.actionButtonsColl != null) {
data['actionButtonsColl'] = this.actionButtonsColl!.map((v) => v.toJson()).toList();
}
data['isActive'] = this.isActive;
data['pageSize'] = this.pageSize;
data['pageNo'] = this.pageNo;
data['languageId'] = this.languageId;
return data;
}
}
class ViewAttachFileColl {
ViewAttachFileColl({
this.attachmentId,
this.fileName,
this.contentType,
this.attachFileStream,
this.base64String,
this.isActive,
this.referenceItemId,
this.content,
this.filePath,
});
dynamic attachmentId;
String? fileName;
String? contentType;
dynamic attachFileStream;
String? base64String;
dynamic isActive;
dynamic referenceItemId;
dynamic content;
dynamic filePath;
ViewAttachFileColl({this.attachmentId, this.fileName, this.contentType, this.attachFileStream, this.base64String, this.isActive, this.referenceItemId, this.content, this.filePath});
ViewAttachFileColl.fromJson(Map<String, dynamic> json) {
attachmentId = json['attachmentId'];
fileName = json['fileName'];
contentType = json['contentType'];
attachFileStream = json['attachFileStream'];
base64String = json['base64String'];
isActive = json['isActive'];
referenceItemId = json['referenceItemId'];
content = json['content'];
filePath = json['filePath'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['attachmentId'] = this.attachmentId;
data['fileName'] = this.fileName;
data['contentType'] = this.contentType;
data['attachFileStream'] = this.attachFileStream;
data['base64String'] = this.base64String;
data['isActive'] = this.isActive;
data['referenceItemId'] = this.referenceItemId;
data['content'] = this.content;
data['filePath'] = this.filePath;
return data;
}
}
class ActionButtonsColl {
late int actionButtonId;
late String btnTextEn;
late String btnTextAr;
late String actionValue;
late dynamic iconOrImage;
late int orderNo;
final dynamic attachmentId;
final String? fileName;
final String? contentType;
final dynamic attachFileStream;
final String? base64String;
final dynamic isActive;
final dynamic referenceItemId;
final dynamic content;
final dynamic filePath;
ActionButtonsColl({required this.actionButtonId, required this.btnTextEn, required this.btnTextAr, required this.actionValue, required this.iconOrImage, required this.orderNo});
factory ViewAttachFileColl.fromJson(Map<String, dynamic> json) => ViewAttachFileColl(
attachmentId: json["attachmentId"],
fileName: json["fileName"] == null ? null : json["fileName"],
contentType: json["contentType"] == null ? null : json["contentType"],
attachFileStream: json["attachFileStream"],
base64String: json["base64String"] == null ? null : json["base64String"],
isActive: json["isActive"],
referenceItemId: json["referenceItemId"],
content: json["content"],
filePath: json["filePath"],
);
ActionButtonsColl.fromJson(Map<String, dynamic> json) {
actionButtonId = json['actionButtonId'];
btnTextEn = json['btnTextEn'];
btnTextAr = json['btnTextAr'];
actionValue = json['actionValue'];
iconOrImage = json['iconOrImage'];
orderNo = json['orderNo'];
}
Map<String, dynamic> toJson() => {
"attachmentId": attachmentId,
"fileName": fileName == null ? null : fileName,
"contentType": contentType == null ? null : contentType,
"attachFileStream": attachFileStream,
"base64String": base64String == null ? null : base64String,
"isActive": isActive,
"referenceItemId": referenceItemId,
"content": content,
"filePath": filePath,
};
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['actionButtonId'] = this.actionButtonId;
data['btnTextEn'] = this.btnTextEn;
data['btnTextAr'] = this.btnTextAr;
data['actionValue'] = this.actionValue;
data['iconOrImage'] = this.iconOrImage;
data['orderNo'] = this.orderNo;
return data;
}
}

@ -5,9 +5,9 @@ class SurveyModel {
String? description;
List<Questions>? questions;
bool? isActive;
Null? pageSize;
Null? pageNo;
Null? languageId;
dynamic pageSize;
dynamic pageNo;
dynamic languageId;
SurveyModel({this.surveyId, this.referenceNo, this.title, this.description, this.questions, this.isActive, this.pageSize, this.pageNo, this.languageId});
@ -51,13 +51,13 @@ class Questions {
bool? isRequired;
String? type;
int? sequenceNo;
Null? surveyId;
dynamic surveyId;
List<Options>? options;
Null? rspPercentage;
Null? isActive;
Null? pageSize;
Null? pageNo;
Null? languageId;
dynamic rspPercentage;
dynamic isActive;
dynamic pageSize;
dynamic pageNo;
dynamic languageId;
Questions({this.questionId, this.title, this.isRequired, this.type, this.sequenceNo, this.surveyId, this.options, this.rspPercentage, this.isActive, this.pageSize, this.pageNo, this.languageId});
@ -107,12 +107,12 @@ class Options {
bool? isCommentsRequired;
int? sequenceNo;
int? questionId;
Null? rspPercentage;
Null? count;
Null? isActive;
Null? pageSize;
Null? pageNo;
Null? languageId;
dynamic rspPercentage;
dynamic count;
dynamic isActive;
dynamic pageSize;
dynamic pageNo;
dynamic languageId;
Options({this.optionId, this.title, this.isCommentsRequired, this.sequenceNo, this.questionId, this.rspPercentage, this.count, this.isActive, this.pageSize, this.pageNo, this.languageId});

@ -6,7 +6,7 @@ class ITGRequest {
List<AllowedActions>? allowedActions;
List<dynamic>? attachments;
List<FieldGoups>? fieldGoups;
Null? grantFields;
dynamic grantFields;
List<WFHistory>? wFHistory;
ITGRequest({this.allowedActions, this.attachments, this.fieldGoups, this.grantFields, this.wFHistory});

File diff suppressed because it is too large Load Diff

@ -10,6 +10,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/ui/chat/chat_home_screen.dart';
import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart';
import 'package:mohem_flutter_app/ui/chat/group_chat.dart';
import 'package:mohem_flutter_app/ui/chat/my_team_screen.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
@ -46,6 +47,7 @@ class _ChatHomeState extends State<ChatHome> {
data.getUserAutoLoginToken().whenComplete(() async {
await data.buildHubConnection();
data.getUserRecentChats();
});
return;
}
@ -89,8 +91,9 @@ class _ChatHomeState extends State<ChatHome> {
child: Row(
children: <Widget>[
myTab(LocaleKeys.mychats.tr(), 0),
myTab(LocaleKeys.favorite.tr(), 1),
AppState().getempStatusIsManager ? myTab(LocaleKeys.myTeam.tr(), 2) : const SizedBox(),
// myTab(LocaleKeys.group.tr(), 1),
myTab(LocaleKeys.favorite.tr(), 2),
AppState().getempStatusIsManager ? myTab(LocaleKeys.myTeam.tr(), 3) : const SizedBox(),
],
),
),
@ -104,6 +107,7 @@ class _ChatHomeState extends State<ChatHome> {
},
children: <Widget>[
ChatHomeScreen(),
// GropChatHomeScreen(),
ChatFavoriteUsersScreen(),
AppState().getempStatusIsManager ? const MyTeamScreen() : const SizedBox(),
],

@ -0,0 +1,699 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
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/main.dart';
import 'package:mohem_flutter_app/models/chat/create_group_request.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart'
as groups;
import 'package:mohem_flutter_app/models/get_action_history_list_model.dart';
import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart';
import 'package:mohem_flutter_app/models/worklist/replacement_list_model.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart';
import 'package:provider/provider.dart';
class CreateGroupBottomSheet extends StatefulWidget {
int? notificationID;
String title, apiMode;
List<GetActionHistoryList>? actionHistoryList;
Function(ReplacementList) onSelectEmployee;
bool fromChat;
groups.GroupResponse groupDetails;
CreateGroupBottomSheet({
Key? key,
required this.title,
required this.apiMode,
this.notificationID,
this.actionHistoryList,
required this.onSelectEmployee,
required this.fromChat,
required this.groupDetails,
}) : super(key: key);
@override
State<CreateGroupBottomSheet> createState() => _CreateGroupBottomSheetState();
}
class _CreateGroupBottomSheetState extends State<CreateGroupBottomSheet> {
TextEditingController username = TextEditingController();
ScrollController sc = ScrollController();
bool isAudioCall = true;
bool isVideoCall = true;
bool isAttachments = true;
bool isShareScreen = true;
String searchText = "";
String groupName = "";
List<String>? optionsList = [
LocaleKeys.fullName.tr(),
LocaleKeys.username.tr(),
LocaleKeys.endDate.tr(),
];
List<GetFavoriteReplacements>? favUsersList;
List<ReplacementList>? replacementList;
List<ReplacementList>? favouriteUserList;
List<ReplacementList>? nonFavouriteUserList;
// Chat Items
late ChatProviderModel provider;
int _selectedSearchIndex = 0;
List<ChatUser> selectedUsers = [];
void fetchUserByInput({bool isNeedLoading = true}) async {
try {
Utils.showLoading(context);
replacementList = await WorkListApiClient().searchUserByInput(
userName: _selectedSearchIndex == 0 ? searchText : "",
userId: _selectedSearchIndex == 1 ? searchText : "",
email: _selectedSearchIndex == 2 ? searchText : "",
);
favouriteUserList = replacementList
?.where((ReplacementList element) => element.isFavorite ?? false)
.toList();
nonFavouriteUserList = replacementList
?.where((ReplacementList element) => !(element.isFavorite ?? false))
.toList();
Utils.hideLoading(context);
setState(() {});
} catch (e) {
Utils.hideLoading(context);
Utils.handleException(e, context, null);
}
if (isNeedLoading) Utils.hideLoading(context);
setState(() {});
return null;
}
void fetchChatUser({bool isNeedLoading = true}) async {
if (provider.pageNo == 1) provider.chatUsersList!.clear();
try {
Utils.showLoading(context);
await ChatApiClient()
.getChatMemberFromSearch(searchText,
AppState().chatDetails!.response!.id!, provider.pageNo)
.then((ChatUserModel value) {
if (value.response != null) {
if (provider.pageNo == 1) {
provider.chatUsersList = value.response;
} else {
print("--------------------------Added More----------------------");
provider.chatUsersList!.addAll(value.response!);
}
}
});
provider.chatUsersList!.removeWhere((ChatUser element) =>
element.id == AppState().chatDetails!.response!.id);
Utils.hideLoading(context);
setState(() {});
} catch (e) {
Utils.hideLoading(context);
Utils.handleException(e, context, null);
}
if (isNeedLoading) Utils.hideLoading(context);
setState(() {});
return null;
}
void scrollListener() async {
if (sc.position.pixels == sc.position.maxScrollExtent) {
provider.pageNo++;
logger.w(provider.chatUsersList!.length);
logger.w(provider.pageNo);
fetchChatUser();
}
}
@override
void initState() {
super.initState();
sc.addListener(scrollListener);
provider = Provider.of<ChatProviderModel>(context, listen: false);
if (widget.groupDetails.groupName !=null) {
setState(() {
groupName = widget.groupDetails.groupName!;
isAudioCall = widget.groupDetails.canAudioC!;
isVideoCall = widget.groupDetails.canVideoC!;
isAttachments = widget.groupDetails.canAttach!;
isShareScreen = widget.groupDetails.canShareS!;
for (groups.GroupUserList items in widget.groupDetails.groupUserList!) {
{
selectedUsers.add(ChatUser.fromJson(items.toJson()));
}
}
});
}
}
@override
void dispose() {
super.dispose();
provider.chatUsersList = [];
provider.pageNo = 1;
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: MediaQuery.of(context).size.height - 100,
child: Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.title.toText24(isBold: true),
21.height,
Row(
children: [
DynamicTextFieldWidget(
LocaleKeys.groupName.tr(),
groupName.isEmpty ? LocaleKeys.enterGroupNamePlease.tr() : groupName,
inputAction: TextInputAction.done,
onChange: (String text) {
groupName = text;
setState(() {});
},
).expanded,
],
),
//11.height,
Row(
children: [
SizedBox(
height: 35,
child: CheckboxListTile(
contentPadding: EdgeInsets.zero,
title: LocaleKeys.audioCall.tr().toText10(),
checkboxShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
side: BorderSide(
width: 1.5,
color: Theme.of(context).unselectedWidgetColor),
value: isAudioCall,
onChanged: (bool? newValue) {
setState(() {
isAudioCall = newValue!;
});
},
controlAffinity: ListTileControlAffinity
.leading, // <-- leading Checkbox
)).expanded,
SizedBox(
height: 35,
child: CheckboxListTile(
contentPadding: EdgeInsets.zero,
title: LocaleKeys.videoCall.tr().toText10(),
checkboxShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
value: isVideoCall,
onChanged: (bool? newValue) {
setState(() {
isVideoCall = newValue!;
});
},
controlAffinity: ListTileControlAffinity
.leading, // <-- leading Checkbox
)).expanded
],
),
Row(
children: [
SizedBox(
height: 35,
child: CheckboxListTile(
contentPadding: EdgeInsets.zero,
title:LocaleKeys.attachments.tr().toText10(),
checkboxShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
value: isAttachments,
onChanged: (bool? newValue) {
setState(() {
isAttachments = newValue!;
});
},
controlAffinity: ListTileControlAffinity
.leading, // <-- leading Checkbox
)).expanded,
SizedBox(
height: 35,
child: CheckboxListTile(
contentPadding: EdgeInsets.zero,
checkboxShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
title:LocaleKeys.shareScreen.tr().toText10(),
value: isShareScreen,
onChanged: (bool? newValue) {
setState(() {
isShareScreen = newValue!;
});
},
controlAffinity: ListTileControlAffinity
.leading, // <-- leading Checkbox
)).expanded
],
),
11.height,
LocaleKeys.userSearch.tr().toText16(),
11.height,
Row(
children: [
radioOption(widget.fromChat ? LocaleKeys.userId.tr() : LocaleKeys.name.tr(), 0,
_selectedSearchIndex),
radioOption(LocaleKeys.userName.tr(), 1, _selectedSearchIndex),
radioOption(LocaleKeys.email.tr(), 2, _selectedSearchIndex),
],
),
14.height,
Row(
children: [
DynamicTextFieldWidget(
LocaleKeys.search.tr(),
LocaleKeys.searchByUserName.tr(),
inputAction: TextInputAction.done,
suffixIconData: Icons.search,
onChange: (String text) {
searchText = text;
setState(() {});
},
).expanded,
IconButton(
constraints: const BoxConstraints(),
onPressed: () async {
provider.chatUsersList!.clear();
provider.pageNo =1;
await SystemChannels.textInput
.invokeMethod('TextInput.hide');
widget.fromChat ? fetchChatUser() : fetchUserByInput();
},
icon: const Icon(Icons.search),
)
],
),
if (replacementList != null)
replacementList!.isEmpty
? Utils.getNoDataWidget(context).expanded
: ListView(
physics: const BouncingScrollPhysics(),
padding: EdgeInsets.only(top: 21, bottom: 8),
children: [
if (favouriteUserList?.isNotEmpty ?? false) ...[
LocaleKeys.favorite.tr().toText16(),
12.height,
ListView.separated(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext cxt, int index) =>
employeeItemView(favouriteUserList![index]),
separatorBuilder:
(BuildContext cxt, int index) => Container(
height: 1,
color: MyColors.borderE3Color,
),
itemCount: favouriteUserList?.length ?? 0),
12.height,
],
if (nonFavouriteUserList?.isNotEmpty ?? false) ...[
"Related".toText16(),
12.height,
ListView.separated(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext cxt, int index) =>
employeeItemView(
nonFavouriteUserList![index]),
separatorBuilder:
(BuildContext cxt, int index) => Container(
height: 1,
color: MyColors.borderE3Color,
),
itemCount: nonFavouriteUserList?.length ?? 0),
],
],
).expanded,
selectedUsers!.isNotEmpty
? SizedBox(
height: 95,
child: ListView.builder(
physics: const ClampingScrollPhysics(),
scrollDirection: Axis.horizontal,
itemCount: selectedUsers!.length,
itemBuilder: (BuildContext context, int index2) {
return Stack(children: [
Column(
children: [
12.height,
Stack(children: [
Container(
padding:const EdgeInsets.all(5),
child: SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
)),
Positioned(
right: 0,
top: 0,
child: InkWell(
child: SvgPicture.asset(
'assets/icons/close.svg',
height:15,
width:15
),
onTap: () {
setState(() {
// provider.chatUsersList![index]
// .isChecked = false;
List<ChatUser> user = provider
.chatUsersList!
.where((ChatUser value) =>
value.userName ==
selectedUsers[index2]
.userName)
.toList();
if (user.isNotEmpty) {
user.first.isChecked = false;
}
selectedUsers.remove(
selectedUsers[index2]);
});
},
))
],),
(selectedUsers![index2]
.userName!
.replaceFirst(".", " ")
.capitalizeFirstofEach ??
"")
.toText12(color: MyColors.darkTextColor)
.paddingOnly(left: 5, top: 5),
selectedUsers![index2].isTyping!
? 'Typing...'
.toText10(
color: MyColors.textMixColor,
)
.paddingOnly(left: 5.0)
: const SizedBox()
],
),
// IconButton(onPressed: (){}, icon: const Icon(Icons.close_outlined, color: Colors.red, size: 20)),
]);
}))
: 0.height,
if (widget.fromChat)
if (provider.chatUsersList != null && widget.fromChat)
provider.chatUsersList!.isEmpty
? Column(
children: [
20.height,
Utils.getNoDataWidget(context),
],
)
: ListView.separated(
itemCount: provider.chatUsersList!.length,
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
controller: sc,
padding: const EdgeInsets.only(bottom: 80.0, top: 20),
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 55,
child: Row(
children: [
Stack(
children: <Widget>[
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
Positioned(
right: 5,
bottom: 1,
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: provider
.chatUsersList![index]
.userStatus ==
1
? MyColors.green2DColor
: Colors.red,
),
).circle(10),
)
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
(provider.chatUsersList![index].userName!
.replaceFirst(".", " ")
.capitalizeFirstofEach ??
"")
.toText14(
color: MyColors.darkTextColor)
.paddingOnly(left: 11, top: 13),
provider.chatUsersList![index].isTyping!
? 'Typing...'
.toText10(
color: MyColors.textMixColor,
)
.paddingOnly(left: 11.0)
: const SizedBox()
],
).expanded,
SizedBox(
width: 60,
child: Row(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
if (provider.chatUsersList![index]
.unreadMessageCount! >
0)
Container(
alignment: Alignment.center,
width: 18,
height: 18,
decoration: const BoxDecoration(
color: MyColors.redColor,
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
child: (provider
.chatUsersList![index]
.unreadMessageCount!
.toString())
.toText10(
color: MyColors.white,
)
.center,
).paddingOnly(right: 10).center,
Checkbox(
value: provider
.chatUsersList![index].isChecked,
shape: CircleBorder(),
onChanged: (bool? value) {
setState(() {
provider.chatUsersList![index]
.isChecked = value;
if (provider.chatUsersList![index]
.isChecked ==
true) {
selectedUsers.add(provider
.chatUsersList![index]);
} else {
selectedUsers.remove(provider
.chatUsersList![index]);
}
});
},
)
],
),
),
],
),
);
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(color: MyColors.lightGreyE5Color)
.paddingOnly(left: 59),
).expanded,
],
).paddingOnly(left: 21, right: 21, bottom: 0, top: 21).expanded,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
DefaultButton(
LocaleKeys.cancel.tr(),
() {
Navigator.pop(context);
provider.chatUsersList = [];
provider.pageNo = 1;
},
textColor: MyColors.grey3AColor,
colors: const [
Color(0xffE6E6E6),
Color(0xffE6E6E6),
],
).paddingOnly(left: 14, right: 14, bottom: 15, top: 10).expanded,
DefaultButton(
LocaleKeys.submit.tr(),
() {
// Navigator.pop(context);
// provider.chatUsersList = [];
// provider.pageNo = 1;
createGroup();
},
textColor: MyColors.whiteColor,
colors: const [
Color(0xff32D892),
Color(0xff1AB170),
],
).paddingOnly(left: 15, right: 15, bottom: 15, top: 10).expanded,
],
)
],
),
);
}
Widget employeeItemView(ReplacementList replacement) {
return InkWell(
onTap: () {
Navigator.pop(context);
widget.onSelectEmployee(replacement);
},
child: SizedBox(
height: 50,
child: Row(
children: [
CircularAvatar(
url: replacement.employeeImage ?? "",
height: 30,
width: 30,
isImageBase64: true,
),
16.width,
Expanded(
child: (replacement.employeeDisplayName ?? "").toText12(),
),
Icon(Icons.star,
size: 16,
color: replacement.isFavorite!
? MyColors.yellowFavColor
: MyColors.borderCEColor),
],
),
),
);
}
Widget radioOption(String title, int value, int groupValue) {
return Row(
children: [
Container(
width: 24,
height: 24,
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(color: MyColors.borderColor, width: 1),
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
),
padding: const EdgeInsets.all(4),
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
color: value == groupValue
? MyColors.grey3AColor
: Colors.transparent,
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
),
),
),
9.width,
title.toText12(color: MyColors.grey57Color)
],
).onPress(() {
_selectedSearchIndex = value;
setState(() {});
}).expanded;
}
void createGroup() async {
RegExp validCharacters = RegExp(r'^[a-zA-Z0-9_\-=@,\.;]+$');
if (!validCharacters.hasMatch(groupName)) {
Utils.showToast(LocaleKeys.enterGroupName.tr());
} else if (groupName.length < 10) {
Utils.showToast(LocaleKeys.groupNameshouldbe.tr());
} else {
List<ChatUser>? mainUsers = [];
ChatUser admin =
ChatUser.fromJson(AppState().chatDetails!.response!.toJson());
admin.isAdmin = true;
admin.userStatus = 2;
admin.unreadMessageCount = 0;
admin.totalCount = 0;
mainUsers.add(admin);
CreateGroupRequest request = CreateGroupRequest(
groupUserList: [...selectedUsers, ...mainUsers].toList(),
canArchive: false,
isMeeting: false,
canShareS: isShareScreen,
canAudioC: isAudioCall,
canAttach: isAttachments,
canVideoC: isVideoCall,
groupName: groupName,
adminUserId: AppState().chatDetails!.response!.id);
if(widget.groupDetails!.groupId !=null){
request.groupId =widget.groupDetails!.groupId;
await provider.updateGroupAndUsers(request);
}else {
await provider.addGroupAndUsers(request);
}
Navigator.pop(context);
}
}
}

@ -0,0 +1,307 @@
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_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/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/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/chat/get_group_chat_history.dart';
import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart';
import 'package:mohem_flutter_app/models/worklist/replacement_list_model.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart';
import 'package:mohem_flutter_app/ui/chat/create_group.dart';
import 'package:mohem_flutter_app/ui/chat/group_chat_detaied_screen.dart';
import 'package:mohem_flutter_app/ui/chat/manage_group.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/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
class GropChatHomeScreen extends StatefulWidget {
const GropChatHomeScreen({Key? key}) : super(key: key);
@override
State<GropChatHomeScreen> createState() => _GropChatHomeScreenState();
}
class _GropChatHomeScreenState extends State<GropChatHomeScreen> {
TextEditingController search = TextEditingController();
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
search.clear();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: MyColors.white,
body: Consumer<ChatProviderModel>(
builder: (BuildContext context, ChatProviderModel m, Widget? child) {
return m.isLoading
? ChatHomeShimmer(
isDetailedScreen: false,
)
: Column(
children: <Widget>[
TextField(
controller: m.searchGroup,
style: const TextStyle(
color: MyColors.darkTextColor,
fontWeight: FontWeight.w500,
fontSize: 12),
onChanged: (String val) {
m.filterGroups(val);
},
decoration: InputDecoration(
border: fieldBorder(radius: 5, color: 0xFFE5E5E5),
focusedBorder:
fieldBorder(radius: 5, color: 0xFFE5E5E5),
enabledBorder:
fieldBorder(radius: 5, color: 0xFFE5E5E5),
contentPadding: const EdgeInsets.all(11),
hintText: LocaleKeys.searchGroup.tr(),
hintStyle: const TextStyle(
color: MyColors.lightTextColor,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w500,
fontSize: 12),
filled: true,
fillColor: MyColors.greyF7Color,
suffixIconConstraints: const BoxConstraints(),
suffixIcon: m.search.text.isNotEmpty
? IconButton(
constraints: const BoxConstraints(),
onPressed: () {
m.clearSelections();
},
icon: const Icon(Icons.clear, size: 22),
color: MyColors.redA3Color,
)
: null,
),
).paddingOnly(top: 20, bottom: 14),
if (m.uGroups != null)
ListView.separated(
itemCount: m.uGroups!.length,
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.only(bottom: 80.0),
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 55,
child: Row(
children: [
Container(
alignment: Alignment.center,
width: 48,
height: 48,
padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.0),
border: Border.all(
width: 1, color: Colors.black),
),
child: SvgPicture.asset(
"assets/images/chat-group.svg",
)),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
(m.uGroups![index]
.groupName!
.toText14(
color: MyColors.darkTextColor)
.paddingOnly(left: 11, top: 16))!,
]),
Align(
alignment: Alignment.centerRight,
child: PopupMenuButton(
onSelected: (String value){
goToSelected(m.uGroups![index], m, value);
},
itemBuilder: (context) => [
PopupMenuItem<String>(
value: '1',
enabled: m.uGroups![index].isAdmin ?? false,
child: (LocaleKeys.edit
.tr()
.toText14(color: m.userGroups?.groupresponse![index].isAdmin == true ? MyColors.darkTextColor: MyColors.lightGreyColor)
.paddingOnly(left: 11, top: 16))),
PopupMenuItem<String>(
value: '2',
enabled: m.uGroups![index].isAdmin ?? false,
child: (LocaleKeys.delete
.tr()
.toText14(color: m.uGroups![index].isAdmin == true ? MyColors.darkTextColor: MyColors.lightGreyColor)
.paddingOnly(left: 11, top: 16))),
PopupMenuItem<String>(
value: '3',
enabled: m.uGroups![index].isAdmin ?? false,
onTap: () {
},
child: (LocaleKeys.manage
.tr()
.toText14(color: m.uGroups![index].isAdmin == true ? MyColors.darkTextColor: MyColors.lightGreyColor)
.paddingOnly(left: 11, top: 16))),
PopupMenuItem<String>(
value: '4',
child: (LocaleKeys.members
.tr()
.toText14(color: MyColors.darkTextColor)
.paddingOnly(left: 11, top: 16))),
],
)
)
.expanded
],
),
).onPress(() {
chatDetails(m.uGroups![index], m,);
// Navigator.pushNamed(
// context,
// AppRoutes.chatDetailed,
// arguments: ChatDetailedScreenParams(
// m.searchedChats![index], false),
// ).then((Object? value) {
// m.clearSelections();
// m.notifyListeners();
// });
});
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(color: MyColors.black)
.paddingOnly(left: 59),
).expanded,
],
).paddingOnly(left: 21, right: 21);
},
),
floatingActionButton: FloatingActionButton(
child: Container(
width: 60,
height: 60,
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
transform: GradientRotation(.46),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
),
),
child: const Icon(
Icons.add,
size: 30,
color: MyColors.white,
),
),
onPressed: () async {
showMyBottomSheet(
context,
callBackFunc: () {},
child: CreateGroupBottomSheet(
title:LocaleKeys.addUsers.tr(),
apiMode: LocaleKeys.delegate.tr(),
fromChat: true,
onSelectEmployee: (ReplacementList _selectedEmployee) {},
groupDetails:GroupResponse(),
),
);
},
),
);
}
OutlineInputBorder fieldBorder({required double radius, required int color}) {
return OutlineInputBorder(
borderRadius: BorderRadius.circular(radius),
borderSide: BorderSide(
color: Color(color),
),
);
}
void goToSelected(GroupResponse? groupDetails, ChatProviderModel m, String value) {
switch(value) {
case '1':
editGroup(groupDetails, m);
break;
case '2':
deleteGroup(groupDetails, m, context);
break;
case '3':
Navigator.pushNamed(context,
AppRoutes.manageGroup,
arguments: groupDetails ,
);
break;
case '4':
Navigator.pushNamed(context,
AppRoutes.groupMembers,
arguments: groupDetails!.groupUserList,
);
break;
}
}
void deleteGroup(
GroupResponse? groupDetails, ChatProviderModel m, BuildContext context) {
groupDetails!.groupUserList;
Utils.confirmDialog(
context,
LocaleKeys.areYouSureWantTodelete.tr(),
onTap: () {
Navigator.pop(context);
m.deleteGroup(groupDetails);
},
);
}
Future<void> chatDetails(GroupResponse? groupDetails, ChatProviderModel m) async {
// await m.getGroupChatHistory(groupDetails!);
Navigator.pushNamed(context,
AppRoutes.groupChatDetailed,
arguments:
GroupChatDetailedScreenParams(
groupDetails,
false));
}
Future<void> editGroup(GroupResponse? groupDetails, ChatProviderModel m) async {
showMyBottomSheet(
context,
callBackFunc: () {},
child: CreateGroupBottomSheet(
title:LocaleKeys.editGroups.tr(),
apiMode: LocaleKeys.delegate.tr(),
fromChat: true,
onSelectEmployee: (ReplacementList _selectedEmployee) {},
groupDetails: groupDetails!,
),
);
}
}

@ -0,0 +1,643 @@
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:just_audio/just_audio.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/colors.dart';
import 'package:mohem_flutter_app/classes/my_custom_stream.dart';
import 'package:mohem_flutter_app/classes/utils.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/main.dart';
import 'package:mohem_flutter_app/models/chat/get_group_chat_history.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_full_image_preview.dart';
import 'package:mohem_flutter_app/ui/chat/common.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
class GroupChatBubble extends StatelessWidget {
GroupChatBubble({Key? key, required this.dateTime, required this.cItem})
: super(key: key);
final String dateTime;
final GetGroupChatHistoryAsync cItem;
bool isCurrentUser = false;
bool isSeen = false;
bool isReplied = false;
bool isVoice = false;
int? fileTypeID;
String? fileTypeName;
late ChatProviderModel provider;
String? fileTypeDescription;
bool isDelivered = false;
String userName = '';
late Offset screenOffset;
void makeAssign() {
isCurrentUser = cItem.currentUserId == AppState().chatDetails!.response!.id
? true
: false;
isSeen = cItem.isSeen == true ? true : false;
isReplied = cItem.groupChatReplyResponse != null ? true : false;
// isVoice = cItem.fileTypeId == 13 && cItem.voiceController != null ? true : false;
fileTypeID = cItem.fileTypeId;
fileTypeName = cItem.fileTypeResponse != null
? cItem.fileTypeResponse!.fileTypeName
: "";
fileTypeDescription = cItem.fileTypeResponse != null
? cItem.fileTypeResponse!.fileTypeDescription
: "";
isDelivered = cItem.currentUserId == AppState().chatDetails!.response!.id &&
cItem.isDelivered == true
? true
: false;
userName = AppState().chatDetails!.response!.userName ==
cItem.currentUserName.toString()
? "You"
: cItem.currentUserName.toString();
}
void playVoice(
BuildContext context, {
required SingleUserChatModel data,
}) async {
if (data.voice != null && data.voice!.existsSync()) {
if (Platform.isIOS) {
Duration? duration = await data.voiceController!
.setAudioSource(MyCustomStream(data.voice!.readAsBytesSync()));
await data.voiceController!.seek(duration);
await data.voiceController!.setLoopMode(LoopMode.off);
await data.voiceController!.setVolume(1.0);
await data.voiceController!.load();
data.voiceController!.play();
} else {
await data.voiceController!.setFilePath(data!.voice!.path);
Duration? duration = await data.voiceController!.load();
await data.voiceController!.seek(duration);
await data.voiceController!.setLoopMode(LoopMode.off);
await data.voiceController!.play();
}
} else {
Utils.showLoading(context);
Uint8List encodedString = await ChatApiClient().downloadURL(
fileName: data.contant!,
fileTypeDescription: provider.getFileTypeDescription(
data.fileTypeResponse!.fileTypeName ?? ""));
// try {
File sFile = await provider.downChatVoice(
encodedString, data.fileTypeResponse!.fileTypeName ?? "", data);
if (sFile.path.isEmpty) {
logger.d("Path Is Emptyyyyyyy");
} else {
logger.d("Path Exsists");
}
data.voice = sFile;
if (Platform.isIOS) {
logger.d("isIOS");
Duration? duration = await data.voiceController!
.setAudioSource(MyCustomStream(data.voice!.readAsBytesSync()));
await data.voiceController!.seek(duration);
await data.voiceController!.setLoopMode(LoopMode.off);
await data.voiceController!.setVolume(1.0);
await data.voiceController!.load();
Utils.hideLoading(context);
data.voiceController!.play();
} else {
Duration? duration =
await data.voiceController!.setFilePath(sFile.path);
await data.voiceController!.setLoopMode(LoopMode.off);
await data.voiceController!.seek(duration);
Utils.hideLoading(context);
await data.voiceController!.play();
}
}
}
void pausePlaying(BuildContext context,
{required SingleUserChatModel data}) async {
await data.voiceController!.pause();
}
void rePlay(BuildContext context, {required SingleUserChatModel data}) async {
if (data.voice != null && data.voice!.existsSync()) {
await data.voiceController!.seek(Duration.zero);
await data.voiceController!.play();
}
}
Stream<PositionData> get _positionDataStream =>
Rx.combineLatest3<Duration, Duration, Duration?, PositionData>(
cItem.voiceController!.positionStream,
cItem.voiceController!.bufferedPositionStream,
cItem.voiceController!.durationStream,
(Duration position, Duration bufferedPosition, Duration? duration) =>
PositionData(
position, bufferedPosition, duration ?? Duration.zero));
@override
Widget build(BuildContext context) {
Size windowSize = MediaQuery.of(context).size;
screenOffset = Offset(windowSize.width / 2, windowSize.height / 2);
makeAssign();
provider = Provider.of<ChatProviderModel>(context, listen: false);
return isCurrentUser ? currentUser(context) : receiptUser(context);
}
Widget currentUser(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (isReplied)
ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border(
left: BorderSide(
width: 6,
color: isCurrentUser
? MyColors.gradiantStartColor
: MyColors.white),
),
color: isCurrentUser
? MyColors.black.withOpacity(0.10)
: MyColors.black.withOpacity(0.30),
),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
(userName)
.toText12(
color: MyColors.gradiantStartColor, isBold: false)
.paddingOnly(right: 5, top: 5, bottom: 0, left: 5),
Directionality(
textDirection: provider.getTextDirection(
cItem.groupChatReplyResponse != null
? cItem.groupChatReplyResponse!.contant
.toString()
: ""),
child: (cItem.groupChatReplyResponse != null
? cItem.groupChatReplyResponse!.contant
.toString()
: "")
.toText10(
color: isCurrentUser
? MyColors.grey71Color
: MyColors.white.withOpacity(0.5),
isBold: false,
maxlines: 4)
.paddingOnly(right: 5, top: 5, bottom: 8, left: 5),
),
],
).expanded,
if (cItem.groupChatReplyResponse != null)
if (cItem.groupChatReplyResponse!.fileTypeId == 12 ||
cItem.groupChatReplyResponse!.fileTypeId == 3 ||
cItem.groupChatReplyResponse!.fileTypeId == 4)
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: SizedBox(
height: 32,
width: 32,
child: showImage(
isReplyPreview: false,
fileName:
cItem.groupChatReplyResponse!.contant!,
fileTypeDescription: cItem
.groupChatReplyResponse!
.fileTypeResponse!
.fileTypeDescription ??
"image/jpg")),
).paddingOnly(left: 10, right: 10, bottom: 16, top: 16),
],
),
),
).paddingOnly(bottom: 7).onPress(() {
// provider.scrollToMsg(cItem);
}),
if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3)
ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: SizedBox(
height: 140,
width: 227,
child: showImage(
isReplyPreview: false,
fileName: cItem.contant!,
fileTypeDescription:
cItem.fileTypeResponse!.fileTypeDescription)
.onPress(() {
showDialog(
context: context,
anchorPoint: screenOffset,
builder: (BuildContext context) => ChatImagePreviewScreen(
imgTitle: cItem.contant!, img: cItem.image!),
);
}),
),
).paddingOnly(bottom: 4),
if (fileTypeID == 13 && cItem.voiceController != null)
currentWaveBubble(context, cItem)
else
Row(
children: [
if (fileTypeID == 1 ||
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8
// || fileTypeID == 2
)
SvgPicture.asset(provider.getType(fileTypeName ?? ""),
height: 30,
width: 22,
alignment: Alignment.center,
fit: BoxFit.cover)
.paddingOnly(left: 0, right: 10),
Directionality(
textDirection: provider.getTextDirection(cItem.contant ?? ""),
child: (cItem.contant ?? "").toText12().expanded),
if (fileTypeID == 1 ||
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8
//|| fileTypeID == 2
)
const Icon(Icons.remove_red_eye, size: 16)
],
),
Align(
alignment: Alignment.centerRight,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
dateTime.toText10(
color: MyColors.grey41Color.withOpacity(.5),
),
7.width,
Icon(isDelivered ? Icons.done_all : Icons.done_all,
color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor,
size: 14),
],
),
),
],
)
.paddingOnly(top: 11, left: 13, right: 13, bottom: 5)
.objectContainerView(disablePadding: true)
.paddingOnly(left: MediaQuery.of(context).size.width * 0.3);
}
Widget receiptUser(BuildContext context) {
return Container(
padding: const EdgeInsets.only(top: 5, left: 8, right: 13, bottom: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: const LinearGradient(
transform: GradientRotation(.83),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: <Color>[
MyColors.gradiantEndColor,
MyColors.gradiantStartColor
],
),
),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
if (isReplied)
ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border(
left: BorderSide(
width: 6,
color: isCurrentUser
? MyColors.gradiantStartColor
: MyColors.white)),
color: isCurrentUser
? MyColors.black.withOpacity(0.10)
: MyColors.black.withOpacity(0.30),
),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
(userName)
.toText12(
color: MyColors.gradiantStartColor,
isBold: false)
.paddingOnly(right: 5, top: 5, bottom: 0, left: 5),
Directionality(
textDirection: provider.getTextDirection(
cItem.groupChatReplyResponse != null
? cItem.groupChatReplyResponse!.contant
.toString()
: ""),
child: (cItem.groupChatReplyResponse != null
? cItem.groupChatReplyResponse!.contant
.toString()
: "")
.toText10(
color: isCurrentUser
? MyColors.grey71Color
: MyColors.white.withOpacity(0.5),
isBold: false,
maxlines: 4)
.paddingOnly(
right: 5, top: 5, bottom: 8, left: 5),
),
],
).expanded,
if (cItem.groupChatReplyResponse != null)
if (cItem.groupChatReplyResponse!.fileTypeId == 12 ||
cItem.groupChatReplyResponse!.fileTypeId == 3 ||
cItem.groupChatReplyResponse!.fileTypeId == 4)
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: SizedBox(
height: 32,
width: 32,
child: showImage(
isReplyPreview: true,
fileName:
cItem.groupChatReplyResponse!.contant!,
fileTypeDescription: cItem
.groupChatReplyResponse!
.fileTypeResponse!
.fileTypeDescription ??
"image/jpg"),
),
).paddingOnly(left: 10, right: 10, bottom: 16, top: 16)
],
),
),
).paddingOnly(bottom: 7).onPress(() {
// provider.scrollToMsg(cItem);
}),
if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3)
ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: SizedBox(
height: 140,
width: 227,
child: showImage(
isReplyPreview: false,
fileName: cItem.contant ?? "",
fileTypeDescription:
cItem.fileTypeResponse!.fileTypeDescription ??
"image/jpg")
.onPress(() {
showDialog(
context: context,
anchorPoint: screenOffset,
builder: (BuildContext context) => ChatImagePreviewScreen(
imgTitle: cItem.contant ?? "", img: cItem.image!),
);
}),
),
).paddingOnly(bottom: 4),
if (fileTypeID == 13 && cItem.voiceController != null)
recipetWaveBubble(context, cItem)
else
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
cItem.currentUserName!.toText10(
color: Colors.black,
).paddingOnly(bottom: 5),
Row(
children: [
if (fileTypeID == 1 ||
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8
// || fileTypeID == 2
)
SvgPicture.asset(provider.getType(fileTypeName ?? ""),
height: 30,
width: 22,
alignment: Alignment.center,
fit: BoxFit.cover)
.paddingOnly(left: 0, right: 10),
Directionality(
textDirection:
provider.getTextDirection(cItem.contant ?? ""),
child: (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: 16)
],
),
Align(
alignment: Alignment.topRight,
child: dateTime.toText10(
color: Colors.white.withOpacity(.71),
).paddingOnly(top:5),
),
],
),
])).paddingOnly(right: MediaQuery.of(context).size.width * 0.3);
}
Widget voiceMsg(BuildContext context) {
return Container();
}
Widget showImage(
{required bool isReplyPreview,
required String fileName,
required String fileTypeDescription}) {
if (cItem.isImageLoaded != null && cItem.image != null) {
return Image.memory(
cItem.image!,
height: isReplyPreview ? 32 : 140,
width: isReplyPreview ? 32 : 227,
fit: BoxFit.cover,
alignment: Alignment.center,
);
} else {
return FutureBuilder<Uint8List>(
future: ChatApiClient().downloadURL(
fileName: fileName, fileTypeDescription: fileTypeDescription),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState != ConnectionState.waiting) {
if (snapshot.data == null) {
return const SizedBox();
} else {
cItem.image = snapshot.data;
cItem.isImageLoaded = true;
return Image.memory(
snapshot.data,
height: isReplyPreview ? 32 : 140,
width: isReplyPreview ? 32 : 227,
fit: BoxFit.cover,
alignment: Alignment.center,
);
}
} else {
return SizedBox(
height: isReplyPreview ? 32 : 140,
width: isReplyPreview ? 32 : 227,
).toShimmer();
}
},
);
}
}
Widget currentWaveBubble(
BuildContext context, GetGroupChatHistoryAsync data) {
return Container(
margin: const EdgeInsets.all(0),
decoration: BoxDecoration(
border: Border(
left: BorderSide(
width: 6,
color:
isCurrentUser ? MyColors.gradiantStartColor : MyColors.white),
),
color: isCurrentUser
? MyColors.black.withOpacity(0.10)
: MyColors.black.withOpacity(0.30),
),
child: Row(
children: [
//need to check and verify for group hence for now commented
// getPlayer(player: data.voiceController!, modelData: data),
StreamBuilder<PositionData>(
stream: _positionDataStream,
builder:
(BuildContext context, AsyncSnapshot<PositionData> snapshot) {
PositionData? positionData = snapshot.data;
return SeekBar(
duration: positionData?.duration ?? Duration.zero,
position: positionData?.position ?? Duration.zero,
bufferedPosition:
positionData?.bufferedPosition ?? Duration.zero,
onChangeEnd: data.voiceController!.seek,
).expanded;
},
),
],
),
).circle(5);
}
Widget recipetWaveBubble(
BuildContext context, GetGroupChatHistoryAsync data) {
return Container(
margin: const EdgeInsets.all(0),
decoration: BoxDecoration(
border: Border(
left: BorderSide(
width: 6,
color:
isCurrentUser ? MyColors.gradiantStartColor : MyColors.white),
),
color: isCurrentUser
? MyColors.black.withOpacity(0.10)
: MyColors.black.withOpacity(0.30),
),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
//commented to verify after
//getPlayer(player: data.voiceController!, modelData: data),
StreamBuilder<PositionData>(
stream: _positionDataStream,
builder:
(BuildContext context, AsyncSnapshot<PositionData> snapshot) {
PositionData? positionData = snapshot.data;
return SeekBar(
duration: positionData?.duration ?? Duration.zero,
position: positionData?.position ?? Duration.zero,
bufferedPosition:
positionData?.bufferedPosition ?? Duration.zero,
onChangeEnd: data.voiceController!.seek,
).expanded;
},
),
],
),
).circle(5);
}
Widget getPlayer(
{required AudioPlayer player, required SingleUserChatModel modelData}) {
return StreamBuilder<PlayerState>(
stream: player.playerStateStream,
builder: (BuildContext context, AsyncSnapshot<PlayerState> snapshot) {
PlayerState? playerState = snapshot.data;
ProcessingState? processingState = playerState?.processingState;
bool? playing = playerState?.playing;
if (processingState == ProcessingState.loading ||
processingState == ProcessingState.buffering) {
return Container(
margin: const EdgeInsets.all(8.0),
width: 30.0,
height: 30.0,
child: const CircularProgressIndicator(),
);
} else if (playing != true) {
return const Icon(
Icons.play_arrow,
size: 30,
color: MyColors.lightGreenColor,
).onPress(() {
playVoice(context, data: modelData);
});
} else if (processingState != ProcessingState.completed) {
return const Icon(
Icons.pause,
size: 30,
color: MyColors.lightGreenColor,
).onPress(() {
pausePlaying(context, data: modelData);
});
} else {
return const Icon(
Icons.replay,
size: 30,
color: MyColors.lightGreenColor,
).onPress(() {
rePlay(context, data: modelData);
});
}
},
);
}
}

@ -0,0 +1,394 @@
import 'dart:async';
import 'dart:convert';
import 'package:audio_waveforms/audio_waveforms.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.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/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/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/call.dart';
import 'package:mohem_flutter_app/models/chat/get_group_chat_history.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart';
import 'package:mohem_flutter_app/provider/chat_call_provider.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/custom_auto_direction.dart';
import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart';
import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart';
import 'package:mohem_flutter_app/ui/chat/common.dart';
import 'package:mohem_flutter_app/ui/chat/group_chat_bubble.dart';
import 'package:mohem_flutter_app/widgets/chat_app_bar_widge.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:signalr_netcore/signalr_client.dart';
import 'package:swipe_to/swipe_to.dart';
class GroupChatDetailedScreenParams {
GroupResponse? groupChatDetails;
bool? isNewChat;
GroupChatDetailedScreenParams(this.groupChatDetails, this.isNewChat);
}
class GroupChatDetailScreen extends StatefulWidget {
const GroupChatDetailScreen({Key? key}) : super(key: key);
@override
State<GroupChatDetailScreen> createState() => _GroupChatDetailScreenState();
}
class _GroupChatDetailScreenState extends State<GroupChatDetailScreen> {
final RefreshController _rc = RefreshController(initialRefresh: false);
late ChatProviderModel data;
late ChatCallProvider callPro;
GroupChatDetailedScreenParams? params;
// var textDirection = TextDirection.RTL;
void getMoreChat() async {
if (params != null) {
data.paginationVal = data.paginationVal + 10;
if (params != null) {
data.getGroupChatHistory(params!.groupChatDetails!
// senderUID: AppState().chatDetails!.response!.id!.toInt(),
// receiverUID: params!.groupChatDetails!.groupId!,
// loadMore: true,
// isNewChat: false,
);
}
}
await Future.delayed(
const Duration(milliseconds: 1000),
);
_rc.loadComplete();
}
@override
void dispose() {
data.disposeAudio();
super.dispose();
}
@override
Widget build(BuildContext context) {
params = ModalRoute.of(context)!.settings.arguments as GroupChatDetailedScreenParams;
data = Provider.of<ChatProviderModel>(context, listen: false);
// callPro = Provider.of<ChatCallProvider>(context, listen: false);
if (params != null) {
data.getGroupChatHistory(
params!.groupChatDetails!
// senderUID: AppState().chatDetails!.response!.id!.toInt(),
// receiverUID: params!.groupChatHistory!.groupId!,
// loadMore: false,
// isNewChat: params!.isNewChat!,
);
data.initAudio(receiverId: params!.groupChatDetails!.groupId!);
}
return Scaffold(
backgroundColor: MyColors.backgroundColor,
appBar: ChatAppBarWidget(
context,
title: params!.groupChatDetails!.groupName.toString().replaceAll(".", " ").capitalizeFirstofEach,
showHomeButton: false,
// showTyping: true,
// chatUser: params!.groupChatHistory!.groupChatHistoryTargetUserList as ChatUser,
actions: [
// SvgPicture.asset("assets/icons/chat/call.svg", width: 21, height: 23).onPress(() {
// makeCall(callType: "AUDIO");
// }),
// 24.width,
// SvgPicture.asset("assets/icons/chat/video_call.svg", width: 21, height: 18).onPress(() {
// makeCall(callType: "VIDEO");
// }),
// 21.width,
],
),
body: SafeArea(
child: Consumer<ChatProviderModel>(
builder: (BuildContext context, ChatProviderModel m, Widget? child) {
return (m.isLoading
? ChatHomeShimmer(
isDetailedScreen: true,
)
: Column(
children: <Widget>[
SmartRefresher(
enablePullDown: false,
enablePullUp: true,
onLoading: () {
getMoreChat();
},
header: const MaterialClassicHeader(
color: MyColors.gradiantEndColor,
),
controller: _rc,
reverse: true,
child: ListView.separated(
controller: m.scrollController,
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
reverse: true,
itemCount: m.groupChatHistory.length,
padding: const EdgeInsets.all(21),
separatorBuilder: (BuildContext cxt, int index) => 8.height,
itemBuilder: (BuildContext context, int i) {
return SwipeTo(
iconColor: MyColors.lightGreenColor,
child: GroupChatBubble(
dateTime: m.groupChatHistory[i].createdDate!,
cItem: m.groupChatHistory[i],
),
onRightSwipe: () {
m.groupChatReply(
m.groupChatHistory[i],
);
},
).onPress(() async {
logger.w(m.userChatHistory[i].toJson());
if (m.userChatHistory[i].fileTypeResponse != null && m.userChatHistory[i].fileTypeId != null) {
if (m.userChatHistory[i].fileTypeId! == 1 ||
m.userChatHistory[i].fileTypeId! == 5 ||
m.userChatHistory[i].fileTypeId! == 7 ||
m.userChatHistory[i].fileTypeId! == 6 ||
m.userChatHistory[i].fileTypeId! == 8
// || m.userChatHistory[i].fileTypeId! == 2
) {
m.getChatMedia(context,
fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.userChatHistory[i].fileTypeId!, fileName: m.userChatHistory[i].contant!);
}
}
});
},
),
).expanded,
if (m.isReplyMsg)
SizedBox(
height: 82,
child: Row(
children: <Widget>[
Container(height: 82, color: MyColors.textMixColor, width: 6),
Container(
color: MyColors.darkTextColor.withOpacity(0.10),
padding: const EdgeInsets.only(top: 11, left: 14, bottom: 14, right: 21),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(AppState().chatDetails!.response!.userName == m.groupChatReplyData.first.currentUserName.toString()
? "You"
: m.groupChatReplyData.first.currentUserName.toString().replaceAll(".", " "))
.toText14(color: MyColors.lightGreenColor),
(m.groupChatReplyData.isNotEmpty ? m.groupChatReplyData.first.contant! : "").toText12(color: MyColors.grey71Color, maxLine: 2)
],
).expanded,
12.width,
if (m.isReplyMsg && m.groupChatReplyData.isNotEmpty) showReplyImage(m.groupChatReplyData, m),
12.width,
const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe),
],
),
).expanded,
],
),
),
if (m.isAttachmentMsg && m.sFileType == ".png" || m.sFileType == ".jpeg" || m.sFileType == ".jpg")
SizedBox(height: 200, width: double.infinity, child: Image.file(m.selectedFile, fit: BoxFit.cover)).paddingOnly(left: 21, right: 21, top: 21),
const Divider(height: 1, color: MyColors.lightGreyEFColor),
if (m.isRecoding)
Column(
children: <Widget>[
Row(
children: [
Text(m.buildTimer()).paddingAll(10),
if (m.isRecoding && m.isPlaying)
WaveBubble(
playerController: m.playerController,
isPlaying: m.playerController.playerState == PlayerState.playing,
onTap: () {},
).expanded
else
AudioWaveforms(
waveStyle: const WaveStyle(
waveColor: MyColors.lightGreenColor,
middleLineColor: Colors.transparent,
extendWaveform: true,
showBottom: true,
showTop: true,
waveThickness: 2,
showMiddleLine: false,
middleLineThickness: 0,
),
padding: const EdgeInsets.all(5),
shouldCalculateScrolledPosition: false,
margin: EdgeInsets.zero,
size: const Size(double.infinity, 30.0),
recorderController: m.recorderController,
backgroundColor: Colors.white,
).expanded,
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Icon(
Icons.delete_outlined,
size: 26,
color: MyColors.lightGreenColor,
).paddingAll(10).onPress(() {
m.deleteRecoding();
}),
SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26)
.onPress(
() => m.sendGroupChatMessage(context,
targetUserId: params!.groupChatDetails!.groupId!,
userStatus: 0,
userEmail: "",
targetUserName: params!.groupChatDetails!.groupName!,
userList: params!.groupChatDetails!.groupUserList!
),
)
.paddingOnly(right: 21),
],
),
],
).objectContainerView(disablePadding: true, radius: 0),
if (!m.isRecoding)
Row(
children: [
CustomAutoDirection(
onDirectionChange: (bool isRTL) => m.onDirectionChange(isRTL),
text: m.msgText,
child: TextField(
// textDirection: m.textDirection,
controller: m.message,
decoration: InputDecoration(
hintTextDirection: m.textDirection,
hintText: m.isAttachmentMsg ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(),
hintStyle: TextStyle(color: m.isAttachmentMsg ? MyColors.darkTextColor : MyColors.grey98Color, fontSize: 14),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
filled: true,
fillColor: MyColors.white,
contentPadding: const EdgeInsets.only(
left: 21,
top: 20,
bottom: 20,
),
prefixIconConstraints: const BoxConstraints(),
prefixIcon: m.sFileType.isNotEmpty
? SvgPicture.asset(m.getType(m.sFileType), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 21, right: 15)
: null,
),
onChanged: (String val) {
m.inputBoxDirection(val);
m.groupTypingInvoke(groupDetails: params!.groupChatDetails!, groupId: params!.groupChatDetails!.groupId!);
},
).expanded,
),
if (m.sFileType.isNotEmpty)
Row(
children: <Widget>[
const Icon(Icons.cancel, size: 15, color: MyColors.redA3Color).paddingOnly(right: 5),
("Clear").toText11(color: MyColors.redA3Color, isUnderLine: true).paddingOnly(left: 0),
],
).onPress(() => m.removeAttachment()).paddingOnly(right: 15),
if (m.sFileType.isEmpty)
RotationTransition(
turns: const AlwaysStoppedAnimation(45 / 360),
child: const Icon(Icons.attach_file_rounded, size: 26, color: MyColors.grey3AColor).onPress(
() => {
m.selectImageToUpload(context)
},
),
).paddingOnly(right: 15),
const Icon(
Icons.mic,
color: MyColors.lightGreenColor,
).paddingOnly(right: 15).onPress(() {
m.startRecoding(context);
}),
SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26)
.onPress(
() =>m.sendGroupChatMessage(context,
targetUserId: params!.groupChatDetails!.groupId!,
userStatus: 0,
userEmail: "",
targetUserName: params!.groupChatDetails!.groupName!,
userList: params!.groupChatDetails!.groupUserList!
),
)
.paddingOnly(right: 21),
],
).objectContainerView(disablePadding: true, radius: 0),
],
));
},
),
),
);
}
Widget showReplyImage(List<GetGroupChatHistoryAsync> data, ChatProviderModel m) {
if (data.first.isImageLoaded! && data.first.image != null) {
return Container(
width: 43,
height: 43,
decoration: BoxDecoration(
border: Border.all(color: MyColors.darkGrey3BColor, width: 1), borderRadius: BorderRadius.circular(10.0), image: DecorationImage(image: MemoryImage(data.first.image!), fit: BoxFit.cover)),
);
} else {
return data.first.fileTypeResponse != null && data.first.fileTypeResponse!.fileTypeName != null
? Container(
width: 43,
height: 43,
constraints: const BoxConstraints(),
decoration: BoxDecoration(border: Border.all(color: MyColors.darkGrey3BColor, width: 1), borderRadius: BorderRadius.circular(10.0), color: Colors.white),
child: SvgPicture.asset(m.getType(data.first.fileTypeResponse!.fileTypeName ?? ""), alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 5, right: 5, top: 5, bottom: 5))
: const SizedBox();
}
}
void makeCall({required String callType}) async {
callPro.initCallListeners();
print("================== Make call Triggered ============================");
// Map<String, dynamic> json = {
// "callerID": AppState().chatDetails!.response!.id!.toString(),
// "callerDetails": AppState().chatDetails!.toJson(),
// "receiverID": params!.chatUser!.id.toString(),
// "receiverDetails": params!.chatUser!.toJson(),
// "title": params!.chatUser!.userName!.replaceAll(".", " "),
// "calltype": callType == "VIDEO" ? "Video" : "Audio",
// };
logger.w(json);
// CallDataModel callData = CallDataModel.fromJson(json);
// await Navigator.push(
// context,
// MaterialPageRoute(
// builder: (BuildContext context) => OutGoingCall(
// isVideoCall: callType == "VIDEO" ? true : false,
// outGoingCallData: callData,
// ),
// ),
// ).then((value) {
// print("then");
// callPro.stopListeners();
// });
}
GroupUserList getCurrentUser(int id, GroupResponse groupChatDetails) {
return groupChatDetails.groupUserList!.firstWhere((GroupUserList item) => item.id ==id);
}
}

@ -0,0 +1,131 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart';
import 'package:mohem_flutter_app/widgets/chat_app_bar_widge.dart';
import 'package:provider/provider.dart';
class GroupMembersScreen extends StatefulWidget {
const GroupMembersScreen({Key? key,}) : super(key: key);
@override
State<GroupMembersScreen> createState() => _GroupMembersScreenState();
}
class _GroupMembersScreenState extends State<GroupMembersScreen> {
late ChatProviderModel provider;
late List<GroupUserList> groupUserList;
@override
void initState() {
super.initState();
provider = Provider.of<ChatProviderModel>(context, listen: false);
}
@override
Widget build(BuildContext context) {
groupUserList = ModalRoute.of(context)!.settings.arguments as List<GroupUserList>;
return Scaffold(
backgroundColor: MyColors.white,
appBar: ChatAppBarWidget(
context,
title: LocaleKeys.groupMembers.tr(),
showHomeButton: false,
),
body:
groupUserList!.isNotEmpty ? ListView.separated(
itemCount: groupUserList!.length,
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.only(bottom: 5.0),
itemBuilder: (BuildContext context, int index) {
if(groupUserList![index].id != AppState().chatDetails!.response!.id) {
return SizedBox(
height: 55,
child: Row(
children: [
Stack(
children: <Widget>[
if (groupUserList![index].image == null)
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
Positioned(
right: 5,
bottom: 1,
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color:groupUserList![index].userStatus == 1
? MyColors.green2DColor
: Colors.red,
),
).circle(10),
)
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(groupUserList![index].userName! ?? "").toText14(
color: MyColors.darkTextColor).paddingOnly(
left: 11, top: 13),
],
).expanded,
Row(
children: [
IconButton(onPressed: (){
goToChat(groupUserList![index]);
}, icon: Icon(Icons.chat))
],
)
],
),
);
} else {
return const SizedBox();
}
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(color: MyColors.lightGreyE5Color).paddingOnly(
left: 70),
).paddingAll(10)
: Column(
children: <Widget>[
Utils
.getNoDataWidget(context)
.expanded,
],
)
);
}
void goToChat(GroupUserList groupUser){
ChatUser chatUser = ChatUser.fromJson(groupUser.toJson());
Navigator.pushNamed(context,
AppRoutes.chatDetailed,
arguments:
ChatDetailedScreenParams(
chatUser,
false));
}
}

@ -0,0 +1,142 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.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/chat_app_bar_widge.dart';
import 'package:provider/provider.dart';
class ManageGroupScreen extends StatefulWidget {
const ManageGroupScreen({
Key? key,
}) : super(key: key);
@override
State<ManageGroupScreen> createState() => _ManageGroupScreenState();
}
class _ManageGroupScreenState extends State<ManageGroupScreen> {
late ChatProviderModel provider;
GroupResponse? groupDetails;
@override
void initState() {
super.initState();
provider = Provider.of<ChatProviderModel>(context, listen: false);
}
@override
Widget build(BuildContext context) {
groupDetails = ModalRoute.of(context)!.settings.arguments as GroupResponse;
return Scaffold(
backgroundColor: MyColors.white,
appBar: ChatAppBarWidget(
context,
title: LocaleKeys.manageGroup.tr(),
showHomeButton: false,
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
LocaleKeys.admin
.tr()
.toText14(color: MyColors.darkTextColor)
.paddingOnly(right: 25)!,
groupDetails!.groupUserList!.isNotEmpty
? ListView.separated(
itemCount: groupDetails!.groupUserList!.length,
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.only(bottom: 5.0),
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 55,
child: Row(
children: [
Stack(
children: <Widget>[
if (groupDetails!.groupUserList![index].image ==
null)
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
Positioned(
right: 5,
bottom: 1,
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: groupDetails!.groupUserList![index]
.userStatus ==
1
? MyColors.green2DColor
: Colors.red,
),
).circle(10),
)
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(groupDetails!
.groupUserList![index].userName! ??
"")
.toText14(color: MyColors.darkTextColor)
.paddingOnly(left: 11, top: 13),
],
).expanded,
Row(
children: [
Switch(
value: groupDetails!
.groupUserList![index].isAdmin!,
onChanged: groupDetails!
.groupUserList![index].id ==
AppState().chatDetails!.response!.id
? null
: (value) {
setState(() {
groupDetails!.groupUserList![index]
.isAdmin = value;
updateGroupAdmin(
groupDetails!.groupUserList!,
groupDetails!.groupId);
});
},
)
],
)
],
),
);
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(color: MyColors.lightGreyE5Color)
.paddingOnly(left: 70),
).paddingAll(10)
: Column(
children: <Widget>[
Utils.getNoDataWidget(context).expanded,
],
)
],
));
}
void updateGroupAdmin(List<GroupUserList> groupUserList, int? groupId) async {
//Group id need to be updated..
provider.updateGroupAdmin(groupId, groupUserList);
}
}

@ -163,7 +163,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
print("-------------------- Survey ----------------------------");
if (val.result!.data!.notificationType == "Survey") {
DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then(
(value) {
(value) {
if (value!.mohemmItgResponseItem!.statusCode == 200) {
if (value.mohemmItgResponseItem!.result!.data != null) {
// Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data);

@ -61,6 +61,11 @@ class _ITGAdsScreenState extends State<ITGAdsScreen> {
isVideo = true;
_futureController = createVideoPlayer(rFile!);
}
advertisementData?.actionButtonsColl!.forEach((element) {
advertisementData?.actionButtonsColl!.removeWhere((element1) => element1.actionButtonId == advertisementData?.skipButtonId);
});
setState(() {});
}
@ -152,55 +157,101 @@ class _ITGAdsScreenState extends State<ITGAdsScreen> {
textStyle: const TextStyle(color: Colors.white, fontSize: 16, letterSpacing: -0.48, fontWeight: FontWeight.bold),
),
50.height,
if (advertisementData?.isOptional ?? false)
DefaultButton(AppState().isArabic(context) ? "يتخطى" : "Skip", () async {
Navigator.pop(context);
DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Skip").then((value) {
logger.d(value);
});
}).paddingOnly(left: 60.0, right: 60.0, top: 8, bottom: 8),
ValueListenableBuilder<bool>(
valueListenable: hasTimerEnded,
builder: (context, val, child) {
if (hasTimerEndedBool) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor))
.onPress(() {
try {
Navigator.pop(context);
DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Like").then((value) {
logger.d(value);
});
} catch (ex) {
logger.wtf(ex);
Utils.handleException(ex, context, null);
}
}),
20.width,
Container(
padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_down, color: MyColors.gradiantEndColor))
.onPress(() {
try {
Navigator.pop(context);
DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Dislike").then((value) {
logger.d(value);
});
} catch (ex) {
logger.wtf(ex);
Utils.handleException(ex, context, null);
}
}),
],
return GridView.builder(
padding: EdgeInsets.zero,
itemCount: advertisementData?.actionButtonsColl!.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
String? btnText = AppState().isArabic(context) ? advertisementData?.actionButtonsColl![index].btnTextAr : advertisementData?.actionButtonsColl![index].btnTextEn;
return DefaultButton(btnText!, () async {
Navigator.pop(context);
DashboardApiClient()
.setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, advertisementData?.actionButtonsColl![index].actionValue)
.then((value) {
logger.d(value);
});
}).paddingOnly(left: 60.0, right: 60.0, top: 8, bottom: 8);
},
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: (7.0),
),
);
// Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Container(padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor))
// .onPress(() {
// try {
// Navigator.pop(context);
// DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Like").then((value) {
// logger.d(value);
// });
// } catch (ex) {
// logger.wtf(ex);
// Utils.handleException(ex, context, null);
// }
// }),
// 20.width,
// Container(
// padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_down, color: MyColors.gradiantEndColor))
// .onPress(() {
// try {
// Navigator.pop(context);
// DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Dislike").then((value) {
// logger.d(value);
// });
// } catch (ex) {
// logger.wtf(ex);
// Utils.handleException(ex, context, null);
// }
// }),
// ],
// );
} else {
return Container();
}
},
),
20.height,
if (advertisementData?.isOptional ?? false)
DefaultButton(AppState().isArabic(context) ? advertisementData?.skipButtonTextAr ?? "Skip" : advertisementData?.skipButtonTextEn ?? "Skip", () async {
Navigator.pop(context);
DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Skip").then((value) {
logger.d(value);
});
}).paddingOnly(left: 100, right: 100)
// if (advertisementData?.isOptional ?? false)
// GridView.builder(
// padding: EdgeInsets.zero,
// itemCount: advertisementData?.actionButtonsColl!.length,
// shrinkWrap: true,
// physics: const NeverScrollableScrollPhysics(),
// itemBuilder: (context, index) {
// String? btnText = AppState().isArabic(context) ? advertisementData?.actionButtonsColl![index].btnTextAr : advertisementData?.actionButtonsColl![index].btnTextEn;
// return DefaultButton(btnText!, () async {
// Navigator.pop(context);
// DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, advertisementData?.actionButtonsColl![index].actionValue).then((value) {
// logger.d(value);
// });
// }).paddingAll(8);
// },
// gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: 2,
// childAspectRatio: (4.0),
// ),
// )
// DefaultButton(AppState().isArabic(context) ? advertisementData?.skipButtonTextAr ?? "Skip" : advertisementData?.skipButtonTextEn ?? "Skip", () async {
// Navigator.pop(context);
// DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Skip").then((value) {
// logger.d(value);
// });
// }).paddingOnly(left: 100, right: 100)
],
);
} else {

@ -103,6 +103,7 @@ class _LoginScreenState extends State<LoginScreen> {
try {
if (!(await Utils.isGoogleServicesAvailable())) {
print("HUAWEI APPPP GALLERYYYY!!!!");
AppNotifications().init(firebaseToken, context);
AppState().setIsHuawei = true;
AppNotifications().initHuaweiPush(checkLoginInfo);
} else {

@ -81,8 +81,8 @@ class MarathonScreen extends StatelessWidget {
displayLocalizedContent(
isPhoneLangArabic: AppState().isArabic(context),
selectedLanguage: provider.demoMarathonDetailModel.selectedLanguage!,
arabicContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr!,
englishContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!,
arabicContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr ?? "",
englishContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn ?? "",
).toText22(
color: MyColors.grey3AColor,
isCentered: true,

@ -94,17 +94,8 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
genericResponseModel = await MyAttendanceApiClient().validateEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp);
SubmitEITTransactionList submitEITTransactionList = await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp);
Utils.hideLoading(context);
await Navigator.pushNamed(
context,
AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(
LocaleKeys.submit.tr(),
submitEITTransactionList.pTRANSACTIONID!,
submitEITTransactionList.pITEMKEY!,
'eit',
popNavigateToSpecificRoute: dynamicParams!.popUntilRoute,
),
);
await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit'));
if (!AppState().cancelRequestTrancsection) {
return;
}
@ -350,13 +341,17 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
if (getEitDffStructureList![j].fORMATTYPE == "X") {
idColName = Utils.reverseFormatDate(idColName!);
if (Utils.isDate(Utils.reverseFormatDate(Utils.formatDateNew(idColName)), "yyyy-MM-dd")) {
idColName = Utils.formatStandardDate(Utils.formatStandardDate(Utils.formatDateNew(idColName)));
if(Utils.isDate(Utils.reverseFormatDate(Utils.formatDateNew(idColName!)), "yyyy-MM-dd")){
idColName = Utils.formatStandardDate(Utils.formatStandardDate(Utils.formatDateNew(idColName!)));
// idColName = DateFormat('yyyy/MM/dd HH:mm:ss').format(date);
} else if (Utils.isDate(Utils.reverseFormatDate(idColName), "dd-MM-yyyy")) {
}else if(Utils.isDate(Utils.reverseFormatDate(idColName!), "dd-MM-yyyy")){
// // change date format on 31/05/2023
DateTime date = DateFormat('dd-MM-yyyy').parse(idColName);
DateTime date = DateFormat('dd-MM-yyyy').parse(idColName!);
idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date);
}
}
}
@ -531,9 +526,12 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
onTap: () async {
if ((getEitDffStructureList![index].eSERVICESDV?.pVALUECOLUMNNAME != null)) {
if (getEitDffStructureList![index].isDefaultTypeIsCDPS) {
selectedDate = DateFormat("yyyy/MM/dd", "en_US").parse(getEitDffStructureList![index].eSERVICESDV!.pVALUECOLUMNNAME!.replaceAll('/"', '').replaceAll(" 00:00:00", ""));
} else {
selectedDate = DateTime.parse(getEitDffStructureList![index].eSERVICESDV!.pVALUECOLUMNNAME!);
if (displayText.contains(" 00:00:00")) {
displayText = displayText.replaceAll(" 00:00:00", "");
}
if (displayText.contains("/")) {
displayText = DateFormat('yyyy-MM-dd', "en_US").format(DateFormat("yyyy/MM/dd", "en_US").parse(displayText));
}
}
}
DateTime date = await _selectDate(context);

@ -75,8 +75,11 @@ class _MyDocumentsFragmentState extends State<MyDocumentsFragment> {
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 11),
itemBuilder: (cxt, index) {
return MyDocumentItem(documentfilteredList[index], getColorByDocumentStatus(documentfilteredList[index].dOCUMENTSTATUS!)).onPress(() {
Navigator.pushNamed(context, AppRoutes.addDynamicInput,
arguments: DynamicListViewParams(documentfilteredList[index].dOCUMENTTYPE!, documentfilteredList[index].fUNCTIONNAME!, selectedEmp: AppState().getUserName, popUntilRoute: AppRoutes.myDocuments));
Navigator.pushNamed(
context,
AppRoutes.addDynamicInput,
arguments: DynamicListViewParams(documentfilteredList[index].dOCUMENTTYPE!, documentfilteredList[index].fUNCTIONNAME!, selectedEmp: AppState().getUserName),
);
});
},
separatorBuilder: (cxt, index) => 12.height,
@ -107,7 +110,7 @@ class _MyDocumentsFragmentState extends State<MyDocumentsFragment> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
title.toText10(),
value.toText20(isBold: true, color: color),
value.toText18(isBold: true, color: color),
],
),
).onPress(() {

@ -164,7 +164,7 @@ class InfoFragment extends StatelessWidget {
),
ItemDetailGrid(
ItemDetailViewCol(LocaleKeys.otherCharges.tr(), poHeaderList[index].oTHERCHARGES?.toString() ?? ""),
ItemDetailViewCol(LocaleKeys.totalPOAmountWithVAT.tr(), poHeaderList[index].tOTPOAMT.toString() ?? ""),
ItemDetailViewCol(LocaleKeys.totalPOAmountWithVAT.tr(), poHeaderList[index].lOCCURTOTPOAMT.toString() ?? ""),
),
ItemDetailGrid(
ItemDetailViewCol(LocaleKeys.totalPOAmountInWords.tr(), poHeaderList[index].tOTPOAMTWORD ?? ""),

@ -47,15 +47,6 @@ class Location {
Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.medium, timeLimit: const Duration(seconds: 5)).then((value) {
done(value);
});
// Geolocator.getLastKnownPosition(forceAndroidLocationManager: true).then((value) {
// if (value == null) {
// Geolocator.getCurrentPosition().then((value) {
// done(value);
// });
// } else {
// done(value);
// }
// });
} else {
// AppPermissions
}

@ -1,13 +1,11 @@
import 'dart:async';
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:geolocator/geolocator.dart';
import 'package:huawei_location/location/fused_location_provider_client.dart';
import 'package:huawei_location/location/location_request.dart';
import 'package:huawei_location/location/location_settings_request.dart';
import 'package:huawei_location/permission/permission_handler.dart';
import 'package:huawei_location/huawei_location.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';
@ -21,7 +19,7 @@ import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/ui/dialogs/success_dialog.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:mohem_flutter_app/widgets/dialogs/dialogs.dart';
import 'package:mohem_flutter_app/widgets/location/Location.dart';
import 'package:mohem_flutter_app/widgets/location/Location.dart' as location;
import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart';
import 'package:mohem_flutter_app/widgets/qr_scanner_dialog.dart';
import 'package:nfc_manager/nfc_manager.dart';
@ -75,26 +73,61 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
}
void checkHuaweiLocationPermission(String attendanceType) async {
PermissionHandler permissionHandler = PermissionHandler();
if (await permissionHandler.hasLocationPermission()) {
getHuaweiCurrentLocation(attendanceType);
} else {
bool has = await requestPermissions();
if (has) {
getHuaweiCurrentLocation(attendanceType);
// Permission_Handler permissionHandler = PermissionHandler();
location.Location.isEnabled((bool isEnabled) async {
if (isEnabled) {
location.Location.havePermission((bool permission) async {
if (permission) {
getHuaweiCurrentLocation(attendanceType);
} else {
bool has = await requestPermissions();
if (has) {
getHuaweiCurrentLocation(attendanceType);
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give location permission to mark attendance",
onTap: () {
Navigator.pop(context);
},
),
);
}
}
});
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give location permission to mark attendance",
onTap: () {
message: "You need to enable location services to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openLocationSettings();
},
),
);
}
}
});
// if (await permissionHandler.hasLocationPermission()) {
// getHuaweiCurrentLocation(attendanceType);
// } else {
// bool has = await requestPermissions();
// if (has) {
// getHuaweiCurrentLocation(attendanceType);
// } else {
// showDialog(
// context: context,
// builder: (BuildContext cxt) => ConfirmDialog(
// message: "You need to give location permission to mark attendance",
// onTap: () {
// Navigator.pop(context);
// },
// ),
// );
// }
// }
}
Future<bool> requestPermissions() async {
@ -134,11 +167,11 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
if (AppState().getIsHuawei) {
checkHuaweiLocationPermission("NFC");
} else {
Location.isEnabled((bool isEnabled) {
location.Location.isEnabled((bool isEnabled) {
if (isEnabled) {
Location.havePermission((bool permission) {
location.Location.havePermission((bool permission) {
if (permission) {
Location.getCurrentLocation(
location.Location.getCurrentLocation(
(Position position, bool isMocked) {
if (isMocked) {
markFakeAttendance("NFC", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
@ -181,11 +214,11 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
if (AppState().getIsHuawei) {
checkHuaweiLocationPermission("WIFI");
} else {
Location.isEnabled((bool isEnabled) {
location.Location.isEnabled((bool isEnabled) {
if (isEnabled) {
Location.havePermission((bool permission) {
location.Location.havePermission((bool permission) {
if (permission) {
Location.getCurrentLocation(
location.Location.getCurrentLocation(
(Position position, bool isMocked) {
if (isMocked) {
markFakeAttendance("WIFI", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
@ -228,11 +261,11 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
if (AppState().getIsHuawei) {
checkHuaweiLocationPermission("QR");
} else {
Location.isEnabled((bool isEnabled) {
location.Location.isEnabled((bool isEnabled) {
if (isEnabled) {
Location.havePermission((bool permission) {
location.Location.havePermission((bool permission) {
if (permission) {
Location.getCurrentLocation(
location.Location.getCurrentLocation(
(Position position, bool isMocked) {
if (isMocked) {
markFakeAttendance("QR", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
@ -277,49 +310,70 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
);
}
void getHuaweiCurrentLocation(String attendanceType) {
void getHuaweiCurrentLocation(String attendanceType) async {
try {
Utils.showLoading(context);
FusedLocationProviderClient locationService = FusedLocationProviderClient();
LocationRequest locationRequest = LocationRequest();
locationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY;
locationRequest.interval = 1000;
locationRequest.interval = 500;
List<LocationRequest> locationRequestList = <LocationRequest>[locationRequest];
LocationSettingsRequest locationSettingsRequest = LocationSettingsRequest(requests: locationRequestList);
locationService.checkLocationSettings(locationSettingsRequest).then((settings) async {
await locationService.getLastLocation().then((value) {
if (value.latitude == null || value.longitude == null) {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "Unable to get your location, Please check your location settings & try again.",
onTap: () {
Navigator.pop(context);
},
),
);
} else {
if (attendanceType == "QR") {
performQrCodeAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
}
if (attendanceType == "WIFI") {
performWifiAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
}
if (attendanceType == "NFC") {
performNfcAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
}
late StreamSubscription<Location> _streamSubscription;
int requestCode = (await (locationService.requestLocationUpdates(locationRequest)))!;
_streamSubscription = locationService.onLocationData!.listen(
(Location location) async {
Utils.hideLoading(context);
await locationService.removeLocationUpdates(requestCode);
if (attendanceType == "QR") {
performQrCodeAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
}
}).catchError((error) {
print("HUAWEI LOCATION getLastLocation ERROR!!!!!");
print(error);
});
}).catchError((error) {
print("HUAWEI LOCATION checkLocationSettings ERROR!!!!!");
print(error);
if (error.code == "LOCATION_SETTINGS_NOT_AVAILABLE") {
// Location service not enabled.
}
});
if (attendanceType == "WIFI") {
performWifiAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
}
if (attendanceType == "NFC") {
performNfcAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
}
requestCode = 0;
},
);
// locationService.checkLocationSettings(locationSettingsRequest).then((settings) async {
// await locationService.getLastLocation().then((value) {
// if (value.latitude == null || value.longitude == null) {
// showDialog(
// context: context,
// builder: (BuildContext cxt) => ConfirmDialog(
// message: "Unable to get your location, Please check your location settings & try again.",
// onTap: () {
// Navigator.pop(context);
// },
// ),
// );
// } else {
// if (attendanceType == "QR") {
// performQrCodeAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
// }
// if (attendanceType == "WIFI") {
// performWifiAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
// }
// if (attendanceType == "NFC") {
// performNfcAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
// }
// }
// }).catchError((error) {
// print("HUAWEI LOCATION getLastLocation ERROR!!!!!");
// print(error);
// });
// }).catchError((error) {
// print("HUAWEI LOCATION checkLocationSettings ERROR!!!!!");
// print(error);
// if (error.code == "LOCATION_SETTINGS_NOT_AVAILABLE") {
// // Location service not enabled.
// }
// });
} catch (error) {
print("HUAWEI LOCATION ERROR!!!!!");
print(error);

@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 3.2.93+300032
version: 3.2.991+300039
environment:
sdk: ">=2.16.0 <3.0.0"
@ -46,7 +46,7 @@ dependencies:
local_auth: ^1.1.9
fluttertoast: ^8.0.8
syncfusion_flutter_calendar: ^19.4.48
# flutter_calendar_carousel: ^2.1.0
# flutter_calendar_carousel: ^2.1.0
pie_chart: ^5.1.0
shared_preferences: ^2.0.12
firebase_messaging: ^13.0.4
@ -54,9 +54,9 @@ dependencies:
logger: ^1.1.0
flutter_countdown_timer: ^4.1.0
nfc_manager: ^3.2.0
# uuid: ^3.0.6
# device_info_plus: ^4.0.0
# android_id: ^0.1.3+1
# uuid: ^3.0.6
# device_info_plus: ^4.0.0
# android_id: ^0.1.3+1
platform_device_id: ^1.0.1
image_picker: ^0.8.5+3
file_picker: ^4.6.1
@ -66,21 +66,21 @@ dependencies:
open_file: ^3.2.1
wifi_iot: ^0.3.18
flutter_html: ^3.0.0-alpha.6
# flutter_barcode_scanner: ^2.0.0
# flutter_barcode_scanner: ^2.0.0
qr_code_scanner: ^1.0.1
# qr_flutter: ^4.0.0
# qr_flutter: ^4.0.0
url_launcher: ^6.0.15
share: 2.0.4
flutter_rating_bar: ^4.0.1
auto_size_text: ^3.0.0
pull_to_refresh: ^2.0.0
# lottie json animations
# lottie json animations
lottie: any
# Marathon Card Swipe
# Marathon Card Swipe
appinio_swiper: ^1.1.1
expandable: ^5.0.1
# networkImage
# networkImage
cached_network_image: ^3.2.2
#Chat
@ -101,12 +101,13 @@ dependencies:
video_player: ^2.5.1
just_audio: ^0.9.30
# safe_device: ^1.1.2
# safe_device: ^1.1.2
flutter_layout_grid: ^2.0.1
#Huawei Dependencies
# huawei_hmsavailability: ^6.6.0+300
huawei_location: 6.0.0+302
# huawei_hmsavailability: ^6.6.0+300
# huawei_location: 6.0.0+302
huawei_location: ^6.11.0+301
huawei_push: ^6.7.0+300
firebase_crashlytics: ^2.9.0
@ -114,7 +115,7 @@ dependencies:
carousel_slider: ^4.2.1
#Huawei Specified
# store_checker: ^1.1.0
# store_checker: ^1.1.0
google_api_availability: ^3.0.1
#todo its for temporary purpose, later will remove this.

Loading…
Cancel
Save