From 9cb71b525e164b4f4b4434bc63464c00e3922462 Mon Sep 17 00:00:00 2001 From: Sultan khan <> Date: Thu, 16 Mar 2023 17:34:06 +0300 Subject: [PATCH 1/9] group chat started --- assets/images/chat-group.svg | 56 +++++ assets/langs/ar-SA.json | 4 +- assets/langs/en-US.json | 4 +- lib/api/chat/chat_api_client.dart | 21 ++ lib/app_state/app_state.dart | 3 +- lib/classes/consts.dart | 8 +- lib/generated/locale_keys.g.dart | 2 + lib/generated_plugin_registrant.dart | 4 +- lib/models/chat/get_user_groups_by_id.dart | 260 +++++++++++++++++++++ lib/provider/chat_provider_model.dart | 13 +- lib/ui/chat/chat_home.dart | 8 +- lib/ui/chat/group_chat.dart | 182 +++++++++++++++ 12 files changed, 554 insertions(+), 11 deletions(-) create mode 100644 assets/images/chat-group.svg create mode 100644 lib/models/chat/get_user_groups_by_id.dart create mode 100644 lib/ui/chat/group_chat.dart diff --git a/assets/images/chat-group.svg b/assets/images/chat-group.svg new file mode 100644 index 0000000..127a793 --- /dev/null +++ b/assets/images/chat-group.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 4178d17..dd7c997 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -524,5 +524,7 @@ "fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية", "noWinner": "حزين! لم يفز أحد اليوم.", "myTeam" : "فريقي", - "youCanPlayDemo": "لكن يمكنك لعب العرض" + "youCanPlayDemo": "لكن يمكنك لعب العرض", + "group" : "مجموعة", + "searchGroup": "مجموعة البحث" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index e4a4266..182dde6 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -524,5 +524,7 @@ "fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.", "noWinner": "Sad! No one won today.", "myTeam" : "My Team", - "youCanPlayDemo": "But you can play demo" + "youCanPlayDemo": "But you can play demo", + "group": "Groups", + "searchGroup": "Search Group" } \ No newline at end of file diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index b4c0a2c..2ef616d 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -13,6 +13,7 @@ import 'package:mohem_flutter_app/exceptions/api_exception.dart'; import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/chat/chat_user_image_model.dart'; import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; +import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart' as groups; 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; @@ -187,4 +188,24 @@ class ChatApiClient { } return imagesData; } + + //group chat apis start here. + Future 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; + } + } + } diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 2b05306..c434ea6 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -77,7 +77,7 @@ class AppState { bool get getIsDemoMarathon => _isDemoMarathon; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 3.9, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 5.2, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; @@ -180,5 +180,4 @@ class AppState { } bool cancelRequestTrancsection = true; - } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 96fd4b0..647c38b 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - static String baseUrl = "https://hmgwebservices.com"; // Live server + static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + // static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; @@ -19,6 +19,10 @@ class ApiConsts { static String chatLoginTokenUrl = chatServerBaseApiUrl + "user/"; static String chatHubConnectionUrl = chatServerBaseUrl + "ConnectionChatHub"; + //Groups + static String getGroupByUserId = chatServerBaseApiUrl + "group/getgroupsbyuserid/"; + + // static String chatSearchMember = chatLoginTokenUrl + "user/"; static String chatRecentUrl = chatServerBaseApiUrl + "UserChatHistory/"; //For a Mem static String chatSingleUserHistoryUrl = chatServerBaseApiUrl + "UserChatHistory/"; diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 184748a..bb05818 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -511,4 +511,6 @@ abstract class LocaleKeys { static const noWinner = 'noWinner'; static const myTeam = 'myTeam'; static const youCanPlayDemo = 'youCanPlayDemo'; + static const group = 'group'; + static const searchGroup = 'searchGroup'; } diff --git a/lib/generated_plugin_registrant.dart b/lib/generated_plugin_registrant.dart index 642c8ec..b59eec2 100644 --- a/lib/generated_plugin_registrant.dart +++ b/lib/generated_plugin_registrant.dart @@ -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); diff --git a/lib/models/chat/get_user_groups_by_id.dart b/lib/models/chat/get_user_groups_by_id.dart new file mode 100644 index 0000000..ee5bbd9 --- /dev/null +++ b/lib/models/chat/get_user_groups_by_id.dart @@ -0,0 +1,260 @@ +import 'dart:convert'; + +class GetUserGroups { + List? response; + Null? errorResponses; + + GetUserGroups({this.response, this.errorResponses}); + factory GetUserGroups.fromRawJson(String str) => GetUserGroups.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + GetUserGroups.fromJson(Map json) { + if (json['response'] != null) { + response = []; + json['response'].forEach((v) { + response!.add(new Response.fromJson(v)); + }); + } + errorResponses = json['errorResponses']; + } + + Map toJson() { + Map data = new Map(); + if (this.response != null) { + data['response'] = this.response!.map((v) => v.toJson()).toList(); + } + data['errorResponses'] = this.errorResponses; + return data; + } +} + +class Response { + 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; + + Response( + {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}); + + Response.fromJson(Map 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 = []; + json['groupUserList'].forEach((v) { + groupUserList!.add(new GroupUserList.fromJson(v)); + }); + } + } + + Map toJson() { + Map data = new Map(); + 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 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 toJson() { + Map data = new Map(); + 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 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 toJson() { + Map data = new Map(); + 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; + } +} diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index 08b148d..dc6350f 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -21,6 +21,7 @@ import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/chat/chat_user_image_model.dart'; import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart'; +import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart' as groups; import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as userLoginToken; import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; import 'package:mohem_flutter_app/models/my_team/get_employee_subordinates_list.dart'; @@ -40,6 +41,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { TextEditingController message = TextEditingController(); TextEditingController search = TextEditingController(); + TextEditingController searchGroup = TextEditingController(); + List userChatHistory = [], repliedMsg = []; List? pChatHistory, searchedChats; String chatCID = ''; @@ -67,7 +70,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { late PlayerController playerController; List getEmployeeSubordinatesList = []; List teamMembersList = []; - + groups.GetUserGroups userGroups =groups.GetUserGroups(); Material.TextDirection textDirection = Material.TextDirection.ltr; //Chat Home Page Counter @@ -125,6 +128,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future getUserRecentChats() async { ChatUserModel recentChat = await ChatApiClient().getRecentChats(); ChatUserModel favUList = await ChatApiClient().getFavUsers(); + userGroups = await ChatApiClient().getGroupsByUserId(); if (favUList.response != null && recentChat.response != null) { favUsersList = favUList.response!; favUsersList.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase())); @@ -1466,4 +1470,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } } + + //group chat functions added here + + void filterGroups(String value) async { + // filter function added here. + notifyListeners(); + } } diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 2e23254..75d916a 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -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 { data.getUserAutoLoginToken().whenComplete(() async { await data.buildHubConnection(); data.getUserRecentChats(); + }); return; } @@ -89,8 +91,9 @@ class _ChatHomeState extends State { child: Row( children: [ 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 { }, children: [ ChatHomeScreen(), + GropChatHomeScreen(), ChatFavoriteUsersScreen(), AppState().getempStatusIsManager ? const MyTeamScreen() : const SizedBox(), ], diff --git a/lib/ui/chat/group_chat.dart b/lib/ui/chat/group_chat.dart new file mode 100644 index 0000000..b3d7301 --- /dev/null +++ b/lib/ui/chat/group_chat.dart @@ -0,0 +1,182 @@ +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/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/provider/chat_provider_model.dart'; +import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.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 createState() => _GropChatHomeScreenState(); +} + +class _GropChatHomeScreenState extends State { + 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( + builder: (BuildContext context, ChatProviderModel m, Widget? child) { + return m.isLoading + ? ChatHomeShimmer( + isDetailedScreen: false, + ) + : Column( + children: [ + TextField( + controller: m.searchGroup, + style: const TextStyle(color: MyColors.darkTextColor, fontWeight: FontWeight.w500, fontSize: 12), + onChanged: (String val) { + m.filter(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.userGroups.response != null) + ListView.separated( + itemCount: m.userGroups.response!.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, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + (m.userGroups?.response![index].groupName!.toText14(color: MyColors.darkTextColor).paddingOnly(left: 11, top: 16) + )!.expanded, + ]) + + ], + ), + ).onPress(() { + 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 { + print(AppState().chatDetails!.response!.token); + showMyBottomSheet( + context, + callBackFunc: () {}, + child: SearchEmployeeBottomSheet( + title: LocaleKeys.searchForEmployee.tr(), + apiMode: LocaleKeys.delegate.tr(), + fromChat: true, + onSelectEmployee: (_selectedEmployee) {}, + ), + ); + }, + ), + ); + } + + OutlineInputBorder fieldBorder({required double radius, required int color}) { + return OutlineInputBorder( + borderRadius: BorderRadius.circular(radius), + borderSide: BorderSide( + color: Color(color), + ), + ); + } +} -- 2.30.2 From 790103bdc91a97c7d93ef1d3026ff5f2a12a23e4 Mon Sep 17 00:00:00 2001 From: Sultan khan <> Date: Wed, 14 Jun 2023 14:46:36 +0300 Subject: [PATCH 2/9] chat changes --- assets/langs/ar-SA.json | 14 +- assets/langs/en-US.json | 17 +- lib/api/profile_api_client.dart | 2 +- lib/app_state/app_state.dart | 2 +- lib/classes/consts.dart | 4 +- lib/generated/codegen_loader.g.dart | 41 ++- lib/generated/locale_keys.g.dart | 13 + lib/models/chat/get_group_chat_history.dart | 8 +- lib/models/chat/target_users.dart | 32 +++ lib/provider/chat_provider_model.dart | 233 +++++++++++++++--- lib/ui/chat/create_group.dart | 32 +-- lib/ui/chat/group_chat.dart | 4 +- lib/ui/chat/group_chat_bubble.dart | 2 +- lib/ui/chat/group_chat_detaied_screen.dart | 36 ++- .../dynamic_screens/dynamic_input_screen.dart | 1 + 15 files changed, 357 insertions(+), 84 deletions(-) create mode 100644 lib/models/chat/target_users.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 02256c2..98a584e 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -535,5 +535,17 @@ "areYouSureWantTodelete": "هل أنت متأكد من أنك تريد الحذف؟", "groupMembers": "أعضاء المجموعة", "manageGroup": "إدارة المجموعة", - "admin": "مسؤل" + "admin": "مسؤل", + "addUsers": "أضف المستخدمين إلى المجموعة", + "editGroups": "تحرير المجموعة", + "groupNameshouldbe": "يجب ألا يقل اسم المجموعة عن 10 أحرف", + "groupName": "أسم المجموعة", + "enterGroupNamePlease": "الرجاء إدخال اسم المجموعة", + "audioCall": "مكالمة صوتية", + "videoCall": "مكالمة فيديو", + "shareScreen": "شاشة المشاركة", + "searchByUserName": "البحث باسم المستخدم", + "userSearch": "بحث المستخدم", + "userName":"اسم المستخدم", + "userId":"معرف المستخدم" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 0c674a3..81edd2d 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -534,5 +534,18 @@ "areYouSureWantTodelete": "Are you sure want to delete?", "groupMembers": "Group Members", "manageGroup": "Manage Group", - "admin": "Admin" -} \ No newline at end of file + "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" +} diff --git a/lib/api/profile_api_client.dart b/lib/api/profile_api_client.dart index 6a8cfb0..2a5f049 100644 --- a/lib/api/profile_api_client.dart +++ b/lib/api/profile_api_client.dart @@ -166,7 +166,7 @@ class ProfileApiClient { ], "P_CONTACT_RELATIONSHIP_ID": contactRelationId, "P_ACTION": actionType, - "PayrollCodeStr": "CS", + "PayrollCodeStr": "HMG", "LegislationCodeStr": "SA", }; postParams.addAll(AppState().postParamsJson); diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 45ec0a4..b065816 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -90,7 +90,7 @@ class AppState { String get getHuaweiPushToken => _huaweiPushToken; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.6, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 33, versionID: 4.6, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 76d2fbd..3777c74 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - // static String baseUrl = "https://hmgwebservices.com"; // Live server + // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index dabf498..1f1a0c3 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -545,7 +545,25 @@ class CodegenLoader extends AssetLoader{ "group": "مجموعة", "searchGroup": "مجموعة البحث", "connectHmgWifi": "قم بتوصيل HMG WIFI", - "connectedHmgWifi": "اتصال HMG WIFI" + "connectedHmgWifi": "اتصال HMG WIFI", + "manage": "يدير", + "members": "أعضاء", + "areYouSureWantTodelete": "هل أنت متأكد من أنك تريد الحذف؟", + "groupMembers": "أعضاء المجموعة", + "manageGroup": "إدارة المجموعة", + "admin": "مسؤل", + "addUsers": "أضف المستخدمين إلى المجموعة", + "editGroups": "تحرير المجموعة", + "groupNameshouldbe": "يجب ألا يقل اسم المجموعة عن 10 أحرف", + "groupName": "أسم المجموعة", + "enterGroupNamePlease": "الرجاء إدخال اسم المجموعة", + "audioCall": "مكالمة صوتية", + "videoCall": "مكالمة فيديو", + "shareScreen": "شاشة المشاركة", + "searchByUserName": "البحث باسم المستخدم", + "userSearch": "بحث المستخدم", + "userName": "اسم المستخدم", + "userId": "معرف المستخدم" }; static const Map en_US = { "mohemm": "Mohemm", @@ -1077,7 +1095,26 @@ static const Map en_US = { "youCanPlayDemo": "But you can play demo", "group": "Groups", "searchGroup": "Search Group", - "connectHmgWifi": "Connect HMG WIFI" + "connectHmgWifi": "Connect HMG WIFI", + "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> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index b9ea8b3..e97a7e6 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -522,4 +522,17 @@ abstract class LocaleKeys { 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'; } diff --git a/lib/models/chat/get_group_chat_history.dart b/lib/models/chat/get_group_chat_history.dart index c0068e2..c8476b1 100644 --- a/lib/models/chat/get_group_chat_history.dart +++ b/lib/models/chat/get_group_chat_history.dart @@ -86,10 +86,10 @@ class GetGroupChatHistoryAsync { fileTypeResponse = json['fileTypeResponse'] != null ? new FileTypeResponse.fromJson(json['fileTypeResponse']) : null; - groupChatReplyResponse = json["userChatReplyResponse"] == null ? null : GroupChatReplyResponse.fromJson(json["userChatReplyResponse"]); + groupChatReplyResponse = json["groupChatReplyResponse"] == null ? null : GroupChatReplyResponse.fromJson(json["groupChatReplyResponse"]); isReplied= json['isReplied']; - isImageLoaded= json['isImageLoaded']; + isImageLoaded= json['isImageLoaded'] ??false; image= json['image']; voice= json['voice']; voiceController = json["fileTypeId"] == 13 ? AudioPlayer() : null; @@ -126,7 +126,7 @@ class GetGroupChatHistoryAsync { } data['isReplied'] =isReplied; - data['isImageLoaded'] = isImageLoaded; + data['isImageLoaded'] = isImageLoaded ?? false; data['image'] = image; data['voice'] = voice; data["fileTypeId"] == 13 ? AudioPlayer() : null; @@ -140,7 +140,7 @@ class GroupChatHistoryTargetUserList { bool? isDelivered; int? targetUserId; String? targetUserName; - Null? userAction; + dynamic? userAction; GroupChatHistoryTargetUserList( {this.groupChatHistoryLineId, diff --git a/lib/models/chat/target_users.dart b/lib/models/chat/target_users.dart new file mode 100644 index 0000000..d399a38 --- /dev/null +++ b/lib/models/chat/target_users.dart @@ -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 json) { + isSeen = json['isSeen']; + isDelivered = json['isDelivered']; + targetUserId = json['targetUserId']; + userAction = json['userAction']; + userStatus = json['userStatus']; + } + + Map toJson() { + Map data = new Map(); + data['isSeen'] = this.isSeen; + data['isDelivered'] = this.isDelivered; + data['targetUserId'] = this.targetUserId; + data['userAction'] = this.userAction; + data['userStatus'] = this.userStatus; + return data; + } +} diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index bb7dd63..824a19f 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -32,6 +32,7 @@ import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as userLoginToken; import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; +import 'package:mohem_flutter_app/models/chat/target_users.dart'; import 'package:mohem_flutter_app/models/my_team/get_employee_subordinates_list.dart'; import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart'; import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; @@ -89,7 +90,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { //Chat Home Page Counter int chatUConvCounter = 0; - late List groupChatHistory; + late List groupChatHistory, groupChatReplyData; /// Search Provider List? chatUsersList = []; @@ -121,6 +122,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); chatHubConnection.on("OnGetChatConversationCount", onNewChatConversion); + + //group On message + + chatHubConnection.on("OnDeliveredGroupChatHistoryAsync", onGroupMsgReceived); } Future getHubConnection() async { @@ -140,6 +145,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void registerEvents() { chatHubConnection.on("OnUpdateUserStatusAsync", changeStatus); // chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); + chatHubConnection.on("OnSubmitChatAsync", OnSubmitChatAsync); chatHubConnection.on("OnUserTypingAsync", onUserTyping); chatHubConnection.on("OnUserCountAsync", userCountAsync); @@ -148,6 +154,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { "OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); chatHubConnection.on( "OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); + chatHubConnection.on( + "OnGetGroupUserStatusAsync", getGroupUserStatus); + + // + // {"type":1,"target":"","arguments":[[{"id":217869,"userName":"Sultan.Khan","email":"Sultan.Khan@cloudsolutions.com.sa","phone":null,"title":"Sultan.Khan","userStatus":1,"image":null,"unreadMessageCount":0,"userAction":3,"isPin":false,"isFav":false,"isAdmin":false,"rKey":null,"totalCount":0,"isHuaweiDevice":false,"deviceToken":null},{"id":15153,"userName":"Tamer.Fanasheh","email":"Tamer.F@cloudsolutions.com.sa","phone":null,"title":"Tamer Fanasheh","userStatus":2,"image":null,"unreadMessageCount":0,"userAction":3,"isPin":false,"isFav":false,"isAdmin":true,"rKey":null,"totalCount":0,"isHuaweiDevice":false,"deviceToken":null}]]} if (kDebugMode) { logger.i("All listeners registered"); @@ -288,6 +299,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List.from( json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); + List getGroupChatHistoryAsync(String str) => + List.from( + json.decode(str).map((x) => groupchathistory.GetGroupChatHistoryAsync.fromJson(x))); + + Future uploadAttachments(String userId, File file) async { dynamic result; try { @@ -316,6 +332,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } + void getGroupUserStatus(List? args){ + //note: need to implement this function... + print(args); + } + void onChatSeen(List? args) { dynamic items = args!.toList(); // for (var user in searchedChats!) { @@ -495,6 +516,107 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } + Future onGroupMsgReceived(List? parameters) async { + List data = [], temp = []; + + + for (dynamic msg in parameters!) { + // groupChatHistory.add(groupchathistory.GetGroupChatHistoryAsync.fromJson(msg)); + data.add(groupchathistory.GetGroupChatHistoryAsync.fromJson(msg)); + temp =data; + // data.first.currentUserId = temp.first.currentUserId; + // data.first.currentUserName = temp.first.currentUserName; + // + // data.first.currentUserId = temp.first.currentUserId; + // data.first.currentUserName = temp.first.currentUserName; + + + if (data.first.fileTypeId == 12 || + data.first.fileTypeId == 4 || + data.first.fileTypeId == 3) { + data.first.image = await ChatApiClient().downloadURL( + fileName: data.first.contant!, + fileTypeDescription: + data.first.fileTypeResponse!.fileTypeDescription ?? + "image/jpg"); + } + if (data.first.groupChatReplyResponse != null) { + if (data.first.fileTypeResponse != null) { + if (data.first.groupChatReplyResponse!.fileTypeId == 12 || + data.first.groupChatReplyResponse!.fileTypeId == 4 || + data.first.groupChatReplyResponse!.fileTypeId == 3) { + data.first.groupChatReplyResponse!.image = await ChatApiClient() + .downloadURL( + fileName: data.first.groupChatReplyResponse!.contant!, + fileTypeDescription: + data.first.fileTypeResponse!.fileTypeDescription ?? + "image/jpg"); + data.first.groupChatReplyResponse!.isImageLoaded = true; + } + } + } + } + + // if (searchedChats != null) { + // dynamic contain = searchedChats! + // .where((ChatUser element) => element.id == data.first.currentUserId); + // if (contain.isEmpty) { + // List emails = []; + // emails.add(await EmailImageEncryption() + // .encrypt(val: data.first.currentUserEmail!)); + // List chatImages = + // await ChatApiClient().getUsersImages(encryptedEmails: emails); + // searchedChats!.add( + // ChatUser( + // id: data.first.currentUserId, + // userName: data.first.currentUserName, + // email: data.first.currentUserEmail, + // unreadMessageCount: 0, + // isImageLoading: false, + // image: chatImages!.first.profilePicture ?? "", + // isImageLoaded: true, + // userStatus: 1, + // isTyping: false, + // userLocalDownlaodedImage: await downloadImageLocal( + // chatImages.first.profilePicture, + // data.first.currentUserId.toString()), + // ), + // ); + // } + // } + groupChatHistory.insert(0, data.first); + setMsgTune(); + // if (isChatScreenActive && data.first.currentUserId == receiverID) { + + // } else { + // if (searchedChats != null) { + // for (ChatUser user in searchedChats!) { + // if (user.id == data.first.currentUserId) { + // int tempCount = user.unreadMessageCount ?? 0; + // user.unreadMessageCount = tempCount + 1; + // } + // } + sort(); + //} + //} + // + // List list = [ + // { + // "userChatHistoryId": data.first.groupId, + // "TargetUserId": temp.first.currentUserId, + // "isDelivered": true, + // "isSeen": isChatScreenActive && data.first.currentUserId == receiverID + // ? true + // : false + // } + // ]; + // updateUserChatHistoryOnMsg(list); + // invokeChatCounter(userId: AppState().chatDetails!.response!.id!); + notifyListeners(); + } + + + void OnSubmitChatAsync(List? parameters) { print(isChatScreenActive); print(receiverID); @@ -711,7 +833,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { String? userEmail, int? userStatus, File? voiceFile, - required bool isVoiceAttached}) async { + required bool isVoiceAttached, + required List userList + }) async { Uuid uuid = const Uuid(); String contentNo = uuid.v4(); String msg; @@ -736,15 +860,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { groupName: targetUserName, isReplied: false, fileTypeId: fileTypeId, - // userChatReplyResponse: isReply ? UserChatReplyResponse.fromJson(repliedMsg.first.toJson()) : null, - // fileTypeResponse: isAttachment - // ? FileTypeResponse( - // fileTypeId: fileTypeId, - // fileTypeName: isVoiceMsg ? getFileExtension(voiceFile!.path).toString() : getFileExtension(selectedFile.path).toString(), - // fileKind: "file", - // fileName: isVoiceMsg ? msg : selectedFile.path.split("/").last, - // fileTypeDescription: isVoiceMsg ? getFileTypeDescription(getFileExtension(voiceFile!.path).toString()) : getFileTypeDescription(getFileExtension(selectedFile.path).toString()), - + fileTypeResponse: isAttachment + ? groupchathistory.FileTypeResponse( + fileTypeId: fileTypeId, + fileTypeName: isVoiceMsg ? getFileExtension(voiceFile!.path).toString() : getFileExtension(selectedFile.path).toString(), + fileKind: "file", + fileName: isVoiceMsg ? msg : selectedFile.path.split("/").last, + fileTypeDescription: isVoiceMsg ? getFileTypeDescription(getFileExtension(voiceFile!.path).toString()) : getFileTypeDescription(getFileExtension(selectedFile.path).toString())) : null, image: image, isImageLoaded: isImageLoaded, voice: isVoiceMsg ? voiceFile! : null, @@ -752,7 +874,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { if (kDebugMode) { logger.i("model data: " + jsonEncode(data)); } - // groupChatHistory.insert(0, data); + groupChatHistory.insert(0, data); isTextMsg = false; isReplyMsg = false; isAttachmentMsg = false; @@ -761,11 +883,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { message.clear(); notifyListeners(); - String chatData = - '{"contant":"$msg","contantNo":"$contentNo","chatEventId":$chatEventId,"fileTypeId":$fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"groupId":$targetGroupId,"groupChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":${AppState().chatDetails!.response!.id},"userAction":0,"userStatus":1}],"conversationId":"${uuid.v4()}"}'; + List targetUsers =[]; + + for (GroupUserList element in userList) { + targetUsers.add(TargetUsers(isDelivered: false,isSeen: false, targetUserId: element.id, userAction: element.userAction, userStatus: element.userStatus)); + + } - // String chatData = - // '{"contant":"$msg","contantNo":"$contentNo","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"$chatCID"}'; + String chatData = + '{"contant":"$msg","contantNo":"$contentNo","chatEventId":$chatEventId,"fileTypeId":$fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"groupId":$targetGroupId,"groupChatHistoryLineRequestList":${json.encode(targetUsers)},"chatReplyId": $chatReplyId,"conversationId":"${uuid.v4()}"}'; await chatHubConnection.invoke("AddGroupChatHistoryAsync", args: [json.decode(chatData)]); @@ -775,7 +901,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { {required int targetUserId, required int userStatus, required String userEmail, - required String targetUserName}) async { + required String targetUserName, + required List userList, + }) async { if (isTextMsg && !isAttachmentMsg && !isVoiceMsg && !isReplyMsg) { logger.d("// Normal Text Message"); if (message.text.isEmpty) { @@ -793,7 +921,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { image: null, isVoiceAttached: false, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); } else if (isTextMsg && !isAttachmentMsg && !isVoiceMsg && isReplyMsg) { logger.d("// Text Message as Reply"); if (message.text.isEmpty) { @@ -804,15 +934,17 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { fileTypeId: null, targetGroupId: targetUserId, targetUserName: targetUserName, - chatReplyId: repliedMsg.first.userChatHistoryId, + chatReplyId: groupChatReplyData.first.groupChatHistoryId, isAttachment: false, isReply: true, - isImageLoaded: repliedMsg.first.isImageLoaded!, - image: repliedMsg.first.image, + isImageLoaded: groupChatReplyData.first.isImageLoaded!, + image: groupChatReplyData.first.image, isVoiceAttached: false, voiceFile: null, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); } // Attachment else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && !isReplyMsg) { @@ -820,12 +952,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Utils.showLoading(context); dynamic value = await uploadAttachments( AppState().chatDetails!.response!.id.toString(), selectedFile); - // String? ext = getFileExtension(selectedFile.path); + String? ext = getFileExtension(selectedFile.path); Utils.hideLoading(context); sendGroupChatToServer( chatEventId: 2, - fileTypeId: "jpg", - //getFileType(ext.toString()), + fileTypeId: getFileType(ext.toString()), targetGroupId: targetUserId, targetUserName: targetUserName, isAttachment: true, @@ -835,18 +966,20 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { image: selectedFile.readAsBytesSync(), isVoiceAttached: false, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); } else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && isReplyMsg) { logger.d("// Image as Reply Msg"); Utils.showLoading(context); dynamic value = await uploadAttachments( AppState().chatDetails!.response!.id.toString(), selectedFile); - // String? ext = getFileExtension(selectedFile.path); + String? ext = getFileExtension(selectedFile.path); Utils.hideLoading(context); sendGroupChatToServer( chatEventId: 2, - fileTypeId: "jpg", - //getFileType(ext.toString()), + fileTypeId: getFileType(ext.toString()), + targetGroupId: targetUserId, targetUserName: targetUserName, isAttachment: true, @@ -856,7 +989,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { image: selectedFile.readAsBytesSync(), isVoiceAttached: false, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); } //Voice @@ -878,12 +1013,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Utils.showLoading(context); dynamic value = await uploadAttachments( AppState().chatDetails!.response!.id.toString(), voiceFile); - // String? ext = getFileExtension(voiceFile.path); + String? ext = getFileExtension(voiceFile.path); Utils.hideLoading(context); sendGroupChatToServer( chatEventId: 2, - fileTypeId: "jpg", - //getFileType(ext.toString()), + fileTypeId: getFileType(ext.toString()), + //, targetGroupId: targetUserId, targetUserName: targetUserName, chatReplyId: null, @@ -893,7 +1028,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { voiceFile: voiceFile, isVoiceAttached: true, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); notifyListeners(); } else if (!isTextMsg && !isAttachmentMsg && isVoiceMsg && isReplyMsg) { logger.d("// Voice as Reply Msg"); @@ -914,12 +1051,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Utils.showLoading(context); dynamic value = await uploadAttachments( AppState().chatDetails!.response!.id.toString(), voiceFile); - // String? ext = getFileExtension(voiceFile.path); + String? ext = getFileExtension(voiceFile.path); Utils.hideLoading(context); sendGroupChatToServer( chatEventId: 2, - fileTypeId: "jpg", - //getFileType(ext.toString()), + fileTypeId: getFileType(ext.toString()), targetGroupId: targetUserId, targetUserName: targetUserName, chatReplyId: null, @@ -929,7 +1065,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { voiceFile: voiceFile, isVoiceAttached: true, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); notifyListeners(); } if (searchedChats != null) { @@ -964,7 +1102,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { {required int targetUserId, required int userStatus, required String userEmail, - required String targetUserName}) async { + required String targetUserName, + + }) async { if (kDebugMode) { print("====================== Values ============================"); print("Is Text " + isTextMsg.toString()); @@ -1266,7 +1406,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { repliedMsg.add(data); notifyListeners(); } - + void groupChatReply(groupchathistory.GetGroupChatHistoryAsync data) { + groupChatReplyData = []; + data.isReplied = true; + isReplyMsg = true; + groupChatReplyData.add(data); + notifyListeners(); + } void closeMe() { repliedMsg = []; isReplyMsg = false; @@ -1551,6 +1697,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { await chatHubConnection .invoke("UserTypingAsync", args: [reciptUser, currentUser]); } + void groupTypingInvoke( + {required GroupResponse groupDetails, required int groupId}) async { + var data = json.decode(json.encode(groupDetails.groupUserList)); + await chatHubConnection + .invoke("GroupTypingAsync", args: ["${groupDetails.adminUser!.userName}",data, groupId ]); + } + //////// Audio Recoding Work //////////////////// diff --git a/lib/ui/chat/create_group.dart b/lib/ui/chat/create_group.dart index 32efe79..43b2635 100644 --- a/lib/ui/chat/create_group.dart +++ b/lib/ui/chat/create_group.dart @@ -186,8 +186,8 @@ class _CreateGroupBottomSheetState extends State { Row( children: [ DynamicTextFieldWidget( - "Group Name", - groupName.isEmpty ? "Please enter group name" : groupName, + LocaleKeys.groupName.tr(), + groupName.isEmpty ? LocaleKeys.enterGroupNamePlease.tr() : groupName, inputAction: TextInputAction.done, onChange: (String text) { groupName = text; @@ -204,7 +204,7 @@ class _CreateGroupBottomSheetState extends State { height: 35, child: CheckboxListTile( contentPadding: EdgeInsets.zero, - title: "Audio Call".toText10(), + title: LocaleKeys.audioCall.tr().toText10(), checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), @@ -225,7 +225,7 @@ class _CreateGroupBottomSheetState extends State { height: 35, child: CheckboxListTile( contentPadding: EdgeInsets.zero, - title: "Video Call".toText10(), + title: LocaleKeys.videoCall.tr().toText10(), checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), value: isVideoCall, @@ -245,7 +245,7 @@ class _CreateGroupBottomSheetState extends State { height: 35, child: CheckboxListTile( contentPadding: EdgeInsets.zero, - title: "Attachments".toText10(), + title:LocaleKeys.attachments.tr().toText10(), checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), value: isAttachments, @@ -263,7 +263,7 @@ class _CreateGroupBottomSheetState extends State { contentPadding: EdgeInsets.zero, checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), - title: "Share Screen".toText10(), + title:LocaleKeys.shareScreen.tr().toText10(), value: isShareScreen, onChanged: (bool? newValue) { setState(() { @@ -276,22 +276,22 @@ class _CreateGroupBottomSheetState extends State { ], ), 11.height, - "User Search".toText16(), + LocaleKeys.userSearch.tr().toText16(), 11.height, Row( children: [ - radioOption(widget.fromChat ? "UserId" : "Name", 0, + radioOption(widget.fromChat ? LocaleKeys.userId.tr() : LocaleKeys.name.tr(), 0, _selectedSearchIndex), - radioOption("User Name", 1, _selectedSearchIndex), - radioOption("Email", 2, _selectedSearchIndex), + radioOption(LocaleKeys.userName.tr(), 1, _selectedSearchIndex), + radioOption(LocaleKeys.email.tr(), 2, _selectedSearchIndex), ], ), 14.height, Row( children: [ DynamicTextFieldWidget( - "Search", - "Search By Username", + LocaleKeys.search.tr(), + LocaleKeys.searchByUserName.tr(), inputAction: TextInputAction.done, suffixIconData: Icons.search, onChange: (String text) { @@ -302,6 +302,8 @@ class _CreateGroupBottomSheetState extends State { IconButton( constraints: const BoxConstraints(), onPressed: () async { + provider.chatUsersList!.clear(); + provider.pageNo =1; await SystemChannels.textInput .invokeMethod('TextInput.hide'); widget.fromChat ? fetchChatUser() : fetchUserByInput(); @@ -318,7 +320,7 @@ class _CreateGroupBottomSheetState extends State { padding: EdgeInsets.only(top: 21, bottom: 8), children: [ if (favouriteUserList?.isNotEmpty ?? false) ...[ - "Favorites".toText16(), + LocaleKeys.favorite.tr().toText16(), 12.height, ListView.separated( physics: const NeverScrollableScrollPhysics(), @@ -662,9 +664,9 @@ class _CreateGroupBottomSheetState extends State { void createGroup() async { RegExp validCharacters = RegExp(r'^[a-zA-Z0-9_\-=@,\.;]+$'); if (!validCharacters.hasMatch(groupName)) { - Utils.showToast("Please enter valid group Name"); + Utils.showToast(LocaleKeys.enterGroupName.tr()); } else if (groupName.length < 10) { - Utils.showToast("Group name should be minimum 10 character long"); + Utils.showToast(LocaleKeys.groupNameshouldbe.tr()); } else { List? mainUsers = []; ChatUser admin = diff --git a/lib/ui/chat/group_chat.dart b/lib/ui/chat/group_chat.dart index 6ba690d..35b4c5c 100644 --- a/lib/ui/chat/group_chat.dart +++ b/lib/ui/chat/group_chat.dart @@ -223,7 +223,7 @@ class _GropChatHomeScreenState extends State { context, callBackFunc: () {}, child: CreateGroupBottomSheet( - title:"Add users to the group", + title:LocaleKeys.addUsers.tr(), apiMode: LocaleKeys.delegate.tr(), fromChat: true, onSelectEmployee: (ReplacementList _selectedEmployee) {}, @@ -295,7 +295,7 @@ void goToSelected(GroupResponse? groupDetails, ChatProviderModel m, String value context, callBackFunc: () {}, child: CreateGroupBottomSheet( - title:"Edit Group", + title:LocaleKeys.editGroups.tr(), apiMode: LocaleKeys.delegate.tr(), fromChat: true, onSelectEmployee: (ReplacementList _selectedEmployee) {}, diff --git a/lib/ui/chat/group_chat_bubble.dart b/lib/ui/chat/group_chat_bubble.dart index 80e6606..69a50df 100644 --- a/lib/ui/chat/group_chat_bubble.dart +++ b/lib/ui/chat/group_chat_bubble.dart @@ -481,7 +481,7 @@ class GroupChatBubble extends StatelessWidget { {required bool isReplyPreview, required String fileName, required String fileTypeDescription}) { - if (cItem.isImageLoaded! && cItem.image != null) { + if (cItem.isImageLoaded != null && cItem.image != null) { return Image.memory( cItem.image!, height: isReplyPreview ? 32 : 140, diff --git a/lib/ui/chat/group_chat_detaied_screen.dart b/lib/ui/chat/group_chat_detaied_screen.dart index cd1fb49..c43a2df 100644 --- a/lib/ui/chat/group_chat_detaied_screen.dart +++ b/lib/ui/chat/group_chat_detaied_screen.dart @@ -148,9 +148,9 @@ class _GroupChatDetailScreenState extends State { cItem: m.groupChatHistory[i], ), onRightSwipe: () { - // m.chatReply( - // m.groupChatHistory[i], - // ); + m.groupChatReply( + m.groupChatHistory[i], + ); }, ).onPress(() async { logger.w(m.userChatHistory[i].toJson()); @@ -184,15 +184,15 @@ class _GroupChatDetailScreenState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString() + (AppState().chatDetails!.response!.userName == m.groupChatReplyData.first.currentUserName.toString() ? "You" - : m.repliedMsg.first.currentUserName.toString().replaceAll(".", " ")) + : m.groupChatReplyData.first.currentUserName.toString().replaceAll(".", " ")) .toText14(color: MyColors.lightGreenColor), - (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(color: MyColors.grey71Color, maxLine: 2) + (m.groupChatReplyData.isNotEmpty ? m.groupChatReplyData.first.contant! : "").toText12(color: MyColors.grey71Color, maxLine: 2) ], ).expanded, 12.width, - if (m.isReplyMsg && m.repliedMsg.isNotEmpty) showReplyImage(m.repliedMsg, m), + if (m.isReplyMsg && m.groupChatReplyData.isNotEmpty) showReplyImage(m.groupChatReplyData, m), 12.width, const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe), ], @@ -249,11 +249,13 @@ class _GroupChatDetailScreenState extends State { }), SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26) .onPress( - () => m.sendChatMessage(context, + () => m.sendGroupChatMessage(context, targetUserId: params!.groupChatDetails!.groupId!, userStatus: 0, userEmail: "", - targetUserName: params!.groupChatDetails!.groupName!), + targetUserName: params!.groupChatDetails!.groupName!, + userList: params!.groupChatDetails!.groupUserList! + ), ) .paddingOnly(right: 21), ], @@ -292,7 +294,7 @@ class _GroupChatDetailScreenState extends State { ), onChanged: (String val) { m.inputBoxDirection(val); - m.userTypingInvoke(currentUser: AppState().chatDetails!.response!.id!, reciptUser: params!.groupChatDetails!.groupId!); + m.groupTypingInvoke(groupDetails: params!.groupChatDetails!, groupId: params!.groupChatDetails!.groupId!); }, ).expanded, ), @@ -307,7 +309,9 @@ class _GroupChatDetailScreenState extends State { RotationTransition( turns: const AlwaysStoppedAnimation(45 / 360), child: const Icon(Icons.attach_file_rounded, size: 26, color: MyColors.grey3AColor).onPress( - () => m.selectImageToUpload(context), + () => { + m.selectImageToUpload(context) + }, ), ).paddingOnly(right: 15), const Icon( @@ -322,7 +326,9 @@ class _GroupChatDetailScreenState extends State { targetUserId: params!.groupChatDetails!.groupId!, userStatus: 0, userEmail: "", - targetUserName: params!.groupChatDetails!.groupName!), + targetUserName: params!.groupChatDetails!.groupName!, + userList: params!.groupChatDetails!.groupUserList! + ), ) .paddingOnly(right: 21), ], @@ -335,7 +341,7 @@ class _GroupChatDetailScreenState extends State { ); } - Widget showReplyImage(List data, ChatProviderModel m) { + Widget showReplyImage(List data, ChatProviderModel m) { if (data.first.isImageLoaded! && data.first.image != null) { return Container( width: 43, @@ -381,4 +387,8 @@ class _GroupChatDetailScreenState extends State { // callPro.stopListeners(); // }); } + GroupUserList getCurrentUser(int id, GroupResponse groupChatDetails) { + return groupChatDetails.groupUserList!.firstWhere((GroupUserList item) => item.id ==id); + } + } diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart index bd9305d..a6ffcf1 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -344,6 +344,7 @@ class _DynamicInputScreenState extends State { // commenting to test // DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!); // idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date); + } } -- 2.30.2 From aca223c7003182a2f1c87d2c4e33ccd7fc1e27df Mon Sep 17 00:00:00 2001 From: Sultan khan <> Date: Wed, 12 Jul 2023 14:44:53 +0300 Subject: [PATCH 3/9] business trip fixed --- lib/app_state/app_state.dart | 2 +- lib/classes/utils.dart | 10 ++++++++ .../dynamic_screens/dynamic_input_screen.dart | 23 +++++++++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index b065816..45ec0a4 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -90,7 +90,7 @@ class AppState { String get getHuaweiPushToken => _huaweiPushToken; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 33, versionID: 4.6, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.6, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index 34831c2..9c55375 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -401,4 +401,14 @@ class Utils { } return false; } + static bool isDate(String input, String format) { + try { + DateTime d = DateFormat(format).parseStrict(input); + //print(d); + return true; + } catch (e) { + //print(e); + return false; + } + } } diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart index a6ffcf1..b780589 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -339,12 +339,27 @@ class _DynamicInputScreenState extends State { } idColName = val; + // if (getEitDffStructureList![j].fORMATTYPE == "X") { + // idColName = Utils.formatDateDefault(idColName!); + // // commenting to test + // // DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!); + // // idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date); + // + // } if (getEitDffStructureList![j].fORMATTYPE == "X") { - idColName = Utils.formatDateDefault(idColName!); - // commenting to test - // DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!); - // idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date); + idColName = Utils.reverseFormatDate(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")){ + + + // // change date format on 31/05/2023 + DateTime date = DateFormat('dd-MM-yyyy').parse(idColName!); + idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date); + + } } } -- 2.30.2 From e39526b5ebef81d61c70bf34cc9cc125c134b295 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 9 Aug 2023 11:41:48 +0300 Subject: [PATCH 4/9] Updates & fixes --- lib/app_state/app_state.dart | 2 +- lib/classes/notifications.dart | 5 +- lib/extensions/int_extensions.dart | 2 - lib/ui/login/login_screen.dart | 1 + lib/widgets/location/Location.dart | 9 -- lib/widgets/mark_attendance_widget.dart | 174 ++++++++++++++++-------- pubspec.yaml | 29 ++-- 7 files changed, 135 insertions(+), 87 deletions(-) diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index f59994c..b0c93ee 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -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; diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index 47d4acd..8f432d7 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -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 initTokenStream(Function loginCallback) async { huawei_push.Push.getTokenStream.listen(_onTokenEvent, onError: _onTokenError).onData((data) { diff --git a/lib/extensions/int_extensions.dart b/lib/extensions/int_extensions.dart index 16bdd29..f46d5bb 100644 --- a/lib/extensions/int_extensions.dart +++ b/lib/extensions/int_extensions.dart @@ -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()); - - } diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 3293e43..5d83fe9 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -103,6 +103,7 @@ class _LoginScreenState extends State { try { if (!(await Utils.isGoogleServicesAvailable())) { print("HUAWEI APPPP GALLERYYYY!!!!"); + AppNotifications().init(firebaseToken, context); AppState().setIsHuawei = true; AppNotifications().initHuaweiPush(checkLoginInfo); } else { diff --git a/lib/widgets/location/Location.dart b/lib/widgets/location/Location.dart index e324618..67d3cdd 100644 --- a/lib/widgets/location/Location.dart +++ b/lib/widgets/location/Location.dart @@ -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 } diff --git a/lib/widgets/mark_attendance_widget.dart b/lib/widgets/mark_attendance_widget.dart index dfb4357..982e316 100644 --- a/lib/widgets/mark_attendance_widget.dart +++ b/lib/widgets/mark_attendance_widget.dart @@ -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 { } 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 requestPermissions() async { @@ -134,11 +167,11 @@ class _MarkAttendanceWidgetState extends State { 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 { 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 { 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 { ); } - 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 locationRequestList = [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 _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); diff --git a/pubspec.yaml b/pubspec.yaml index bc70be9..d154f9f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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 -- 2.30.2 From 5098aa7f901d3114b7ef5b602eabf0b6599759ae Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 10 Aug 2023 14:20:47 +0300 Subject: [PATCH 5/9] my docs upload fix --- android/gradle/wrapper/gradle-wrapper.properties | 2 +- lib/ui/screens/my_documents/my_documents_fragment.dart | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index ed1a787..2f8758c 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -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 \ No newline at end of file diff --git a/lib/ui/screens/my_documents/my_documents_fragment.dart b/lib/ui/screens/my_documents/my_documents_fragment.dart index 89ad69d..e1be0a4 100644 --- a/lib/ui/screens/my_documents/my_documents_fragment.dart +++ b/lib/ui/screens/my_documents/my_documents_fragment.dart @@ -75,8 +75,11 @@ class _MyDocumentsFragmentState extends State { 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 { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ title.toText10(), - value.toText20(isBold: true, color: color), + value.toText18(isBold: true, color: color), ], ), ).onPress(() { -- 2.30.2 From 333dba37777c2ba4633ae7f3d5d4ee2f0c933eee Mon Sep 17 00:00:00 2001 From: Sultan khan <> Date: Thu, 24 Aug 2023 17:12:21 +0300 Subject: [PATCH 6/9] business mission issue fixed. --- .../dynamic_screens/dynamic_input_screen.dart | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart index b780589..ea9d0a4 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -532,11 +532,20 @@ class _DynamicInputScreenState extends State { isEnable: false, 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 (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); String dateString = date.toString().split(' ').first; -- 2.30.2 From a48d70364296b63cffbaba2bc7a770ae0650ddf5 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 24 Aug 2023 18:19:46 +0300 Subject: [PATCH 7/9] ITG ADs update --- lib/api/dashboard_api_client.dart | 2 +- lib/classes/consts.dart | 4 +- lib/models/itg/advertisement.dart | 220 +++++++++++------- lib/models/itg/survey_model.dart | 30 +-- .../itg_forms_models/itg_request_model.dart | 2 +- lib/ui/landing/dashboard_screen.dart | 2 +- .../itg/its_add_screen_video_image.dart | 127 +++++++--- 7 files changed, 243 insertions(+), 144 deletions(-) diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index 544ba71..77cc37d 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -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 postParams = { diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 45ef661..32b3fc7 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - static String baseUrl = "https://hmgwebservices.com"; // Live server + static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + // static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; diff --git a/lib/models/itg/advertisement.dart b/lib/models/itg/advertisement.dart index 96f4037..ebcf704 100644 --- a/lib/models/itg/advertisement.dart +++ b/lib/models/itg/advertisement.dart @@ -1,108 +1,156 @@ class Advertisement { + int? advertisementId; + String? advertisementTitle; + int? durationInSeconds; + bool? showDelete; + dynamic acknowledgment; + late bool isOptional; + List? viewAttachFileColl; + int? skipButtonId; + List? 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; - 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 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.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 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 = []; + json['viewAttachFileColl'].forEach((v) { + viewAttachFileColl!.add(ViewAttachFileColl.fromJson(v)); + }); + } + skipButtonId = json['skipButtonId']; + if (json['actionButtonsColl'] != null) { + actionButtonsColl = []; + json['actionButtonsColl'].forEach((v) { + actionButtonsColl!.add(ActionButtonsColl.fromJson(v)); + }); + } + isActive = json['isActive']; + pageSize = json['pageSize']; + pageNo = json['pageNo']; + languageId = json['languageId']; + } - Map 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.from(viewAttachFileColl!.map((x) => x.toJson())), - "isActive": isActive == null ? null : isActive, - "pageSize": pageSize, - "pageNo": pageNo, - "languageId": languageId, - }; + Map toJson() { + Map data = Map(); + 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 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 toJson() { + Map data = new Map(); + 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 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 json) { + actionButtonId = json['actionButtonId']; + btnTextEn = json['btnTextEn']; + btnTextAr = json['btnTextAr']; + actionValue = json['actionValue']; + iconOrImage = json['iconOrImage']; + orderNo = json['orderNo']; + } - Map 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 toJson() { + Map data = new Map(); + 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; + } } diff --git a/lib/models/itg/survey_model.dart b/lib/models/itg/survey_model.dart index 7cdbbdd..f9ac415 100644 --- a/lib/models/itg/survey_model.dart +++ b/lib/models/itg/survey_model.dart @@ -5,9 +5,9 @@ class SurveyModel { String? description; List? 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; - 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}); diff --git a/lib/models/itg_forms_models/itg_request_model.dart b/lib/models/itg_forms_models/itg_request_model.dart index ba10305..87d8280 100644 --- a/lib/models/itg_forms_models/itg_request_model.dart +++ b/lib/models/itg_forms_models/itg_request_model.dart @@ -6,7 +6,7 @@ class ITGRequest { List? allowedActions; List? attachments; List? fieldGoups; - Null? grantFields; + dynamic grantFields; List? wFHistory; ITGRequest({this.allowedActions, this.attachments, this.fieldGoups, this.grantFields, this.wFHistory}); diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 2db09d0..4116594 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -163,7 +163,7 @@ class _DashboardScreenState extends State 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); diff --git a/lib/ui/landing/itg/its_add_screen_video_image.dart b/lib/ui/landing/itg/its_add_screen_video_image.dart index 1e280d8..8ce89d0 100644 --- a/lib/ui/landing/itg/its_add_screen_video_image.dart +++ b/lib/ui/landing/itg/its_add_screen_video_image.dart @@ -61,6 +61,11 @@ class _ITGAdsScreenState extends State { 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 { 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( 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 { -- 2.30.2 From ed9705f18f424f300eb1ca164d93cbc34a83b9af Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 3 Sep 2023 09:56:24 +0300 Subject: [PATCH 8/9] fixes --- lib/generated/codegen_loader.g.dart | 3 +-- lib/ui/work_list/worklist_fragments/info_fragments.dart | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 1daf8f7..1e2d5af 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -1098,8 +1098,7 @@ static const Map en_US = { "allDocuments": "All\nDocuments", "expiredDocuments": "Expired\nDocuments", "missingDocuments": "Missing\nDocuments", - "uploadedDocuments": "Uploaded\nDocuments" - "resetAdPassword": "Reset AD Password", + "uploadedDocuments": "Uploaded\nDocuments", "manage": "Manage", "members": "Members", "areYouSureWantTodelete": "Are you sure want to delete?", diff --git a/lib/ui/work_list/worklist_fragments/info_fragments.dart b/lib/ui/work_list/worklist_fragments/info_fragments.dart index d2c64f3..5edb6f1 100644 --- a/lib/ui/work_list/worklist_fragments/info_fragments.dart +++ b/lib/ui/work_list/worklist_fragments/info_fragments.dart @@ -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 ?? ""), -- 2.30.2 From 281f0bab7885f2f1e1c2a7c7fac04566878d0552 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 20 Sep 2023 09:27:08 +0300 Subject: [PATCH 9/9] updates --- ios/Runner/Info.plist | 1 - lib/provider/chat_provider_model.dart | 2 +- lib/ui/chat/chat_home.dart | 4 ++-- lib/ui/marathon/marathon_screen.dart | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 24ba08c..cb62b88 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -65,7 +65,6 @@ fetch remote-notification - voip UILaunchStoryboardName LaunchScreen diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index 824a19f..00545b2 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -168,7 +168,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future getUserRecentChats() async { ChatUserModel recentChat = await ChatApiClient().getRecentChats(); ChatUserModel favUList = await ChatApiClient().getFavUsers(); - userGroups = await ChatApiClient().getGroupsByUserId(); + // userGroups = await ChatApiClient().getGroupsByUserId(); if (favUList.response != null && recentChat.response != null) { favUsersList = favUList.response!; favUsersList.sort((ChatUser a, ChatUser b) => diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index dc4265f..426c9a2 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -91,7 +91,7 @@ class _ChatHomeState extends State { child: Row( children: [ myTab(LocaleKeys.mychats.tr(), 0), - myTab(LocaleKeys.group.tr(), 1), + // myTab(LocaleKeys.group.tr(), 1), myTab(LocaleKeys.favorite.tr(), 2), AppState().getempStatusIsManager ? myTab(LocaleKeys.myTeam.tr(), 3) : const SizedBox(), ], @@ -107,7 +107,7 @@ class _ChatHomeState extends State { }, children: [ ChatHomeScreen(), - GropChatHomeScreen(), + // GropChatHomeScreen(), ChatFavoriteUsersScreen(), AppState().getempStatusIsManager ? const MyTeamScreen() : const SizedBox(), ], diff --git a/lib/ui/marathon/marathon_screen.dart b/lib/ui/marathon/marathon_screen.dart index 6dbbd18..d5fc8c4 100644 --- a/lib/ui/marathon/marathon_screen.dart +++ b/lib/ui/marathon/marathon_screen.dart @@ -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, -- 2.30.2